@ykdz/template 0.0.41 → 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.
- package/node_modules/@ykdz/template-builtin-presets/dist/src/foundation.js +111 -99
- package/node_modules/@ykdz/template-builtin-presets/dist/src/rust-bin/definition.js +29 -4
- package/node_modules/@ykdz/template-builtin-presets/dist/src/shared/vue.js +11 -2
- package/node_modules/@ykdz/template-builtin-presets/dist/src/ts-cli/definition.js +14 -4
- package/node_modules/@ykdz/template-builtin-presets/dist/src/ts-lib/definition.js +13 -0
- package/node_modules/@ykdz/template-builtin-presets/dist/src/vike-app/definition.js +44 -10
- package/node_modules/@ykdz/template-builtin-presets/dist/src/vue-app/definition.js +4 -1
- package/node_modules/@ykdz/template-builtin-presets/dist/src/vue-hono-app/definition.js +19 -8
- package/node_modules/@ykdz/template-builtin-presets/package.json +23 -10
- package/node_modules/@ykdz/template-builtin-presets/templates/foundation/.github/workflows/check-deployment-diagnostics.yml +30 -29
- package/node_modules/@ykdz/template-builtin-presets/templates/foundation/.github/workflows/check-deployment.yml +8 -21
- package/node_modules/@ykdz/template-builtin-presets/templates/foundation/.github/workflows/check-diagnostics.yml +21 -5
- package/node_modules/@ykdz/template-builtin-presets/templates/foundation/.github/workflows/check.yml +4 -2
- package/node_modules/@ykdz/template-builtin-presets/templates/foundation/AGENTS.md.template +7 -1
- package/node_modules/@ykdz/template-builtin-presets/templates/foundation/gitignore +1 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/foundation/pnpm-workspace.yaml +3 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/foundation/scripts/node-test-count-reporter.ts +31 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/foundation/scripts/run-rust-tests.ts +100 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/foundation/scripts/run-turbo-boundaries.ts +74 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/foundation/scripts/task-gates.ts +589 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/foundation/turbo-projections/database-preparation.json +17 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/foundation/turbo-projections/deployment.json +13 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/foundation/turbo-projections/rust-toolchain.json +5 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/foundation/turbo-projections/vue-hono-joint-e2e.json +13 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/foundation/turbo.json +14 -15
- package/node_modules/@ykdz/template-builtin-presets/templates/foundation/typescript-config/turbo.json +30 -1
- package/node_modules/@ykdz/template-builtin-presets/templates/rust-bin/tsconfig.scripts.json +12 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/rust-bin/turbo.json +19 -4
- package/node_modules/@ykdz/template-builtin-presets/templates/shared/vue/TESTING.md +7 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/shared/vue/src/components/CounterButton.vue +18 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/shared/vue/test/counter.browser.test.ts +16 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/shared/vue/test/{app.test.ts → counter.node.test.ts} +1 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/shared/vue/tsconfig.test.json +1 -1
- package/node_modules/@ykdz/template-builtin-presets/templates/shared/vue/vitest.config.ts +50 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication/check-artifact.ts +16 -5
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication/release.yml +5 -2
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication/turbo.json +5 -2
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication-setup/bridge.ts +1 -1
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/src/cli-command-identity.ts +0 -45
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/test/e2e/run-journeys.test.ts +11 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/test/integration/command.test.ts +43 -39
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/test/unit/cli-command-identity.test.ts +52 -52
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/tsconfig.json +1 -1
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/turbo.json +58 -3
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-lib/test/greet.test.ts +20 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-lib/tsconfig.json +1 -1
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-lib/turbo.json +44 -1
- package/node_modules/@ykdz/template-builtin-presets/templates/vike-app/db/test/todos.test.ts +8 -11
- package/node_modules/@ykdz/template-builtin-presets/templates/vike-app/db/turbo.json +38 -1
- package/node_modules/@ykdz/template-builtin-presets/templates/vike-app/db-migrations/turbo.json +44 -1
- package/node_modules/@ykdz/template-builtin-presets/templates/vike-app/web/playwright.config.ts +18 -2
- package/node_modules/@ykdz/template-builtin-presets/templates/vike-app/web/test/counter.browser.test.ts +14 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/vike-app/web/tsconfig.test.json +8 -2
- package/node_modules/@ykdz/template-builtin-presets/templates/vike-app/web/turbo.json +61 -1
- package/node_modules/@ykdz/template-builtin-presets/templates/vike-app/web/vitest.config.ts +29 -2
- package/node_modules/@ykdz/template-builtin-presets/templates/vue-app/src/App.vue +2 -12
- package/node_modules/@ykdz/template-builtin-presets/templates/vue-app/turbo.json +60 -2
- package/node_modules/@ykdz/template-builtin-presets/templates/vue-hono-app/api/test/app.test.ts +7 -6
- package/node_modules/@ykdz/template-builtin-presets/templates/vue-hono-app/api/tsconfig.json +2 -7
- package/node_modules/@ykdz/template-builtin-presets/templates/vue-hono-app/api/turbo.json +46 -1
- package/node_modules/@ykdz/template-builtin-presets/templates/vue-hono-app/web/src/App.vue +2 -11
- package/node_modules/@ykdz/template-builtin-presets/templates/vue-hono-app/web/turbo.json +57 -1
- package/node_modules/@ykdz/template-core/dist/ci-diagnostic-artifact.d.ts +1 -1
- package/node_modules/@ykdz/template-core/dist/ci-diagnostic-artifact.js +6 -3
- package/node_modules/@ykdz/template-core/dist/module-graph.d.ts +0 -9
- package/node_modules/@ykdz/template-core/dist/module-graph.js +0 -40
- package/node_modules/@ykdz/template-core/dist/package-contribution.d.ts +2 -2
- package/node_modules/@ykdz/template-core/dist/package-contribution.js +2 -44
- package/node_modules/@ykdz/template-core/dist/pnpm-workspace.yaml +3 -0
- package/node_modules/@ykdz/template-core/dist/project-github.js +7 -3
- package/node_modules/@ykdz/template-core/dist/renderer.d.ts +1 -0
- package/node_modules/@ykdz/template-core/dist/renderer.js +39 -1
- package/node_modules/@ykdz/template-core/dist/template-boundary-check.js +34 -16
- package/node_modules/@ykdz/template-core/package.json +0 -5
- package/package.json +4 -10
- package/node_modules/@ykdz/template-builtin-presets/templates/rust-bin/.github/workflows/check.yml +0 -23
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-lib/.github/workflows/check.yml +0 -19
- package/node_modules/@ykdz/template-builtin-presets/templates/vue-app/.github/workflows/check.yml +0 -20
- package/node_modules/@ykdz/template-builtin-presets/templates/vue-app/vitest.config.ts +0 -8
- package/node_modules/@ykdz/template-builtin-presets/templates/vue-hono-app/api/vitest.config.ts +0 -15
- package/node_modules/@ykdz/template-builtin-presets/templates/vue-hono-app/web/vitest.config.ts +0 -10
|
@@ -2,8 +2,64 @@
|
|
|
2
2
|
"extends": ["//"],
|
|
3
3
|
"tags": ["app"],
|
|
4
4
|
"tasks": {
|
|
5
|
+
"browser:prepare": {
|
|
6
|
+
"cache": false,
|
|
7
|
+
"outputs": [],
|
|
8
|
+
"tags": ["work:preparation"]
|
|
9
|
+
},
|
|
5
10
|
"build": {
|
|
6
|
-
"
|
|
11
|
+
"cache": true,
|
|
12
|
+
"dependsOn": ["^build"],
|
|
13
|
+
"outputs": ["dist/**"],
|
|
14
|
+
"tags": ["quality:light"]
|
|
15
|
+
},
|
|
16
|
+
"dev": {
|
|
17
|
+
"cache": false,
|
|
18
|
+
"outputs": [],
|
|
19
|
+
"tags": ["work:development"]
|
|
20
|
+
},
|
|
21
|
+
"format:check": {
|
|
22
|
+
"cache": true,
|
|
23
|
+
"outputs": [],
|
|
24
|
+
"tags": ["quality:light"]
|
|
25
|
+
},
|
|
26
|
+
"format:write": {
|
|
27
|
+
"cache": false,
|
|
28
|
+
"dependsOn": ["lint:fix"],
|
|
29
|
+
"outputs": [],
|
|
30
|
+
"tags": ["work:repair"]
|
|
31
|
+
},
|
|
32
|
+
"lint": {
|
|
33
|
+
"cache": true,
|
|
34
|
+
"outputs": [],
|
|
35
|
+
"tags": ["quality:light"]
|
|
36
|
+
},
|
|
37
|
+
"lint:fix": {
|
|
38
|
+
"cache": false,
|
|
39
|
+
"outputs": [],
|
|
40
|
+
"tags": ["work:repair"]
|
|
41
|
+
},
|
|
42
|
+
"preview": {
|
|
43
|
+
"cache": false,
|
|
44
|
+
"outputs": [],
|
|
45
|
+
"tags": ["work:development"]
|
|
46
|
+
},
|
|
47
|
+
"test": {
|
|
48
|
+
"cache": true,
|
|
49
|
+
"outputs": [],
|
|
50
|
+
"tags": ["quality:light"]
|
|
51
|
+
},
|
|
52
|
+
"test:browser": {
|
|
53
|
+
"cache": true,
|
|
54
|
+
"dependsOn": ["browser:prepare"],
|
|
55
|
+
"outputs": [],
|
|
56
|
+
"tags": ["quality:heavy"]
|
|
57
|
+
},
|
|
58
|
+
"typecheck": {
|
|
59
|
+
"cache": true,
|
|
60
|
+
"dependsOn": ["^typecheck"],
|
|
61
|
+
"outputs": [],
|
|
62
|
+
"tags": ["quality:light"]
|
|
7
63
|
}
|
|
8
64
|
}
|
|
9
65
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ComponentOwner } from "./module-graph.ts";
|
|
2
2
|
/** Closed, owner-scoped native evidence a Package Contribution may retain in CI. */
|
|
3
3
|
export type CiDiagnosticArtifactDeclaration = {
|
|
4
|
-
readonly kind: "playwright";
|
|
4
|
+
readonly kind: "playwright" | "vitest-browser";
|
|
5
5
|
readonly owner: ComponentOwner;
|
|
6
6
|
};
|
|
7
7
|
/**
|
|
@@ -28,7 +28,7 @@ export function assertCiDiagnosticArtifactDeclaration(value) {
|
|
|
28
28
|
if (!isRecord(value) || !hasExactKeys(value, ["kind", "owner"])) {
|
|
29
29
|
throw new Error("CI Diagnostic Artifact declarations may contain only kind and owner");
|
|
30
30
|
}
|
|
31
|
-
if (value.kind !== "playwright") {
|
|
31
|
+
if (value.kind !== "playwright" && value.kind !== "vitest-browser") {
|
|
32
32
|
throw new Error("Unsupported CI Diagnostic Artifact kind");
|
|
33
33
|
}
|
|
34
34
|
if (!isRecord(value.owner) || !hasExactKeys(value.owner, ["kind", "path"])) {
|
|
@@ -42,7 +42,7 @@ export function assertCiDiagnosticArtifactDeclaration(value) {
|
|
|
42
42
|
throw new Error("CI Diagnostic Artifact owner has an unsafe Package Boundary path");
|
|
43
43
|
}
|
|
44
44
|
return {
|
|
45
|
-
kind:
|
|
45
|
+
kind: value.kind,
|
|
46
46
|
owner: value.owner.kind === "workspace-orchestration"
|
|
47
47
|
? { kind: "workspace-orchestration", path: "." }
|
|
48
48
|
: { kind: "package-boundary", path: value.owner.path },
|
|
@@ -69,5 +69,8 @@ export function composeCiDiagnosticArtifacts(options) {
|
|
|
69
69
|
const key = `${declaration.kind}:${declaration.owner.path}`;
|
|
70
70
|
artifacts.set(key, declaration);
|
|
71
71
|
}
|
|
72
|
-
return [...artifacts.values()].toSorted((left, right) =>
|
|
72
|
+
return [...artifacts.values()].toSorted((left, right) => {
|
|
73
|
+
const ownerOrder = left.owner.path.localeCompare(right.owner.path);
|
|
74
|
+
return ownerOrder === 0 ? left.kind.localeCompare(right.kind) : ownerOrder;
|
|
75
|
+
});
|
|
73
76
|
}
|
|
@@ -46,15 +46,6 @@ export declare function normalizeEnvironmentNeeds(options: {
|
|
|
46
46
|
export declare function parseEnvironmentNeedsMetadata(value: unknown): EnvironmentNeedsMetadata;
|
|
47
47
|
export declare function rustToolchainEnvironmentNeed(owner: ComponentOwner): RustToolchainEnvironmentNeed;
|
|
48
48
|
export declare function dockerEngineEnvironmentNeed(): DockerEngineEnvironmentNeed;
|
|
49
|
-
export declare const qualityTaskVocabulary: readonly ["format:check", "lint", "typecheck", "build", "test", "test:e2e"];
|
|
50
|
-
export declare function renderTurboRunCommand(taskNames: readonly string[], args?: readonly string[], options?: {
|
|
51
|
-
readonly outputLogs?: "errors-only" | "full";
|
|
52
|
-
readonly continueAfterFailure?: boolean;
|
|
53
|
-
readonly taskPrefix?: boolean;
|
|
54
|
-
}): string;
|
|
55
|
-
export declare function renderRootCheckCommand(additionalTasks?: readonly string[]): string;
|
|
56
|
-
export declare function renderDeploymentCheckCommand(): string;
|
|
57
|
-
export declare function renderFixCommand(): string;
|
|
58
49
|
export declare function playwrightBrowserAssetsEnvironmentNeed(options: {
|
|
59
50
|
readonly browser: "chromium";
|
|
60
51
|
readonly owner: ComponentOwner;
|
|
@@ -152,46 +152,6 @@ export function rustToolchainEnvironmentNeed(owner) {
|
|
|
152
152
|
export function dockerEngineEnvironmentNeed() {
|
|
153
153
|
return { kind: "docker-engine" };
|
|
154
154
|
}
|
|
155
|
-
export const qualityTaskVocabulary = [
|
|
156
|
-
"format:check",
|
|
157
|
-
"lint",
|
|
158
|
-
"typecheck",
|
|
159
|
-
"build",
|
|
160
|
-
"test",
|
|
161
|
-
"test:e2e",
|
|
162
|
-
];
|
|
163
|
-
export function renderTurboRunCommand(taskNames, args = [], options = {}) {
|
|
164
|
-
return [
|
|
165
|
-
"turbo run",
|
|
166
|
-
...taskNames,
|
|
167
|
-
...args,
|
|
168
|
-
...(options.continueAfterFailure
|
|
169
|
-
? ["--continue=dependencies-successful"]
|
|
170
|
-
: []),
|
|
171
|
-
`--output-logs=${options.outputLogs ?? "errors-only"}`,
|
|
172
|
-
"--log-order=grouped",
|
|
173
|
-
...(options.taskPrefix ? ["--log-prefix=task"] : []),
|
|
174
|
-
].join(" ");
|
|
175
|
-
}
|
|
176
|
-
export function renderRootCheckCommand(additionalTasks = []) {
|
|
177
|
-
return [
|
|
178
|
-
"pnpm run boundaries",
|
|
179
|
-
renderTurboRunCommand([...qualityTaskVocabulary, ...additionalTasks], [], {
|
|
180
|
-
continueAfterFailure: true,
|
|
181
|
-
taskPrefix: true,
|
|
182
|
-
}),
|
|
183
|
-
].join(" && ");
|
|
184
|
-
}
|
|
185
|
-
export function renderDeploymentCheckCommand() {
|
|
186
|
-
return renderTurboRunCommand(["deployment"], [], { taskPrefix: true });
|
|
187
|
-
}
|
|
188
|
-
export function renderFixCommand() {
|
|
189
|
-
return renderTurboRunCommand(["lint:fix", "format:write"], [], {
|
|
190
|
-
continueAfterFailure: true,
|
|
191
|
-
outputLogs: "full",
|
|
192
|
-
taskPrefix: true,
|
|
193
|
-
});
|
|
194
|
-
}
|
|
195
155
|
export function playwrightBrowserAssetsEnvironmentNeed(options) {
|
|
196
156
|
return {
|
|
197
157
|
kind: "playwright-browser-assets",
|
|
@@ -80,9 +80,9 @@ export type PackageContribution = {
|
|
|
80
80
|
/** Closed native CI evidence owned by this Package Boundary. */
|
|
81
81
|
readonly ciDiagnosticArtifacts?: readonly CiDiagnosticArtifactDeclaration[];
|
|
82
82
|
};
|
|
83
|
-
/**
|
|
83
|
+
/** 校验 CLI 命令名的格式及工作区内是否重名。 */
|
|
84
84
|
export declare function validateCliCommandName(commandName: string, occupiedCommandNames?: readonly string[]): string;
|
|
85
|
-
/**
|
|
85
|
+
/** 校验完整生成计划中的命令名格式和唯一性。 */
|
|
86
86
|
export declare function assertPackageContributionCommandNames(contributions: readonly PackageContribution[]): readonly PackageContribution[];
|
|
87
87
|
export declare function assertPackageContribution(contribution: PackageContribution, provenance?: {
|
|
88
88
|
readonly definitionName?: string;
|
|
@@ -6,46 +6,7 @@ const operationPath = (operation) => {
|
|
|
6
6
|
return operation.path;
|
|
7
7
|
return "";
|
|
8
8
|
};
|
|
9
|
-
|
|
10
|
-
"aux",
|
|
11
|
-
"bash",
|
|
12
|
-
"bun",
|
|
13
|
-
"cmd",
|
|
14
|
-
"com1",
|
|
15
|
-
"com2",
|
|
16
|
-
"com3",
|
|
17
|
-
"com4",
|
|
18
|
-
"com5",
|
|
19
|
-
"com6",
|
|
20
|
-
"com7",
|
|
21
|
-
"com8",
|
|
22
|
-
"com9",
|
|
23
|
-
"con",
|
|
24
|
-
"corepack",
|
|
25
|
-
"deno",
|
|
26
|
-
"git",
|
|
27
|
-
"lpt1",
|
|
28
|
-
"lpt2",
|
|
29
|
-
"lpt3",
|
|
30
|
-
"lpt4",
|
|
31
|
-
"lpt5",
|
|
32
|
-
"lpt6",
|
|
33
|
-
"lpt7",
|
|
34
|
-
"lpt8",
|
|
35
|
-
"lpt9",
|
|
36
|
-
"node",
|
|
37
|
-
"nul",
|
|
38
|
-
"npm",
|
|
39
|
-
"npx",
|
|
40
|
-
"pnpm",
|
|
41
|
-
"powershell",
|
|
42
|
-
"prn",
|
|
43
|
-
"pwsh",
|
|
44
|
-
"sh",
|
|
45
|
-
"yarn",
|
|
46
|
-
"zsh",
|
|
47
|
-
]);
|
|
48
|
-
/** Validates the portable executable name promised by a CLI Package Boundary. */
|
|
9
|
+
/** 校验 CLI 命令名的格式及工作区内是否重名。 */
|
|
49
10
|
export function validateCliCommandName(commandName, occupiedCommandNames = []) {
|
|
50
11
|
if (/[/\\]/u.test(commandName)) {
|
|
51
12
|
throw new Error(`CLI command name must not be a path; received ${JSON.stringify(commandName)}`);
|
|
@@ -62,9 +23,6 @@ export function validateCliCommandName(commandName, occupiedCommandNames = []) {
|
|
|
62
23
|
if (!/^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/u.test(commandName)) {
|
|
63
24
|
throw new Error(`CLI command name must use lowercase ASCII letters, digits, and single hyphens; received ${JSON.stringify(commandName)}`);
|
|
64
25
|
}
|
|
65
|
-
if (reservedSystemToolNames.has(commandName)) {
|
|
66
|
-
throw new Error(`CLI command name is a reserved system tool; received ${JSON.stringify(commandName)}`);
|
|
67
|
-
}
|
|
68
26
|
if (occupiedCommandNames.includes(commandName)) {
|
|
69
27
|
throw new Error(`CLI command name is already used by another workspace package; received ${JSON.stringify(commandName)}`);
|
|
70
28
|
}
|
|
@@ -77,7 +35,7 @@ function manifestBinEntries(contribution) {
|
|
|
77
35
|
}
|
|
78
36
|
return Object.entries(bin);
|
|
79
37
|
}
|
|
80
|
-
/**
|
|
38
|
+
/** 校验完整生成计划中的命令名格式和唯一性。 */
|
|
81
39
|
export function assertPackageContributionCommandNames(contributions) {
|
|
82
40
|
const commandOwner = new Map();
|
|
83
41
|
for (const contribution of contributions) {
|
|
@@ -26,6 +26,7 @@ catalog:
|
|
|
26
26
|
"@devcontainers/cli": 0.89.0
|
|
27
27
|
"@hono/node-server": ^2.0.12
|
|
28
28
|
"@playwright/test": 1.64.0
|
|
29
|
+
"@vitest/browser-playwright": ^5.0.0
|
|
29
30
|
"@tailwindcss/vite": ^4.3.3
|
|
30
31
|
"@types/node": ^24.13.3
|
|
31
32
|
"@types/web-bluetooth": ^0.0.21
|
|
@@ -48,6 +49,7 @@ catalog:
|
|
|
48
49
|
spdx-expression-parse: ^5.0.0
|
|
49
50
|
"@types/spdx-expression-parse": ^4.0.0
|
|
50
51
|
pinia: ^4.0.2
|
|
52
|
+
playwright: 1.64.0
|
|
51
53
|
srvx: ^1.0.0
|
|
52
54
|
tailwindcss: ^4.3.3
|
|
53
55
|
tar: ^7.5.22
|
|
@@ -60,6 +62,7 @@ catalog:
|
|
|
60
62
|
vike: ^0.4.260
|
|
61
63
|
vike-vue: ^0.9.12
|
|
62
64
|
vitest: ^5.0.0
|
|
65
|
+
vitest-browser-vue: ^3.1.0
|
|
63
66
|
vue: ^3.5.40
|
|
64
67
|
vue-tsc: ^3.3.9
|
|
65
68
|
yaml: ^2.9.0
|
|
@@ -33,10 +33,14 @@ export function projectCheckWorkflowTemplateReplacements(options) {
|
|
|
33
33
|
});
|
|
34
34
|
if (declarations.length === 0)
|
|
35
35
|
return {};
|
|
36
|
+
const ownerPaths = (kind) => declarations
|
|
37
|
+
.filter((declaration) => declaration.kind === kind)
|
|
38
|
+
.map((declaration) => declaration.owner.path)
|
|
39
|
+
.toSorted()
|
|
40
|
+
.join("\n ");
|
|
36
41
|
return {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
.join("\n "),
|
|
42
|
+
PLAYWRIGHT_DIAGNOSTIC_OWNER_PATHS: ownerPaths("playwright"),
|
|
43
|
+
VITEST_BROWSER_DIAGNOSTIC_OWNER_PATHS: ownerPaths("vitest-browser"),
|
|
40
44
|
};
|
|
41
45
|
}
|
|
42
46
|
export function projectDependabotConfig(policy) {
|
|
@@ -124,13 +124,17 @@ async function renderMergeJson(operation, options) {
|
|
|
124
124
|
}
|
|
125
125
|
async function renderMergeJsonTemplate(operation, options) {
|
|
126
126
|
const sourcePath = resolveTemplateSource(operation.source, operation.from);
|
|
127
|
+
const sourceText = await readFile(sourcePath, "utf8");
|
|
127
128
|
let patch;
|
|
128
129
|
try {
|
|
129
|
-
patch = JSON.parse(
|
|
130
|
+
patch = JSON.parse(sourceText);
|
|
130
131
|
}
|
|
131
132
|
catch (error) {
|
|
132
133
|
throw new Error(`Invalid JSON Template Source ${operation.from}: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
|
|
133
134
|
}
|
|
135
|
+
if (operation.replacements !== undefined) {
|
|
136
|
+
patch = replaceJsonTemplateVariables(patch, operation.replacements);
|
|
137
|
+
}
|
|
134
138
|
await mergeJsonIntoFile({
|
|
135
139
|
options,
|
|
136
140
|
patch,
|
|
@@ -140,6 +144,40 @@ async function renderMergeJsonTemplate(operation, options) {
|
|
|
140
144
|
nestedKeyOrder: operation.nestedKeyOrder,
|
|
141
145
|
});
|
|
142
146
|
}
|
|
147
|
+
function replaceJsonTemplateVariables(value, replacements) {
|
|
148
|
+
const used = new Set();
|
|
149
|
+
const replaceString = (source) => source.replaceAll(/\{\{([A-Za-z][A-Za-z0-9_]*)\}\}/g, (_placeholder, name) => {
|
|
150
|
+
const replacement = replacements[name];
|
|
151
|
+
if (replacement === undefined) {
|
|
152
|
+
throw new Error(`JSON 模板缺少变量:${name}`);
|
|
153
|
+
}
|
|
154
|
+
used.add(name);
|
|
155
|
+
return replacement;
|
|
156
|
+
});
|
|
157
|
+
const visit = (current) => {
|
|
158
|
+
if (typeof current === "string") {
|
|
159
|
+
return replaceString(current);
|
|
160
|
+
}
|
|
161
|
+
if (Array.isArray(current)) {
|
|
162
|
+
return current.map(visit);
|
|
163
|
+
}
|
|
164
|
+
if (typeof current === "object" && current !== null) {
|
|
165
|
+
const entries = Object.entries(current).map(([key, nestedValue]) => [replaceString(key), visit(nestedValue)]);
|
|
166
|
+
if (new Set(entries.map(([key]) => key)).size !== entries.length) {
|
|
167
|
+
throw new Error("JSON 模板变量替换后产生重复对象键");
|
|
168
|
+
}
|
|
169
|
+
return Object.fromEntries(entries);
|
|
170
|
+
}
|
|
171
|
+
return current;
|
|
172
|
+
};
|
|
173
|
+
const rendered = visit(value);
|
|
174
|
+
for (const name of Object.keys(replacements)) {
|
|
175
|
+
if (!used.has(name)) {
|
|
176
|
+
throw new Error(`JSON 模板替换项未被使用:${name}`);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
return rendered;
|
|
180
|
+
}
|
|
143
181
|
async function mergeJsonIntoFile(options) {
|
|
144
182
|
const to = resolveContainedPath(options.options.targetRoot, options.toPath);
|
|
145
183
|
let existing = {};
|
|
@@ -612,14 +612,20 @@ const workflowTemplateVariants = new Map([
|
|
|
612
612
|
".github/workflows/check-diagnostics.yml",
|
|
613
613
|
{
|
|
614
614
|
operationKind: "writeTextTemplate",
|
|
615
|
-
replacementKeys: [
|
|
615
|
+
replacementKeys: [
|
|
616
|
+
"PLAYWRIGHT_DIAGNOSTIC_OWNER_PATHS",
|
|
617
|
+
"VITEST_BROWSER_DIAGNOSTIC_OWNER_PATHS",
|
|
618
|
+
],
|
|
616
619
|
},
|
|
617
620
|
],
|
|
618
621
|
[
|
|
619
622
|
".github/workflows/check-deployment-diagnostics.yml",
|
|
620
623
|
{
|
|
621
624
|
operationKind: "writeTextTemplate",
|
|
622
|
-
replacementKeys: [
|
|
625
|
+
replacementKeys: [
|
|
626
|
+
"PLAYWRIGHT_DIAGNOSTIC_OWNER_PATHS",
|
|
627
|
+
"VITEST_BROWSER_DIAGNOSTIC_OWNER_PATHS",
|
|
628
|
+
],
|
|
623
629
|
},
|
|
624
630
|
],
|
|
625
631
|
]);
|
|
@@ -650,20 +656,25 @@ function isSafePackageBoundaryPath(value) {
|
|
|
650
656
|
function expectedDiagnosticOwnerPaths(options) {
|
|
651
657
|
const blueprintPackagePaths = options.blueprint.packages.map((packageDefinition) => packageDefinition.path);
|
|
652
658
|
if (!blueprintPackagePaths.every(isSafePackageBoundaryPath)) {
|
|
653
|
-
return { valid: false,
|
|
659
|
+
return { valid: false, playwright: "", vitestBrowser: "" };
|
|
654
660
|
}
|
|
655
661
|
const blueprintOwners = new Set(blueprintPackagePaths);
|
|
656
|
-
const owners =
|
|
662
|
+
const owners = {
|
|
663
|
+
playwright: new Set(),
|
|
664
|
+
"vitest-browser": new Set(),
|
|
665
|
+
};
|
|
657
666
|
for (const declaration of options.diagnosticArtifactDeclarations) {
|
|
658
667
|
if (!isRecord(declaration) ||
|
|
659
668
|
!hasExactKeys(declaration, ["kind", "owner"])) {
|
|
660
|
-
return { valid: false,
|
|
669
|
+
return { valid: false, playwright: "", vitestBrowser: "" };
|
|
661
670
|
}
|
|
662
|
-
if (declaration.kind !== "playwright"
|
|
663
|
-
|
|
671
|
+
if ((declaration.kind !== "playwright" &&
|
|
672
|
+
declaration.kind !== "vitest-browser") ||
|
|
673
|
+
!isRecord(declaration.owner)) {
|
|
674
|
+
return { valid: false, playwright: "", vitestBrowser: "" };
|
|
664
675
|
}
|
|
665
676
|
if (!hasExactKeys(declaration.owner, ["kind", "path"])) {
|
|
666
|
-
return { valid: false,
|
|
677
|
+
return { valid: false, playwright: "", vitestBrowser: "" };
|
|
667
678
|
}
|
|
668
679
|
const ownerPath = declaration.owner.path;
|
|
669
680
|
const workspaceOwner = declaration.owner.kind === "workspace-orchestration" && ownerPath === ".";
|
|
@@ -672,13 +683,16 @@ function expectedDiagnosticOwnerPaths(options) {
|
|
|
672
683
|
isSafePackageBoundaryPath(ownerPath) &&
|
|
673
684
|
blueprintOwners.has(ownerPath);
|
|
674
685
|
if (!workspaceOwner && !packageOwner) {
|
|
675
|
-
return { valid: false,
|
|
686
|
+
return { valid: false, playwright: "", vitestBrowser: "" };
|
|
676
687
|
}
|
|
677
|
-
owners.add(ownerPath);
|
|
688
|
+
owners[declaration.kind].add(ownerPath);
|
|
678
689
|
}
|
|
679
690
|
return {
|
|
680
691
|
valid: true,
|
|
681
|
-
|
|
692
|
+
playwright: [...owners.playwright].toSorted().join("\n "),
|
|
693
|
+
vitestBrowser: [...owners["vitest-browser"]]
|
|
694
|
+
.toSorted()
|
|
695
|
+
.join("\n "),
|
|
682
696
|
};
|
|
683
697
|
}
|
|
684
698
|
function sourceFileForWorkflowOperation(options) {
|
|
@@ -723,21 +737,25 @@ async function protectedWorkflowProjectionViolations(plans) {
|
|
|
723
737
|
: undefined;
|
|
724
738
|
const replacementValid = operation?.kind === "writeTextTemplate" &&
|
|
725
739
|
hasExactReplacementKeys(operation.replacements, [
|
|
726
|
-
"
|
|
740
|
+
"PLAYWRIGHT_DIAGNOSTIC_OWNER_PATHS",
|
|
741
|
+
"VITEST_BROWSER_DIAGNOSTIC_OWNER_PATHS",
|
|
727
742
|
]) &&
|
|
728
|
-
operation.replacements.
|
|
729
|
-
expectedDiagnosticOwners.
|
|
743
|
+
operation.replacements.PLAYWRIGHT_DIAGNOSTIC_OWNER_PATHS ===
|
|
744
|
+
expectedDiagnosticOwners.playwright &&
|
|
745
|
+
operation.replacements.VITEST_BROWSER_DIAGNOSTIC_OWNER_PATHS ===
|
|
746
|
+
expectedDiagnosticOwners.vitestBrowser;
|
|
730
747
|
const sourceBackedExactlyOnce = matchingOperations.length === 1 &&
|
|
731
748
|
operation !== undefined &&
|
|
732
749
|
(operation.kind === "copyFile" || operation.kind === "writeTextTemplate");
|
|
733
|
-
const diagnosticsExpected = expectedDiagnosticOwners.
|
|
750
|
+
const diagnosticsExpected = expectedDiagnosticOwners.playwright !== "" ||
|
|
751
|
+
expectedDiagnosticOwners.vitestBrowser !== "";
|
|
734
752
|
const operationValid = expectedDiagnosticOwners.valid &&
|
|
735
753
|
sourceBackedExactlyOnce &&
|
|
736
754
|
variant !== undefined &&
|
|
737
755
|
operation?.kind === variant.operationKind &&
|
|
738
756
|
(operation.kind === "copyFile"
|
|
739
757
|
? variant.replacementKeys.length === 0 && !diagnosticsExpected
|
|
740
|
-
: variant.replacementKeys.length ===
|
|
758
|
+
: variant.replacementKeys.length === 2 &&
|
|
741
759
|
diagnosticsExpected &&
|
|
742
760
|
replacementValid);
|
|
743
761
|
if (operationValid)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ykdz/template",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.42",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Project template generator for YKDZ starter projects.",
|
|
6
6
|
"keywords": [
|
|
@@ -67,8 +67,7 @@
|
|
|
67
67
|
"oxfmt": "^0.71.0",
|
|
68
68
|
"oxlint": "^1.77.0",
|
|
69
69
|
"oxlint-tsgolint": "^7.0.2001",
|
|
70
|
-
"typescript-7": "npm:typescript@^7.0.2"
|
|
71
|
-
"vitest": "^5.0.0"
|
|
70
|
+
"typescript-7": "npm:typescript@^7.0.2"
|
|
72
71
|
},
|
|
73
72
|
"bundleDependencies": [
|
|
74
73
|
"@valibot/to-json-schema",
|
|
@@ -88,11 +87,6 @@
|
|
|
88
87
|
"engines": {
|
|
89
88
|
"node": "^24.21.0"
|
|
90
89
|
},
|
|
91
|
-
"turbo": {
|
|
92
|
-
"tags": [
|
|
93
|
-
"template-cli"
|
|
94
|
-
]
|
|
95
|
-
},
|
|
96
90
|
"scripts": {
|
|
97
91
|
"build": "rm -rf dist && tsc -p tsconfig.build.json",
|
|
98
92
|
"format:check": "oxfmt --list-different --config ../../oxfmt.config.ts .",
|
|
@@ -100,8 +94,8 @@
|
|
|
100
94
|
"lint": "oxlint --quiet --format=unix --config ../../oxlint.config.ts --ignore-pattern dist .",
|
|
101
95
|
"lint:fix": "oxlint --format=unix --config ../../oxlint.config.ts --ignore-pattern dist . --fix",
|
|
102
96
|
"pack:bundled": "pnpm --config.node-linker=hoisted pack",
|
|
103
|
-
"
|
|
104
|
-
"test": "
|
|
97
|
+
"test": "node --conditions=source --experimental-strip-types --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 'test/**/*.light.test.ts'",
|
|
98
|
+
"test:integration": "node --conditions=source --experimental-strip-types --test --test-concurrency=1 --test-timeout=300000 --test-reporter=spec --test-reporter=@ykdz/template-builtin-presets/node-test-count-reporter --test-reporter-destination=stdout --test-reporter-destination=stderr 'test/**/*.integration.test.ts'",
|
|
105
99
|
"test:e2e": "node --conditions=source test/e2e/check-source-and-distribution.ts",
|
|
106
100
|
"typecheck": "tsc -p tsconfig.json --noEmit --pretty false"
|
|
107
101
|
}
|
package/node_modules/@ykdz/template-builtin-presets/templates/rust-bin/.github/workflows/check.yml
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
name: Check
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
pull_request:
|
|
5
|
-
push:
|
|
6
|
-
branches:
|
|
7
|
-
- main
|
|
8
|
-
|
|
9
|
-
jobs:
|
|
10
|
-
check:
|
|
11
|
-
runs-on: ubuntu-latest
|
|
12
|
-
steps:
|
|
13
|
-
- uses: actions/checkout@v7
|
|
14
|
-
- uses: actions/setup-node@v7
|
|
15
|
-
with:
|
|
16
|
-
node-version-file: package.json
|
|
17
|
-
- run: corepack enable
|
|
18
|
-
- uses: dtolnay/rust-toolchain@stable
|
|
19
|
-
with:
|
|
20
|
-
components: rustfmt, clippy
|
|
21
|
-
- uses: Swatinem/rust-cache@v2
|
|
22
|
-
- run: pnpm install
|
|
23
|
-
- run: pnpm run check
|
package/node_modules/@ykdz/template-builtin-presets/templates/ts-lib/.github/workflows/check.yml
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
name: Check
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
pull_request:
|
|
5
|
-
push:
|
|
6
|
-
branches:
|
|
7
|
-
- main
|
|
8
|
-
|
|
9
|
-
jobs:
|
|
10
|
-
check:
|
|
11
|
-
runs-on: ubuntu-latest
|
|
12
|
-
steps:
|
|
13
|
-
- uses: actions/checkout@v7
|
|
14
|
-
- uses: actions/setup-node@v7
|
|
15
|
-
with:
|
|
16
|
-
node-version-file: package.json
|
|
17
|
-
- run: corepack enable
|
|
18
|
-
- run: pnpm install
|
|
19
|
-
- run: pnpm run check
|
package/node_modules/@ykdz/template-builtin-presets/templates/vue-app/.github/workflows/check.yml
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
name: Check
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
pull_request:
|
|
5
|
-
push:
|
|
6
|
-
branches:
|
|
7
|
-
- main
|
|
8
|
-
|
|
9
|
-
jobs:
|
|
10
|
-
check:
|
|
11
|
-
runs-on: ubuntu-latest
|
|
12
|
-
steps:
|
|
13
|
-
- uses: actions/checkout@v7
|
|
14
|
-
- uses: actions/setup-node@v7
|
|
15
|
-
with:
|
|
16
|
-
node-version-file: package.json
|
|
17
|
-
- run: corepack enable
|
|
18
|
-
- run: pnpm install
|
|
19
|
-
- run: pnpm --filter ./apps/web exec playwright install --with-deps chromium
|
|
20
|
-
- run: pnpm run check
|