@ykdz/template 0.0.24 → 0.0.25
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.d.ts +3 -5
- package/node_modules/@ykdz/template-builtin-presets/dist/src/foundation.js +172 -165
- package/node_modules/@ykdz/template-builtin-presets/dist/src/rust-bin/definition.js +4 -24
- package/node_modules/@ykdz/template-builtin-presets/dist/src/shared/vue.d.ts +0 -3
- package/node_modules/@ykdz/template-builtin-presets/dist/src/shared/vue.js +8 -26
- package/node_modules/@ykdz/template-builtin-presets/dist/src/ts-lib/definition.js +5 -29
- package/node_modules/@ykdz/template-builtin-presets/dist/src/vike-app/definition.js +24 -50
- package/node_modules/@ykdz/template-builtin-presets/dist/src/vue-app/definition.js +2 -4
- package/node_modules/@ykdz/template-builtin-presets/dist/src/vue-hono-app/definition.js +9 -26
- package/node_modules/@ykdz/template-builtin-presets/package.json +2 -1
- package/node_modules/@ykdz/template-builtin-presets/templates/foundation/pnpm-workspace.dynamic.txt +1 -5
- package/node_modules/@ykdz/template-builtin-presets/templates/foundation/pnpm-workspace.yaml +1 -2
- package/node_modules/@ykdz/template-builtin-presets/templates/foundation/scripts/check-boundaries.ts +12 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/foundation/scripts/run-root-owned-task.ts +69 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/foundation/tsconfig.json +6 -1
- package/node_modules/@ykdz/template-builtin-presets/templates/foundation/turbo.json +15 -8
- package/node_modules/@ykdz/template-builtin-presets/templates/vike-app/db/turbo.json +1 -1
- package/node_modules/@ykdz/template-builtin-presets/templates/vike-app/db-migrations/turbo.json +2 -2
- package/node_modules/@ykdz/template-builtin-presets/templates/vike-app/web/Dockerfile +3 -4
- package/node_modules/@ykdz/template-builtin-presets/templates/vike-app/web/scripts/check-standalone-deployment.ts +1 -1
- package/node_modules/@ykdz/template-builtin-presets/templates/vike-app/web/turbo.json +3 -3
- package/node_modules/@ykdz/template-builtin-presets/templates/vue-app/turbo.json +3 -3
- package/node_modules/@ykdz/template-builtin-presets/templates/vue-hono-app/api/turbo.json +1 -1
- package/node_modules/@ykdz/template-builtin-presets/templates/vue-hono-app/web/playwright.config.ts +1 -1
- package/node_modules/@ykdz/template-builtin-presets/templates/vue-hono-app/web/turbo.json +2 -2
- package/node_modules/@ykdz/template-core/dist/dependency-catalog.d.ts +0 -1
- package/node_modules/@ykdz/template-core/dist/dependency-catalog.js +2 -8
- package/node_modules/@ykdz/template-core/dist/module-graph.d.ts +39 -37
- package/node_modules/@ykdz/template-core/dist/module-graph.js +84 -142
- package/node_modules/@ykdz/template-core/dist/package-contribution.d.ts +3 -5
- package/node_modules/@ykdz/template-core/dist/package-contribution.js +7 -7
- package/node_modules/@ykdz/template-core/dist/pnpm-workspace.yaml +0 -2
- package/node_modules/@ykdz/template-core/dist/project-github.d.ts +11 -3
- package/node_modules/@ykdz/template-core/dist/project-github.js +30 -35
- package/node_modules/@ykdz/template-core/dist/project-linking-v2.d.ts +1 -1
- package/package.json +1 -1
- package/node_modules/@ykdz/template-builtin-presets/templates/foundation/.pnpmfile.cts +0 -14
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { CheckEnvironmentNeed, DeploymentEnvironmentNeed } from "@ykdz/template-core/module-graph";
|
|
2
2
|
import { type PackageContribution } from "@ykdz/template-core/package-contribution";
|
|
3
3
|
import type { BuiltInPresetDefinition, GenerationContext } from "@ykdz/template-core/preset-definition";
|
|
4
4
|
import { type ProjectBlueprintV2 } from "@ykdz/template-core/project-blueprint-v2";
|
|
@@ -23,10 +23,8 @@ export type GeneratedRepositoryPlan = {
|
|
|
23
23
|
readonly toolchain: BuiltInGenerationContext["toolchain"];
|
|
24
24
|
};
|
|
25
25
|
readonly operations: readonly RenderOperation[];
|
|
26
|
-
readonly checks: readonly CheckComponent[];
|
|
27
|
-
readonly fixes: readonly FixComponent[];
|
|
28
26
|
readonly environmentNeeds: readonly CheckEnvironmentNeed[];
|
|
29
|
-
readonly
|
|
27
|
+
readonly deploymentEnvironmentNeeds: readonly DeploymentEnvironmentNeed[];
|
|
30
28
|
/** Structured manifests used to derive the generated Dependency Catalog. */
|
|
31
29
|
readonly manifests: readonly Readonly<Record<string, unknown>>[];
|
|
32
30
|
readonly dependencyCatalog: Readonly<Record<string, string>>;
|
|
@@ -42,7 +40,7 @@ export type BuiltInPresetTemplateSourceCheckContext = {
|
|
|
42
40
|
/**
|
|
43
41
|
* The Foundation persists the non-rendering half of every Package
|
|
44
42
|
* Contribution with the Generated Repository. Package Addition cannot infer
|
|
45
|
-
*
|
|
43
|
+
* fix, deployment, or maintenance semantics from a package name (or
|
|
46
44
|
* from a lossy subset of scripts), so this is the durable topology it reads.
|
|
47
45
|
*/
|
|
48
46
|
/** Resolve an owned source handle for diagnostics and source checks. */
|
|
@@ -4,7 +4,7 @@ import { fileURLToPath } from "node:url";
|
|
|
4
4
|
import { collectGeneratedManifestCatalogReferences, selectTemplateDependencyCatalogEntries, } from "@ykdz/template-core/dependency-catalog";
|
|
5
5
|
import { browserTestToolLayer } from "@ykdz/template-core/devcontainer";
|
|
6
6
|
import { editorCustomizationForCapabilities, loadEditorCustomizationDeclarations, } from "@ykdz/template-core/editor-customization";
|
|
7
|
-
import {
|
|
7
|
+
import { checkEnvironmentNeedFact, checkEnvironmentNeedFromFact, deploymentEnvironmentNeedFact, deploymentEnvironmentNeedFromFact, renderDeploymentCheckCommand, renderFixCommand, renderRootCheckCommand, } from "@ykdz/template-core/module-graph";
|
|
8
8
|
import { assertPackageContribution, } from "@ykdz/template-core/package-contribution";
|
|
9
9
|
import { assertProjectBlueprintV2, validateProjectBlueprintV2 as validateCoreProjectBlueprintV2, } from "@ykdz/template-core/project-blueprint-v2";
|
|
10
10
|
import { projectCheckWorkflowTemplateReplacements, projectDependabotTemplateReplacements, } from "@ykdz/template-core/project-github";
|
|
@@ -17,10 +17,11 @@ import { tsLibDefinition } from "./ts-lib/definition.js";
|
|
|
17
17
|
import { vikeAppDefinition } from "./vike-app/definition.js";
|
|
18
18
|
import { vueAppDefinition } from "./vue-app/definition.js";
|
|
19
19
|
import { vueHonoAppDefinition } from "./vue-hono-app/definition.js";
|
|
20
|
+
const environmentNeedsPath = ".template/environment-needs.json";
|
|
20
21
|
/**
|
|
21
22
|
* The Foundation persists the non-rendering half of every Package
|
|
22
23
|
* Contribution with the Generated Repository. Package Addition cannot infer
|
|
23
|
-
*
|
|
24
|
+
* fix, deployment, or maintenance semantics from a package name (or
|
|
24
25
|
* from a lossy subset of scripts), so this is the durable topology it reads.
|
|
25
26
|
*/
|
|
26
27
|
/** Resolve an owned source handle for diagnostics and source checks. */
|
|
@@ -110,10 +111,85 @@ export function createGenerationContext(options) {
|
|
|
110
111
|
toolchain: options.toolchain,
|
|
111
112
|
};
|
|
112
113
|
}
|
|
114
|
+
function isRecord(value) {
|
|
115
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
116
|
+
}
|
|
117
|
+
function environmentNeedOwner(value) {
|
|
118
|
+
if (!isRecord(value))
|
|
119
|
+
return undefined;
|
|
120
|
+
if (value.kind === "workspace-orchestration" && value.path === ".") {
|
|
121
|
+
return { kind: "workspace-orchestration", path: "." };
|
|
122
|
+
}
|
|
123
|
+
if (value.kind === "package-boundary" && typeof value.path === "string") {
|
|
124
|
+
return { kind: "package-boundary", path: value.path };
|
|
125
|
+
}
|
|
126
|
+
return undefined;
|
|
127
|
+
}
|
|
128
|
+
function persistedCheckEnvironmentNeedFact(value) {
|
|
129
|
+
if (!isRecord(value))
|
|
130
|
+
return undefined;
|
|
131
|
+
const owner = environmentNeedOwner(value.owner);
|
|
132
|
+
if (owner === undefined)
|
|
133
|
+
return undefined;
|
|
134
|
+
switch (value.kind) {
|
|
135
|
+
case "playwright-browser-assets":
|
|
136
|
+
return value.browser === "chromium"
|
|
137
|
+
? { kind: value.kind, browser: value.browser, owner }
|
|
138
|
+
: undefined;
|
|
139
|
+
case "shellcheck-command":
|
|
140
|
+
return { kind: value.kind, owner };
|
|
141
|
+
case "rust-toolchain":
|
|
142
|
+
return value.toolchain === "stable"
|
|
143
|
+
? { kind: value.kind, toolchain: value.toolchain, owner }
|
|
144
|
+
: undefined;
|
|
145
|
+
default:
|
|
146
|
+
return undefined;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
function readPersistedEnvironmentNeeds(targetDir) {
|
|
150
|
+
const filePath = path.join(targetDir, environmentNeedsPath);
|
|
151
|
+
if (!existsSync(filePath)) {
|
|
152
|
+
throw new Error(`Package Addition requires explicit Check Environment Need facts: ${environmentNeedsPath} is missing`);
|
|
153
|
+
}
|
|
154
|
+
let value;
|
|
155
|
+
try {
|
|
156
|
+
value = JSON.parse(readFileSync(filePath, "utf8"));
|
|
157
|
+
}
|
|
158
|
+
catch (error) {
|
|
159
|
+
throw new Error(`Package Addition requires valid Check Environment Need facts: ${error instanceof Error ? error.message : String(error)}`);
|
|
160
|
+
}
|
|
161
|
+
if (!isRecord(value) ||
|
|
162
|
+
value.schemaVersion !== 1 ||
|
|
163
|
+
!Array.isArray(value.check) ||
|
|
164
|
+
!Array.isArray(value.deployment)) {
|
|
165
|
+
throw new Error(`Package Addition requires valid Check Environment Need facts in ${environmentNeedsPath}`);
|
|
166
|
+
}
|
|
167
|
+
const check = value.check.map(persistedCheckEnvironmentNeedFact);
|
|
168
|
+
if (check.some((fact) => fact === undefined)) {
|
|
169
|
+
throw new Error(`Package Addition requires supported Check Environment Need facts in ${environmentNeedsPath}`);
|
|
170
|
+
}
|
|
171
|
+
if (value.deployment.some((fact) => !isRecord(fact) || fact.kind !== "docker-engine")) {
|
|
172
|
+
throw new Error(`Package Addition requires supported deployment Environment Need facts in ${environmentNeedsPath}`);
|
|
173
|
+
}
|
|
174
|
+
return {
|
|
175
|
+
check: check.map(checkEnvironmentNeedFromFact),
|
|
176
|
+
deployment: value.deployment.map((fact) => deploymentEnvironmentNeedFromFact(fact)),
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
function uniqueEnvironmentNeeds(needs) {
|
|
180
|
+
const seen = new Set();
|
|
181
|
+
return needs.filter((need) => {
|
|
182
|
+
const key = JSON.stringify(need);
|
|
183
|
+
if (seen.has(key))
|
|
184
|
+
return false;
|
|
185
|
+
seen.add(key);
|
|
186
|
+
return true;
|
|
187
|
+
});
|
|
188
|
+
}
|
|
113
189
|
/**
|
|
114
|
-
* Package Addition reconstructs generic current facts from the Blueprint
|
|
115
|
-
*
|
|
116
|
-
*
|
|
190
|
+
* Package Addition reconstructs generic current facts from the Blueprint,
|
|
191
|
+
* manifest truth, and explicit persisted Environment Need facts. Environment
|
|
192
|
+
* preparation is never derived from task script text.
|
|
117
193
|
*/
|
|
118
194
|
function existingPackageContribution(options) {
|
|
119
195
|
const packageRoot = path.join(options.context.targetDir, options.definition.path);
|
|
@@ -129,15 +205,10 @@ function existingPackageContribution(options) {
|
|
|
129
205
|
throw new Error(`Package Addition requires manifest truth for ${options.definition.path}: expected name ${options.definition.name}`);
|
|
130
206
|
}
|
|
131
207
|
const record = manifest;
|
|
132
|
-
const scripts = typeof record.scripts === "object" && record.scripts !== null
|
|
133
|
-
? record.scripts
|
|
134
|
-
: {};
|
|
135
|
-
const owner = {
|
|
136
|
-
kind: "package-boundary",
|
|
137
|
-
path: options.definition.path,
|
|
138
|
-
};
|
|
139
208
|
const dependencyMaintenance = existingDependencyMaintenancePolicy(options.context.targetDir);
|
|
140
|
-
const
|
|
209
|
+
const environmentNeeds = options.environmentNeeds.filter((need) => need.owner.kind === "package-boundary" &&
|
|
210
|
+
need.owner.path === options.definition.path);
|
|
211
|
+
const rust = environmentNeeds.some((need) => need.kind === "rust-toolchain");
|
|
141
212
|
const editorRecommendationsPath = path.join(options.context.targetDir, ".vscode/extensions.json");
|
|
142
213
|
const editorRecommendations = existsSync(editorRecommendationsPath)
|
|
143
214
|
? JSON.parse(readFileSync(editorRecommendationsPath, "utf8")).recommendations
|
|
@@ -157,32 +228,6 @@ function existingPackageContribution(options) {
|
|
|
157
228
|
? ["vitest"]
|
|
158
229
|
: []),
|
|
159
230
|
];
|
|
160
|
-
const checks = rust
|
|
161
|
-
? [
|
|
162
|
-
{ kind: "rustfmt-check", owner },
|
|
163
|
-
{ kind: "cargo-clippy", owner },
|
|
164
|
-
{ kind: "cargo-test", owner },
|
|
165
|
-
]
|
|
166
|
-
: [
|
|
167
|
-
...(scripts["typecheck:run"] === undefined
|
|
168
|
-
? []
|
|
169
|
-
: [{ kind: "typescript-typecheck", owner }]),
|
|
170
|
-
...(scripts["lint:run"] === undefined
|
|
171
|
-
? []
|
|
172
|
-
: [{ kind: "oxc-lint", owner }]),
|
|
173
|
-
...(scripts["format:check:run"] === undefined
|
|
174
|
-
? []
|
|
175
|
-
: [{ kind: "oxc-format-check", owner }]),
|
|
176
|
-
...(scripts["build:run"] === undefined
|
|
177
|
-
? []
|
|
178
|
-
: [{ kind: "build", owner }]),
|
|
179
|
-
...(scripts["test:run"] === undefined
|
|
180
|
-
? []
|
|
181
|
-
: [{ kind: "unit-test", owner }]),
|
|
182
|
-
...(scripts["test:e2e:run"] === undefined
|
|
183
|
-
? []
|
|
184
|
-
: [{ kind: "e2e-test", owner }]),
|
|
185
|
-
];
|
|
186
231
|
return {
|
|
187
232
|
definition: options.definition,
|
|
188
233
|
manifest: record,
|
|
@@ -195,34 +240,7 @@ function existingPackageContribution(options) {
|
|
|
195
240
|
: {},
|
|
196
241
|
},
|
|
197
242
|
operations: [],
|
|
198
|
-
|
|
199
|
-
fixes: rust
|
|
200
|
-
? [{ kind: "rustfmt-write", owner }]
|
|
201
|
-
: [
|
|
202
|
-
...(scripts["format:write:run"] === undefined
|
|
203
|
-
? []
|
|
204
|
-
: [{ kind: "oxc-format-write", owner }]),
|
|
205
|
-
...(scripts["lint:fix:run"] === undefined
|
|
206
|
-
? []
|
|
207
|
-
: [{ kind: "oxc-lint-fix", owner }]),
|
|
208
|
-
],
|
|
209
|
-
environmentNeeds: [
|
|
210
|
-
...(rust ? [rustToolchainEnvironmentNeed(owner)] : []),
|
|
211
|
-
...(scripts["test:e2e:run"] === undefined
|
|
212
|
-
? []
|
|
213
|
-
: [
|
|
214
|
-
playwrightBrowserAssetsEnvironmentNeed({
|
|
215
|
-
browser: "chromium",
|
|
216
|
-
owner,
|
|
217
|
-
}),
|
|
218
|
-
]),
|
|
219
|
-
...(Object.values(scripts).some((script) => typeof script === "string" && script.includes("shellcheck"))
|
|
220
|
-
? [shellCheckEnvironmentNeed(owner)]
|
|
221
|
-
: []),
|
|
222
|
-
],
|
|
223
|
-
...(scripts["check:deployment"] === undefined
|
|
224
|
-
? {}
|
|
225
|
-
: { deploymentChecks: [{ kind: "deployment-image", owner }] }),
|
|
243
|
+
environmentNeeds,
|
|
226
244
|
foundation: {
|
|
227
245
|
toolchains: rust
|
|
228
246
|
? { rust: { toolchain: "stable", components: ["rustfmt", "clippy"] } }
|
|
@@ -287,38 +305,6 @@ function existingDependencyMaintenancePolicy(targetDir) {
|
|
|
287
305
|
interval: "weekly",
|
|
288
306
|
};
|
|
289
307
|
}
|
|
290
|
-
function unique(values) {
|
|
291
|
-
return [...new Set(values)];
|
|
292
|
-
}
|
|
293
|
-
function rootCheckCommand(checks) {
|
|
294
|
-
const rootTasks = unique(checks
|
|
295
|
-
.filter((check) => check.owner.kind === "workspace-orchestration")
|
|
296
|
-
.map(checkComponentTaskName));
|
|
297
|
-
const packageChecks = checks.filter((check) => check.owner.kind === "package-boundary");
|
|
298
|
-
const packageTasks = unique(packageChecks.map(checkComponentTaskName));
|
|
299
|
-
const packageFilters = unique(packageChecks.map((check) => `--filter './${check.owner.path}'`));
|
|
300
|
-
return [
|
|
301
|
-
"pnpm run check:boundaries",
|
|
302
|
-
...rootTasks.map((task) => `pnpm run ${task}`),
|
|
303
|
-
...(packageTasks.length === 0
|
|
304
|
-
? []
|
|
305
|
-
: [renderTurboRunCommand(packageTasks, packageFilters)]),
|
|
306
|
-
].join(" && ");
|
|
307
|
-
}
|
|
308
|
-
function rootFixCommand(fixes) {
|
|
309
|
-
const rootTasks = unique(fixes
|
|
310
|
-
.filter((fix) => fix.owner.kind === "workspace-orchestration")
|
|
311
|
-
.map(fixComponentTaskName));
|
|
312
|
-
const packageFixes = fixes.filter((fix) => fix.owner.kind === "package-boundary");
|
|
313
|
-
const packageTasks = unique(packageFixes.map(fixComponentTaskName));
|
|
314
|
-
const packageFilters = unique(packageFixes.map((fix) => `--filter './${fix.owner.path}'`));
|
|
315
|
-
return [
|
|
316
|
-
...rootTasks.map((task) => `pnpm run ${task}`),
|
|
317
|
-
...(packageTasks.length === 0
|
|
318
|
-
? []
|
|
319
|
-
: [renderTurboRunCommand(packageTasks, packageFilters)]),
|
|
320
|
-
].join(" && ");
|
|
321
|
-
}
|
|
322
308
|
function devcontainerDockerfileOperations(options) {
|
|
323
309
|
const hasBrowserTests = options.environmentNeeds.some((need) => need.kind === "playwright-browser-assets");
|
|
324
310
|
const hasShellChecks = options.environmentNeeds.some((need) => need.kind === "shellcheck-command");
|
|
@@ -366,40 +352,22 @@ function devcontainerDockerfileOperations(options) {
|
|
|
366
352
|
}
|
|
367
353
|
function foundationPlan(options) {
|
|
368
354
|
assertProjectBlueprintV2(options.blueprint);
|
|
369
|
-
const
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
kind: "oxc-format-write",
|
|
386
|
-
owner: { kind: "workspace-orchestration", path: "." },
|
|
387
|
-
},
|
|
388
|
-
{
|
|
389
|
-
kind: "oxc-lint-fix",
|
|
390
|
-
owner: { kind: "workspace-orchestration", path: "." },
|
|
391
|
-
},
|
|
392
|
-
];
|
|
393
|
-
const checks = [
|
|
394
|
-
...foundationChecks,
|
|
395
|
-
...options.contributions.flatMap((item) => item.checks),
|
|
396
|
-
];
|
|
397
|
-
const fixes = [
|
|
398
|
-
...foundationFixes,
|
|
399
|
-
...options.contributions.flatMap((item) => item.fixes),
|
|
400
|
-
];
|
|
401
|
-
const environmentNeeds = options.contributions.flatMap((item) => item.environmentNeeds);
|
|
402
|
-
const deploymentChecks = options.contributions.flatMap((item) => item.deploymentChecks ?? []);
|
|
355
|
+
const environmentNeeds = uniqueEnvironmentNeeds(options.contributions.flatMap((item) => item.environmentNeeds));
|
|
356
|
+
const deploymentEnvironmentNeeds = uniqueEnvironmentNeeds([
|
|
357
|
+
...(options.existingDeploymentEnvironmentNeeds ?? []),
|
|
358
|
+
...options.contributions.flatMap((item) => item.deploymentEnvironmentNeeds ?? []),
|
|
359
|
+
]);
|
|
360
|
+
const persistedEnvironmentNeeds = {
|
|
361
|
+
schemaVersion: 1,
|
|
362
|
+
check: environmentNeeds.map(checkEnvironmentNeedFact),
|
|
363
|
+
deployment: deploymentEnvironmentNeeds.map(deploymentEnvironmentNeedFact),
|
|
364
|
+
};
|
|
365
|
+
const hasDeploymentTask = options.contributions.some((contribution) => {
|
|
366
|
+
const scripts = contribution.manifest.scripts;
|
|
367
|
+
return (typeof scripts === "object" &&
|
|
368
|
+
scripts !== null &&
|
|
369
|
+
typeof scripts.deployment === "string");
|
|
370
|
+
});
|
|
403
371
|
const packagePaths = options.contributions.map((contribution) => contribution.definition.path);
|
|
404
372
|
if (new Set(packagePaths).size !== packagePaths.length)
|
|
405
373
|
throw new Error("Package Contributions must have unique Package Paths");
|
|
@@ -414,9 +382,15 @@ function foundationPlan(options) {
|
|
|
414
382
|
throw new Error("Foundation requires one coordinated Rust toolchain");
|
|
415
383
|
}
|
|
416
384
|
const workspacePackageGlobs = [
|
|
385
|
+
"apps/*",
|
|
386
|
+
"packages/*",
|
|
417
387
|
...new Set([
|
|
418
|
-
...options.blueprint.packages
|
|
419
|
-
|
|
388
|
+
...options.blueprint.packages
|
|
389
|
+
.map((definition) => `${definition.path.split("/")[0]}/*`)
|
|
390
|
+
.filter((glob) => glob !== "apps/*" && glob !== "packages/*"),
|
|
391
|
+
...options.contributions
|
|
392
|
+
.flatMap((contribution) => contribution.foundation.workspacePackageGlobs ?? [])
|
|
393
|
+
.filter((glob) => glob !== "apps/*" && glob !== "packages/*"),
|
|
420
394
|
]),
|
|
421
395
|
];
|
|
422
396
|
const editorCustomization = editorCustomizationForCapabilities(options.contributions.flatMap((contribution) => contribution.foundation.editorCapabilities), loadEditorCustomizationDeclarations(resolveTemplateSource(templateSources.editorCustomization, "capabilities.json")));
|
|
@@ -434,22 +408,17 @@ function foundationPlan(options) {
|
|
|
434
408
|
private: true,
|
|
435
409
|
type: "module",
|
|
436
410
|
scripts: {
|
|
437
|
-
check:
|
|
438
|
-
|
|
439
|
-
...(
|
|
440
|
-
? {}
|
|
441
|
-
: {
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
fix:
|
|
447
|
-
|
|
448
|
-
"format:write:run": "oxfmt --write --config oxfmt.config.ts .",
|
|
449
|
-
"lint:run": "oxlint --quiet --format=unix --config oxlint.config.ts .",
|
|
450
|
-
"lint:fix:run": "oxlint --format=unix --config oxlint.config.ts . --fix",
|
|
451
|
-
typecheck: "pnpm run typecheck:run",
|
|
452
|
-
"typecheck:run": "tsc -p tsconfig.json --noEmit --pretty false",
|
|
411
|
+
check: renderRootCheckCommand(),
|
|
412
|
+
boundaries: "node scripts/check-boundaries.ts",
|
|
413
|
+
...(hasDeploymentTask
|
|
414
|
+
? { "check:deployment": renderDeploymentCheckCommand() }
|
|
415
|
+
: {}),
|
|
416
|
+
fix: renderFixCommand(),
|
|
417
|
+
"format:check": "node scripts/run-root-owned-task.ts format:check",
|
|
418
|
+
"format:write": "node scripts/run-root-owned-task.ts format:write",
|
|
419
|
+
lint: "node scripts/run-root-owned-task.ts lint",
|
|
420
|
+
"lint:fix": "node scripts/run-root-owned-task.ts lint:fix",
|
|
421
|
+
typecheck: "tsc -p tsconfig.json --noEmit --pretty false",
|
|
453
422
|
},
|
|
454
423
|
devDependencies: {
|
|
455
424
|
"@types/node": "catalog:",
|
|
@@ -467,7 +436,6 @@ function foundationPlan(options) {
|
|
|
467
436
|
rootManifest,
|
|
468
437
|
]));
|
|
469
438
|
const dependencyOverrides = {
|
|
470
|
-
"valibot>typescript": "-",
|
|
471
439
|
...(Object.hasOwn(dependencyCatalog, "vue") ||
|
|
472
440
|
Object.hasOwn(dependencyCatalog, "pinia")
|
|
473
441
|
? vuePnpmDependencyOverrides
|
|
@@ -488,10 +456,16 @@ function foundationPlan(options) {
|
|
|
488
456
|
.toSorted(([left], [right]) => left.localeCompare(right))
|
|
489
457
|
.map(([name, version]) => ` ${JSON.stringify(name)}: ${String(version)}`)
|
|
490
458
|
.join("\n"),
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
459
|
+
DEPENDENCY_OVERRIDES_SECTION: Object.keys(dependencyOverrides).length === 0
|
|
460
|
+
? ""
|
|
461
|
+
: [
|
|
462
|
+
"",
|
|
463
|
+
"overrides:",
|
|
464
|
+
...Object.entries(dependencyOverrides)
|
|
465
|
+
.toSorted(([left], [right]) => left.localeCompare(right))
|
|
466
|
+
.map(([dependency, version]) => ` ${JSON.stringify(dependency)}: ${JSON.stringify(version)}`),
|
|
467
|
+
"",
|
|
468
|
+
].join("\n"),
|
|
495
469
|
},
|
|
496
470
|
...(options.mode === "addition" ? { overwrite: true } : {}),
|
|
497
471
|
}
|
|
@@ -507,7 +481,9 @@ function foundationPlan(options) {
|
|
|
507
481
|
from: ".github/workflows/check.dynamic.template",
|
|
508
482
|
to: ".github/workflows/check.yml",
|
|
509
483
|
replacements: projectCheckWorkflowTemplateReplacements({
|
|
510
|
-
|
|
484
|
+
environment: { needs: environmentNeeds },
|
|
485
|
+
deploymentEnvironmentNeeds,
|
|
486
|
+
hasDeploymentTask,
|
|
511
487
|
}),
|
|
512
488
|
...(options.mode === "addition" ? { overwrite: true } : {}),
|
|
513
489
|
};
|
|
@@ -538,14 +514,20 @@ function foundationPlan(options) {
|
|
|
538
514
|
{
|
|
539
515
|
kind: "copyFile",
|
|
540
516
|
source: templateSources.foundation,
|
|
541
|
-
from: ".
|
|
542
|
-
to: ".
|
|
517
|
+
from: "turbo.json",
|
|
518
|
+
to: "turbo.json",
|
|
543
519
|
},
|
|
544
520
|
{
|
|
545
521
|
kind: "copyFile",
|
|
546
522
|
source: templateSources.foundation,
|
|
547
|
-
from: "
|
|
548
|
-
to: "
|
|
523
|
+
from: "scripts/check-boundaries.ts",
|
|
524
|
+
to: "scripts/check-boundaries.ts",
|
|
525
|
+
},
|
|
526
|
+
{
|
|
527
|
+
kind: "copyFile",
|
|
528
|
+
source: templateSources.foundation,
|
|
529
|
+
from: "scripts/run-root-owned-task.ts",
|
|
530
|
+
to: "scripts/run-root-owned-task.ts",
|
|
549
531
|
},
|
|
550
532
|
{
|
|
551
533
|
kind: "copyFile",
|
|
@@ -623,6 +605,22 @@ function foundationPlan(options) {
|
|
|
623
605
|
source: templateSources.foundation,
|
|
624
606
|
from: "rust/devcontainer/rust.Dockerfile",
|
|
625
607
|
},
|
|
608
|
+
...(environmentNeeds.some((need) => need.kind === "playwright-browser-assets")
|
|
609
|
+
? [
|
|
610
|
+
{
|
|
611
|
+
source: templateSources.sharedDevcontainer,
|
|
612
|
+
from: "browser-test.Dockerfile",
|
|
613
|
+
},
|
|
614
|
+
]
|
|
615
|
+
: []),
|
|
616
|
+
...(environmentNeeds.some((need) => need.kind === "shellcheck-command")
|
|
617
|
+
? [
|
|
618
|
+
{
|
|
619
|
+
source: templateSources.sharedDevcontainer,
|
|
620
|
+
from: "shellcheck.Dockerfile",
|
|
621
|
+
},
|
|
622
|
+
]
|
|
623
|
+
: []),
|
|
626
624
|
],
|
|
627
625
|
},
|
|
628
626
|
]),
|
|
@@ -632,6 +630,11 @@ function foundationPlan(options) {
|
|
|
632
630
|
to: ".template/blueprint.json",
|
|
633
631
|
value: options.blueprint,
|
|
634
632
|
},
|
|
633
|
+
{
|
|
634
|
+
kind: "writeJson",
|
|
635
|
+
to: environmentNeedsPath,
|
|
636
|
+
value: persistedEnvironmentNeeds,
|
|
637
|
+
},
|
|
635
638
|
{
|
|
636
639
|
kind: "writeJson",
|
|
637
640
|
to: ".template/generation.json",
|
|
@@ -714,10 +717,8 @@ function foundationPlan(options) {
|
|
|
714
717
|
toolchain: options.context.toolchain,
|
|
715
718
|
},
|
|
716
719
|
operations,
|
|
717
|
-
checks,
|
|
718
|
-
fixes,
|
|
719
720
|
environmentNeeds,
|
|
720
|
-
|
|
721
|
+
deploymentEnvironmentNeeds,
|
|
721
722
|
manifests: [
|
|
722
723
|
...options.contributions.map((item) => item.manifest),
|
|
723
724
|
rootManifest,
|
|
@@ -780,7 +781,12 @@ export function planGeneratedRepositoryPackageAddition(options) {
|
|
|
780
781
|
: {}),
|
|
781
782
|
};
|
|
782
783
|
assertProjectBlueprintV2(blueprint);
|
|
783
|
-
const
|
|
784
|
+
const persistedEnvironmentNeeds = readPersistedEnvironmentNeeds(options.context.targetDir);
|
|
785
|
+
const existingContributions = options.blueprint.packages.map((definition) => existingPackageContribution({
|
|
786
|
+
context: options.context,
|
|
787
|
+
definition,
|
|
788
|
+
environmentNeeds: persistedEnvironmentNeeds.check,
|
|
789
|
+
}));
|
|
784
790
|
if (existingContributions.length !== options.blueprint.packages.length ||
|
|
785
791
|
existingContributions.some((existing) => !options.blueprint.packages.some((definition) => definition.path === existing.definition.path &&
|
|
786
792
|
definition.name === existing.definition.name))) {
|
|
@@ -792,6 +798,7 @@ export function planGeneratedRepositoryPackageAddition(options) {
|
|
|
792
798
|
blueprint,
|
|
793
799
|
contributions: [...existingContributions, contribution],
|
|
794
800
|
renderContributions: [contribution],
|
|
801
|
+
existingDeploymentEnvironmentNeeds: persistedEnvironmentNeeds.deployment,
|
|
795
802
|
mode: "addition",
|
|
796
803
|
});
|
|
797
804
|
}
|
|
@@ -12,10 +12,10 @@ function cargoPackageName(projectName) {
|
|
|
12
12
|
}
|
|
13
13
|
function packageScripts() {
|
|
14
14
|
return {
|
|
15
|
-
"format:check
|
|
16
|
-
"format:write
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
"format:check": "cargo fmt --all -- --check",
|
|
16
|
+
"format:write": "cargo fmt --all",
|
|
17
|
+
lint: "cargo clippy --workspace --all-targets -- -D warnings",
|
|
18
|
+
test: "cargo test --workspace",
|
|
19
19
|
};
|
|
20
20
|
}
|
|
21
21
|
function rustContribution(context) {
|
|
@@ -71,26 +71,6 @@ function rustContribution(context) {
|
|
|
71
71
|
engines: { node: context.toolchain.nodeLtsMajor },
|
|
72
72
|
},
|
|
73
73
|
operations,
|
|
74
|
-
checks: [
|
|
75
|
-
{
|
|
76
|
-
kind: "rustfmt-check",
|
|
77
|
-
owner: { kind: "package-boundary", path: definition.path },
|
|
78
|
-
},
|
|
79
|
-
{
|
|
80
|
-
kind: "cargo-clippy",
|
|
81
|
-
owner: { kind: "package-boundary", path: definition.path },
|
|
82
|
-
},
|
|
83
|
-
{
|
|
84
|
-
kind: "cargo-test",
|
|
85
|
-
owner: { kind: "package-boundary", path: definition.path },
|
|
86
|
-
},
|
|
87
|
-
],
|
|
88
|
-
fixes: [
|
|
89
|
-
{
|
|
90
|
-
kind: "rustfmt-write",
|
|
91
|
-
owner: { kind: "package-boundary", path: definition.path },
|
|
92
|
-
},
|
|
93
|
-
],
|
|
94
74
|
environmentNeeds: [
|
|
95
75
|
rustToolchainEnvironmentNeed({
|
|
96
76
|
kind: "package-boundary",
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { type CheckComponent, type FixComponent } from "@ykdz/template-core/module-graph";
|
|
2
1
|
import type { PackageContribution } from "@ykdz/template-core/package-contribution";
|
|
3
2
|
import type { GenerationContext } from "@ykdz/template-core/preset-definition";
|
|
4
3
|
import type { PackageDefinition } from "@ykdz/template-core/project-blueprint-v2";
|
|
@@ -26,8 +25,6 @@ export declare function vueApplicationScripts(): Record<string, string>;
|
|
|
26
25
|
export declare function sharedVueSourceOperations(packagePath: string): readonly RenderOperation[];
|
|
27
26
|
/** Vike shares Vue's compiler runner, but owns its distinct Vike source tree. */
|
|
28
27
|
export declare function vueTypecheckRunnerSourceOperation(packagePath: string): RenderOperation;
|
|
29
|
-
export declare function vueApplicationChecks(packagePath: string): readonly CheckComponent[];
|
|
30
|
-
export declare function vueApplicationFixes(packagePath: string): readonly FixComponent[];
|
|
31
28
|
export declare function vueApplicationEnvironmentNeeds(packagePath: string): import("@ykdz/template-core/module-graph").PlaywrightBrowserAssetsEnvironmentNeed[];
|
|
32
29
|
export declare function vueApplicationManifest(options: {
|
|
33
30
|
readonly context: GenerationContext;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { playwrightBrowserAssetsEnvironmentNeed
|
|
1
|
+
import { playwrightBrowserAssetsEnvironmentNeed } from "@ykdz/template-core/module-graph";
|
|
2
2
|
import { templateSources } from "../template-sources.js";
|
|
3
3
|
/** Vue's tooling peers need these repository policy overrides, never Core defaults. */
|
|
4
4
|
export const vuePnpmDependencyOverrides = {
|
|
@@ -22,15 +22,15 @@ const sharedVueSourceFiles = [
|
|
|
22
22
|
];
|
|
23
23
|
export function vueApplicationScripts() {
|
|
24
24
|
return {
|
|
25
|
-
|
|
25
|
+
build: "vite build",
|
|
26
26
|
dev: "vite",
|
|
27
|
-
"format:check
|
|
28
|
-
"format:write
|
|
29
|
-
|
|
30
|
-
"lint:fix
|
|
27
|
+
"format:check": "oxfmt --list-different --config ../../oxfmt.config.ts .",
|
|
28
|
+
"format:write": "oxfmt --write --config ../../oxfmt.config.ts .",
|
|
29
|
+
lint: "oxlint --quiet --format=unix --config ../../oxlint.config.ts .",
|
|
30
|
+
"lint:fix": "oxlint --format=unix --config ../../oxlint.config.ts . --fix",
|
|
31
31
|
preview: "vite preview",
|
|
32
|
-
|
|
33
|
-
"test:e2e
|
|
32
|
+
test: "vitest run --reporter=agent --silent=passed-only",
|
|
33
|
+
"test:e2e": "node scripts/run-playwright.ts",
|
|
34
34
|
};
|
|
35
35
|
}
|
|
36
36
|
export function sharedVueSourceOperations(packagePath) {
|
|
@@ -50,24 +50,6 @@ export function vueTypecheckRunnerSourceOperation(packagePath) {
|
|
|
50
50
|
to: `${packagePath}/scripts/run-vue-tsc.ts`,
|
|
51
51
|
};
|
|
52
52
|
}
|
|
53
|
-
export function vueApplicationChecks(packagePath) {
|
|
54
|
-
const owner = { kind: "package-boundary", path: packagePath };
|
|
55
|
-
return [
|
|
56
|
-
{ kind: "typescript-typecheck", owner },
|
|
57
|
-
{ kind: "oxc-lint", owner },
|
|
58
|
-
{ kind: "oxc-format-check", owner },
|
|
59
|
-
{ kind: "build", owner },
|
|
60
|
-
{ kind: "unit-test", owner },
|
|
61
|
-
{ kind: "e2e-test", owner },
|
|
62
|
-
];
|
|
63
|
-
}
|
|
64
|
-
export function vueApplicationFixes(packagePath) {
|
|
65
|
-
const owner = { kind: "package-boundary", path: packagePath };
|
|
66
|
-
return [
|
|
67
|
-
{ kind: "oxc-format-write", owner },
|
|
68
|
-
{ kind: "oxc-lint-fix", owner },
|
|
69
|
-
];
|
|
70
|
-
}
|
|
71
53
|
export function vueApplicationEnvironmentNeeds(packagePath) {
|
|
72
54
|
return [
|
|
73
55
|
playwrightBrowserAssetsEnvironmentNeed({
|
|
@@ -2,11 +2,11 @@ import { fileURLToPath } from "node:url";
|
|
|
2
2
|
import { templateSources } from "../template-sources.js";
|
|
3
3
|
function packageScripts() {
|
|
4
4
|
return {
|
|
5
|
-
"format:check
|
|
6
|
-
"format:write
|
|
7
|
-
|
|
8
|
-
"lint:fix
|
|
9
|
-
|
|
5
|
+
"format:check": "oxfmt --list-different --config ../../oxfmt.config.ts .",
|
|
6
|
+
"format:write": "oxfmt --write --config ../../oxfmt.config.ts .",
|
|
7
|
+
lint: "oxlint --quiet --format=unix --config ../../oxlint.config.ts --ignore-pattern node_modules .",
|
|
8
|
+
"lint:fix": "oxlint --format=unix --config ../../oxlint.config.ts . --fix",
|
|
9
|
+
typecheck: "tsc -p tsconfig.json --noEmit --pretty false",
|
|
10
10
|
};
|
|
11
11
|
}
|
|
12
12
|
function libraryContribution(options) {
|
|
@@ -67,30 +67,6 @@ function libraryContribution(options) {
|
|
|
67
67
|
scripts: packageScripts(),
|
|
68
68
|
},
|
|
69
69
|
operations,
|
|
70
|
-
checks: [
|
|
71
|
-
{
|
|
72
|
-
kind: "typescript-typecheck",
|
|
73
|
-
owner: { kind: "package-boundary", path: definition.path },
|
|
74
|
-
},
|
|
75
|
-
{
|
|
76
|
-
kind: "oxc-lint",
|
|
77
|
-
owner: { kind: "package-boundary", path: definition.path },
|
|
78
|
-
},
|
|
79
|
-
{
|
|
80
|
-
kind: "oxc-format-check",
|
|
81
|
-
owner: { kind: "package-boundary", path: definition.path },
|
|
82
|
-
},
|
|
83
|
-
],
|
|
84
|
-
fixes: [
|
|
85
|
-
{
|
|
86
|
-
kind: "oxc-format-write",
|
|
87
|
-
owner: { kind: "package-boundary", path: definition.path },
|
|
88
|
-
},
|
|
89
|
-
{
|
|
90
|
-
kind: "oxc-lint-fix",
|
|
91
|
-
owner: { kind: "package-boundary", path: definition.path },
|
|
92
|
-
},
|
|
93
|
-
],
|
|
94
70
|
environmentNeeds: [],
|
|
95
71
|
foundation: {
|
|
96
72
|
toolchains: {},
|