Skip to content

Commit

Permalink
refactor(client): factorize some code that allow patching eslint conf…
Browse files Browse the repository at this point in the history
…ig, ts config and vitest config
  • Loading branch information
murdos committed Jan 26, 2025
1 parent d36f451 commit 6c956d7
Show file tree
Hide file tree
Showing 8 changed files with 131 additions and 63 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package tech.jhipster.lite.generator.client.react.core.domain;

import static tech.jhipster.lite.generator.typescript.common.domain.EslintShortcuts.eslintTypescriptRule;
import static tech.jhipster.lite.generator.typescript.common.domain.TsConfigShortcuts.tsConfigCompilerOption;
import static tech.jhipster.lite.generator.typescript.common.domain.VitestShortcuts.vitestCoverageExclusion;
import static tech.jhipster.lite.module.domain.JHipsterModule.JHipsterModuleBuilder;
import static tech.jhipster.lite.module.domain.JHipsterModule.LINE_BREAK;
import static tech.jhipster.lite.module.domain.JHipsterModule.from;
Expand All @@ -19,13 +22,11 @@
import static tech.jhipster.lite.module.domain.replacement.ReplacementCondition.always;

import java.util.function.Consumer;
import tech.jhipster.lite.module.domain.Indentation;
import tech.jhipster.lite.module.domain.JHipsterModule;
import tech.jhipster.lite.module.domain.file.JHipsterDestination;
import tech.jhipster.lite.module.domain.file.JHipsterSource;
import tech.jhipster.lite.module.domain.npm.NpmLazyInstaller;
import tech.jhipster.lite.module.domain.properties.JHipsterModuleProperties;
import tech.jhipster.lite.module.domain.replacement.MandatoryReplacer;

