@ykdz/template 0.0.40 → 0.0.42

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. package/node_modules/@ykdz/template-builtin-presets/dist/src/foundation.js +144 -101
  2. package/node_modules/@ykdz/template-builtin-presets/dist/src/rust-bin/definition.js +29 -4
  3. package/node_modules/@ykdz/template-builtin-presets/dist/src/shared/vue.js +11 -2
  4. package/node_modules/@ykdz/template-builtin-presets/dist/src/ts-cli/definition.js +14 -4
  5. package/node_modules/@ykdz/template-builtin-presets/dist/src/ts-lib/definition.js +13 -0
  6. package/node_modules/@ykdz/template-builtin-presets/dist/src/vike-app/definition.js +44 -10
  7. package/node_modules/@ykdz/template-builtin-presets/dist/src/vue-app/definition.js +4 -1
  8. package/node_modules/@ykdz/template-builtin-presets/dist/src/vue-hono-app/definition.js +19 -8
  9. package/node_modules/@ykdz/template-builtin-presets/package.json +23 -10
  10. package/node_modules/@ykdz/template-builtin-presets/templates/foundation/.github/workflows/check-deployment-diagnostics.yml +30 -29
  11. package/node_modules/@ykdz/template-builtin-presets/templates/foundation/.github/workflows/check-deployment.yml +8 -21
  12. package/node_modules/@ykdz/template-builtin-presets/templates/foundation/.github/workflows/check-diagnostics.yml +21 -5
  13. package/node_modules/@ykdz/template-builtin-presets/templates/foundation/.github/workflows/check.yml +4 -2
  14. package/node_modules/@ykdz/template-builtin-presets/templates/foundation/AGENTS.md.template +9 -1
  15. package/node_modules/@ykdz/template-builtin-presets/templates/{shared/devcontainer/node-pnpm.Dockerfile → foundation/devcontainer/base.Dockerfile} +14 -1
  16. package/node_modules/@ykdz/template-builtin-presets/templates/foundation/gitignore +1 -0
  17. package/node_modules/@ykdz/template-builtin-presets/templates/foundation/pnpm-workspace.yaml +3 -0
  18. package/node_modules/@ykdz/template-builtin-presets/templates/foundation/scripts/node-test-count-reporter.ts +31 -0
  19. package/node_modules/@ykdz/template-builtin-presets/templates/foundation/scripts/run-rust-tests.ts +100 -0
  20. package/node_modules/@ykdz/template-builtin-presets/templates/foundation/scripts/run-turbo-boundaries.ts +74 -0
  21. package/node_modules/@ykdz/template-builtin-presets/templates/foundation/scripts/task-gates.ts +589 -0
  22. package/node_modules/@ykdz/template-builtin-presets/templates/foundation/turbo-projections/database-preparation.json +17 -0
  23. package/node_modules/@ykdz/template-builtin-presets/templates/foundation/turbo-projections/deployment.json +13 -0
  24. package/node_modules/@ykdz/template-builtin-presets/templates/foundation/turbo-projections/rust-toolchain.json +5 -0
  25. package/node_modules/@ykdz/template-builtin-presets/templates/foundation/turbo-projections/vue-hono-joint-e2e.json +13 -0
  26. package/node_modules/@ykdz/template-builtin-presets/templates/foundation/turbo.json +14 -15
  27. package/node_modules/@ykdz/template-builtin-presets/templates/foundation/typescript-config/turbo.json +30 -1
  28. package/node_modules/@ykdz/template-builtin-presets/templates/rust-bin/devcontainer/rust.Dockerfile +1 -5
  29. package/node_modules/@ykdz/template-builtin-presets/templates/rust-bin/tsconfig.scripts.json +12 -0
  30. package/node_modules/@ykdz/template-builtin-presets/templates/rust-bin/turbo.json +19 -4
  31. package/node_modules/@ykdz/template-builtin-presets/templates/shared/devcontainer/github-cli.Dockerfile +1 -3
  32. package/node_modules/@ykdz/template-builtin-presets/templates/shared/vue/TESTING.md +7 -0
  33. package/node_modules/@ykdz/template-builtin-presets/templates/shared/vue/src/components/CounterButton.vue +18 -0
  34. package/node_modules/@ykdz/template-builtin-presets/templates/shared/vue/test/counter.browser.test.ts +16 -0
  35. package/node_modules/@ykdz/template-builtin-presets/templates/shared/vue/test/{app.test.ts → counter.node.test.ts} +1 -0
  36. package/node_modules/@ykdz/template-builtin-presets/templates/shared/vue/tsconfig.test.json +1 -1
  37. package/node_modules/@ykdz/template-builtin-presets/templates/shared/vue/vitest.config.ts +50 -0
  38. package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication/check-artifact.ts +16 -5
  39. package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication/release.yml +5 -2
  40. package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication/turbo.json +5 -2
  41. package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication-setup/bridge.ts +1 -1
  42. package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/src/cli-command-identity.ts +0 -45
  43. package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/test/e2e/run-journeys.test.ts +11 -0
  44. package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/test/integration/command.test.ts +43 -39
  45. package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/test/unit/cli-command-identity.test.ts +52 -52
  46. package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/tsconfig.json +1 -1
  47. package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/turbo.json +58 -3
  48. package/node_modules/@ykdz/template-builtin-presets/templates/ts-lib/test/greet.test.ts +20 -0
  49. package/node_modules/@ykdz/template-builtin-presets/templates/ts-lib/tsconfig.json +1 -1
  50. package/node_modules/@ykdz/template-builtin-presets/templates/ts-lib/turbo.json +44 -1
  51. package/node_modules/@ykdz/template-builtin-presets/templates/vike-app/db/test/todos.test.ts +8 -11
  52. package/node_modules/@ykdz/template-builtin-presets/templates/vike-app/db/turbo.json +38 -1
  53. package/node_modules/@ykdz/template-builtin-presets/templates/vike-app/db-migrations/turbo.json +44 -1
  54. package/node_modules/@ykdz/template-builtin-presets/templates/vike-app/web/playwright.config.ts +18 -2
  55. package/node_modules/@ykdz/template-builtin-presets/templates/vike-app/web/test/counter.browser.test.ts +14 -0
  56. package/node_modules/@ykdz/template-builtin-presets/templates/vike-app/web/tsconfig.test.json +8 -2
  57. package/node_modules/@ykdz/template-builtin-presets/templates/vike-app/web/turbo.json +61 -1
  58. package/node_modules/@ykdz/template-builtin-presets/templates/vike-app/web/vitest.config.ts +29 -2
  59. package/node_modules/@ykdz/template-builtin-presets/templates/vue-app/src/App.vue +2 -12
  60. package/node_modules/@ykdz/template-builtin-presets/templates/vue-app/turbo.json +60 -2
  61. package/node_modules/@ykdz/template-builtin-presets/templates/vue-hono-app/api/test/app.test.ts +7 -6
  62. package/node_modules/@ykdz/template-builtin-presets/templates/vue-hono-app/api/tsconfig.json +2 -7
  63. package/node_modules/@ykdz/template-builtin-presets/templates/vue-hono-app/api/turbo.json +46 -1
  64. package/node_modules/@ykdz/template-builtin-presets/templates/vue-hono-app/web/src/App.vue +2 -11
  65. package/node_modules/@ykdz/template-builtin-presets/templates/vue-hono-app/web/turbo.json +57 -1
  66. package/node_modules/@ykdz/template-core/dist/ci-diagnostic-artifact.d.ts +1 -1
  67. package/node_modules/@ykdz/template-core/dist/ci-diagnostic-artifact.js +6 -3
  68. package/node_modules/@ykdz/template-core/dist/dependency-catalog.d.ts +0 -1
  69. package/node_modules/@ykdz/template-core/dist/dependency-catalog.js +0 -19
  70. package/node_modules/@ykdz/template-core/dist/module-graph.d.ts +0 -9
  71. package/node_modules/@ykdz/template-core/dist/module-graph.js +0 -40
  72. package/node_modules/@ykdz/template-core/dist/package-contribution.d.ts +2 -2
  73. package/node_modules/@ykdz/template-core/dist/package-contribution.js +2 -44
  74. package/node_modules/@ykdz/template-core/dist/pnpm-workspace.yaml +4 -1
  75. package/node_modules/@ykdz/template-core/dist/project-github.d.ts +0 -59
  76. package/node_modules/@ykdz/template-core/dist/project-github.js +7 -70
  77. package/node_modules/@ykdz/template-core/dist/renderer.d.ts +1 -0
  78. package/node_modules/@ykdz/template-core/dist/renderer.js +39 -1
  79. package/node_modules/@ykdz/template-core/dist/template-boundary-check.js +34 -16
  80. package/node_modules/@ykdz/template-core/package.json +0 -5
  81. package/package.json +4 -10
  82. package/node_modules/@ykdz/template-builtin-presets/templates/rust-bin/.github/workflows/check.yml +0 -23
  83. package/node_modules/@ykdz/template-builtin-presets/templates/ts-lib/.github/workflows/check.yml +0 -19
  84. package/node_modules/@ykdz/template-builtin-presets/templates/vue-app/.github/workflows/check.yml +0 -20
  85. package/node_modules/@ykdz/template-builtin-presets/templates/vue-app/vitest.config.ts +0 -8
  86. package/node_modules/@ykdz/template-builtin-presets/templates/vue-hono-app/api/vitest.config.ts +0 -15
  87. package/node_modules/@ykdz/template-builtin-presets/templates/vue-hono-app/web/vitest.config.ts +0 -10
