From 6edfacdd3a9377194eeb5895c5ee816bce31c11c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Mino?= Date: Fri, 13 Sep 2024 23:27:14 +0200 Subject: [PATCH 01/15] feat: vue-core now depends on typescript module --- .../vue/core/infrastructure/primary/VueModuleConfiguration.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/tech/jhipster/lite/generator/client/vue/core/infrastructure/primary/VueModuleConfiguration.java b/src/main/java/tech/jhipster/lite/generator/client/vue/core/infrastructure/primary/VueModuleConfiguration.java index 0b5baf0fac7..412fe160780 100644 --- a/src/main/java/tech/jhipster/lite/generator/client/vue/core/infrastructure/primary/VueModuleConfiguration.java +++ b/src/main/java/tech/jhipster/lite/generator/client/vue/core/infrastructure/primary/VueModuleConfiguration.java @@ -19,7 +19,7 @@ JHipsterModuleResource vueCoreModule(VueApplicationService vue) { .slug(VUE_CORE) .propertiesDefinition(JHipsterModulePropertiesDefinition.builder().addIndentation().build()) .apiDoc("Frontend - Vue", "Add Vue+Vite") - .organization(JHipsterModuleOrganization.builder().feature(CLIENT_CORE).addDependency(INIT).addDependency(PRETTIER).build()) + .organization(JHipsterModuleOrganization.builder().feature(CLIENT_CORE).addDependency(TYPESCRIPT).addDependency(PRETTIER).build()) .tags("client", "init", "vue") .factory(vue::buildVueModule); } From 7bfd3c6311f1ff03c4e44e69fff872a3fbf3d89a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Mino?= Date: Fri, 13 Sep 2024 23:27:40 +0200 Subject: [PATCH 02/15] fix: avoid duplicated type in package.json --- .../lite/generator/client/vue/core/domain/VueModulesFactory.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactory.java b/src/main/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactory.java index 19ba80b4523..8bc4c18d562 100644 --- a/src/main/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactory.java +++ b/src/main/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactory.java @@ -42,7 +42,6 @@ public JHipsterModule buildVueModule(JHipsterModuleProperties properties) { .preCommitActions(stagedFilesFilter("{src/**/,}*.{ts,vue}"), preCommitCommands("eslint --fix", "prettier --write")) .documentation(documentationTitle("Vue"), DOCUMENTATION_SOURCE.file("vue.md")) .packageJson() - .type(MODULE) .addDependency(packageName("vue"), VUE) .addDependency(packageName("axios"), VUE) .addDependency(packageName("vue-router"), VUE) From e6d21a48cbd78c35c41691f137891512442ba083 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Mino?= Date: Sat, 14 Sep 2024 18:58:58 +0200 Subject: [PATCH 03/15] chore: remove now redundant dependencies and scripts in vue-core, already declared in typescript module --- .../vue/core/domain/VueModulesFactory.java | 18 +----------------- .../vue/core/domain/VueModulesFactoryTest.java | 18 +----------------- 2 files changed, 2 insertions(+), 34 deletions(-) diff --git a/src/main/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactory.java b/src/main/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactory.java index 8bc4c18d562..375ee3107fe 100644 --- a/src/main/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactory.java +++ b/src/main/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactory.java @@ -45,40 +45,24 @@ public JHipsterModule buildVueModule(JHipsterModuleProperties properties) { .addDependency(packageName("vue"), VUE) .addDependency(packageName("axios"), VUE) .addDependency(packageName("vue-router"), VUE) - .addDevDependency(packageName("@typescript-eslint/parser"), COMMON) .addDevDependency(packageName("@vitejs/plugin-vue"), VUE) - .addDevDependency(packageName("typescript-eslint"), COMMON) - .addDevDependency(packageName("globals"), COMMON) .addDevDependency(packageName("@vue/test-utils"), VUE) .addDevDependency(packageName("@vue/tsconfig"), VUE) - .addDevDependency(packageName("@vitest/coverage-istanbul"), COMMON) - .addDevDependency(packageName("eslint"), COMMON) - .addDevDependency(packageName("eslint-config-prettier"), COMMON) .addDevDependency(packageName("eslint-plugin-vue"), VUE) .addDevDependency(packageName("jsdom"), COMMON) - .addDevDependency(packageName("typescript"), COMMON) .addDevDependency(packageName("vite"), COMMON) - .addDevDependency(packageName("vite-tsconfig-paths"), COMMON) - .addDevDependency(packageName("vitest"), COMMON) - .addDevDependency(packageName("vitest-sonar-reporter"), COMMON) .addDevDependency(packageName("vue-tsc"), VUE) .addDevDependency(packageName("@types/sinon"), VUE) .addDevDependency(packageName("sinon"), VUE) - .addDevDependency(packageName("npm-run-all2"), COMMON) + .addDevDependency(packageName("piqure"), VUE) .addScript(scriptKey("build"), scriptCommand("npm-run-all build:*")) .addScript(scriptKey("build:tsc"), scriptCommand("vue-tsc -p tsconfig.build.json --noEmit")) .addScript(scriptKey("build:vite"), scriptCommand("vite build --emptyOutDir")) .addScript(scriptKey("dev"), scriptCommand("npm-run-all --parallel dev:*")) .addScript(scriptKey("dev:vite"), scriptCommand("vite")) - .addScript(scriptKey("watch"), scriptCommand("npm-run-all --parallel watch:*")) - .addDevDependency(packageName("piqure"), VUE) - .addScript(scriptKey("lint"), scriptCommand("eslint .")) .addScript(scriptKey("preview"), scriptCommand("vite preview")) .addScript(scriptKey("start"), scriptCommand("vite")) .addScript(scriptKey("watch:tsc"), scriptCommand("npm run build:tsc -- --watch")) - .addScript(scriptKey("test"), scriptCommand("npm run watch:test")) - .addScript(scriptKey("watch:test"), scriptCommand("vitest --")) - .addScript(scriptKey("test:coverage"), scriptCommand("vitest run --coverage")) .and() .files() .add(SOURCE.template("eslint.config.js.mustache"), to("eslint.config.js")) diff --git a/src/test/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactoryTest.java b/src/test/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactoryTest.java index 0c753d47ad6..7a1f47f6052 100644 --- a/src/test/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactoryTest.java +++ b/src/test/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactoryTest.java @@ -28,42 +28,26 @@ void shouldCreateVueModule() { .hasFiles("documentation/vue.md") .hasFile("package.json") .containing(nodeDependency("vue")) - .containing(nodeDependency("@typescript-eslint/parser")) .containing(nodeDependency("@vitejs/plugin-vue")) - .containing(nodeDependency("typescript-eslint")) - .containing(nodeDependency("globals")) .containing(nodeDependency("@vue/test-utils")) .containing(nodeDependency("@vue/tsconfig")) - .containing(nodeDependency("@vitest/coverage-istanbul")) - .containing(nodeDependency("eslint")) - .containing(nodeDependency("eslint-config-prettier")) .containing(nodeDependency("eslint-plugin-vue")) .containing(nodeDependency("jsdom")) - .containing(nodeDependency("typescript")) .containing(nodeDependency("vite")) - .containing(nodeDependency("vite-tsconfig-paths")) - .containing(nodeDependency("vitest")) - .containing(nodeDependency("vitest-sonar-reporter")) .containing(nodeDependency("vue-tsc")) .containing(nodeDependency("@types/sinon")) .containing(nodeDependency("sinon")) .containing(nodeDependency("axios")) .containing(nodeDependency("vue-router")) - .containing(nodeDependency("npm-run-all2")) + .containing(nodeDependency("piqure")) .containing(nodeScript("build", "npm-run-all build:*")) .containing(nodeScript("build:tsc", "vue-tsc -p tsconfig.build.json --noEmit")) .containing(nodeScript("build:vite", "vite build --emptyOutDir")) .containing(nodeScript("dev", "npm-run-all --parallel dev:*")) .containing(nodeScript("dev:vite", "vite")) - .containing(nodeScript("watch", "npm-run-all --parallel watch:*")) .containing(nodeScript("watch:tsc", "npm run build:tsc -- --watch")) - .containing(nodeScript("watch:test", "vitest --")) - .containing(nodeDependency("piqure")) - .containing(nodeScript("lint", "eslint .")) .containing(nodeScript("preview", "vite preview")) .containing(nodeScript("start", "vite")) - .containing(nodeScript("test", "npm run watch:test")) - .containing(nodeScript("test:coverage", "vitest run --coverage")) .and() .hasFile(".lintstagedrc.cjs") .containing( From 10bec12a8ddbab49614fba3086d39152bbc79b0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Mino?= Date: Sat, 14 Sep 2024 20:34:25 +0200 Subject: [PATCH 04/15] feat(vue): patch tsconfig.json from typescript module rather than overwriting it --- .../vue/core/domain/VueModulesFactory.java | 17 ++++++++++-- .../generator/client/vue/tsconfig.json | 13 ---------- .../core/domain/VueModulesFactoryTest.java | 26 +++++++++++++++++-- .../secondary/JHipsterModulesAssertions.java | 4 +++ 4 files changed, 43 insertions(+), 17 deletions(-) delete mode 100644 src/main/resources/generator/client/vue/tsconfig.json diff --git a/src/main/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactory.java b/src/main/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactory.java index 375ee3107fe..cba36d1b9bc 100644 --- a/src/main/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactory.java +++ b/src/main/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactory.java @@ -1,14 +1,16 @@ package tech.jhipster.lite.generator.client.vue.core.domain; import static tech.jhipster.lite.module.domain.JHipsterModule.*; -import static tech.jhipster.lite.module.domain.packagejson.NodeModuleFormat.MODULE; import static tech.jhipster.lite.module.domain.packagejson.VersionSource.COMMON; import static tech.jhipster.lite.module.domain.packagejson.VersionSource.VUE; +import static tech.jhipster.lite.module.domain.replacement.ReplacementCondition.notContainingReplacement; +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.properties.JHipsterModuleProperties; +import tech.jhipster.lite.module.domain.replacement.TextReplacer; import tech.jhipster.lite.shared.error.domain.Assert; public class VueModulesFactory { @@ -66,7 +68,6 @@ public JHipsterModule buildVueModule(JHipsterModuleProperties properties) { .and() .files() .add(SOURCE.template("eslint.config.js.mustache"), to("eslint.config.js")) - .add(SOURCE.file("tsconfig.json"), to("tsconfig.json")) .add(SOURCE.file("tsconfig.build.json"), to("tsconfig.build.json")) .batch(SOURCE, to(".")) .addTemplate("vite.config.ts") @@ -98,10 +99,22 @@ public JHipsterModule buildVueModule(JHipsterModuleProperties properties) { .add(APP_SOURCE.template("test/webapp/unit/shared/http/infrastructure/secondary/AxiosStub.ts.mustache"), TEST_DESTINATION.append("unit/shared/http/infrastructure/secondary/AxiosStub.ts")) .add(APP_SOURCE.template("test/webapp/unit/router/infrastructure/primary/HomeRouter.spec.ts.mustache"), TEST_DESTINATION.append("unit/router/infrastructure/primary/HomeRouter.spec.ts")) .and() + .mandatoryReplacements() + .in(path("tsconfig.json")) + .add(text("@tsconfig/recommended/tsconfig.json"), "@vue/tsconfig/tsconfig.dom.json") + .add(lineAfterRegex("\"compilerOptions\":"), compilerOption( "sourceMap", true, properties.indentation())) + .add(lineAfterRegex("\"compilerOptions\":"), compilerOption( "allowJs", true, properties.indentation())) + .add(new TextReplacer(notContainingReplacement(), "\"types\": ["), "\"types\": [\"vite/client\", ") + .and() + .and() .build(); //@formatter:on } + private static String compilerOption(String optionName, boolean optionValue, Indentation indentation) { + return indentation.times(2) + "\"%s\": %s,".formatted(optionName, optionValue); + } + public JHipsterModule buildPiniaModule(JHipsterModuleProperties properties) { Assert.notNull("properties", properties); diff --git a/src/main/resources/generator/client/vue/tsconfig.json b/src/main/resources/generator/client/vue/tsconfig.json deleted file mode 100644 index 6bef65ee0e8..00000000000 --- a/src/main/resources/generator/client/vue/tsconfig.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "extends": "@vue/tsconfig/tsconfig.dom.json", - "compilerOptions": { - "allowJs": true, - "sourceMap": true, - "types": ["vite/client", "vitest/globals"], - "baseUrl": ".", - "paths": { - "@/*": ["src/main/webapp/app/*"] - } - }, - "include": ["src/main/webapp/**/*", "src/test/webapp/unit/**/*"] -} diff --git a/src/test/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactoryTest.java b/src/test/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactoryTest.java index 7a1f47f6052..eda1c00fe6b 100644 --- a/src/test/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactoryTest.java +++ b/src/test/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactoryTest.java @@ -24,7 +24,7 @@ void shouldCreateVueModule() { JHipsterModule module = factory.buildVueModule(properties); //@formatter:off - assertThatModuleWithFiles(module, packageJsonFile(), lintStagedConfigFile()) + assertThatModuleWithFiles(module, packageJsonFile(), lintStagedConfigFile(), tsConfigFile()) .hasFiles("documentation/vue.md") .hasFile("package.json") .containing(nodeDependency("vue")) @@ -59,7 +59,29 @@ void shouldCreateVueModule() { """ ) .and() - .hasPrefixedFiles("", ".npmrc", "eslint.config.js", "tsconfig.json", "tsconfig.build.json", "vite.config.ts", "vitest.config.ts") + .hasPrefixedFiles("", ".npmrc", "eslint.config.js", "tsconfig.build.json", "vite.config.ts", "vitest.config.ts") + .hasFile("tsconfig.json") + .containing("\"extends\": \"@vue/tsconfig/tsconfig.dom.json\"") + .containing("\"allowJs\": true,") + .containing("\"sourceMap\": true,") + .containing("\"types\": [\"vite/client\", ") + .containing(""" + { + "extends": "@vue/tsconfig/tsconfig.dom.json", + "compilerOptions": { + "allowJs": true, + "sourceMap": true, + "types": ["vite/client", "vitest/globals"], + "baseUrl": ".", + "paths": { + "@/*": ["src/main/webapp/app/*"] + } + }, + "include": ["src/main/webapp/**/*", "src/test/webapp/unit/**/*"] + } + """ + ) + .and() .hasFiles("src/main/webapp/app/shared/http/infrastructure/secondary/AxiosHttp.ts") .hasFiles("src/main/webapp/index.html") .hasPrefixedFiles("src/main/webapp/app", "env.d.ts", "AppVue.vue", "injections.ts", "router.ts", "main.ts") diff --git a/src/test/java/tech/jhipster/lite/module/infrastructure/secondary/JHipsterModulesAssertions.java b/src/test/java/tech/jhipster/lite/module/infrastructure/secondary/JHipsterModulesAssertions.java index 1b2dbd1d3b8..215b15714fb 100644 --- a/src/test/java/tech/jhipster/lite/module/infrastructure/secondary/JHipsterModulesAssertions.java +++ b/src/test/java/tech/jhipster/lite/module/infrastructure/secondary/JHipsterModulesAssertions.java @@ -60,6 +60,10 @@ public static ModuleFile lintStagedConfigFile() { return file("src/test/resources/projects/init/.lintstagedrc.cjs", ".lintstagedrc.cjs"); } + public static ModuleFile tsConfigFile() { + return file("src/main/resources/generator/typescript/tsconfig.json", "tsconfig.json"); + } + public static ModuleFile emptyLintStagedConfigFile() { return file("src/test/resources/projects/init/.lintstagedrc.empty.cjs", ".lintstagedrc.cjs"); } From f423b879a2f2283172ec8621e77201598d9a59d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Mino?= Date: Sat, 14 Sep 2024 20:46:44 +0200 Subject: [PATCH 05/15] refactor: introduce an 'apply' method on JHipsterModuleBuilder that allow factorizing/splitting a block of operations on a moduleBuilder --- .../vue/core/domain/VueModulesFactory.java | 16 ++++++-- .../lite/module/domain/JHipsterModule.java | 38 ++++++++----------- 2 files changed, 28 insertions(+), 26 deletions(-) diff --git a/src/main/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactory.java b/src/main/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactory.java index cba36d1b9bc..09c0883b58c 100644 --- a/src/main/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactory.java +++ b/src/main/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactory.java @@ -5,6 +5,7 @@ import static tech.jhipster.lite.module.domain.packagejson.VersionSource.VUE; import static tech.jhipster.lite.module.domain.replacement.ReplacementCondition.notContainingReplacement; +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; @@ -99,15 +100,22 @@ public JHipsterModule buildVueModule(JHipsterModuleProperties properties) { .add(APP_SOURCE.template("test/webapp/unit/shared/http/infrastructure/secondary/AxiosStub.ts.mustache"), TEST_DESTINATION.append("unit/shared/http/infrastructure/secondary/AxiosStub.ts")) .add(APP_SOURCE.template("test/webapp/unit/router/infrastructure/primary/HomeRouter.spec.ts.mustache"), TEST_DESTINATION.append("unit/router/infrastructure/primary/HomeRouter.spec.ts")) .and() + .apply(patchTsConfig(properties)) + .build(); + //@formatter:on + } + + private Consumer 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(lineAfterRegex("\"compilerOptions\":"), compilerOption( "sourceMap", true, properties.indentation())) - .add(lineAfterRegex("\"compilerOptions\":"), compilerOption( "allowJs", true, properties.indentation())) + .add(lineAfterRegex("\"compilerOptions\":"), compilerOption("sourceMap", true, properties.indentation())) + .add(lineAfterRegex("\"compilerOptions\":"), compilerOption("allowJs", true, properties.indentation())) .add(new TextReplacer(notContainingReplacement(), "\"types\": ["), "\"types\": [\"vite/client\", ") .and() - .and() - .build(); + .and(); //@formatter:on } diff --git a/src/main/java/tech/jhipster/lite/module/domain/JHipsterModule.java b/src/main/java/tech/jhipster/lite/module/domain/JHipsterModule.java index dbf6231e28c..f48c7892227 100644 --- a/src/main/java/tech/jhipster/lite/module/domain/JHipsterModule.java +++ b/src/main/java/tech/jhipster/lite/module/domain/JHipsterModule.java @@ -1,13 +1,12 @@ package tech.jhipster.lite.module.domain; -import static tech.jhipster.lite.module.domain.replacement.ReplacementCondition.*; +import static tech.jhipster.lite.module.domain.replacement.ReplacementCondition.always; +import static tech.jhipster.lite.module.domain.replacement.ReplacementCondition.notContainingReplacement; import java.nio.file.Paths; -import java.util.Collection; -import java.util.EnumMap; -import java.util.HashMap; -import java.util.Map; +import java.util.*; import java.util.Map.Entry; +import java.util.function.Consumer; import java.util.function.Function; import java.util.regex.Pattern; import java.util.stream.Stream; @@ -22,41 +21,29 @@ import tech.jhipster.lite.module.domain.gitignore.JHipsterModuleGitIgnore.JHipsterModuleGitIgnoreBuilder; import tech.jhipster.lite.module.domain.gradleconfiguration.JHipsterModuleGradleConfigurations; import tech.jhipster.lite.module.domain.gradleconfiguration.JHipsterModuleGradleConfigurations.JHipsterModuleGradleConfigurationBuilder; -import tech.jhipster.lite.module.domain.gradleplugin.GradleCommunityPlugin; +import tech.jhipster.lite.module.domain.gradleplugin.*; import tech.jhipster.lite.module.domain.gradleplugin.GradleCommunityPlugin.GradleCommunityPluginIdBuilder; -import tech.jhipster.lite.module.domain.gradleplugin.GradleCommunityProfilePlugin; import tech.jhipster.lite.module.domain.gradleplugin.GradleCommunityProfilePlugin.GradleCommunityProfilePluginIdBuilder; -import tech.jhipster.lite.module.domain.gradleplugin.GradleCorePlugin; import tech.jhipster.lite.module.domain.gradleplugin.GradleCorePlugin.GradleCorePluginIdBuilder; -import tech.jhipster.lite.module.domain.gradleplugin.JHipsterModuleGradlePlugins; import tech.jhipster.lite.module.domain.gradleplugin.JHipsterModuleGradlePlugins.JHipsterModuleGradlePluginBuilder; import tech.jhipster.lite.module.domain.javabuild.*; import tech.jhipster.lite.module.domain.javabuild.JHipsterModuleMavenBuildExtensions.JHipsterModuleMavenBuildExtensionsBuilder; import tech.jhipster.lite.module.domain.javabuild.MavenBuildExtension.MavenBuildExtensionGroupIdBuilder; -import tech.jhipster.lite.module.domain.javabuildprofile.BuildProfileActivation; +import tech.jhipster.lite.module.domain.javabuildprofile.*; import tech.jhipster.lite.module.domain.javabuildprofile.BuildProfileActivation.BuildProfileActivationBuilder; -import tech.jhipster.lite.module.domain.javabuildprofile.BuildProfileId; -import tech.jhipster.lite.module.domain.javabuildprofile.JHipsterModuleJavaBuildProfiles; import tech.jhipster.lite.module.domain.javabuildprofile.JHipsterModuleJavaBuildProfiles.JHipsterModuleJavaBuildProfilesBuilder; -import tech.jhipster.lite.module.domain.javadependency.DependencyId; -import tech.jhipster.lite.module.domain.javadependency.JHipsterModuleJavaDependencies; +import tech.jhipster.lite.module.domain.javadependency.*; import tech.jhipster.lite.module.domain.javadependency.JHipsterModuleJavaDependencies.JHipsterModuleJavaDependenciesBuilder; -import tech.jhipster.lite.module.domain.javadependency.JavaDependency; import tech.jhipster.lite.module.domain.javadependency.JavaDependency.JavaDependencyGroupIdBuilder; import tech.jhipster.lite.module.domain.javaproperties.*; import tech.jhipster.lite.module.domain.javaproperties.JHipsterModuleSpringFactories.JHipsterModuleSpringFactoriesBuilder; import tech.jhipster.lite.module.domain.javaproperties.JHipsterModuleSpringProperties.JHipsterModuleSpringPropertiesBuilder; -import tech.jhipster.lite.module.domain.mavenplugin.JHipsterModuleMavenPlugins; +import tech.jhipster.lite.module.domain.mavenplugin.*; import tech.jhipster.lite.module.domain.mavenplugin.JHipsterModuleMavenPlugins.JHipsterModuleMavenPluginsBuilder; -import tech.jhipster.lite.module.domain.mavenplugin.MavenPlugin; import tech.jhipster.lite.module.domain.mavenplugin.MavenPlugin.MavenPluginGroupIdBuilder; -import tech.jhipster.lite.module.domain.mavenplugin.MavenPluginExecution; import tech.jhipster.lite.module.domain.mavenplugin.MavenPluginExecution.MavenPluginExecutionGoalsBuilder; -import tech.jhipster.lite.module.domain.packagejson.JHipsterModulePackageJson; +import tech.jhipster.lite.module.domain.packagejson.*; import tech.jhipster.lite.module.domain.packagejson.JHipsterModulePackageJson.JHipsterModulePackageJsonBuilder; -import tech.jhipster.lite.module.domain.packagejson.PackageName; -import tech.jhipster.lite.module.domain.packagejson.ScriptCommand; -import tech.jhipster.lite.module.domain.packagejson.ScriptKey; import tech.jhipster.lite.module.domain.postaction.JHipsterModulePostActions; import tech.jhipster.lite.module.domain.postaction.JHipsterModulePostActions.JHipsterModulePostActionsBuilder; import tech.jhipster.lite.module.domain.properties.JHipsterModuleProperties; @@ -526,6 +513,13 @@ JHipsterModuleProperties properties() { return properties; } + public JHipsterModuleBuilder apply(Consumer builderCustomizer) { + Assert.notNull("builderCustomizer", builderCustomizer); + builderCustomizer.accept(this); + + return this; + } + public JHipsterModuleBuilder documentation(DocumentationTitle title, JHipsterSource source) { shortcuts.documentation(title, source); From d146288b9e13cbf9164920b58c0a347017eee4f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Mino?= Date: Sat, 14 Sep 2024 20:49:04 +0200 Subject: [PATCH 06/15] fix(vue): remove unused @tsconfig/recommended dependency --- .../lite/generator/client/vue/core/domain/VueModulesFactory.java | 1 + .../generator/client/vue/core/domain/VueModulesFactoryTest.java | 1 + 2 files changed, 2 insertions(+) diff --git a/src/main/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactory.java b/src/main/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactory.java index 09c0883b58c..63169c65e59 100644 --- a/src/main/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactory.java +++ b/src/main/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactory.java @@ -45,6 +45,7 @@ public JHipsterModule buildVueModule(JHipsterModuleProperties properties) { .preCommitActions(stagedFilesFilter("{src/**/,}*.{ts,vue}"), preCommitCommands("eslint --fix", "prettier --write")) .documentation(documentationTitle("Vue"), DOCUMENTATION_SOURCE.file("vue.md")) .packageJson() + .removeDevDependency(packageName("@tsconfig/recommended")) .addDependency(packageName("vue"), VUE) .addDependency(packageName("axios"), VUE) .addDependency(packageName("vue-router"), VUE) diff --git a/src/test/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactoryTest.java b/src/test/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactoryTest.java index eda1c00fe6b..ed8e8ee830a 100644 --- a/src/test/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactoryTest.java +++ b/src/test/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactoryTest.java @@ -27,6 +27,7 @@ void shouldCreateVueModule() { assertThatModuleWithFiles(module, packageJsonFile(), lintStagedConfigFile(), tsConfigFile()) .hasFiles("documentation/vue.md") .hasFile("package.json") + .notContaining(nodeDependency("@tsconfig/recommended")) .containing(nodeDependency("vue")) .containing(nodeDependency("@vitejs/plugin-vue")) .containing(nodeDependency("@vue/test-utils")) From e8ce836fb84603869ba75e5243494645b1ddde0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Mino?= Date: Sat, 14 Sep 2024 20:49:36 +0200 Subject: [PATCH 07/15] chore(vue): remove full tsconfig.json assertion, not required anymore --- .../vue/core/domain/VueModulesFactoryTest.java | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/src/test/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactoryTest.java b/src/test/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactoryTest.java index ed8e8ee830a..744ce3b9e9b 100644 --- a/src/test/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactoryTest.java +++ b/src/test/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactoryTest.java @@ -66,22 +66,6 @@ void shouldCreateVueModule() { .containing("\"allowJs\": true,") .containing("\"sourceMap\": true,") .containing("\"types\": [\"vite/client\", ") - .containing(""" - { - "extends": "@vue/tsconfig/tsconfig.dom.json", - "compilerOptions": { - "allowJs": true, - "sourceMap": true, - "types": ["vite/client", "vitest/globals"], - "baseUrl": ".", - "paths": { - "@/*": ["src/main/webapp/app/*"] - } - }, - "include": ["src/main/webapp/**/*", "src/test/webapp/unit/**/*"] - } - """ - ) .and() .hasFiles("src/main/webapp/app/shared/http/infrastructure/secondary/AxiosHttp.ts") .hasFiles("src/main/webapp/index.html") From 5c80f4d0260fd18f043fc52d2a644ce10be19742 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Mino?= Date: Sat, 14 Sep 2024 20:53:19 +0200 Subject: [PATCH 08/15] chore: move creation of .npmrc file from vue to typescript module --- .../generator/client/vue/core/domain/VueModulesFactory.java | 4 ---- .../typescript/core/domain/TypescriptModuleFactory.java | 4 ++++ .../client/vue/core/domain/VueModulesFactoryTest.java | 2 +- .../typescript/domain/core/TypescriptModuleFactoryTest.java | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactory.java b/src/main/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactory.java index 63169c65e59..a2725b7f8ab 100644 --- a/src/main/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactory.java +++ b/src/main/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactory.java @@ -20,7 +20,6 @@ public class VueModulesFactory { private static final JHipsterSource APP_SOURCE = from("client/vue/webapp/app"); private static final JHipsterSource DOCUMENTATION_SOURCE = SOURCE.append("documentation"); private static final JHipsterSource IMAGE_SOURCE = SOURCE.append("webapp/content/images"); - private static final JHipsterSource SOURCE_COMMON = from("client/common"); private static final JHipsterDestination MAIN_DESTINATION = to("src/main/webapp/app"); private static final JHipsterDestination TEST_DESTINATION = to("src/test/webapp"); @@ -75,9 +74,6 @@ public JHipsterModule buildVueModule(JHipsterModuleProperties properties) { .addTemplate("vite.config.ts") .addTemplate("vitest.config.ts") .and() - .batch(SOURCE_COMMON, to(".")) - .addFile(".npmrc") - .and() .add(SOURCE.template("webapp/index.html"), to("src/main/webapp/index.html")) .batch(APP_SOURCE, MAIN_DESTINATION) .addTemplate("env.d.ts") diff --git a/src/main/java/tech/jhipster/lite/generator/typescript/core/domain/TypescriptModuleFactory.java b/src/main/java/tech/jhipster/lite/generator/typescript/core/domain/TypescriptModuleFactory.java index 100acd2d94a..d388061ba08 100644 --- a/src/main/java/tech/jhipster/lite/generator/typescript/core/domain/TypescriptModuleFactory.java +++ b/src/main/java/tech/jhipster/lite/generator/typescript/core/domain/TypescriptModuleFactory.java @@ -12,6 +12,7 @@ public class TypescriptModuleFactory { private static final JHipsterSource SOURCE = from("typescript"); + private static final JHipsterSource SOURCE_COMMON = from("client/common"); public JHipsterModule buildModule(JHipsterModuleProperties properties) { Assert.notNull("properties", properties); @@ -42,6 +43,9 @@ public JHipsterModule buildModule(JHipsterModuleProperties properties) { .addScript(scriptKey("watch:test"), scriptCommand("vitest --")) .and() .files() + .batch(SOURCE_COMMON, to(".")) + .addFile(".npmrc") + .and() .batch(SOURCE, to(".")) .addFile("tsconfig.json") .addTemplate("vitest.config.ts") diff --git a/src/test/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactoryTest.java b/src/test/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactoryTest.java index 744ce3b9e9b..6e8358cc659 100644 --- a/src/test/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactoryTest.java +++ b/src/test/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactoryTest.java @@ -60,7 +60,7 @@ void shouldCreateVueModule() { """ ) .and() - .hasPrefixedFiles("", ".npmrc", "eslint.config.js", "tsconfig.build.json", "vite.config.ts", "vitest.config.ts") + .hasPrefixedFiles("", "eslint.config.js", "tsconfig.build.json", "vite.config.ts", "vitest.config.ts") .hasFile("tsconfig.json") .containing("\"extends\": \"@vue/tsconfig/tsconfig.dom.json\"") .containing("\"allowJs\": true,") diff --git a/src/test/java/tech/jhipster/lite/generator/typescript/domain/core/TypescriptModuleFactoryTest.java b/src/test/java/tech/jhipster/lite/generator/typescript/domain/core/TypescriptModuleFactoryTest.java index 0bf06af3607..2edea734ed5 100644 --- a/src/test/java/tech/jhipster/lite/generator/typescript/domain/core/TypescriptModuleFactoryTest.java +++ b/src/test/java/tech/jhipster/lite/generator/typescript/domain/core/TypescriptModuleFactoryTest.java @@ -44,6 +44,6 @@ void shouldCreateTypescriptModule() { .containing(nodeScript("watch:tsc", "tsc --noEmit --watch")) .containing(nodeScript("lint", "eslint .")) .and() - .hasPrefixedFiles("", "eslint.config.js", "tsconfig.json"); + .hasPrefixedFiles("", ".npmrc", "eslint.config.js", "tsconfig.json"); } } From d9e0226b8adaff779f8b5752d063a95b66a86f6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Mino?= Date: Sat, 14 Sep 2024 21:12:50 +0200 Subject: [PATCH 09/15] chore(typescript): remove 'import-x' plugin for eslint It's currently only used in typescript module, no other client module uses it. We might reintroduce it in future, if needed. --- .../core/domain/TypescriptModuleFactory.java | 1 - .../typescript/eslint.config.js.mustache | 28 +------------------ .../core/TypescriptModuleFactoryTest.java | 1 - 3 files changed, 1 insertion(+), 29 deletions(-) diff --git a/src/main/java/tech/jhipster/lite/generator/typescript/core/domain/TypescriptModuleFactory.java b/src/main/java/tech/jhipster/lite/generator/typescript/core/domain/TypescriptModuleFactory.java index d388061ba08..846154ab34e 100644 --- a/src/main/java/tech/jhipster/lite/generator/typescript/core/domain/TypescriptModuleFactory.java +++ b/src/main/java/tech/jhipster/lite/generator/typescript/core/domain/TypescriptModuleFactory.java @@ -28,7 +28,6 @@ public JHipsterModule buildModule(JHipsterModuleProperties properties) { .addDevDependency(packageName("@vitest/coverage-istanbul"), COMMON) .addDevDependency(packageName("eslint"), COMMON) .addDevDependency(packageName("eslint-config-prettier"), COMMON) - .addDevDependency(packageName("eslint-plugin-import-x"), COMMON) .addDevDependency(packageName("globals"), COMMON) .addDevDependency(packageName("npm-run-all2"), COMMON) .addDevDependency(packageName("typescript-eslint"), COMMON) diff --git a/src/main/resources/generator/typescript/eslint.config.js.mustache b/src/main/resources/generator/typescript/eslint.config.js.mustache index 8fc3802f7cc..1dbd6fc1fcc 100644 --- a/src/main/resources/generator/typescript/eslint.config.js.mustache +++ b/src/main/resources/generator/typescript/eslint.config.js.mustache @@ -1,5 +1,4 @@ import js from '@eslint/js'; -import imports from 'eslint-plugin-import-x'; import globals from 'globals'; import typescript from 'typescript-eslint'; @@ -12,35 +11,10 @@ export default typescript.config( }, }, { - ignores: [ - '{{projectBuildDirectory}}/' - ], + ignores: ['{{projectBuildDirectory}}/'], }, js.configs.recommended, ...typescript.configs.recommended.map(config => (config.name === 'typescript-eslint/base' ? config : { ...config, files: ['**/*.ts'] })), - { - extends: [imports.flatConfigs.recommended, imports.flatConfigs.typescript], - languageOptions: { - // import plugin does not use ecmaVersion and sourceType from languageOptions object - parserOptions: { - ecmaVersion: 2022, - sourceType: 'module', - }, - }, - rules: { - 'import-x/no-unresolved': 'off', - 'import-x/order': [ - 'error', - { - alphabetize: { - order: 'asc', - caseInsensitive: true, - }, - 'newlines-between': 'always', - }, - ], - }, - }, { files: ['src/*/webapp/**/*.ts'], languageOptions: { diff --git a/src/test/java/tech/jhipster/lite/generator/typescript/domain/core/TypescriptModuleFactoryTest.java b/src/test/java/tech/jhipster/lite/generator/typescript/domain/core/TypescriptModuleFactoryTest.java index 2edea734ed5..d73723f1797 100644 --- a/src/test/java/tech/jhipster/lite/generator/typescript/domain/core/TypescriptModuleFactoryTest.java +++ b/src/test/java/tech/jhipster/lite/generator/typescript/domain/core/TypescriptModuleFactoryTest.java @@ -31,7 +31,6 @@ void shouldCreateTypescriptModule() { .containing(nodeDependency("@vitest/coverage-istanbul")) .containing(nodeDependency("eslint")) .containing(nodeDependency("eslint-config-prettier")) - .containing(nodeDependency("eslint-plugin-import-x")) .containing(nodeDependency("globals")) .containing(nodeDependency("typescript-eslint")) .containing(nodeDependency("vite-tsconfig-paths")) From 5a4ee1e257b6164e5d995f285fb45107705b98e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Mino?= Date: Sat, 14 Sep 2024 21:14:10 +0200 Subject: [PATCH 10/15] fix(vue): piqure should be runtime dependency, not a dev dependency --- .../generator/client/vue/core/domain/VueModulesFactory.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactory.java b/src/main/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactory.java index a2725b7f8ab..70f1d55c893 100644 --- a/src/main/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactory.java +++ b/src/main/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactory.java @@ -48,6 +48,7 @@ public JHipsterModule buildVueModule(JHipsterModuleProperties properties) { .addDependency(packageName("vue"), VUE) .addDependency(packageName("axios"), VUE) .addDependency(packageName("vue-router"), VUE) + .addDependency(packageName("piqure"), VUE) .addDevDependency(packageName("@vitejs/plugin-vue"), VUE) .addDevDependency(packageName("@vue/test-utils"), VUE) .addDevDependency(packageName("@vue/tsconfig"), VUE) @@ -57,7 +58,6 @@ public JHipsterModule buildVueModule(JHipsterModuleProperties properties) { .addDevDependency(packageName("vue-tsc"), VUE) .addDevDependency(packageName("@types/sinon"), VUE) .addDevDependency(packageName("sinon"), VUE) - .addDevDependency(packageName("piqure"), VUE) .addScript(scriptKey("build"), scriptCommand("npm-run-all build:*")) .addScript(scriptKey("build:tsc"), scriptCommand("vue-tsc -p tsconfig.build.json --noEmit")) .addScript(scriptKey("build:vite"), scriptCommand("vite build --emptyOutDir")) From 989a1687e38694da5669046c53c25e4117dc2660 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Mino?= Date: Sat, 14 Sep 2024 21:32:52 +0200 Subject: [PATCH 11/15] test(cucumber): module typescript should now be applied before vue-core module --- src/test/features/client/vue.feature | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/test/features/client/vue.feature b/src/test/features/client/vue.feature index 3092bb9150d..ecbfa354129 100644 --- a/src/test/features/client/vue.feature +++ b/src/test/features/client/vue.feature @@ -2,9 +2,10 @@ Feature: Vue.js modules Scenario: Should apply vue core module When I apply modules to default project - | init | - | prettier | - | vue-core | + | init | + | prettier | + | typescript | + | vue-core | Then I should have files in "src/main/webapp/app" | AppVue.vue | From 839cdd09206f85e03c8268320d1c71ef9684ae3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Mino?= Date: Sat, 14 Sep 2024 22:15:35 +0200 Subject: [PATCH 12/15] test(tests-ci): typescript module needs to be applied before vue-core --- tests-ci/generate.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests-ci/generate.sh b/tests-ci/generate.sh index c6cc189b5b9..fba0ab04a1c 100755 --- a/tests-ci/generate.sh +++ b/tests-ci/generate.sh @@ -180,6 +180,7 @@ elif [[ $application == 'fullapp' ]]; then frontend_server_plugin applyModules \ + "typescript" \ "vue-core" \ "cypress-component-tests" \ "playwright-e2e" @@ -411,6 +412,7 @@ elif [[ $application == 'vueapp' ]]; then frontend_server_plugin applyModules \ + "typescript" \ "vue-core" \ "vue-pinia" \ "playwright-component-tests" \ From c9ebe99a64a5a75092221f848cb5b8f973a85182 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Mino?= Date: Sat, 14 Sep 2024 23:01:22 +0200 Subject: [PATCH 13/15] feat(vue): patch vitest config file from typescript module rather than overwriting it --- .../vue/core/domain/VueModulesFactory.java | 22 +++++++- .../client/vue/vitest.config.ts.mustache | 50 ------------------- .../typescript/vitest.config.ts.mustache | 2 - .../core/domain/VueModulesFactoryTest.java | 26 +++++++--- .../secondary/JHipsterModulesAssertions.java | 8 ++- 5 files changed, 47 insertions(+), 61 deletions(-) delete mode 100644 src/main/resources/generator/client/vue/vitest.config.ts.mustache diff --git a/src/main/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactory.java b/src/main/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactory.java index 70f1d55c893..c0c15623802 100644 --- a/src/main/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactory.java +++ b/src/main/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactory.java @@ -72,7 +72,6 @@ public JHipsterModule buildVueModule(JHipsterModuleProperties properties) { .add(SOURCE.file("tsconfig.build.json"), to("tsconfig.build.json")) .batch(SOURCE, to(".")) .addTemplate("vite.config.ts") - .addTemplate("vitest.config.ts") .and() .add(SOURCE.template("webapp/index.html"), to("src/main/webapp/index.html")) .batch(APP_SOURCE, MAIN_DESTINATION) @@ -98,6 +97,7 @@ public JHipsterModule buildVueModule(JHipsterModuleProperties properties) { .add(APP_SOURCE.template("test/webapp/unit/router/infrastructure/primary/HomeRouter.spec.ts.mustache"), TEST_DESTINATION.append("unit/router/infrastructure/primary/HomeRouter.spec.ts")) .and() .apply(patchTsConfig(properties)) + .apply(patchVitestConfig(properties)) .build(); //@formatter:on } @@ -120,6 +120,26 @@ private static String compilerOption(String optionName, boolean optionValue, Ind return indentation.times(2) + "\"%s\": %s,".formatted(optionName, optionValue); } + private Consumer patchVitestConfig(JHipsterModuleProperties properties) { + //@formatter:off + return moduleBuilder -> moduleBuilder + .mandatoryReplacements() + .in(path("vitest.config.ts")) + .add(lineAfterRegex("from 'vitest/config';"), "import vue from '@vitejs/plugin-vue';") + .add(new TextReplacer(notContainingReplacement(), "plugins: ["), "plugins: [vue(), ") + .add(text("environment: 'node',"), "environment: 'jsdom',") + .add(lineAfterRegex("configDefaults.coverage.exclude"), vitestCoverageExclusion(properties.indentation(),"src/main/webapp/**/*.component.ts")) + .add(lineAfterRegex("configDefaults.coverage.exclude"), vitestCoverageExclusion(properties.indentation(),"src/main/webapp/app/router.ts")) + .add(lineAfterRegex("configDefaults.coverage.exclude"), vitestCoverageExclusion(properties.indentation(),"src/main/webapp/app/injections.ts")) + .add(lineAfterRegex("configDefaults.coverage.exclude"), vitestCoverageExclusion(properties.indentation(),"src/main/webapp/app/main.ts")) + .and(); + //@formatter:on + } + + private static String vitestCoverageExclusion(Indentation indentation, String filePattern) { + return indentation.times(4) + "'" + filePattern + "',"; + } + public JHipsterModule buildPiniaModule(JHipsterModuleProperties properties) { Assert.notNull("properties", properties); diff --git a/src/main/resources/generator/client/vue/vitest.config.ts.mustache b/src/main/resources/generator/client/vue/vitest.config.ts.mustache deleted file mode 100644 index 4f92410710d..00000000000 --- a/src/main/resources/generator/client/vue/vitest.config.ts.mustache +++ /dev/null @@ -1,50 +0,0 @@ -/// - -import tsconfigPaths from 'vite-tsconfig-paths'; -import { defineConfig, configDefaults } from 'vitest/config'; -import vue from '@vitejs/plugin-vue'; - -export default defineConfig({ - plugins: [vue(), tsconfigPaths()], - test: { - reporters: ['verbose', 'vitest-sonar-reporter'], - outputFile: { - 'vitest-sonar-reporter': '{{projectBuildDirectory}}/test-results/TESTS-results-sonar.xml', - }, - globals: true, - logHeapUsage: true, - poolOptions: { - threads: { - minThreads: 1, - maxThreads: 2, - }, - }, - environment: 'jsdom', - cache: false, - include: ['src/test/webapp/unit/**/*.{test,spec}.?(c|m)[jt]s?(x)'], - coverage: { - include: ['src/main/webapp/**/*.ts?(x)'], - exclude: [ - ...configDefaults.coverage.exclude as string[], - 'src/main/webapp/app/main.ts', - 'src/main/webapp/app/injections.ts', - 'src/main/webapp/app/router.ts', - 'src/main/webapp/**/*.component.ts', - ], - provider: 'istanbul', - reportsDirectory: '{{projectBuildDirectory}}/test-results/', - reporter: ['html', 'json-summary', 'text', 'text-summary', 'lcov', 'clover'], - thresholds: { - perFile: true, - autoUpdate: true, - 100: true, - }, - watermarks: { - statements: [100, 100], - branches: [100, 100], - functions: [100, 100], - lines: [100, 100], - }, - }, - }, -}); diff --git a/src/main/resources/generator/typescript/vitest.config.ts.mustache b/src/main/resources/generator/typescript/vitest.config.ts.mustache index 2a0eaee09ce..0dc4d9d3e8e 100644 --- a/src/main/resources/generator/typescript/vitest.config.ts.mustache +++ b/src/main/resources/generator/typescript/vitest.config.ts.mustache @@ -22,7 +22,6 @@ export default defineConfig({ cache: false, include: ['src/test/webapp/unit/**/*.{test,spec}.?(c|m)[jt]s?(x)'], coverage: { - all: true, thresholds: { perFile: true, autoUpdate: true, @@ -32,7 +31,6 @@ export default defineConfig({ exclude: [ ...configDefaults.coverage.exclude as string[], ], - clean: true, provider: 'istanbul', reportsDirectory: '{{projectBuildDirectory}}/test-results/', reporter: ['html', 'json-summary', 'text', 'text-summary', 'lcov', 'clover'], diff --git a/src/test/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactoryTest.java b/src/test/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactoryTest.java index 6e8358cc659..1652e354b26 100644 --- a/src/test/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactoryTest.java +++ b/src/test/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactoryTest.java @@ -24,7 +24,7 @@ void shouldCreateVueModule() { JHipsterModule module = factory.buildVueModule(properties); //@formatter:off - assertThatModuleWithFiles(module, packageJsonFile(), lintStagedConfigFile(), tsConfigFile()) + assertThatModuleWithFiles(module, packageJsonFile(), lintStagedConfigFile(), tsConfigFile(), vitestConfigFile()) .hasFiles("documentation/vue.md") .hasFile("package.json") .notContaining(nodeDependency("@tsconfig/recommended")) @@ -62,11 +62,25 @@ void shouldCreateVueModule() { .and() .hasPrefixedFiles("", "eslint.config.js", "tsconfig.build.json", "vite.config.ts", "vitest.config.ts") .hasFile("tsconfig.json") - .containing("\"extends\": \"@vue/tsconfig/tsconfig.dom.json\"") - .containing("\"allowJs\": true,") - .containing("\"sourceMap\": true,") - .containing("\"types\": [\"vite/client\", ") - .and() + .containing("\"extends\": \"@vue/tsconfig/tsconfig.dom.json\"") + .containing("\"allowJs\": true,") + .containing("\"sourceMap\": true,") + .containing("\"types\": [\"vite/client\", ") + .and() + .hasFile("vitest.config.ts") + .containing("import vue from '@vitejs/plugin-vue';") + .containing("plugins: [vue(), tsconfigPaths()],") + .containing("environment: 'jsdom',") + .containing(""" + exclude: [ + ...configDefaults.coverage.exclude as string[], + 'src/main/webapp/app/main.ts', + 'src/main/webapp/app/injections.ts', + 'src/main/webapp/app/router.ts', + 'src/main/webapp/**/*.component.ts', + """ + ) + .and() .hasFiles("src/main/webapp/app/shared/http/infrastructure/secondary/AxiosHttp.ts") .hasFiles("src/main/webapp/index.html") .hasPrefixedFiles("src/main/webapp/app", "env.d.ts", "AppVue.vue", "injections.ts", "router.ts", "main.ts") diff --git a/src/test/java/tech/jhipster/lite/module/infrastructure/secondary/JHipsterModulesAssertions.java b/src/test/java/tech/jhipster/lite/module/infrastructure/secondary/JHipsterModulesAssertions.java index 215b15714fb..7775a882e63 100644 --- a/src/test/java/tech/jhipster/lite/module/infrastructure/secondary/JHipsterModulesAssertions.java +++ b/src/test/java/tech/jhipster/lite/module/infrastructure/secondary/JHipsterModulesAssertions.java @@ -1,7 +1,7 @@ package tech.jhipster.lite.module.infrastructure.secondary; -import static org.assertj.core.api.Assertions.*; -import static tech.jhipster.lite.TestFileUtils.*; +import static org.assertj.core.api.Assertions.assertThat; +import static tech.jhipster.lite.TestFileUtils.contentNormalizingNewLines; import java.io.IOException; import java.nio.file.*; @@ -64,6 +64,10 @@ public static ModuleFile tsConfigFile() { return file("src/main/resources/generator/typescript/tsconfig.json", "tsconfig.json"); } + public static ModuleFile vitestConfigFile() { + return file("src/main/resources/generator/typescript/vitest.config.ts.mustache", "vitest.config.ts"); + } + public static ModuleFile emptyLintStagedConfigFile() { return file("src/test/resources/projects/init/.lintstagedrc.empty.cjs", ".lintstagedrc.cjs"); } From df4f8f64d5606158e942d1d53e0a19eb8ee2da1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Mino?= Date: Sat, 14 Sep 2024 23:25:26 +0200 Subject: [PATCH 14/15] feat(module-builder): add a new API that allows to directly add a {Mandatory|Optional} replacer to the replacements This allows reusing replacers, and improves readability and maintainability of the code --- .../vue/core/domain/VueModulesFactory.java | 23 +++++++++++-------- .../domain/JHipsterModuleShortcuts.java | 8 +++++-- ...terModuleMandatoryReplacementsFactory.java | 6 +++++ ...sterModuleOptionalReplacementsFactory.java | 6 +++++ .../JHipsterModuleReplacementsFactory.java | 8 +++++++ 5 files changed, 39 insertions(+), 12 deletions(-) diff --git a/src/main/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactory.java b/src/main/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactory.java index c0c15623802..da8c26dabe5 100644 --- a/src/main/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactory.java +++ b/src/main/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactory.java @@ -11,6 +11,7 @@ import tech.jhipster.lite.module.domain.file.JHipsterDestination; import tech.jhipster.lite.module.domain.file.JHipsterSource; import tech.jhipster.lite.module.domain.properties.JHipsterModuleProperties; +import tech.jhipster.lite.module.domain.replacement.MandatoryReplacer; import tech.jhipster.lite.module.domain.replacement.TextReplacer; import tech.jhipster.lite.shared.error.domain.Assert; @@ -108,16 +109,17 @@ private Consumer patchTsConfig(JHipsterModuleProperties p .mandatoryReplacements() .in(path("tsconfig.json")) .add(text("@tsconfig/recommended/tsconfig.json"), "@vue/tsconfig/tsconfig.dom.json") - .add(lineAfterRegex("\"compilerOptions\":"), compilerOption("sourceMap", true, properties.indentation())) - .add(lineAfterRegex("\"compilerOptions\":"), compilerOption("allowJs", true, properties.indentation())) + .add(tsConfigCompilerOption("sourceMap", true, properties.indentation())) + .add(tsConfigCompilerOption("allowJs", true, properties.indentation())) .add(new TextReplacer(notContainingReplacement(), "\"types\": ["), "\"types\": [\"vite/client\", ") .and() .and(); //@formatter:on } - private static String compilerOption(String optionName, boolean optionValue, Indentation indentation) { - return indentation.times(2) + "\"%s\": %s,".formatted(optionName, optionValue); + 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 patchVitestConfig(JHipsterModuleProperties properties) { @@ -128,16 +130,17 @@ private Consumer patchVitestConfig(JHipsterModuleProperti .add(lineAfterRegex("from 'vitest/config';"), "import vue from '@vitejs/plugin-vue';") .add(new TextReplacer(notContainingReplacement(), "plugins: ["), "plugins: [vue(), ") .add(text("environment: 'node',"), "environment: 'jsdom',") - .add(lineAfterRegex("configDefaults.coverage.exclude"), vitestCoverageExclusion(properties.indentation(),"src/main/webapp/**/*.component.ts")) - .add(lineAfterRegex("configDefaults.coverage.exclude"), vitestCoverageExclusion(properties.indentation(),"src/main/webapp/app/router.ts")) - .add(lineAfterRegex("configDefaults.coverage.exclude"), vitestCoverageExclusion(properties.indentation(),"src/main/webapp/app/injections.ts")) - .add(lineAfterRegex("configDefaults.coverage.exclude"), vitestCoverageExclusion(properties.indentation(),"src/main/webapp/app/main.ts")) + .add(vitestCoverageExclusion(properties,"src/main/webapp/**/*.component.ts")) + .add(vitestCoverageExclusion(properties,"src/main/webapp/app/router.ts")) + .add(vitestCoverageExclusion(properties,"src/main/webapp/app/injections.ts")) + .add(vitestCoverageExclusion(properties,"src/main/webapp/app/main.ts")) .and(); //@formatter:on } - private static String vitestCoverageExclusion(Indentation indentation, String filePattern) { - return indentation.times(4) + "'" + filePattern + "',"; + private static MandatoryReplacer vitestCoverageExclusion(JHipsterModuleProperties properties, String filePattern) { + Indentation indentation = properties.indentation(); + return new MandatoryReplacer(lineAfterRegex("configDefaults.coverage.exclude"), indentation.times(4) + "'" + filePattern + "',"); } public JHipsterModule buildPiniaModule(JHipsterModuleProperties properties) { diff --git a/src/main/java/tech/jhipster/lite/module/domain/JHipsterModuleShortcuts.java b/src/main/java/tech/jhipster/lite/module/domain/JHipsterModuleShortcuts.java index 8addcf7a988..6fc7f3416ba 100644 --- a/src/main/java/tech/jhipster/lite/module/domain/JHipsterModuleShortcuts.java +++ b/src/main/java/tech/jhipster/lite/module/domain/JHipsterModuleShortcuts.java @@ -68,14 +68,18 @@ void springTestLogger(String name, LogLevel level) { Assert.notBlank("name", name); Assert.notNull("level", level); - builder.optionalReplacements().in(SPRING_TEST_LOG_FILE).add(JHIPSTER_LOGGER_NEEDLE, logger(name, level)); + builder.optionalReplacements().in(SPRING_TEST_LOG_FILE).add(logConfigurationEntry(name, level)); } void springMainLogger(String name, LogLevel level) { Assert.notBlank("name", name); Assert.notNull("level", level); - builder.optionalReplacements().in(SPRING_MAIN_LOG_FILE).add(JHIPSTER_LOGGER_NEEDLE, logger(name, level)); + builder.optionalReplacements().in(SPRING_MAIN_LOG_FILE).add(logConfigurationEntry(name, level)); + } + + private OptionalReplacer logConfigurationEntry(String name, LogLevel level) { + return new OptionalReplacer(JHIPSTER_LOGGER_NEEDLE, logger(name, level)); } private String logger(String name, LogLevel level) { diff --git a/src/main/java/tech/jhipster/lite/module/domain/replacement/JHipsterModuleMandatoryReplacementsFactory.java b/src/main/java/tech/jhipster/lite/module/domain/replacement/JHipsterModuleMandatoryReplacementsFactory.java index 8f7c3550e43..35a31ffff05 100644 --- a/src/main/java/tech/jhipster/lite/module/domain/replacement/JHipsterModuleMandatoryReplacementsFactory.java +++ b/src/main/java/tech/jhipster/lite/module/domain/replacement/JHipsterModuleMandatoryReplacementsFactory.java @@ -52,6 +52,12 @@ private JHipsterModuleFileMandatoryReplacementsFactoryBuilder( super(replacements, file); } + public JHipsterModuleFileMandatoryReplacementsFactoryBuilder add(MandatoryReplacer mandatoryReplacer) { + replacements().add(buildReplacer(file(), mandatoryReplacer.replacer(), mandatoryReplacer.updatedValue())); + + return this; + } + @Override protected ContentReplacer buildReplacer(JHipsterProjectFilePath file, ElementReplacer toReplace, String replacement) { return new MandatoryFileReplacer(file, new MandatoryReplacer(toReplace, replacement)); diff --git a/src/main/java/tech/jhipster/lite/module/domain/replacement/JHipsterModuleOptionalReplacementsFactory.java b/src/main/java/tech/jhipster/lite/module/domain/replacement/JHipsterModuleOptionalReplacementsFactory.java index e5d3e3a8ebc..66df8a99bc9 100644 --- a/src/main/java/tech/jhipster/lite/module/domain/replacement/JHipsterModuleOptionalReplacementsFactory.java +++ b/src/main/java/tech/jhipster/lite/module/domain/replacement/JHipsterModuleOptionalReplacementsFactory.java @@ -80,6 +80,12 @@ private JHipsterModuleFileOptionalReplacementsFactoryBuilder( super(replacements, file); } + public JHipsterModuleFileOptionalReplacementsFactoryBuilder add(OptionalReplacer mandatoryReplacer) { + replacements().add(buildReplacer(file(), mandatoryReplacer.replacer(), mandatoryReplacer.updatedValue())); + + return this; + } + @Override protected ContentReplacer buildReplacer(JHipsterProjectFilePath file, ElementReplacer toReplace, String replacement) { return new OptionalFileReplacer(file, new OptionalReplacer(toReplace, replacement)); diff --git a/src/main/java/tech/jhipster/lite/module/domain/replacement/JHipsterModuleReplacementsFactory.java b/src/main/java/tech/jhipster/lite/module/domain/replacement/JHipsterModuleReplacementsFactory.java index 59f7957f5ee..ce4abf2b286 100644 --- a/src/main/java/tech/jhipster/lite/module/domain/replacement/JHipsterModuleReplacementsFactory.java +++ b/src/main/java/tech/jhipster/lite/module/domain/replacement/JHipsterModuleReplacementsFactory.java @@ -80,6 +80,14 @@ public Builder add(ElementReplacer elementToReplace, String replacement) { return self(); } + protected ReplacementsBuilder replacements() { + return replacements; + } + + protected JHipsterProjectFilePath file() { + return file; + } + @SuppressWarnings("unchecked") private Builder self() { return (Builder) this; From b52e17c6a23459ac31e2f969d97b3148937f61bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Mino?= Date: Sun, 15 Sep 2024 10:11:50 +0200 Subject: [PATCH 15/15] feat(vue): patch eslint config file from typescript module rather than overwriting it --- .../vue/core/domain/VueModulesFactory.java | 33 +++++++++++++++- .../client/vue/eslint.config.js.mustache | 39 ------------------- .../core/domain/VueModulesFactoryTest.java | 24 +++++++++++- .../secondary/JHipsterModulesAssertions.java | 4 ++ 4 files changed, 59 insertions(+), 41 deletions(-) delete mode 100644 src/main/resources/generator/client/vue/eslint.config.js.mustache diff --git a/src/main/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactory.java b/src/main/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactory.java index da8c26dabe5..39055c1524c 100644 --- a/src/main/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactory.java +++ b/src/main/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactory.java @@ -69,7 +69,6 @@ public JHipsterModule buildVueModule(JHipsterModuleProperties properties) { .addScript(scriptKey("watch:tsc"), scriptCommand("npm run build:tsc -- --watch")) .and() .files() - .add(SOURCE.template("eslint.config.js.mustache"), to("eslint.config.js")) .add(SOURCE.file("tsconfig.build.json"), to("tsconfig.build.json")) .batch(SOURCE, to(".")) .addTemplate("vite.config.ts") @@ -97,12 +96,44 @@ public JHipsterModule buildVueModule(JHipsterModuleProperties properties) { .add(APP_SOURCE.template("test/webapp/unit/shared/http/infrastructure/secondary/AxiosStub.ts.mustache"), TEST_DESTINATION.append("unit/shared/http/infrastructure/secondary/AxiosStub.ts")) .add(APP_SOURCE.template("test/webapp/unit/router/infrastructure/primary/HomeRouter.spec.ts.mustache"), TEST_DESTINATION.append("unit/router/infrastructure/primary/HomeRouter.spec.ts")) .and() + .apply(patchEslintConfig(properties)) .apply(patchTsConfig(properties)) .apply(patchVitestConfig(properties)) .build(); //@formatter:on } + private Consumer patchEslintConfig(JHipsterModuleProperties properties) { + String vuePluginConfig = + """ + \t...vue.configs['flat/recommended'], + \t{ + \t\tfiles: ['**/*.vue'], + \t\tlanguageOptions: { + \t\t\tparserOptions: { parser: '@typescript-eslint/parser' }, + \t\t\tglobals: { ...globals.browser }, + \t\t}, + \t},\ + """.replace("\t", properties.indentation().spaces()); + //@formatter:off + return moduleBuilder -> moduleBuilder + .mandatoryReplacements() + .in(path("eslint.config.js")) + .add(lineAfterRegex("from 'typescript-eslint'"), "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())) + .and() + .and(); + //@formatter:on + } + + private static MandatoryReplacer eslintTypescriptVueRule(String rule, Indentation indentation) { + return new MandatoryReplacer(lineAfterRegex("quotes: \\['error', 'single'"), indentation.times(3) + rule); + } + private Consumer patchTsConfig(JHipsterModuleProperties properties) { //@formatter:off return moduleBuilder -> moduleBuilder diff --git a/src/main/resources/generator/client/vue/eslint.config.js.mustache b/src/main/resources/generator/client/vue/eslint.config.js.mustache deleted file mode 100644 index bba52802447..00000000000 --- a/src/main/resources/generator/client/vue/eslint.config.js.mustache +++ /dev/null @@ -1,39 +0,0 @@ -import globals from 'globals'; -import typescript from 'typescript-eslint'; -import js from '@eslint/js'; -import vue from 'eslint-plugin-vue'; - -export default typescript.config( - { - languageOptions: { - globals: { - ...globals.node, - }, - }, - }, - { - ignores: ['{{projectBuildDirectory}}/'], - }, - js.configs.recommended, - ...typescript.configs.recommended.map(config => (config.name === 'typescript-eslint/base' ? config : { ...config, files: ['**/*.ts'] })), - ...vue.configs['flat/recommended'], - { - files: ['**/*.vue'], - languageOptions: { - parserOptions: { parser: '@typescript-eslint/parser' }, - globals: { ...globals.browser }, - }, - }, - { - files: ['src/*/webapp/**/*.vue', 'src/*/webapp/**/*.ts'], - languageOptions: { - globals: { ...globals.browser }, - }, - rules: { - quotes: ['error', 'single', { avoidEscape: true }], - '@typescript-eslint/no-explicit-any': 'off', - 'vue/html-self-closing': 'off', - '@typescript-eslint/no-empty-object-type': 'off', - }, - }, -); diff --git a/src/test/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactoryTest.java b/src/test/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactoryTest.java index 1652e354b26..4aa78c54eff 100644 --- a/src/test/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactoryTest.java +++ b/src/test/java/tech/jhipster/lite/generator/client/vue/core/domain/VueModulesFactoryTest.java @@ -24,7 +24,7 @@ void shouldCreateVueModule() { JHipsterModule module = factory.buildVueModule(properties); //@formatter:off - assertThatModuleWithFiles(module, packageJsonFile(), lintStagedConfigFile(), tsConfigFile(), vitestConfigFile()) + assertThatModuleWithFiles(module, packageJsonFile(), lintStagedConfigFile(), tsConfigFile(), vitestConfigFile(), eslintConfigFile()) .hasFiles("documentation/vue.md") .hasFile("package.json") .notContaining(nodeDependency("@tsconfig/recommended")) @@ -81,6 +81,28 @@ void shouldCreateVueModule() { """ ) .and() + .hasFile("eslint.config.js") + .containing("import vue from 'eslint-plugin-vue';") + .containing(""" + ...vue.configs['flat/recommended'], + { + files: ['**/*.vue'], + languageOptions: { + parserOptions: { parser: '@typescript-eslint/parser' }, + globals: { ...globals.browser }, + }, + }, + """ + ) + .containing(""" + rules: { + quotes: ['error', 'single', { avoidEscape: true }], + '@typescript-eslint/no-empty-object-type': 'off', + '@typescript-eslint/no-explicit-any': 'off', + 'vue/html-self-closing': 'off', + """ + ) + .and() .hasFiles("src/main/webapp/app/shared/http/infrastructure/secondary/AxiosHttp.ts") .hasFiles("src/main/webapp/index.html") .hasPrefixedFiles("src/main/webapp/app", "env.d.ts", "AppVue.vue", "injections.ts", "router.ts", "main.ts") diff --git a/src/test/java/tech/jhipster/lite/module/infrastructure/secondary/JHipsterModulesAssertions.java b/src/test/java/tech/jhipster/lite/module/infrastructure/secondary/JHipsterModulesAssertions.java index 7775a882e63..cb33baf5c79 100644 --- a/src/test/java/tech/jhipster/lite/module/infrastructure/secondary/JHipsterModulesAssertions.java +++ b/src/test/java/tech/jhipster/lite/module/infrastructure/secondary/JHipsterModulesAssertions.java @@ -68,6 +68,10 @@ public static ModuleFile vitestConfigFile() { return file("src/main/resources/generator/typescript/vitest.config.ts.mustache", "vitest.config.ts"); } + public static ModuleFile eslintConfigFile() { + return file("src/main/resources/generator/typescript/eslint.config.js.mustache", "eslint.config.js"); + } + public static ModuleFile emptyLintStagedConfigFile() { return file("src/test/resources/projects/init/.lintstagedrc.empty.cjs", ".lintstagedrc.cjs"); }