public class ReactCoreModulesFactory {

Expand Down Expand Up @@ -142,10 +143,6 @@ private Consumer<JHipsterModuleBuilder> patchEslintConfig(JHipsterModuleProperti
.add(
regex("[ \\t]+quotes: \\['error', 'single', \\{ avoidEscape: true }],"),
"""
\t\t\t'react/react-in-jsx-scope': 'off',
\t\t\t'@typescript-eslint/no-explicit-any': 'off',
\t\t\t'@typescript-eslint/await-thenable': 'off',
\t\t\t'@typescript-eslint/consistent-type-imports': 'error',
\t\t\t'@typescript-eslint/no-misused-promises': [
\t\t\t\t'error',
\t\t\t\t{
Expand All @@ -155,7 +152,11 @@ private Consumer<JHipsterModuleBuilder> patchEslintConfig(JHipsterModuleProperti
""".replace("\t", properties.indentation().spaces())
)
.and()
.and();
.and()
.apply(eslintTypescriptRule("'@typescript-eslint/consistent-type-imports': 'error'", properties.indentation()))
.apply(eslintTypescriptRule("'@typescript-eslint/await-thenable': 'off'", properties.indentation()))
.apply(eslintTypescriptRule("'@typescript-eslint/no-explicit-any': 'off'", properties.indentation()))
.apply(eslintTypescriptRule("'react/react-in-jsx-scope': 'off'", properties.indentation()));
//@formatter:on
}

Expand All @@ -167,20 +168,15 @@ private Consumer<JHipsterModuleBuilder> patchTsConfig(JHipsterModuleProperties p
.mandatoryReplacements()
.in(path("tsconfig.json"))
.add(text("@tsconfig/recommended/tsconfig.json"), "@tsconfig/vite-react/tsconfig.json")
.add(tsConfigCompilerOption("composite", false, properties.indentation()))
.add(tsConfigCompilerOption("forceConsistentCasingInFileNames", true, properties.indentation()))
.add(tsConfigCompilerOption("allowSyntheticDefaultImports", true, properties.indentation()))
.add(text(DEFAULT_TSCONFIG_PATH), pathsReplacement)
.and()
.and();
.and()
.apply(tsConfigCompilerOption("composite", false, properties.indentation()))
.apply(tsConfigCompilerOption("forceConsistentCasingInFileNames", true, properties.indentation()))
.apply(tsConfigCompilerOption("allowSyntheticDefaultImports", true, properties.indentation()));
//@formatter:on
}

private static MandatoryReplacer tsConfigCompilerOption(String optionName, boolean optionValue, Indentation indentation) {
String compilerOption = indentation.times(2) + "\"%s\": %s,".formatted(optionName, optionValue);
return new MandatoryReplacer(lineAfterRegex("\"compilerOptions\":"), compilerOption);
}

private Consumer<JHipsterModuleBuilder> patchVitestConfig(JHipsterModuleProperties properties) {
//@formatter:off
return moduleBuilder -> moduleBuilder
Expand All @@ -189,16 +185,10 @@ private Consumer<JHipsterModuleBuilder> patchVitestConfig(JHipsterModuleProperti
.add(lineAfterRegex("from 'vitest/config';"), "import react from '@vitejs/plugin-react';")
.add(text("plugins: ["), "plugins: [react(), ")
.add(text("environment: 'node',"), "environment: 'jsdom',")
.add(vitestCoverageExclusion("src/main/webapp/app/index.tsx"))
.add(vitestCoverageExclusion("src/main/webapp/app/injections.ts"))
.and();
.and()
.and()
.apply(vitestCoverageExclusion("src/main/webapp/app/index.tsx"))
.apply(vitestCoverageExclusion("src/main/webapp/app/injections.ts"));
//@formatter:on
}

private static MandatoryReplacer vitestCoverageExclusion(String filePattern) {
return new MandatoryReplacer(
text("(configDefaults.coverage.exclude as string[])"),
"(configDefaults.coverage.exclude as string[])" + ", '%s'".formatted(filePattern)
);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package tech.jhipster.lite.generator.client.react.i18n.domain;

import static tech.jhipster.lite.generator.typescript.common.domain.VitestShortcuts.vitestCoverageExclusion;
import static tech.jhipster.lite.module.domain.JHipsterModule.LINE_BREAK;
import static tech.jhipster.lite.module.domain.JHipsterModule.append;
import static tech.jhipster.lite.module.domain.JHipsterModule.from;
Expand Down Expand Up @@ -75,10 +76,8 @@ public JHipsterModule buildModule(JHipsterModuleProperties properties) {
});
});""" )
.and()
.in(path("./vitest.config.ts"))
.add(lineAfterText("'src/main/webapp/app/index.tsx',"), properties.indentation().times(4) + "'src/main/webapp/app/i18n.ts',")
.and()
.and()
.apply(vitestCoverageExclusion("src/main/webapp/app/i18n.ts"))
.build();
//@formatter:off
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package tech.jhipster.lite.generator.client.vue.core.domain;

import static tech.jhipster.lite.generator.typescript.common.domain.EslintShortcuts.eslintTypescriptRule;
import static tech.jhipster.lite.generator.typescript.common.domain.TsConfigShortcuts.tsConfigCompilerOption;
import static tech.jhipster.lite.generator.typescript.common.domain.VitestShortcuts.vitestCoverageExclusion;
import static tech.jhipster.lite.module.domain.JHipsterModule.JHipsterModuleBuilder;
import static tech.jhipster.lite.module.domain.JHipsterModule.documentationTitle;
import static tech.jhipster.lite.module.domain.JHipsterModule.from;
Expand All @@ -18,13 +21,11 @@
import static tech.jhipster.lite.module.domain.npm.JHLiteNpmVersionSource.VUE;

import java.util.function.Consumer;
import tech.jhipster.lite.module.domain.Indentation;
import tech.jhipster.lite.module.domain.JHipsterModule;
import tech.jhipster.lite.module.domain.file.JHipsterDestination;
import tech.jhipster.lite.module.domain.file.JHipsterSource;
import tech.jhipster.lite.module.domain.npm.NpmLazyInstaller;
import tech.jhipster.lite.module.domain.properties.JHipsterModuleProperties;
import tech.jhipster.lite.module.domain.replacement.MandatoryReplacer;
import tech.jhipster.lite.shared.error.domain.Assert;

public class VueModulesFactory {
Expand Down Expand Up @@ -122,7 +123,7 @@ public JHipsterModule buildVueModule(JHipsterModuleProperties properties) {
.and()
.apply(patchEslintConfig(properties))
.apply(patchTsConfig(properties))
.apply(patchVitestConfig(properties))
.apply(patchVitestConfig())
.build();
//@formatter:on
}
Expand All @@ -146,61 +147,46 @@ private Consumer<JHipsterModuleBuilder> patchEslintConfig(JHipsterModuleProperti
.add(lineAfterRegex("from '@eslint/js'"), "import vue from 'eslint-plugin-vue';")
.add(lineAfterRegex("...typescript.configs.recommended"), vuePluginConfig)
.add(text("files: ['src/*/webapp/**/*.ts']"), "files: ['src/*/webapp/**/*.vue', 'src/*/webapp/**/*.ts']")
.add(eslintTypescriptVueRule("'vue/html-self-closing': 'off',", properties.indentation()))
.add(eslintTypescriptVueRule("'@typescript-eslint/no-explicit-any': 'off',", properties.indentation()))
.add(eslintTypescriptVueRule("'@typescript-eslint/no-empty-object-type': 'off',", properties.indentation()))
.add(eslintTypescriptVueRule("'@typescript-eslint/consistent-type-imports': 'error',", properties.indentation()))
.and()
.and();
.and()
.apply(eslintTypescriptRule("'vue/html-self-closing': 'off'", properties.indentation()))
.apply(eslintTypescriptRule("'@typescript-eslint/no-explicit-any': 'off'", properties.indentation()))
.apply(eslintTypescriptRule("'@typescript-eslint/no-empty-object-type': 'off'", properties.indentation()))
.apply(eslintTypescriptRule("'@typescript-eslint/consistent-type-imports': 'error'", properties.indentation()));
//@formatter:on
}

private static MandatoryReplacer eslintTypescriptVueRule(String rule, Indentation indentation) {
return new MandatoryReplacer(lineAfterRegex("quotes: \\['error', 'single'"), indentation.times(3) + rule);
}

private Consumer<JHipsterModuleBuilder> patchTsConfig(JHipsterModuleProperties properties) {
//@formatter:off
return moduleBuilder -> moduleBuilder
.mandatoryReplacements()
.in(path("tsconfig.json"))
.add(text("@tsconfig/recommended/tsconfig.json"), "@vue/tsconfig/tsconfig.dom.json")
.add(tsConfigCompilerOption("sourceMap", true, properties.indentation()))
.add(tsConfigCompilerOption("allowJs", true, properties.indentation()))
.add(text("\"types\": ["), "\"types\": [\"vite/client\", ")
.and()
.and();
.and()
.apply(tsConfigCompilerOption("sourceMap", true, properties.indentation()))
.apply(tsConfigCompilerOption("allowJs", true, properties.indentation()));
//@formatter:on
}

private static MandatoryReplacer tsConfigCompilerOption(String optionName, boolean optionValue, Indentation indentation) {
String compilerOption = indentation.times(2) + "\"%s\": %s,".formatted(optionName, optionValue);
return new MandatoryReplacer(lineAfterRegex("\"compilerOptions\":"), compilerOption);
}

private Consumer<JHipsterModuleBuilder> patchVitestConfig(JHipsterModuleProperties properties) {
private Consumer<JHipsterModuleBuilder> patchVitestConfig() {
//@formatter:off
return moduleBuilder -> moduleBuilder
.mandatoryReplacements()
.in(path("vitest.config.ts"))
.add(lineAfterRegex("from 'vitest/config';"), "import vue from '@vitejs/plugin-vue';")
.add(text("plugins: ["), "plugins: [vue(), ")
.add(text("environment: 'node',"), "environment: 'jsdom',")
.add(vitestCoverageExclusion("src/main/webapp/**/*.component.ts"))
.add(vitestCoverageExclusion("src/main/webapp/app/router.ts"))
.add(vitestCoverageExclusion("src/main/webapp/app/injections.ts"))
.add(vitestCoverageExclusion("src/main/webapp/app/main.ts"))
.and();
.and()
.and()
.apply(vitestCoverageExclusion("src/main/webapp/**/*.component.ts"))
.apply(vitestCoverageExclusion("src/main/webapp/app/router.ts"))
.apply(vitestCoverageExclusion("src/main/webapp/app/injections.ts"))
.apply(vitestCoverageExclusion("src/main/webapp/app/main.ts"));
//@formatter:on
}

private static MandatoryReplacer vitestCoverageExclusion(String filePattern) {
return new MandatoryReplacer(
text("(configDefaults.coverage.exclude as string[])"),
"(configDefaults.coverage.exclude as string[])" + ", '" + filePattern + "'"
);
}

public JHipsterModule buildPiniaModule(JHipsterModuleProperties properties) {
Assert.notNull("properties", properties);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package tech.jhipster.lite.generator.typescript.common.domain;

import static tech.jhipster.lite.module.domain.JHipsterModule.lineAfterRegex;
import static tech.jhipster.lite.module.domain.JHipsterModule.path;

import java.util.function.Consumer;
import tech.jhipster.lite.module.domain.Indentation;
import tech.jhipster.lite.module.domain.JHipsterModule;
import tech.jhipster.lite.module.domain.replacement.MandatoryReplacer;

public final class EslintShortcuts {

private EslintShortcuts() {}

public static Consumer<JHipsterModule.JHipsterModuleBuilder> eslintTypescriptRule(String rule, Indentation indentation) {
//@formatter:off
return moduleBuilder -> moduleBuilder
.mandatoryReplacements()
.in(path("eslint.config.js"))
.add(eslintTypescriptVueRuleReplacement(rule, indentation))
.and()
.and();
//@formatter:on
}

private static MandatoryReplacer eslintTypescriptVueRuleReplacement(String rule, Indentation indentation) {
return new MandatoryReplacer(lineAfterRegex("rules: \\{"), indentation.times(3) + rule + ",");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package tech.jhipster.lite.generator.typescript.common.domain;

import static tech.jhipster.lite.module.domain.JHipsterModule.lineAfterRegex;
import static tech.jhipster.lite.module.domain.JHipsterModule.path;

import java.util.function.Consumer;
import tech.jhipster.lite.module.domain.Indentation;
import tech.jhipster.lite.module.domain.JHipsterModule;
import tech.jhipster.lite.module.domain.replacement.MandatoryReplacer;

public final class TsConfigShortcuts {

private TsConfigShortcuts() {}

public static Consumer<JHipsterModule.JHipsterModuleBuilder> tsConfigCompilerOption(
String optionName,
boolean optionValue,
Indentation indentation
) {
//@formatter:off
return moduleBuilder -> moduleBuilder
.mandatoryReplacements()
.in(path("tsconfig.json"))
.add(tsConfigCompilerOptionReplacement(optionName, optionValue, indentation))
.and();
//@formatter:on
}

private static MandatoryReplacer tsConfigCompilerOptionReplacement(String optionName, boolean optionValue, Indentation indentation) {
String compilerOption = indentation.times(2) + "\"%s\": %s,".formatted(optionName, optionValue);
return new MandatoryReplacer(lineAfterRegex("\"compilerOptions\":"), compilerOption);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package tech.jhipster.lite.generator.typescript.common.domain;

import static tech.jhipster.lite.module.domain.JHipsterModule.path;
import static tech.jhipster.lite.module.domain.JHipsterModule.text;

import java.util.function.Consumer;
import tech.jhipster.lite.module.domain.JHipsterModule;
import tech.jhipster.lite.module.domain.replacement.MandatoryReplacer;

public final class VitestShortcuts {

private VitestShortcuts() {}

public static Consumer<JHipsterModule.JHipsterModuleBuilder> vitestCoverageExclusion(String exclusionFilePattern) {
//@formatter:off
return moduleBuilder -> moduleBuilder
.mandatoryReplacements()
.in(path("vitest.config.ts"))
.add(vitestCoverageExclusionReplacement(exclusionFilePattern));
//@formatter:on
}

private static MandatoryReplacer vitestCoverageExclusionReplacement(String filePattern) {
return new MandatoryReplacer(
text("(configDefaults.coverage.exclude as string[])"),
"(configDefaults.coverage.exclude as string[])" + ", '%s'".formatted(filePattern)
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
@tech.jhipster.lite.SharedKernel
package tech.jhipster.lite.generator.typescript.common;
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,11 @@ export default typescript.config(
globals: { ...globals.browser },
},
rules: {
quotes: ['error', 'single', { avoidEscape: true }],
'@typescript-eslint/consistent-type-imports': 'error',
'@typescript-eslint/no-empty-object-type': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'vue/html-self-closing': 'off',
quotes: ['error', 'single', { avoidEscape: true }],
},
},
);

0 comments on commit 6c956d7

Please sign in to comment.