@@ -31,13 +31,16 @@ function replayDefinitions(initialPackages) {
31
31
  migrations: initialPackages.require("migrations"),
32
32
  };
33
33
  }
34
- function foundation(packageDefinitions) {
34
+ function foundation(packageDefinitions, includeFrontendTools = false) {
35
35
  const workspacePackageGlobs = [
36
36
  ...new Set(Object.values(packageDefinitions).map((definition) => `${definition.path.split("/")[0]}/*`)),
37
37
  ];
38
38
  return {
39
39
  toolchains: {},
40
- editorCapabilities: ["oxc-format-lint", "vue", "tailwind", "vitest"],
40
+ editorCapabilities: [
41
+ "oxc-format-lint",
42
+ ...(includeFrontendTools ? ["vue", "tailwind", "vitest"] : []),
43
+ ],
41
44
  typescriptConfigurationPackage: { dependency: "required" },
42
45
  dependencyMaintenance: {
43
46
  ecosystems: ["npm", "github-actions", "docker"],
@@ -57,7 +60,9 @@ function webScripts() {
57
60
  "lint:fix": "oxlint --type-aware --format=unix . --fix",
58
61
  preview: "DATABASE_PROFILE=dev vike preview",
59
62
  start: "node ./dist/server/index.mjs",
60
- test: "vitest run --reporter=agent --silent=passed-only --passWithNoTests",
63
+ "browser:prepare": "playwright install chromium",
64
+ test: "vitest run --project=node --reporter=agent --silent=passed-only --passWithNoTests",
65
+ "test:browser": "vitest run --project=browser --reporter=agent --silent=passed-only",
61
66
  "test:e2e": "DATABASE_PROFILE=e2e playwright test",
62
67
  typecheck: "node --conditions=source scripts/run-vue-tsc.ts --build --noEmit --pretty false",
63
68
  };
@@ -71,7 +76,7 @@ function databaseScripts() {
71
76
  "format:write": "oxfmt --write .",
72
77
  lint: "oxlint --quiet --format=unix .",
73
78
  "lint:fix": "oxlint --format=unix . --fix",
74
- test: "DATABASE_PROFILE=test NODE_OPTIONS=--conditions=source vitest run --reporter=agent --silent=passed-only",
79
+ test: "DATABASE_PROFILE=test node --conditions=source --test --test-reporter=spec --test-reporter=./scripts/node-test-count-reporter.ts --test-reporter-destination=stdout --test-reporter-destination=stderr 'test/**/*.test.ts'",
75
80
  typecheck: "tsc -p tsconfig.json --noEmit --pretty false",
76
81
  };
77
82
  }
@@ -131,7 +136,7 @@ function webContribution(context, packageDefinitions = definitions(context)) {
131
136
  "web/server/api.ts",
132
137
  "web/test/playwright-teardown.ts",
133
138
  "web/test/e2e/app.spec.ts",
134
- "web/turbo.json",
139
+ "web/test/counter.browser.test.ts",
135
140
  "web/types/env.d.ts",
136
141
  "web/vitest.config.ts",
137
142
  "web/tsconfig.json",
@@ -147,6 +152,19 @@ function webContribution(context, packageDefinitions = definitions(context)) {
147
152
  multilineArrays: ["files"],
148
153
  },
149
154
  ...copyOperations(context, web.path, sourceFiles),
155
+ {
156
+ kind: "writeTextTemplate",
157
+ source: templateSources.vikeApp,
158
+ from: "web/turbo.json",
159
+ to: `${web.path}/turbo.json`,
160
+ replacements: { DATABASE_PACKAGE_NAME: db.name },
161
+ },
162
+ {
163
+ kind: "copyFile",
164
+ source: templateSources.vue,
165
+ from: "TESTING.md",
166
+ to: `${web.path}/TESTING.md`,
167
+ },
150
168
  {
151
169
  kind: "writeTextTemplate",
152
170
  source: templateSources.vikeApp,
@@ -251,6 +269,9 @@ function webContribution(context, packageDefinitions = definitions(context)) {
251
269
  typescript: "catalog:",
252
270
  vite: "catalog:",
253
271
  vitest: "catalog:",
272
+ "@vitest/browser-playwright": "catalog:",
273
+ playwright: "catalog:",
274
+ "vitest-browser-vue": "catalog:",
254
275
  "vue-tsc": "catalog:",
255
276
  },
256
277
  engines: { node: context.toolchain.nodeLtsMajor },
@@ -260,9 +281,12 @@ function webContribution(context, packageDefinitions = definitions(context)) {
260
281
  environmentNeeds: [
261
282
  playwrightBrowserAssetsEnvironmentNeed({ browser: "chromium", owner }),
262
283
  ],
263
- ciDiagnosticArtifacts: [{ kind: "playwright", owner }],
284
+ ciDiagnosticArtifacts: [
285
+ { kind: "playwright", owner },
286
+ { kind: "vitest-browser", owner },
287
+ ],
264
288
  foundation: {
265
- ...foundation(packageDefinitions),
289
+ ...foundation(packageDefinitions, true),
266
290
  deploymentCheck: {
267
291
  kind: "application-container-with-database-migrations",
268
292
  applicationPackageName: web.name,
@@ -373,8 +397,6 @@ function databaseContribution(context, packageDefinitions = definitions(context)
373
397
  oxlint: "catalog:",
374
398
  "oxlint-tsgolint": "catalog:",
375
399
  "typescript-7": "catalog:",
376
- vite: "catalog:",
377
- vitest: "catalog:",
378
400
  },
379
401
  engines: { node: context.toolchain.nodeLtsMajor },
380
402
  },
@@ -386,6 +408,12 @@ function databaseContribution(context, packageDefinitions = definitions(context)
386
408
  multilineArrays: ["files"],
387
409
  },
388
410
  ...copyOperations(context, db.path, sourceFiles),
411
+ ...["node-test-count-reporter.ts"].map((name) => ({
412
+ kind: "copyFile",
413
+ source: templateSources.foundation,
414
+ from: `scripts/${name}`,
415
+ to: `${db.path}/scripts/${name}`,
416
+ })),
389
417
  ],
390
418
  environmentNeeds: [],
391
419
  foundation: {
@@ -409,7 +437,6 @@ function migrationsContribution(context, packageDefinitions = definitions(contex
409
437
  "db-migrations/tsconfig.build.json",
410
438
  "db-migrations/drizzle/migrations/20260709120325_old_captain_flint/migration.sql",
411
439
  "db-migrations/drizzle/migrations/20260709120325_old_captain_flint/snapshot.json",
412
- "db-migrations/turbo.json",
413
440
  ];
414
441
  return {
415
442
  definition: migrations,
@@ -438,6 +465,13 @@ function migrationsContribution(context, packageDefinitions = definitions(contex
438
465
  multilineArrays: ["files"],
439
466
  },
440
467
  ...copyOperations(context, migrations.path, sourceFiles),
468
+ {
469
+ kind: "writeTextTemplate",
470
+ source: templateSources.vikeApp,
471
+ from: "db-migrations/turbo.json",
472
+ to: `${migrations.path}/turbo.json`,
473
+ replacements: { DATABASE_PACKAGE_NAME: db.name },
474
+ },
441
475
  {
442
476
  kind: "writeTextTemplate",
443
477
  source: templateSources.vikeApp,
@@ -19,7 +19,6 @@ function appContribution(options) {
19
19
  "index.html",
20
20
  "playwright.config.ts",
21
21
  "vite.config.ts",
22
- "vitest.config.ts",
23
22
  "turbo.json",
24
23
  "src/App.vue",
25
24
  "test/e2e/app.spec.ts",
@@ -49,6 +48,10 @@ function appContribution(options) {
49
48
  kind: "playwright",
50
49
  owner: { kind: "package-boundary", path: definition.path },
51
50
  },
51
+ {
52
+ kind: "vitest-browser",
53
+ owner: { kind: "package-boundary", path: definition.path },
54
+ },
52
55
  ],
53
56
  foundation: {
54
57
  toolchains: {},
@@ -11,7 +11,7 @@ function apiScripts() {
11
11
  lint: "oxlint --quiet --format=unix .",
12
12
  "lint:fix": "oxlint --format=unix . --fix",
13
13
  start: "node dist/server.js",
14
- test: "vitest run --reporter=agent --silent=passed-only",
14
+ test: "node --conditions=source --test --test-reporter=spec --test-reporter=./scripts/node-test-count-reporter.ts --test-reporter-destination=stdout --test-reporter-destination=stderr 'test/**/*.test.ts'",
15
15
  typecheck: "tsc -p tsconfig.json --noEmit --pretty false",
16
16
  };
17
17
  }
@@ -21,10 +21,13 @@ function webScripts() {
21
21
  typecheck: "node --conditions=source scripts/run-vue-tsc.ts --build --noEmit --pretty false",
22
22
  };
23
23
  }
24
- function packageFoundation(packagePath) {
24
+ function packageFoundation(packagePath, includeFrontendTools = false) {
25
25
  return {
26
26
  toolchains: {},
27
- editorCapabilities: ["oxc-format-lint", "vue", "tailwind", "vitest"],
27
+ editorCapabilities: [
28
+ "oxc-format-lint",
29
+ ...(includeFrontendTools ? ["vue", "tailwind", "vitest"] : []),
30
+ ],
28
31
  typescriptConfigurationPackage: { dependency: "required" },
29
32
  dependencyMaintenance: {
30
33
  ecosystems: ["npm", "github-actions", "docker"],
@@ -52,7 +55,6 @@ function apiContribution(context, definition = {
52
55
  };
53
56
  const sourceFiles = [
54
57
  "turbo.json",
55
- "vitest.config.ts",
56
58
  "tsconfig.json",
57
59
  "tsconfig.build.json",
58
60
  "src/index.ts",
@@ -75,6 +77,12 @@ function apiContribution(context, definition = {
75
77
  from: `api/${from}`,
76
78
  to: `${definition.path}/${from}`,
77
79
  }),
80
+ ...["node-test-count-reporter.ts"].map((name) => ({
81
+ kind: "copyFile",
82
+ source: templateSources.foundation,
83
+ from: `scripts/${name}`,
84
+ to: `${definition.path}/scripts/${name}`,
85
+ })),
78
86
  ];
79
87
  return {
80
88
  definition,
@@ -92,8 +100,6 @@ function apiContribution(context, definition = {
92
100
  oxlint: "catalog:",
93
101
  "oxlint-tsgolint": "catalog:",
94
102
  "typescript-7": "catalog:",
95
- vite: "catalog:",
96
- vitest: "catalog:",
97
103
  },
98
104
  engines: { node: context.toolchain.nodeLtsMajor },
99
105
  },
@@ -112,7 +118,6 @@ function webContribution(context, apiDefinition, definition = {
112
118
  "env.d.ts",
113
119
  "index.html",
114
120
  "vite.config.ts",
115
- "vitest.config.ts",
116
121
  "turbo.json",
117
122
  "src/api.ts",
118
123
  "src/App.vue",
@@ -138,8 +143,14 @@ function webContribution(context, apiDefinition, definition = {
138
143
  }),
139
144
  operations,
140
145
  environmentNeeds: [],
146
+ ciDiagnosticArtifacts: [
147
+ {
148
+ kind: "vitest-browser",
149
+ owner: { kind: "package-boundary", path: definition.path },
150
+ },
151
+ ],
141
152
  foundation: {
142
- ...packageFoundation(definition.path),
153
+ ...packageFoundation(definition.path, true),
143
154
  vueHonoJointE2e: {
144
155
  kind: "vue-hono-joint-e2e",
145
156
  apiPackageName: apiDefinition.name,
@@ -15,16 +15,32 @@
15
15
  "source": "./src/index.ts",
16
16
  "types": "./dist/src/index.d.ts",
17
17
  "default": "./dist/src/index.js"
18
+ },
19
+ "./task-gates": {
20
+ "source": "./templates/foundation/scripts/task-gates.ts",
21
+ "types": "./templates/foundation/scripts/task-gates.ts",
22
+ "default": "./templates/foundation/scripts/task-gates.ts"
23
+ },
24
+ "./node-test-count-reporter": {
25
+ "source": "./templates/foundation/scripts/node-test-count-reporter.ts",
26
+ "types": "./templates/foundation/scripts/node-test-count-reporter.ts",
27
+ "default": "./templates/foundation/scripts/node-test-count-reporter.ts"
28
+ },
29
+ "./turbo-boundaries": {
30
+ "source": "./templates/foundation/scripts/run-turbo-boundaries.ts",
31
+ "types": "./templates/foundation/scripts/run-turbo-boundaries.ts",
32
+ "default": "./templates/foundation/scripts/run-turbo-boundaries.ts"
18
33
  }
19
34
  },
20
35
  "scripts": {
21
36
  "build": "rm -rf dist && tsc -p tsconfig.build.json",
22
37
  "format:check": "oxfmt --list-different --config ../../oxfmt.config.ts .",
23
38
  "format:write": "oxfmt --write --config ../../oxfmt.config.ts .",
24
- "lint": "oxlint --quiet --format=unix --config ../../oxlint.config.ts --ignore-pattern dist --ignore-pattern templates . && oxlint --quiet --format=unix --config ../../oxlint.config.ts templates/ts-cli/publication-setup/bridge.ts",
25
- "lint:fix": "oxlint --format=unix --config ../../oxlint.config.ts --ignore-pattern dist --ignore-pattern templates . --fix && oxlint --format=unix --config ../../oxlint.config.ts templates/ts-cli/publication-setup/bridge.ts --fix",
26
- "test": "vitest run --config vitest.config.ts --reporter=agent --silent=passed-only --maxWorkers=1",
27
- "typecheck": "tsc -p tsconfig.json --noEmit --pretty false"
39
+ "lint": "oxlint --quiet --format=unix --config ../../oxlint.config.ts --ignore-pattern dist --ignore-pattern templates . && oxlint --quiet --format=unix --config ../../oxlint.config.ts templates/ts-cli/publication-setup/bridge.ts && oxlint --quiet --format=unix --config ../../oxlint.template-source.config.ts templates/foundation/scripts/task-gates.ts templates/foundation/scripts/node-test-count-reporter.ts templates/foundation/scripts/run-turbo-boundaries.ts",
40
+ "lint:fix": "oxlint --format=unix --config ../../oxlint.config.ts --ignore-pattern dist --ignore-pattern templates . --fix && oxlint --format=unix --config ../../oxlint.config.ts templates/ts-cli/publication-setup/bridge.ts --fix && oxlint --format=unix --config ../../oxlint.template-source.config.ts templates/foundation/scripts/task-gates.ts templates/foundation/scripts/node-test-count-reporter.ts templates/foundation/scripts/run-turbo-boundaries.ts --fix",
41
+ "test": "node --conditions=source --experimental-strip-types --import=./test-support/setup.ts --test --test-concurrency=2 --test-timeout=60000 --test-reporter=spec --test-reporter=@ykdz/template-builtin-presets/node-test-count-reporter --test-reporter-destination=stdout --test-reporter-destination=stderr 'src/**/*.light.test.ts'",
42
+ "test:integration": "node --conditions=source --experimental-strip-types scripts/run-installed-integration.ts",
43
+ "typecheck": "tsc -p tsconfig.json --noEmit --pretty false && tsc -p tsconfig.template-scripts.json --noEmit --pretty false"
28
44
  },
29
45
  "dependencies": {
30
46
  "@ykdz/template-core": "workspace:*",
@@ -50,6 +66,7 @@
50
66
  "@valibot/to-json-schema": "catalog:",
51
67
  "@vikejs/hono": "catalog:",
52
68
  "@vitejs/plugin-vue": "catalog:",
69
+ "@vitest/browser-playwright": "catalog:",
53
70
  "@vue/devtools-api": "catalog:",
54
71
  "@vue/tsconfig": "catalog:",
55
72
  "@ykdz/cli-contract": "catalog:",
@@ -71,6 +88,7 @@
71
88
  "vike-vue": "catalog:",
72
89
  "vite": "catalog:",
73
90
  "vitest": "catalog:",
91
+ "vitest-browser-vue": "catalog:",
74
92
  "vue": "catalog:",
75
93
  "vue-tsc": "catalog:"
76
94
  },
@@ -85,10 +103,5 @@
85
103
  "smol-toml",
86
104
  "unbash",
87
105
  "yaml"
88
- ],
89
- "turbo": {
90
- "tags": [
91
- "template-builtin-presets"
92
- ]
93
- }
106
+ ]
94
107
  }
@@ -15,23 +15,9 @@ concurrency:
15
15
 
16
16
  jobs:
17
17
  check:
18
- name: ${{ matrix.job_name }}
18
+ name: Full Check
19
19
  runs-on: ubuntu-latest
20
- timeout-minutes: ${{ matrix.timeout_minutes }}
21
- strategy:
22
- fail-fast: false
23
- matrix:
24
- include:
25
- - capability: root
26
- job_name: Root Check
27
- task_entrypoint: pnpm run check
28
- timeout_minutes: 30
29
- requires_docker: false
30
- - capability: deployment
31
- job_name: Deployment Check
32
- task_entrypoint: pnpm run check:deployment
33
- timeout_minutes: 45
34
- requires_docker: true
20
+ timeout-minutes: 45
35
21
  steps:
36
22
  - name: Checkout source
37
23
  uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
@@ -46,22 +32,26 @@ jobs:
46
32
  uses: pnpm/action-setup@d9184bf108216479bc5a137cc391f4d7b14c870b # v6.1.0
47
33
  with:
48
34
  cache: true
49
- - name: Set up Docker Buildx
50
- uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4.4.1
51
- if: matrix.requires_docker
52
35
  - name: Install dependencies
53
36
  run: pnpm install --frozen-lockfile
54
- - name: Run selected Check
55
- run: ${{ matrix.task_entrypoint }}
56
- - name: Stage Root Check diagnostics
57
- if: failure() && matrix.capability == 'root'
37
+ - name: Run Light Check
38
+ run: node --conditions=source scripts/task-gates.ts check
39
+ - name: Set up Docker Buildx
40
+ uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4.4.1
41
+ - name: Run Heavy Check
42
+ run: node --conditions=source scripts/task-gates.ts check:heavy
43
+ - name: Stage Check diagnostics
44
+ if: failure()
58
45
  env:
59
- DIAGNOSTIC_OWNER_PATHS: |-
60
- {{DIAGNOSTIC_OWNER_PATHS}}
46
+ PLAYWRIGHT_DIAGNOSTIC_OWNER_PATHS: |-
47
+ {{PLAYWRIGHT_DIAGNOSTIC_OWNER_PATHS}}
48
+ VITEST_BROWSER_DIAGNOSTIC_OWNER_PATHS: |-
49
+ {{VITEST_BROWSER_DIAGNOSTIC_OWNER_PATHS}}
61
50
  run: |
62
51
  rm -rf .template-ci-diagnostics
63
52
  mkdir -p .template-ci-diagnostics
64
- printf '%s\n' "$DIAGNOSTIC_OWNER_PATHS" | while IFS= read -r owner_path; do
53
+ printf '%s\n' "$PLAYWRIGHT_DIAGNOSTIC_OWNER_PATHS" | while IFS= read -r owner_path; do
54
+ [ -n "$owner_path" ] || continue
65
55
  for diagnostic_directory in test-results playwright-report; do
66
56
  source_path="$owner_path/$diagnostic_directory"
67
57
  destination_path=".template-ci-diagnostics/$owner_path/$diagnostic_directory"
@@ -71,11 +61,22 @@ jobs:
71
61
  fi
72
62
  done
73
63
  done
74
- - name: Upload Root Check diagnostics
75
- if: failure() && matrix.capability == 'root'
64
+ printf '%s\n' "$VITEST_BROWSER_DIAGNOSTIC_OWNER_PATHS" | while IFS= read -r owner_path; do
65
+ [ -n "$owner_path" ] || continue
66
+ diagnostic_directory=".vitest/attachments/failure-screenshots"
67
+ source_path="$owner_path/$diagnostic_directory"
68
+ destination_path=".template-ci-diagnostics/$owner_path/$diagnostic_directory"
69
+ if [ -d "$source_path" ]; then
70
+ mkdir -p "$(dirname "$destination_path")"
71
+ cp -R "$source_path" "$destination_path"
72
+ fi
73
+ done
74
+ - name: Upload Check diagnostics
75
+ if: failure()
76
76
  uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
77
77
  with:
78
- name: root-check-diagnostics
78
+ name: check-diagnostics
79
79
  path: .template-ci-diagnostics
80
+ include-hidden-files: true
80
81
  if-no-files-found: ignore
81
82
  retention-days: 7
@@ -15,23 +15,9 @@ concurrency:
15
15
 
16
16
  jobs:
17
17
  check:
18
- name: ${{ matrix.job_name }}
18
+ name: Full Check
19
19
  runs-on: ubuntu-latest
20
- timeout-minutes: ${{ matrix.timeout_minutes }}
21
- strategy:
22
- fail-fast: false
23
- matrix:
24
- include:
25
- - capability: root
26
- job_name: Root Check
27
- task_entrypoint: pnpm run check
28
- timeout_minutes: 30
29
- requires_docker: false
30
- - capability: deployment
31
- job_name: Deployment Check
32
- task_entrypoint: pnpm run check:deployment
33
- timeout_minutes: 45
34
- requires_docker: true
20
+ timeout-minutes: 45
35
21
  steps:
36
22
  - name: Checkout source
37
23
  uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
@@ -46,10 +32,11 @@ jobs:
46
32
  uses: pnpm/action-setup@d9184bf108216479bc5a137cc391f4d7b14c870b # v6.1.0
47
33
  with:
48
34
  cache: true
49
- - name: Set up Docker Buildx
50
- uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4.4.1
51
- if: matrix.requires_docker
52
35
  - name: Install dependencies
53
36
  run: pnpm install --frozen-lockfile
54
- - name: Run selected Check
55
- run: ${{ matrix.task_entrypoint }}
37
+ - name: Run Light Check
38
+ run: node --conditions=source scripts/task-gates.ts check
39
+ - name: Set up Docker Buildx
40
+ uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4.4.1
41
+ - name: Run Heavy Check
42
+ run: node --conditions=source scripts/task-gates.ts check:heavy
@@ -34,17 +34,22 @@ jobs:
34
34
  cache: true
35
35
  - name: Install dependencies
36
36
  run: pnpm install --frozen-lockfile
37
- - name: Run Root Check
38
- run: pnpm run check
37
+ - name: Run Light Check
38
+ run: node --conditions=source scripts/task-gates.ts check
39
+ - name: Run Heavy Check
40
+ run: node --conditions=source scripts/task-gates.ts check:heavy
39
41
  - name: Stage Root Check diagnostics
40
42
  if: failure()
41
43
  env:
42
- DIAGNOSTIC_OWNER_PATHS: |-
43
- {{DIAGNOSTIC_OWNER_PATHS}}
44
+ PLAYWRIGHT_DIAGNOSTIC_OWNER_PATHS: |-
45
+ {{PLAYWRIGHT_DIAGNOSTIC_OWNER_PATHS}}
46
+ VITEST_BROWSER_DIAGNOSTIC_OWNER_PATHS: |-
47
+ {{VITEST_BROWSER_DIAGNOSTIC_OWNER_PATHS}}
44
48
  run: |
45
49
  rm -rf .template-ci-diagnostics
46
50
  mkdir -p .template-ci-diagnostics
47
- printf '%s\n' "$DIAGNOSTIC_OWNER_PATHS" | while IFS= read -r owner_path; do
51
+ printf '%s\n' "$PLAYWRIGHT_DIAGNOSTIC_OWNER_PATHS" | while IFS= read -r owner_path; do
52
+ [ -n "$owner_path" ] || continue
48
53
  for diagnostic_directory in test-results playwright-report; do
49
54
  source_path="$owner_path/$diagnostic_directory"
50
55
  destination_path=".template-ci-diagnostics/$owner_path/$diagnostic_directory"
@@ -54,11 +59,22 @@ jobs:
54
59
  fi
55
60
  done
56
61
  done
62
+ printf '%s\n' "$VITEST_BROWSER_DIAGNOSTIC_OWNER_PATHS" | while IFS= read -r owner_path; do
63
+ [ -n "$owner_path" ] || continue
64
+ diagnostic_directory=".vitest/attachments/failure-screenshots"
65
+ source_path="$owner_path/$diagnostic_directory"
66
+ destination_path=".template-ci-diagnostics/$owner_path/$diagnostic_directory"
67
+ if [ -d "$source_path" ]; then
68
+ mkdir -p "$(dirname "$destination_path")"
69
+ cp -R "$source_path" "$destination_path"
70
+ fi
71
+ done
57
72
  - name: Upload Root Check diagnostics
58
73
  if: failure()
59
74
  uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
60
75
  with:
61
76
  name: root-check-diagnostics
62
77
  path: .template-ci-diagnostics
78
+ include-hidden-files: true
63
79
  if-no-files-found: ignore
64
80
  retention-days: 7
@@ -34,5 +34,7 @@ jobs:
34
34
  cache: true
35
35
  - name: Install dependencies
36
36
  run: pnpm install --frozen-lockfile
37
- - name: Run Root Check
38
- run: pnpm run check
37
+ - name: Run Light Check
38
+ run: node --conditions=source scripts/task-gates.ts check
39
+ - name: Run Heavy Check
40
+ run: node --conditions=source scripts/task-gates.ts check:heavy
@@ -6,12 +6,20 @@
6
6
 
7
7
  若这些限制与 Spec、Ticket、ADR 等权威本地文档冲突,应该以权威本地文档为准。
8
8
 
9
- - 开发自动化:非临时维护脚本必须使用 `scripts/**/*.ts` 中可擦除的 TypeScript,而不是 `.mjs` 等 JavaScript 脚本;归所属非构建 TypeScript 项目并受 format、lint、typecheck 覆盖,防止腐化;产品 build 不产出这些脚本。普通 Node 自动化使用原生 TypeScript 执行链。
9
+ - 开发自动化:非临时维护脚本必须使用 `scripts/**/*.ts` 中可擦除的 TypeScript,而不是 `.mjs` 等 JavaScript 脚本;归所属非构建 TypeScript 项目并受 format、lint、typecheck 覆盖,防止腐化;产品 build 不产出这些脚本。普通 Node 自动化使用原生 TypeScript 执行链
10
10
  - 临时脚本:编写临时脚本时,应该将其放到有临时目录语义的位置
11
11
  - 任务归属:优先使用工具原生配置;直接命令与简单 `&&` 编排写在所属 package manifest;只有复杂逻辑才新增 TypeScript script
12
+ - 脚本职责:新增 `package.json scripts` 时,同步在所属 `turbo.json` 声明任务及唯一准确职责;附加标签可自定义,包标签不能替代任务职责。子包自管任务与包标签,根包维护自身任务和全局政策;缺失、未知或冲突职责应使检查失败
13
+ - 按需工作:现有专门职责之外、需单独选择的工作显式声明 `work:on-demand`,仍接受全仓校验。用于证明正确性、兼容性或可发布性的工作必须进入正式验收或其内部步骤,不能通过改名或按需归类避开验收
14
+ - 任务配置:依赖交由 Turbo 原生图表达;有职责的无命令聚合节点必须能到达实际工作,必要的无职责中转节点可以保留。改名或删除脚本时同步清理失效定义与引用
15
+ - 公共入口:保留 `check`、`check:heavy`、`check:full`、`fix` 的统一校验与执行接线,按职责发现任务;CI 直接调用同一实现并校验公共命令接线。开发调试可直接调用所属叶命令
16
+ - 验收唯一入口:同一验收职责只保留一个正式入口和一份实现,开发、CI 与发布复用该实现;仅供内部调用的参数化步骤留在所属实现中
17
+ - 测试表达:默认优先在用例位置使用所属运行器的原生断言、普通循环和局部异步协调表达行为;简单重复不构成提取 helper 的理由。确有复用需求且维护收益足够时才提取职责具体的资产;生成资产必须保持模板源所有权,并由所属包的格式、lint、类型检查、相关行为任务和缓存输入覆盖
12
18
  - 包边界:本地文件系统访问留在所属包内;跨包代码与资源通过声明依赖和公开 exports 获取,跨包任务交根 Turbo/pnpm 编排。不要以根目录定位器、跨包物理路径或 `@boundaries-ignore` 绕过边界
13
19
  - 最小充分测试:不要过度编写单元测试,包括为硬删除设计的防回归测试(可以临时存在,但是硬删除完成后必须删除,最好放在可丢弃分支中方便清理)、为文档内容或任何文件编写的存在性测试等,确保测试覆盖且仅覆盖业务逻辑本身的正负项
14
20
  - YAGNI:除非有明确目的,否则不要规划收益不足的安全边界等内容。简单的代码在未来真的遇到新需求时,重构起来远比一个充满防御性冗余设计的复杂系统要容易得多
15
21
  - 正式处理链路:开发、回放和端到端验收应复用生产的正式处理链路与制品,入口和配置可不同;同类流程只保留一份实现,迁移后删除旧链路,局部测试不得冒充全链路验收
16
22
  - 用户界面:不要将任何技术细节泄漏到用户可见的 UI 中
17
23
  - 逐步验收:先通过改动相关的局部门禁,交付前再执行较重的验收任务
24
+ - 减少持久文档:以代码和少量权威文档作为事实依据;只有明确被允许时,才新增或修改持久文档。过程记录、临时方案等放入临时目录
25
+ - 彻底迁移:迁移或迭代替换旧实现时,同步删除已失效的文档、逻辑和代码。只有任务明确要求兼容或临时绕行时,才保留相应旧内容
@@ -6,7 +6,20 @@ ENV PNPM_HOME="/pnpm"
6
6
  ENV PATH="$PNPM_HOME/bin:$PNPM_HOME:$PATH"
7
7
  ENV COREPACK_ENABLE_DOWNLOAD_PROMPT=0
8
8
  RUN apt-get update \
9
- && apt-get install -y --no-install-recommends ca-certificates git procps bubblewrap \
9
+ && apt-get install -y --no-install-recommends \
10
+ bubblewrap \
11
+ ca-certificates \
12
+ curl \
13
+ file \
14
+ git \
15
+ iproute2 \
16
+ jq \
17
+ openssh-client \
18
+ procps \
19
+ python-is-python3 \
20
+ python3 \
21
+ ripgrep \
22
+ unzip \
10
23
  && rm -rf /var/lib/apt/lists/* \
11
24
  && git config --system init.defaultBranch main \
12
25
  && install -d -m 0755 "$PNPM_HOME" "$PNPM_HOME/bin" \
@@ -6,6 +6,7 @@ target/
6
6
  coverage/
7
7
  .env
8
8
  .template/
9
+ .vitest/
9
10
  data/
10
11
  playwright-report/
11
12
  test-results/
@@ -23,10 +23,13 @@ allowBuilds:
23
23
  esbuild: true
24
24
 
25
25
  catalog:
26
+ "@vitest/browser-playwright": ^5.0.0
26
27
  "@types/node": ^24.13.3
27
28
  oxfmt: ^0.71.0
28
29
  oxlint: ^1.77.0
29
30
  oxlint-tsgolint: ^7.0.2001
31
+ playwright: 1.64.0
30
32
  turbo: 2.11.7
31
33
  typescript-7: npm:typescript@^7.0.2
32
34
  valibot: ^1.4.2
35
+ vitest-browser-vue: ^3.1.0
@@ -0,0 +1,31 @@
1
+ const emptySuiteDiagnostic =
2
+ "没有执行任何 Node 业务测试用例;请检查测试 glob 与测试内容";
3
+
4
+ function isRecord(value: unknown): value is Record<string, unknown> {
5
+ return typeof value === "object" && value !== null && !Array.isArray(value);
6
+ }
7
+
8
+ export default async function* requireExecutedTestCase(
9
+ events: AsyncIterable<unknown>,
10
+ ): AsyncGenerator<string> {
11
+ let count = 0;
12
+
13
+ for await (const event of events) {
14
+ if (
15
+ !isRecord(event) ||
16
+ (event.type !== "test:pass" && event.type !== "test:fail")
17
+ ) {
18
+ continue;
19
+ }
20
+ const data = event.data;
21
+ if (!isRecord(data) || typeof data.entryFile !== "string") continue;
22
+ if (data.skip || data.todo) continue;
23
+ if (!isRecord(data.details) || data.details.type !== "test") continue;
24
+ count += 1;
25
+ }
26
+
27
+ if (count === 0) {
28
+ process.exitCode = 1;
29
+ yield `${emptySuiteDiagnostic}\n`;
30
+ }
31
+ }