@ykdz/template 0.0.3 → 0.0.5
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 +26 -2
- package/dist/src/declarations.d.ts +38 -3
- package/dist/src/declarations.js +75 -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 +20 -2
- package/dist/src/next-step-instructions.d.ts +0 -1
- package/dist/src/next-step-instructions.js +35 -0
- package/dist/src/package-addition-support.d.ts +5 -0
- package/dist/src/package-addition-support.js +4 -0
- package/dist/src/package-addition.d.ts +2 -1
- package/dist/src/package-addition.js +557 -55
- package/dist/src/package-linking.d.ts +55 -0
- package/dist/src/package-linking.js +116 -0
- package/dist/src/preset-projection.d.ts +4 -2
- 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 +96 -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 +258 -76
- package/dist/templates/projection-plans.d.ts +0 -1
- package/dist/templates/registry.d.ts +0 -1
- package/dist/templates/registry.js +5 -2
- package/dist/templates/rust-bin/projection.d.ts +2 -3
- package/dist/templates/rust-bin/projection.js +171 -53
- package/dist/templates/ts-lib/projection.d.ts +2 -3
- package/dist/templates/ts-lib/projection.js +251 -87
- package/dist/templates/vue-app/projection.d.ts +2 -3
- package/dist/templates/vue-app/projection.js +266 -94
- package/dist/templates/vue-hono-app/projection.d.ts +0 -1
- package/dist/templates/vue-hono-app/projection.js +232 -108
- package/package.json +10 -5
- package/pnpm-workspace.yaml +1 -0
- package/templates/hono-api/.github/dependabot.yml +13 -0
- package/templates/hono-api/src/server.ts +1 -1
- package/templates/hono-api/test/app.test.ts +1 -1
- 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/ts-lib/src/name-schema.ts +3 -0
- package/templates/vue-app/.github/dependabot.yml +13 -0
- package/templates/vue-app/.github/workflows/check.yml +1 -1
- package/templates/vue-app/src/App.vue +1 -1
- package/templates/vue-app/test/app.test.ts +1 -1
- package/templates/vue-hono-app/.github/dependabot.yml +13 -0
- package/templates/vue-hono-app/web/src/App.vue +2 -2
- package/templates/vue-hono-app/web/test/app.test.ts +1 -1
- 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>] [--link-from <package-path>]...",
|
|
16
16
|
" template presets",
|
|
17
17
|
" template schema preset",
|
|
18
18
|
" template schema blueprint",
|
|
@@ -22,6 +22,8 @@ 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",
|
|
26
|
+
" --link-from <path> Existing consumer Package Path to link from; repeatable",
|
|
25
27
|
" --scope <name> Package scope for workspace package names",
|
|
26
28
|
" --yes Accept defaults for non-interactive generation",
|
|
27
29
|
" --dry-run Print the planned generation without writing files",
|
|
@@ -281,6 +283,8 @@ async function confirmInit(targetDir, blueprint) {
|
|
|
281
283
|
function parseAddPackageOptions(args) {
|
|
282
284
|
let preset = "";
|
|
283
285
|
let name = "";
|
|
286
|
+
let packagePath;
|
|
287
|
+
const linkFrom = [];
|
|
284
288
|
for (let index = 2; index < args.length; index += 1) {
|
|
285
289
|
const arg = args[index];
|
|
286
290
|
if (arg === "--preset") {
|
|
@@ -301,6 +305,24 @@ function parseAddPackageOptions(args) {
|
|
|
301
305
|
index += 1;
|
|
302
306
|
continue;
|
|
303
307
|
}
|
|
308
|
+
if (arg === "--path") {
|
|
309
|
+
const value = args[index + 1];
|
|
310
|
+
if (!value) {
|
|
311
|
+
throw new Error("--path requires a value");
|
|
312
|
+
}
|
|
313
|
+
packagePath = value;
|
|
314
|
+
index += 1;
|
|
315
|
+
continue;
|
|
316
|
+
}
|
|
317
|
+
if (arg === "--link-from") {
|
|
318
|
+
const value = args[index + 1];
|
|
319
|
+
if (!value) {
|
|
320
|
+
throw new Error("--link-from requires a value");
|
|
321
|
+
}
|
|
322
|
+
linkFrom.push(value);
|
|
323
|
+
index += 1;
|
|
324
|
+
continue;
|
|
325
|
+
}
|
|
304
326
|
throw new Error(`Unknown option: ${arg}`);
|
|
305
327
|
}
|
|
306
328
|
if (!preset) {
|
|
@@ -309,7 +331,7 @@ function parseAddPackageOptions(args) {
|
|
|
309
331
|
if (!name) {
|
|
310
332
|
throw new Error("add package requires --name");
|
|
311
333
|
}
|
|
312
|
-
return { preset, name };
|
|
334
|
+
return { preset, name, path: packagePath, linkFrom };
|
|
313
335
|
}
|
|
314
336
|
async function main(args) {
|
|
315
337
|
const command = args[0];
|
|
@@ -405,6 +427,8 @@ async function main(args) {
|
|
|
405
427
|
cwd: process.cwd(),
|
|
406
428
|
preset: options.preset,
|
|
407
429
|
name: options.name,
|
|
430
|
+
path: options.path,
|
|
431
|
+
linkFrom: options.linkFrom,
|
|
408
432
|
});
|
|
409
433
|
console.log(`Added ${options.preset} package ${options.name}`);
|
|
410
434
|
return;
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import * as v from "valibot";
|
|
2
|
+
import type { PackageAdditionSupport } from "./package-addition-support.js";
|
|
3
|
+
import type { PackageLinkIntent, PackageRole, PackageSourcePreset } from "./package-linking.js";
|
|
2
4
|
export type BuiltInPreset = {
|
|
3
5
|
name: string;
|
|
4
6
|
title: string;
|
|
@@ -6,6 +8,7 @@ export type BuiltInPreset = {
|
|
|
6
8
|
generation: "supported" | "future";
|
|
7
9
|
supportedPackageManagers: readonly PackageManager[];
|
|
8
10
|
supportedProjectKinds: readonly ProjectKind[];
|
|
11
|
+
packageAdditionSupport: PackageAdditionSupport;
|
|
9
12
|
features: readonly FeatureName[];
|
|
10
13
|
};
|
|
11
14
|
export type PackageManager = "pnpm";
|
|
@@ -23,6 +26,8 @@ export type PresetFile = {
|
|
|
23
26
|
export type ProjectPackage = {
|
|
24
27
|
name: string;
|
|
25
28
|
path: string;
|
|
29
|
+
role?: PackageRole;
|
|
30
|
+
sourcePreset?: PackageSourcePreset;
|
|
26
31
|
};
|
|
27
32
|
export type ProjectBlueprint = {
|
|
28
33
|
schemaVersion: 1;
|
|
@@ -31,6 +36,7 @@ export type ProjectBlueprint = {
|
|
|
31
36
|
projectKind: ProjectKind;
|
|
32
37
|
features: FeatureName[];
|
|
33
38
|
packages?: ProjectPackage[];
|
|
39
|
+
packageLinkIntents?: PackageLinkIntent[];
|
|
34
40
|
};
|
|
35
41
|
export declare const builtInPresets: readonly BuiltInPreset[];
|
|
36
42
|
export declare const presetFileJsonSchema: {
|
|
@@ -67,7 +73,7 @@ export declare const presetFileJsonSchema: {
|
|
|
67
73
|
readonly type: "array";
|
|
68
74
|
readonly minItems: 1;
|
|
69
75
|
readonly items: {
|
|
70
|
-
readonly enum: readonly ["
|
|
76
|
+
readonly enum: readonly ["multi-package"];
|
|
71
77
|
};
|
|
72
78
|
readonly uniqueItems: true;
|
|
73
79
|
};
|
|
@@ -99,7 +105,7 @@ export declare const blueprintJsonSchema: {
|
|
|
99
105
|
readonly enum: readonly ["pnpm"];
|
|
100
106
|
};
|
|
101
107
|
readonly projectKind: {
|
|
102
|
-
readonly enum: readonly ["
|
|
108
|
+
readonly enum: readonly ["multi-package"];
|
|
103
109
|
};
|
|
104
110
|
readonly features: {
|
|
105
111
|
readonly type: "array";
|
|
@@ -123,6 +129,30 @@ export declare const blueprintJsonSchema: {
|
|
|
123
129
|
readonly type: "string";
|
|
124
130
|
readonly minLength: 1;
|
|
125
131
|
};
|
|
132
|
+
readonly role: {
|
|
133
|
+
readonly enum: readonly ["runtime-service", "shared-library"];
|
|
134
|
+
};
|
|
135
|
+
readonly sourcePreset: {
|
|
136
|
+
readonly enum: readonly ["hono-api", "ts-lib", "vue-app"];
|
|
137
|
+
};
|
|
138
|
+
};
|
|
139
|
+
};
|
|
140
|
+
};
|
|
141
|
+
readonly packageLinkIntents: {
|
|
142
|
+
readonly type: "array";
|
|
143
|
+
readonly items: {
|
|
144
|
+
readonly type: "object";
|
|
145
|
+
readonly additionalProperties: false;
|
|
146
|
+
readonly required: readonly ["consumerPackagePath", "providerPackagePath"];
|
|
147
|
+
readonly properties: {
|
|
148
|
+
readonly consumerPackagePath: {
|
|
149
|
+
readonly type: "string";
|
|
150
|
+
readonly minLength: 1;
|
|
151
|
+
};
|
|
152
|
+
readonly providerPackagePath: {
|
|
153
|
+
readonly type: "string";
|
|
154
|
+
readonly minLength: 1;
|
|
155
|
+
};
|
|
126
156
|
};
|
|
127
157
|
};
|
|
128
158
|
};
|
|
@@ -146,6 +176,12 @@ export declare const projectBlueprintSchema: v.StrictObjectSchema<{
|
|
|
146
176
|
readonly packages: v.OptionalSchema<v.ArraySchema<v.StrictObjectSchema<{
|
|
147
177
|
readonly name: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
148
178
|
readonly path: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
179
|
+
readonly role: v.OptionalSchema<v.PicklistSchema<["runtime-service", "shared-library"], undefined>, undefined>;
|
|
180
|
+
readonly sourcePreset: v.OptionalSchema<v.PicklistSchema<["hono-api", "ts-lib", "vue-app"], undefined>, undefined>;
|
|
181
|
+
}, undefined>, undefined>, undefined>;
|
|
182
|
+
readonly packageLinkIntents: v.OptionalSchema<v.ArraySchema<v.StrictObjectSchema<{
|
|
183
|
+
readonly consumerPackagePath: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
184
|
+
readonly providerPackagePath: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
149
185
|
}, undefined>, undefined>, undefined>;
|
|
150
186
|
}, undefined>;
|
|
151
187
|
export type ValidationIssue = {
|
|
@@ -162,4 +198,3 @@ export type ValidationResult<T> = {
|
|
|
162
198
|
export declare function validatePresetFile(input: unknown): ValidationResult<PresetFile>;
|
|
163
199
|
export declare function findBuiltInPreset(name: string): BuiltInPreset | undefined;
|
|
164
200
|
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,16 +77,42 @@ 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
|
+
role: { enum: ["runtime-service", "shared-library"] },
|
|
82
|
+
sourcePreset: { enum: ["hono-api", "ts-lib", "vue-app"] },
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
packageLinkIntents: {
|
|
87
|
+
type: "array",
|
|
88
|
+
items: {
|
|
89
|
+
type: "object",
|
|
90
|
+
additionalProperties: false,
|
|
91
|
+
required: ["consumerPackagePath", "providerPackagePath"],
|
|
92
|
+
properties: {
|
|
93
|
+
consumerPackagePath: { type: "string", minLength: 1 },
|
|
94
|
+
providerPackagePath: { type: "string", minLength: 1 },
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
},
|
|
85
99
|
};
|
|
86
100
|
const nonEmptyString = v.pipe(v.string(), v.minLength(1));
|
|
87
101
|
const packageManagerSchema = v.picklist(["pnpm"]);
|
|
88
|
-
const projectKindSchema = v.picklist([
|
|
102
|
+
const projectKindSchema = v.picklist([
|
|
103
|
+
"single-package",
|
|
104
|
+
"multi-package",
|
|
105
|
+
]);
|
|
89
106
|
const featureNameSchema = v.picklist(featureNames);
|
|
107
|
+
const packageRoleSchema = v.picklist([
|
|
108
|
+
"runtime-service",
|
|
109
|
+
"shared-library",
|
|
110
|
+
]);
|
|
111
|
+
const packageSourcePresetSchema = v.picklist([
|
|
112
|
+
"hono-api",
|
|
113
|
+
"ts-lib",
|
|
114
|
+
"vue-app",
|
|
115
|
+
]);
|
|
90
116
|
export const presetFileSchema = v.strictObject({
|
|
91
117
|
schemaVersion: v.literal(1),
|
|
92
118
|
name: nonEmptyString,
|
|
@@ -94,7 +120,7 @@ export const presetFileSchema = v.strictObject({
|
|
|
94
120
|
description: nonEmptyString,
|
|
95
121
|
supportedPackageManagers: v.array(packageManagerSchema),
|
|
96
122
|
supportedProjectKinds: v.pipe(v.array(projectKindSchema), v.minLength(1)),
|
|
97
|
-
features: v.array(featureNameSchema)
|
|
123
|
+
features: v.array(featureNameSchema),
|
|
98
124
|
});
|
|
99
125
|
export const projectBlueprintSchema = v.strictObject({
|
|
100
126
|
schemaVersion: v.literal(1),
|
|
@@ -104,8 +130,14 @@ export const projectBlueprintSchema = v.strictObject({
|
|
|
104
130
|
features: v.array(featureNameSchema),
|
|
105
131
|
packages: v.optional(v.array(v.strictObject({
|
|
106
132
|
name: nonEmptyString,
|
|
107
|
-
path: nonEmptyString
|
|
108
|
-
|
|
133
|
+
path: nonEmptyString,
|
|
134
|
+
role: v.optional(packageRoleSchema),
|
|
135
|
+
sourcePreset: v.optional(packageSourcePresetSchema),
|
|
136
|
+
}))),
|
|
137
|
+
packageLinkIntents: v.optional(v.array(v.strictObject({
|
|
138
|
+
consumerPackagePath: nonEmptyString,
|
|
139
|
+
providerPackagePath: nonEmptyString,
|
|
140
|
+
}))),
|
|
109
141
|
});
|
|
110
142
|
function formatIssuePath(issue) {
|
|
111
143
|
if (!issue.path || issue.path.length === 0) {
|
|
@@ -116,7 +148,7 @@ function formatIssuePath(issue) {
|
|
|
116
148
|
function shapeIssues(issues) {
|
|
117
149
|
return issues.map((issue) => ({
|
|
118
150
|
path: formatIssuePath(issue),
|
|
119
|
-
message: issue.message
|
|
151
|
+
message: issue.message,
|
|
120
152
|
}));
|
|
121
153
|
}
|
|
122
154
|
function duplicateIssues(values, path) {
|
|
@@ -130,7 +162,7 @@ function duplicateIssues(values, path) {
|
|
|
130
162
|
}
|
|
131
163
|
return [...duplicates].map((value) => ({
|
|
132
164
|
path,
|
|
133
|
-
message: `Duplicate value: ${value}
|
|
165
|
+
message: `Duplicate value: ${value}`,
|
|
134
166
|
}));
|
|
135
167
|
}
|
|
136
168
|
function generationSupportIssue(preset, path) {
|
|
@@ -139,7 +171,13 @@ function generationSupportIssue(preset, path) {
|
|
|
139
171
|
}
|
|
140
172
|
return {
|
|
141
173
|
path,
|
|
142
|
-
message: `Preset ${preset.name} is not supported for generation in this version
|
|
174
|
+
message: `Preset ${preset.name} is not supported for generation in this version`,
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
function unsupportedSinglePackageProjectShapeIssue(path) {
|
|
178
|
+
return {
|
|
179
|
+
path,
|
|
180
|
+
message: "single-package Project Shape is unsupported in V1; use the workspace monorepo Project Shape",
|
|
143
181
|
};
|
|
144
182
|
}
|
|
145
183
|
export function validatePresetFile(input) {
|
|
@@ -150,8 +188,11 @@ export function validatePresetFile(input) {
|
|
|
150
188
|
const semanticIssues = [
|
|
151
189
|
...duplicateIssues(result.output.supportedPackageManagers, "$.supportedPackageManagers"),
|
|
152
190
|
...duplicateIssues(result.output.supportedProjectKinds, "$.supportedProjectKinds"),
|
|
153
|
-
...duplicateIssues(result.output.features, "$.features")
|
|
191
|
+
...duplicateIssues(result.output.features, "$.features"),
|
|
154
192
|
];
|
|
193
|
+
if (result.output.supportedProjectKinds.includes("single-package")) {
|
|
194
|
+
semanticIssues.push(unsupportedSinglePackageProjectShapeIssue("$.supportedProjectKinds"));
|
|
195
|
+
}
|
|
155
196
|
const builtInPreset = findBuiltInPreset(result.output.name);
|
|
156
197
|
const unsupportedGeneration = builtInPreset
|
|
157
198
|
? generationSupportIssue(builtInPreset, "$.name")
|
|
@@ -175,12 +216,15 @@ export function validateProjectBlueprint(input) {
|
|
|
175
216
|
const blueprint = result.output;
|
|
176
217
|
const preset = findBuiltInPreset(blueprint.preset);
|
|
177
218
|
const semanticIssues = [
|
|
178
|
-
...duplicateIssues(blueprint.features, "$.features")
|
|
219
|
+
...duplicateIssues(blueprint.features, "$.features"),
|
|
179
220
|
];
|
|
221
|
+
if (blueprint.projectKind === "single-package") {
|
|
222
|
+
semanticIssues.push(unsupportedSinglePackageProjectShapeIssue("$.projectKind"));
|
|
223
|
+
}
|
|
180
224
|
if (!preset) {
|
|
181
225
|
semanticIssues.push({
|
|
182
226
|
path: "$.preset",
|
|
183
|
-
message: `Unknown built-in preset: ${blueprint.preset}
|
|
227
|
+
message: `Unknown built-in preset: ${blueprint.preset}`,
|
|
184
228
|
});
|
|
185
229
|
}
|
|
186
230
|
else {
|
|
@@ -192,19 +236,20 @@ export function validateProjectBlueprint(input) {
|
|
|
192
236
|
!preset.supportedPackageManagers.includes(blueprint.packageManager)) {
|
|
193
237
|
semanticIssues.push({
|
|
194
238
|
path: "$.packageManager",
|
|
195
|
-
message: `${blueprint.packageManager} is not supported by preset ${preset.name}
|
|
239
|
+
message: `${blueprint.packageManager} is not supported by preset ${preset.name}`,
|
|
196
240
|
});
|
|
197
241
|
}
|
|
198
|
-
if (!blueprint.packageManager &&
|
|
242
|
+
if (!blueprint.packageManager &&
|
|
243
|
+
preset.supportedPackageManagers.length > 0) {
|
|
199
244
|
semanticIssues.push({
|
|
200
245
|
path: "$.packageManager",
|
|
201
|
-
message: `packageManager is required by preset ${preset.name}
|
|
246
|
+
message: `packageManager is required by preset ${preset.name}`,
|
|
202
247
|
});
|
|
203
248
|
}
|
|
204
249
|
if (!preset.supportedProjectKinds.includes(blueprint.projectKind)) {
|
|
205
250
|
semanticIssues.push({
|
|
206
251
|
path: "$.projectKind",
|
|
207
|
-
message: `${blueprint.projectKind} is not supported by preset ${preset.name}
|
|
252
|
+
message: `${blueprint.projectKind} is not supported by preset ${preset.name}`,
|
|
208
253
|
});
|
|
209
254
|
}
|
|
210
255
|
const supportedFeatures = new Set(preset.features);
|
|
@@ -212,18 +257,12 @@ export function validateProjectBlueprint(input) {
|
|
|
212
257
|
if (!supportedFeatures.has(feature)) {
|
|
213
258
|
semanticIssues.push({
|
|
214
259
|
path: "$.features",
|
|
215
|
-
message: `${feature} is not supported by preset ${preset.name}
|
|
260
|
+
message: `${feature} is not supported by preset ${preset.name}`,
|
|
216
261
|
});
|
|
217
262
|
}
|
|
218
263
|
}
|
|
219
264
|
}
|
|
220
265
|
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
266
|
semanticIssues.push(...duplicateIssues(blueprint.packages.map((projectPackage) => projectPackage.name), "$.packages.name"), ...duplicateIssues(blueprint.packages.map((projectPackage) => projectPackage.path), "$.packages.path"));
|
|
228
267
|
}
|
|
229
268
|
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 {};
|