@ykdz/template 0.0.3 → 0.0.4
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/README.md +1 -1
- package/dist/src/cli.d.ts +0 -1
- package/dist/src/cli.js +14 -2
- package/dist/src/declarations.d.ts +2 -3
- package/dist/src/declarations.js +46 -36
- package/dist/src/dependency-catalog.d.ts +9 -1
- package/dist/src/dependency-catalog.js +69 -0
- package/dist/src/devcontainer.d.ts +49 -9
- package/dist/src/devcontainer.js +192 -14
- package/dist/src/editor-customization.d.ts +0 -1
- package/dist/src/editor-customization.js +54 -47
- package/dist/src/generation-context.d.ts +0 -1
- package/dist/src/generation-context.js +4 -1
- package/dist/src/module-graph.d.ts +8 -5
- package/dist/src/module-graph.js +10 -0
- package/dist/src/next-step-instructions.d.ts +0 -1
- package/dist/src/next-step-instructions.js +35 -0
- package/dist/src/package-addition.d.ts +1 -1
- package/dist/src/package-addition.js +170 -15
- package/dist/src/preset-projection.d.ts +1 -1
- package/dist/src/project-github.d.ts +3 -2
- package/dist/src/project-github.js +24 -6
- package/dist/src/renderer.d.ts +16 -2
- package/dist/src/renderer.js +95 -12
- package/dist/src/runtime-paths.d.ts +0 -1
- package/dist/src/template-boundary-check.d.ts +34 -0
- package/dist/src/template-boundary-check.js +448 -0
- package/dist/src/toolchain-resolution.d.ts +0 -1
- package/dist/templates/hono-api/projection.d.ts +2 -3
- package/dist/templates/hono-api/projection.js +230 -69
- package/dist/templates/projection-plans.d.ts +0 -1
- package/dist/templates/registry.d.ts +0 -1
- package/dist/templates/registry.js +2 -2
- package/dist/templates/rust-bin/projection.d.ts +2 -3
- package/dist/templates/rust-bin/projection.js +161 -53
- package/dist/templates/ts-lib/projection.d.ts +2 -3
- package/dist/templates/ts-lib/projection.js +215 -64
- package/dist/templates/vue-app/projection.d.ts +2 -3
- package/dist/templates/vue-app/projection.js +246 -83
- package/dist/templates/vue-hono-app/projection.d.ts +0 -1
- package/dist/templates/vue-hono-app/projection.js +191 -87
- package/package.json +10 -5
- package/pnpm-workspace.yaml +1 -0
- package/templates/hono-api/.github/dependabot.yml +13 -0
- package/templates/rust-bin/.github/dependabot.yml +18 -1
- package/templates/rust-bin/rust-toolchain.toml +3 -0
- package/templates/rust-bin/rustfmt.toml +2 -0
- package/templates/shared/devcontainer/browser-test.Dockerfile +2 -0
- package/templates/shared/devcontainer/node-pnpm.Dockerfile +6 -0
- package/templates/shared/devcontainer/rust.Dockerfile +16 -0
- package/templates/shared/editor-customization/capabilities.json +56 -0
- package/templates/ts-lib/.github/dependabot.yml +13 -0
- package/templates/ts-lib/src/index.ts +5 -1
- package/templates/vue-app/.github/dependabot.yml +13 -0
- package/templates/vue-app/.github/workflows/check.yml +1 -1
- package/templates/vue-hono-app/.github/dependabot.yml +13 -0
- package/dist/src/cli.d.ts.map +0 -1
- package/dist/src/declarations.d.ts.map +0 -1
- package/dist/src/dependency-catalog.d.ts.map +0 -1
- package/dist/src/devcontainer.d.ts.map +0 -1
- package/dist/src/editor-customization.d.ts.map +0 -1
- package/dist/src/generation-context.d.ts.map +0 -1
- package/dist/src/module-graph.d.ts.map +0 -1
- package/dist/src/next-step-instructions.d.ts.map +0 -1
- package/dist/src/package-addition.d.ts.map +0 -1
- package/dist/src/preset-projection.d.ts.map +0 -1
- package/dist/src/project-github.d.ts.map +0 -1
- package/dist/src/renderer.d.ts.map +0 -1
- package/dist/src/runtime-paths.d.ts.map +0 -1
- package/dist/src/toolchain-resolution.d.ts.map +0 -1
- package/dist/templates/hono-api/projection.d.ts.map +0 -1
- package/dist/templates/projection-plans.d.ts.map +0 -1
- package/dist/templates/registry.d.ts.map +0 -1
- package/dist/templates/rust-bin/projection.d.ts.map +0 -1
- package/dist/templates/ts-lib/projection.d.ts.map +0 -1
- package/dist/templates/vue-app/projection.d.ts.map +0 -1
- package/dist/templates/vue-hono-app/projection.d.ts.map +0 -1
- package/templates/hono-api/projection.ts +0 -453
- package/templates/projection-plans.ts +0 -135
- package/templates/registry.ts +0 -59
- package/templates/rust-bin/projection.ts +0 -346
- package/templates/ts-lib/projection.ts +0 -454
- package/templates/vue-app/projection.ts +0 -687
- package/templates/vue-hono-app/projection.ts +0 -669
package/README.md
CHANGED
|
@@ -12,7 +12,7 @@ Available commands:
|
|
|
12
12
|
|
|
13
13
|
```sh
|
|
14
14
|
template init <dir> --preset <name> --yes
|
|
15
|
-
template add package --preset <name> --name <name>
|
|
15
|
+
template add package --preset <name> --name <name> [--path <package-path>]
|
|
16
16
|
template presets
|
|
17
17
|
template schema preset
|
|
18
18
|
template schema blueprint
|
package/dist/src/cli.d.ts
CHANGED
package/dist/src/cli.js
CHANGED
|
@@ -12,7 +12,7 @@ function usage() {
|
|
|
12
12
|
return [
|
|
13
13
|
"Usage:",
|
|
14
14
|
" template init <dir> --preset <name> --yes",
|
|
15
|
-
" template add package --preset <name> --name <name>",
|
|
15
|
+
" template add package --preset <name> --name <name> [--path <package-path>]",
|
|
16
16
|
" template presets",
|
|
17
17
|
" template schema preset",
|
|
18
18
|
" template schema blueprint",
|
|
@@ -22,6 +22,7 @@ function usage() {
|
|
|
22
22
|
"Options:",
|
|
23
23
|
" --preset <name> Project preset to generate",
|
|
24
24
|
" --name <name> Package name to add",
|
|
25
|
+
" --path <path> Two-segment Package Path to add",
|
|
25
26
|
" --scope <name> Package scope for workspace package names",
|
|
26
27
|
" --yes Accept defaults for non-interactive generation",
|
|
27
28
|
" --dry-run Print the planned generation without writing files",
|
|
@@ -281,6 +282,7 @@ async function confirmInit(targetDir, blueprint) {
|
|
|
281
282
|
function parseAddPackageOptions(args) {
|
|
282
283
|
let preset = "";
|
|
283
284
|
let name = "";
|
|
285
|
+
let packagePath;
|
|
284
286
|
for (let index = 2; index < args.length; index += 1) {
|
|
285
287
|
const arg = args[index];
|
|
286
288
|
if (arg === "--preset") {
|
|
@@ -301,6 +303,15 @@ function parseAddPackageOptions(args) {
|
|
|
301
303
|
index += 1;
|
|
302
304
|
continue;
|
|
303
305
|
}
|
|
306
|
+
if (arg === "--path") {
|
|
307
|
+
const value = args[index + 1];
|
|
308
|
+
if (!value) {
|
|
309
|
+
throw new Error("--path requires a value");
|
|
310
|
+
}
|
|
311
|
+
packagePath = value;
|
|
312
|
+
index += 1;
|
|
313
|
+
continue;
|
|
314
|
+
}
|
|
304
315
|
throw new Error(`Unknown option: ${arg}`);
|
|
305
316
|
}
|
|
306
317
|
if (!preset) {
|
|
@@ -309,7 +320,7 @@ function parseAddPackageOptions(args) {
|
|
|
309
320
|
if (!name) {
|
|
310
321
|
throw new Error("add package requires --name");
|
|
311
322
|
}
|
|
312
|
-
return { preset, name };
|
|
323
|
+
return { preset, name, path: packagePath };
|
|
313
324
|
}
|
|
314
325
|
async function main(args) {
|
|
315
326
|
const command = args[0];
|
|
@@ -405,6 +416,7 @@ async function main(args) {
|
|
|
405
416
|
cwd: process.cwd(),
|
|
406
417
|
preset: options.preset,
|
|
407
418
|
name: options.name,
|
|
419
|
+
path: options.path,
|
|
408
420
|
});
|
|
409
421
|
console.log(`Added ${options.preset} package ${options.name}`);
|
|
410
422
|
return;
|
|
@@ -67,7 +67,7 @@ export declare const presetFileJsonSchema: {
|
|
|
67
67
|
readonly type: "array";
|
|
68
68
|
readonly minItems: 1;
|
|
69
69
|
readonly items: {
|
|
70
|
-
readonly enum: readonly ["
|
|
70
|
+
readonly enum: readonly ["multi-package"];
|
|
71
71
|
};
|
|
72
72
|
readonly uniqueItems: true;
|
|
73
73
|
};
|
|
@@ -99,7 +99,7 @@ export declare const blueprintJsonSchema: {
|
|
|
99
99
|
readonly enum: readonly ["pnpm"];
|
|
100
100
|
};
|
|
101
101
|
readonly projectKind: {
|
|
102
|
-
readonly enum: readonly ["
|
|
102
|
+
readonly enum: readonly ["multi-package"];
|
|
103
103
|
};
|
|
104
104
|
readonly features: {
|
|
105
105
|
readonly type: "array";
|
|
@@ -162,4 +162,3 @@ export type ValidationResult<T> = {
|
|
|
162
162
|
export declare function validatePresetFile(input: unknown): ValidationResult<PresetFile>;
|
|
163
163
|
export declare function findBuiltInPreset(name: string): BuiltInPreset | undefined;
|
|
164
164
|
export declare function validateProjectBlueprint(input: unknown): ValidationResult<ProjectBlueprint>;
|
|
165
|
-
//# sourceMappingURL=declarations.d.ts.map
|
package/dist/src/declarations.js
CHANGED
|
@@ -12,7 +12,7 @@ const featureNames = [
|
|
|
12
12
|
"dependabot",
|
|
13
13
|
"rustfmt-clippy",
|
|
14
14
|
"cargo-test",
|
|
15
|
-
"native-binary-release"
|
|
15
|
+
"native-binary-release",
|
|
16
16
|
];
|
|
17
17
|
export const presetFileJsonSchema = {
|
|
18
18
|
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
@@ -27,7 +27,7 @@ export const presetFileJsonSchema = {
|
|
|
27
27
|
"description",
|
|
28
28
|
"supportedPackageManagers",
|
|
29
29
|
"supportedProjectKinds",
|
|
30
|
-
"features"
|
|
30
|
+
"features",
|
|
31
31
|
],
|
|
32
32
|
properties: {
|
|
33
33
|
schemaVersion: { const: 1 },
|
|
@@ -37,20 +37,20 @@ export const presetFileJsonSchema = {
|
|
|
37
37
|
supportedPackageManagers: {
|
|
38
38
|
type: "array",
|
|
39
39
|
items: { enum: ["pnpm"] },
|
|
40
|
-
uniqueItems: true
|
|
40
|
+
uniqueItems: true,
|
|
41
41
|
},
|
|
42
42
|
supportedProjectKinds: {
|
|
43
43
|
type: "array",
|
|
44
44
|
minItems: 1,
|
|
45
|
-
items: { enum: ["
|
|
46
|
-
uniqueItems: true
|
|
45
|
+
items: { enum: ["multi-package"] },
|
|
46
|
+
uniqueItems: true,
|
|
47
47
|
},
|
|
48
48
|
features: {
|
|
49
49
|
type: "array",
|
|
50
50
|
items: { enum: featureNames },
|
|
51
|
-
uniqueItems: true
|
|
52
|
-
}
|
|
53
|
-
}
|
|
51
|
+
uniqueItems: true,
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
54
|
};
|
|
55
55
|
export const blueprintJsonSchema = {
|
|
56
56
|
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
@@ -63,11 +63,11 @@ export const blueprintJsonSchema = {
|
|
|
63
63
|
schemaVersion: { const: 1 },
|
|
64
64
|
preset: { type: "string", minLength: 1 },
|
|
65
65
|
packageManager: { enum: ["pnpm"] },
|
|
66
|
-
projectKind: { enum: ["
|
|
66
|
+
projectKind: { enum: ["multi-package"] },
|
|
67
67
|
features: {
|
|
68
68
|
type: "array",
|
|
69
69
|
items: { enum: featureNames },
|
|
70
|
-
uniqueItems: true
|
|
70
|
+
uniqueItems: true,
|
|
71
71
|
},
|
|
72
72
|
packages: {
|
|
73
73
|
type: "array",
|
|
@@ -77,15 +77,18 @@ export const blueprintJsonSchema = {
|
|
|
77
77
|
required: ["name", "path"],
|
|
78
78
|
properties: {
|
|
79
79
|
name: { type: "string", minLength: 1 },
|
|
80
|
-
path: { type: "string", minLength: 1 }
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
}
|
|
80
|
+
path: { type: "string", minLength: 1 },
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
85
|
};
|
|
86
86
|
const nonEmptyString = v.pipe(v.string(), v.minLength(1));
|
|
87
87
|
const packageManagerSchema = v.picklist(["pnpm"]);
|
|
88
|
-
const projectKindSchema = v.picklist([
|
|
88
|
+
const projectKindSchema = v.picklist([
|
|
89
|
+
"single-package",
|
|
90
|
+
"multi-package",
|
|
91
|
+
]);
|
|
89
92
|
const featureNameSchema = v.picklist(featureNames);
|
|
90
93
|
export const presetFileSchema = v.strictObject({
|
|
91
94
|
schemaVersion: v.literal(1),
|
|
@@ -94,7 +97,7 @@ export const presetFileSchema = v.strictObject({
|
|
|
94
97
|
description: nonEmptyString,
|
|
95
98
|
supportedPackageManagers: v.array(packageManagerSchema),
|
|
96
99
|
supportedProjectKinds: v.pipe(v.array(projectKindSchema), v.minLength(1)),
|
|
97
|
-
features: v.array(featureNameSchema)
|
|
100
|
+
features: v.array(featureNameSchema),
|
|
98
101
|
});
|
|
99
102
|
export const projectBlueprintSchema = v.strictObject({
|
|
100
103
|
schemaVersion: v.literal(1),
|
|
@@ -104,8 +107,8 @@ export const projectBlueprintSchema = v.strictObject({
|
|
|
104
107
|
features: v.array(featureNameSchema),
|
|
105
108
|
packages: v.optional(v.array(v.strictObject({
|
|
106
109
|
name: nonEmptyString,
|
|
107
|
-
path: nonEmptyString
|
|
108
|
-
})))
|
|
110
|
+
path: nonEmptyString,
|
|
111
|
+
}))),
|
|
109
112
|
});
|
|
110
113
|
function formatIssuePath(issue) {
|
|
111
114
|
if (!issue.path || issue.path.length === 0) {
|
|
@@ -116,7 +119,7 @@ function formatIssuePath(issue) {
|
|
|
116
119
|
function shapeIssues(issues) {
|
|
117
120
|
return issues.map((issue) => ({
|
|
118
121
|
path: formatIssuePath(issue),
|
|
119
|
-
message: issue.message
|
|
122
|
+
message: issue.message,
|
|
120
123
|
}));
|
|
121
124
|
}
|
|
122
125
|
function duplicateIssues(values, path) {
|
|
@@ -130,7 +133,7 @@ function duplicateIssues(values, path) {
|
|
|
130
133
|
}
|
|
131
134
|
return [...duplicates].map((value) => ({
|
|
132
135
|
path,
|
|
133
|
-
message: `Duplicate value: ${value}
|
|
136
|
+
message: `Duplicate value: ${value}`,
|
|
134
137
|
}));
|
|
135
138
|
}
|
|
136
139
|
function generationSupportIssue(preset, path) {
|
|
@@ -139,7 +142,13 @@ function generationSupportIssue(preset, path) {
|
|
|
139
142
|
}
|
|
140
143
|
return {
|
|
141
144
|
path,
|
|
142
|
-
message: `Preset ${preset.name} is not supported for generation in this version
|
|
145
|
+
message: `Preset ${preset.name} is not supported for generation in this version`,
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
function unsupportedSinglePackageProjectShapeIssue(path) {
|
|
149
|
+
return {
|
|
150
|
+
path,
|
|
151
|
+
message: "single-package Project Shape is unsupported in V1; use the workspace monorepo Project Shape",
|
|
143
152
|
};
|
|
144
153
|
}
|
|
145
154
|
export function validatePresetFile(input) {
|
|
@@ -150,8 +159,11 @@ export function validatePresetFile(input) {
|
|
|
150
159
|
const semanticIssues = [
|
|
151
160
|
...duplicateIssues(result.output.supportedPackageManagers, "$.supportedPackageManagers"),
|
|
152
161
|
...duplicateIssues(result.output.supportedProjectKinds, "$.supportedProjectKinds"),
|
|
153
|
-
...duplicateIssues(result.output.features, "$.features")
|
|
162
|
+
...duplicateIssues(result.output.features, "$.features"),
|
|
154
163
|
];
|
|
164
|
+
if (result.output.supportedProjectKinds.includes("single-package")) {
|
|
165
|
+
semanticIssues.push(unsupportedSinglePackageProjectShapeIssue("$.supportedProjectKinds"));
|
|
166
|
+
}
|
|
155
167
|
const builtInPreset = findBuiltInPreset(result.output.name);
|
|
156
168
|
const unsupportedGeneration = builtInPreset
|
|
157
169
|
? generationSupportIssue(builtInPreset, "$.name")
|
|
@@ -175,12 +187,15 @@ export function validateProjectBlueprint(input) {
|
|
|
175
187
|
const blueprint = result.output;
|
|
176
188
|
const preset = findBuiltInPreset(blueprint.preset);
|
|
177
189
|
const semanticIssues = [
|
|
178
|
-
...duplicateIssues(blueprint.features, "$.features")
|
|
190
|
+
...duplicateIssues(blueprint.features, "$.features"),
|
|
179
191
|
];
|
|
192
|
+
if (blueprint.projectKind === "single-package") {
|
|
193
|
+
semanticIssues.push(unsupportedSinglePackageProjectShapeIssue("$.projectKind"));
|
|
194
|
+
}
|
|
180
195
|
if (!preset) {
|
|
181
196
|
semanticIssues.push({
|
|
182
197
|
path: "$.preset",
|
|
183
|
-
message: `Unknown built-in preset: ${blueprint.preset}
|
|
198
|
+
message: `Unknown built-in preset: ${blueprint.preset}`,
|
|
184
199
|
});
|
|
185
200
|
}
|
|
186
201
|
else {
|
|
@@ -192,19 +207,20 @@ export function validateProjectBlueprint(input) {
|
|
|
192
207
|
!preset.supportedPackageManagers.includes(blueprint.packageManager)) {
|
|
193
208
|
semanticIssues.push({
|
|
194
209
|
path: "$.packageManager",
|
|
195
|
-
message: `${blueprint.packageManager} is not supported by preset ${preset.name}
|
|
210
|
+
message: `${blueprint.packageManager} is not supported by preset ${preset.name}`,
|
|
196
211
|
});
|
|
197
212
|
}
|
|
198
|
-
if (!blueprint.packageManager &&
|
|
213
|
+
if (!blueprint.packageManager &&
|
|
214
|
+
preset.supportedPackageManagers.length > 0) {
|
|
199
215
|
semanticIssues.push({
|
|
200
216
|
path: "$.packageManager",
|
|
201
|
-
message: `packageManager is required by preset ${preset.name}
|
|
217
|
+
message: `packageManager is required by preset ${preset.name}`,
|
|
202
218
|
});
|
|
203
219
|
}
|
|
204
220
|
if (!preset.supportedProjectKinds.includes(blueprint.projectKind)) {
|
|
205
221
|
semanticIssues.push({
|
|
206
222
|
path: "$.projectKind",
|
|
207
|
-
message: `${blueprint.projectKind} is not supported by preset ${preset.name}
|
|
223
|
+
message: `${blueprint.projectKind} is not supported by preset ${preset.name}`,
|
|
208
224
|
});
|
|
209
225
|
}
|
|
210
226
|
const supportedFeatures = new Set(preset.features);
|
|
@@ -212,18 +228,12 @@ export function validateProjectBlueprint(input) {
|
|
|
212
228
|
if (!supportedFeatures.has(feature)) {
|
|
213
229
|
semanticIssues.push({
|
|
214
230
|
path: "$.features",
|
|
215
|
-
message: `${feature} is not supported by preset ${preset.name}
|
|
231
|
+
message: `${feature} is not supported by preset ${preset.name}`,
|
|
216
232
|
});
|
|
217
233
|
}
|
|
218
234
|
}
|
|
219
235
|
}
|
|
220
236
|
if (blueprint.packages) {
|
|
221
|
-
if (blueprint.projectKind === "single-package" && blueprint.packages.length > 1) {
|
|
222
|
-
semanticIssues.push({
|
|
223
|
-
path: "$.packages",
|
|
224
|
-
message: "single-package blueprints support exactly one package"
|
|
225
|
-
});
|
|
226
|
-
}
|
|
227
237
|
semanticIssues.push(...duplicateIssues(blueprint.packages.map((projectPackage) => projectPackage.name), "$.packages.name"), ...duplicateIssues(blueprint.packages.map((projectPackage) => projectPackage.path), "$.packages.path"));
|
|
228
238
|
}
|
|
229
239
|
if (semanticIssues.length > 0) {
|
|
@@ -4,7 +4,15 @@ export type GeneratedDependencyCatalogOptions = {
|
|
|
4
4
|
readonly packages?: readonly string[];
|
|
5
5
|
readonly allowBuilds?: Record<string, boolean>;
|
|
6
6
|
};
|
|
7
|
+
export type GeneratedPackageManifestDependencies = {
|
|
8
|
+
readonly dependencies?: Record<string, string>;
|
|
9
|
+
readonly devDependencies?: Record<string, string>;
|
|
10
|
+
readonly optionalDependencies?: Record<string, string>;
|
|
11
|
+
readonly peerDependencies?: Record<string, string>;
|
|
12
|
+
};
|
|
7
13
|
export declare function loadTemplateDependencyCatalog(): TemplateDependencyCatalog;
|
|
8
14
|
export declare function selectTemplateDependencyCatalogEntries(dependencies: readonly string[], catalog?: TemplateDependencyCatalog): TemplateDependencyCatalog;
|
|
15
|
+
export declare function collectGeneratedManifestCatalogDependencies(manifests: readonly GeneratedPackageManifestDependencies[]): string[];
|
|
16
|
+
export declare function collectGeneratedManifestCatalogReferences(manifests: readonly GeneratedPackageManifestDependencies[]): string[];
|
|
17
|
+
export declare function pnpmWorkspaceYamlWithCatalogDependencies(workspaceYaml: string, dependencies: readonly string[], templateCatalog?: TemplateDependencyCatalog): string;
|
|
9
18
|
export declare function renderGeneratedPnpmWorkspaceYaml(options: GeneratedDependencyCatalogOptions): string;
|
|
10
|
-
//# sourceMappingURL=dependency-catalog.d.ts.map
|
|
@@ -42,9 +42,78 @@ export function selectTemplateDependencyCatalogEntries(dependencies, catalog = l
|
|
|
42
42
|
}
|
|
43
43
|
return selected;
|
|
44
44
|
}
|
|
45
|
+
export function collectGeneratedManifestCatalogDependencies(manifests) {
|
|
46
|
+
const dependencies = new Set();
|
|
47
|
+
for (const manifest of manifests) {
|
|
48
|
+
for (const dependencyMap of [
|
|
49
|
+
manifest.dependencies,
|
|
50
|
+
manifest.devDependencies,
|
|
51
|
+
manifest.optionalDependencies,
|
|
52
|
+
manifest.peerDependencies,
|
|
53
|
+
]) {
|
|
54
|
+
for (const [dependency, specifier] of Object.entries(dependencyMap ?? {})) {
|
|
55
|
+
if (specifier !== "catalog:") {
|
|
56
|
+
throw new Error(`Generated manifest dependency ${dependency} must use catalog:, got ${specifier}`);
|
|
57
|
+
}
|
|
58
|
+
dependencies.add(dependency);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return [...dependencies].sort();
|
|
63
|
+
}
|
|
64
|
+
export function collectGeneratedManifestCatalogReferences(manifests) {
|
|
65
|
+
const dependencies = new Set();
|
|
66
|
+
for (const manifest of manifests) {
|
|
67
|
+
for (const dependencyMap of [
|
|
68
|
+
manifest.dependencies,
|
|
69
|
+
manifest.devDependencies,
|
|
70
|
+
manifest.optionalDependencies,
|
|
71
|
+
manifest.peerDependencies,
|
|
72
|
+
]) {
|
|
73
|
+
for (const [dependency, specifier] of Object.entries(dependencyMap ?? {})) {
|
|
74
|
+
if (specifier.startsWith("catalog:")) {
|
|
75
|
+
dependencies.add(dependency);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return [...dependencies].sort();
|
|
81
|
+
}
|
|
45
82
|
function renderCatalogKey(key) {
|
|
46
83
|
return key.startsWith("@") ? JSON.stringify(key) : key;
|
|
47
84
|
}
|
|
85
|
+
export function pnpmWorkspaceYamlWithCatalogDependencies(workspaceYaml, dependencies, templateCatalog = loadTemplateDependencyCatalog()) {
|
|
86
|
+
const catalogStart = workspaceYaml
|
|
87
|
+
.split(/\r?\n/)
|
|
88
|
+
.findIndex((line) => line === "catalog:");
|
|
89
|
+
if (catalogStart === -1) {
|
|
90
|
+
throw new Error("Cannot update pnpm Dependency Catalog: missing catalog section");
|
|
91
|
+
}
|
|
92
|
+
const existingCatalog = parseTemplateDependencyCatalog(workspaceYaml);
|
|
93
|
+
const missingDependencies = dependencies.filter((dependency) => existingCatalog[dependency] === undefined);
|
|
94
|
+
if (missingDependencies.length === 0) {
|
|
95
|
+
return workspaceYaml;
|
|
96
|
+
}
|
|
97
|
+
const nextCatalog = {
|
|
98
|
+
...existingCatalog,
|
|
99
|
+
...selectTemplateDependencyCatalogEntries(missingDependencies, templateCatalog),
|
|
100
|
+
};
|
|
101
|
+
const lines = workspaceYaml.split(/\r?\n/);
|
|
102
|
+
const catalogEnd = lines.findIndex((line, index) => index > catalogStart && line.length > 0 && !line.startsWith(" "));
|
|
103
|
+
const replacementEnd = catalogEnd === -1 ? lines.length : catalogEnd;
|
|
104
|
+
const catalogLines = [
|
|
105
|
+
"catalog:",
|
|
106
|
+
...Object.entries(nextCatalog)
|
|
107
|
+
.sort(([left], [right]) => left.localeCompare(right))
|
|
108
|
+
.map(([dependency, version]) => ` ${renderCatalogKey(dependency)}: ${version}`),
|
|
109
|
+
"",
|
|
110
|
+
];
|
|
111
|
+
return [
|
|
112
|
+
...lines.slice(0, catalogStart),
|
|
113
|
+
...catalogLines,
|
|
114
|
+
...lines.slice(replacementEnd),
|
|
115
|
+
].join("\n");
|
|
116
|
+
}
|
|
48
117
|
export function renderGeneratedPnpmWorkspaceYaml(options) {
|
|
49
118
|
const catalog = selectTemplateDependencyCatalogEntries(options.dependencies);
|
|
50
119
|
const packages = options.packages ?? ["."];
|
|
@@ -1,18 +1,58 @@
|
|
|
1
|
-
|
|
1
|
+
import type { WriteTextFromFragmentsOperation } from "./renderer.js";
|
|
2
|
+
export type DevelopmentContainerNodePnpmLayer = {
|
|
3
|
+
readonly kind: "node-pnpm";
|
|
2
4
|
readonly nodeVersion: string;
|
|
3
5
|
readonly packageManagerPin: string;
|
|
4
6
|
};
|
|
5
|
-
export type
|
|
6
|
-
readonly
|
|
7
|
-
readonly
|
|
7
|
+
export type DevelopmentContainerBrowserTestLayer = {
|
|
8
|
+
readonly kind: "browser-test";
|
|
9
|
+
readonly playwrightCliPackage: string;
|
|
8
10
|
};
|
|
9
|
-
export
|
|
10
|
-
|
|
11
|
-
|
|
11
|
+
export type DevelopmentContainerRustLayer = {
|
|
12
|
+
readonly kind: "rust";
|
|
13
|
+
readonly toolchain: string;
|
|
14
|
+
};
|
|
15
|
+
type DevelopmentContainerCapabilityLayer = DevelopmentContainerBrowserTestLayer | DevelopmentContainerRustLayer;
|
|
16
|
+
export type DevelopmentContainerPlan = {
|
|
17
|
+
readonly devcontainer: Record<string, unknown>;
|
|
18
|
+
readonly dockerfile: string;
|
|
19
|
+
readonly dockerfileOperation?: WriteTextFromFragmentsOperation;
|
|
20
|
+
};
|
|
21
|
+
export type DevelopmentContainerDockerfileLayer = {
|
|
22
|
+
readonly kind: "base" | "capability";
|
|
12
23
|
readonly name: string;
|
|
24
|
+
readonly text: string;
|
|
25
|
+
};
|
|
26
|
+
export declare function composeDevelopmentContainerDockerfile(options: {
|
|
27
|
+
readonly layers: readonly DevelopmentContainerDockerfileLayer[];
|
|
28
|
+
}): string;
|
|
29
|
+
export declare function nodePnpmToolLayer(options: {
|
|
13
30
|
readonly nodeVersion: string;
|
|
14
31
|
readonly packageManagerPin: string;
|
|
32
|
+
}): DevelopmentContainerNodePnpmLayer;
|
|
33
|
+
export declare function browserTestToolLayer(): DevelopmentContainerBrowserTestLayer;
|
|
34
|
+
export declare function rustToolLayer(options?: {
|
|
35
|
+
readonly toolchain?: string;
|
|
36
|
+
}): DevelopmentContainerRustLayer;
|
|
37
|
+
export declare function dockerfileFirstNodePnpmDevcontainer(options: {
|
|
38
|
+
readonly name: string;
|
|
39
|
+
readonly layer: DevelopmentContainerNodePnpmLayer;
|
|
40
|
+
readonly extensions: readonly string[];
|
|
41
|
+
readonly settings?: Record<string, unknown>;
|
|
42
|
+
}): DevelopmentContainerPlan;
|
|
43
|
+
export declare function checkedDockerfileFirstNodePnpmDevcontainer(options: {
|
|
44
|
+
readonly name: string;
|
|
45
|
+
readonly layer: DevelopmentContainerNodePnpmLayer;
|
|
46
|
+
readonly additionalLayers?: readonly DevelopmentContainerCapabilityLayer[];
|
|
47
|
+
readonly extensions: readonly string[];
|
|
48
|
+
readonly settings?: Record<string, unknown>;
|
|
49
|
+
readonly mounts?: readonly string[];
|
|
50
|
+
}): DevelopmentContainerPlan;
|
|
51
|
+
export declare function dockerfileFirstRustPnpmDevcontainer(options: {
|
|
52
|
+
readonly name: string;
|
|
53
|
+
readonly nodeLayer: DevelopmentContainerNodePnpmLayer;
|
|
54
|
+
readonly rustLayer: DevelopmentContainerRustLayer;
|
|
15
55
|
readonly extensions: readonly string[];
|
|
16
56
|
readonly settings?: Record<string, unknown>;
|
|
17
|
-
}):
|
|
18
|
-
|
|
57
|
+
}): DevelopmentContainerPlan;
|
|
58
|
+
export {};
|