@ykdz/template 0.0.9 → 0.0.11
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/dist/cli.js +2 -2
- package/node_modules/@ykdz/template-builtin-source/dist/src/index.d.ts +4 -4
- package/node_modules/@ykdz/template-builtin-source/dist/src/index.js +12 -5
- package/node_modules/@ykdz/template-builtin-source/dist/templates/hono-api/projection.d.ts +1 -1
- package/node_modules/@ykdz/template-builtin-source/dist/templates/hono-api/projection.js +1 -1
- package/node_modules/@ykdz/template-builtin-source/dist/templates/projection-plans.js +9 -6
- package/node_modules/@ykdz/template-builtin-source/dist/templates/rust-bin/projection.d.ts +1 -1
- package/node_modules/@ykdz/template-builtin-source/dist/templates/rust-bin/projection.js +1 -1
- package/node_modules/@ykdz/template-builtin-source/dist/templates/ts-lib/projection.d.ts +1 -1
- package/node_modules/@ykdz/template-builtin-source/dist/templates/ts-lib/projection.js +1 -1
- package/node_modules/@ykdz/template-builtin-source/dist/templates/vue-app/projection.d.ts +1 -1
- package/node_modules/@ykdz/template-builtin-source/dist/templates/vue-app/projection.js +9 -4
- package/node_modules/@ykdz/template-builtin-source/dist/templates/vue-hono-app/projection.d.ts +1 -1
- package/node_modules/@ykdz/template-builtin-source/dist/templates/vue-hono-app/projection.js +7 -7
- package/node_modules/@ykdz/template-builtin-source/package.json +4 -3
- package/node_modules/@ykdz/template-builtin-source/templates/preset-source.json +39 -11
- package/node_modules/@ykdz/template-builtin-source/templates/vue-app/scripts/run-playwright.ts +25 -0
- package/node_modules/@ykdz/template-builtin-source/templates/vue-app/src/App.vue +18 -4
- package/node_modules/@ykdz/template-builtin-source/templates/vue-hono-app/web/scripts/run-playwright.ts +25 -0
- package/node_modules/@ykdz/template-builtin-source/templates/vue-hono-app/web/src/App.vue +18 -4
- package/node_modules/@ykdz/template-core/dist/declarations.d.ts +2 -203
- package/node_modules/@ykdz/template-core/dist/declarations.js +1 -303
- package/node_modules/@ykdz/template-core/dist/devcontainer.d.ts +17 -0
- package/node_modules/@ykdz/template-core/dist/devcontainer.js +22 -21
- package/node_modules/@ykdz/template-core/dist/editor-customization.d.ts +10 -1
- package/node_modules/@ykdz/template-core/dist/editor-customization.js +36 -26
- package/node_modules/@ykdz/template-core/dist/generated-scenarios.d.ts +5 -0
- package/node_modules/@ykdz/template-core/dist/generated-scenarios.js +42 -24
- package/node_modules/@ykdz/template-core/dist/generation-context.d.ts +1 -1
- package/node_modules/@ykdz/template-core/dist/module-graph.d.ts +19 -1
- package/node_modules/@ykdz/template-core/dist/module-graph.js +42 -3
- package/node_modules/@ykdz/template-core/dist/next-step-instructions.d.ts +2 -0
- package/node_modules/@ykdz/template-core/dist/next-step-instructions.js +11 -22
- package/node_modules/@ykdz/template-core/dist/package-addition-support.d.ts +2 -1
- package/node_modules/@ykdz/template-core/dist/package-addition-support.js +2 -4
- package/node_modules/@ykdz/template-core/dist/package-addition.js +4 -3
- package/node_modules/@ykdz/template-core/dist/package-linking.d.ts +2 -6
- package/node_modules/@ykdz/template-core/dist/package-linking.js +1 -1
- package/node_modules/@ykdz/template-core/dist/pnpm-workspace.yaml +3 -5
- package/node_modules/@ykdz/template-core/dist/preset-projection.d.ts +1 -2
- package/node_modules/@ykdz/template-core/dist/preset-source.d.ts +4 -418
- package/node_modules/@ykdz/template-core/dist/preset-source.js +81 -726
- package/node_modules/@ykdz/template-core/dist/project-github.js +2 -6
- package/node_modules/@ykdz/template-core/dist/projection-capabilities.d.ts +5 -53
- package/node_modules/@ykdz/template-core/dist/projection-capabilities.js +108 -507
- package/node_modules/@ykdz/template-core/dist/toolchain-resolution.js +1 -1
- package/node_modules/@ykdz/template-core/package.json +4 -3
- package/node_modules/@ykdz/template-shared/dist/index.d.ts +794 -0
- package/node_modules/@ykdz/template-shared/dist/index.js +1637 -0
- package/node_modules/@ykdz/template-shared/package.json +32 -0
- package/package.json +9 -6
|
@@ -1,203 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
import type { PackageLinkIntent, PackageRole, PackageSourcePreset } from "./package-linking.js";
|
|
4
|
-
export type BuiltInPreset = {
|
|
5
|
-
name: string;
|
|
6
|
-
title: string;
|
|
7
|
-
description: string;
|
|
8
|
-
generation: "supported" | "future";
|
|
9
|
-
supportedPackageManagers: readonly PackageManager[];
|
|
10
|
-
supportedProjectKinds: readonly ProjectKind[];
|
|
11
|
-
packageAdditionSupport: PackageAdditionSupport;
|
|
12
|
-
features: readonly FeatureName[];
|
|
13
|
-
};
|
|
14
|
-
export type PackageManager = "pnpm";
|
|
15
|
-
export type ProjectKind = "single-package" | "multi-package";
|
|
16
|
-
export type FeatureName = "pnpm-catalog" | "oxc-format-lint" | "strict-typescript" | "root-check" | "fix-command" | "devcontainer" | "github-actions" | "dependabot" | "rustfmt-clippy" | "cargo-test" | "native-binary-release";
|
|
17
|
-
export type PresetFile = {
|
|
18
|
-
schemaVersion: 1;
|
|
19
|
-
name: string;
|
|
20
|
-
title: string;
|
|
21
|
-
description: string;
|
|
22
|
-
supportedPackageManagers: PackageManager[];
|
|
23
|
-
supportedProjectKinds: ProjectKind[];
|
|
24
|
-
features: FeatureName[];
|
|
25
|
-
};
|
|
26
|
-
export type ProjectPackage = {
|
|
27
|
-
name: string;
|
|
28
|
-
path: string;
|
|
29
|
-
role?: PackageRole;
|
|
30
|
-
sourcePreset?: PackageSourcePreset;
|
|
31
|
-
};
|
|
32
|
-
export type ProjectBlueprint = {
|
|
33
|
-
schemaVersion: 1;
|
|
34
|
-
preset: string;
|
|
35
|
-
packageManager?: PackageManager;
|
|
36
|
-
projectKind: ProjectKind;
|
|
37
|
-
features: FeatureName[];
|
|
38
|
-
packages?: ProjectPackage[];
|
|
39
|
-
packageLinkIntents?: PackageLinkIntent[];
|
|
40
|
-
};
|
|
41
|
-
export declare const presetFileJsonSchema: {
|
|
42
|
-
readonly $schema: "https://json-schema.org/draft/2020-12/schema";
|
|
43
|
-
readonly $id: "https://ykdz.dev/schemas/project-kit/preset-file.schema.json";
|
|
44
|
-
readonly title: "Project Kit Preset File";
|
|
45
|
-
readonly type: "object";
|
|
46
|
-
readonly additionalProperties: false;
|
|
47
|
-
readonly required: readonly ["schemaVersion", "name", "title", "description", "supportedPackageManagers", "supportedProjectKinds", "features"];
|
|
48
|
-
readonly properties: {
|
|
49
|
-
readonly schemaVersion: {
|
|
50
|
-
readonly const: 1;
|
|
51
|
-
};
|
|
52
|
-
readonly name: {
|
|
53
|
-
readonly type: "string";
|
|
54
|
-
readonly minLength: 1;
|
|
55
|
-
};
|
|
56
|
-
readonly title: {
|
|
57
|
-
readonly type: "string";
|
|
58
|
-
readonly minLength: 1;
|
|
59
|
-
};
|
|
60
|
-
readonly description: {
|
|
61
|
-
readonly type: "string";
|
|
62
|
-
readonly minLength: 1;
|
|
63
|
-
};
|
|
64
|
-
readonly supportedPackageManagers: {
|
|
65
|
-
readonly type: "array";
|
|
66
|
-
readonly items: {
|
|
67
|
-
readonly enum: readonly ["pnpm"];
|
|
68
|
-
};
|
|
69
|
-
readonly uniqueItems: true;
|
|
70
|
-
};
|
|
71
|
-
readonly supportedProjectKinds: {
|
|
72
|
-
readonly type: "array";
|
|
73
|
-
readonly minItems: 1;
|
|
74
|
-
readonly items: {
|
|
75
|
-
readonly enum: readonly ["multi-package"];
|
|
76
|
-
};
|
|
77
|
-
readonly uniqueItems: true;
|
|
78
|
-
};
|
|
79
|
-
readonly features: {
|
|
80
|
-
readonly type: "array";
|
|
81
|
-
readonly items: {
|
|
82
|
-
readonly enum: FeatureName[];
|
|
83
|
-
};
|
|
84
|
-
readonly uniqueItems: true;
|
|
85
|
-
};
|
|
86
|
-
};
|
|
87
|
-
};
|
|
88
|
-
export declare const blueprintJsonSchema: {
|
|
89
|
-
readonly $schema: "https://json-schema.org/draft/2020-12/schema";
|
|
90
|
-
readonly $id: "https://ykdz.dev/schemas/project-kit/blueprint.schema.json";
|
|
91
|
-
readonly title: "Project Kit Blueprint";
|
|
92
|
-
readonly type: "object";
|
|
93
|
-
readonly additionalProperties: false;
|
|
94
|
-
readonly required: readonly ["schemaVersion", "preset", "projectKind", "features"];
|
|
95
|
-
readonly properties: {
|
|
96
|
-
readonly schemaVersion: {
|
|
97
|
-
readonly const: 1;
|
|
98
|
-
};
|
|
99
|
-
readonly preset: {
|
|
100
|
-
readonly type: "string";
|
|
101
|
-
readonly minLength: 1;
|
|
102
|
-
};
|
|
103
|
-
readonly packageManager: {
|
|
104
|
-
readonly enum: readonly ["pnpm"];
|
|
105
|
-
};
|
|
106
|
-
readonly projectKind: {
|
|
107
|
-
readonly enum: readonly ["multi-package"];
|
|
108
|
-
};
|
|
109
|
-
readonly features: {
|
|
110
|
-
readonly type: "array";
|
|
111
|
-
readonly items: {
|
|
112
|
-
readonly enum: FeatureName[];
|
|
113
|
-
};
|
|
114
|
-
readonly uniqueItems: true;
|
|
115
|
-
};
|
|
116
|
-
readonly packages: {
|
|
117
|
-
readonly type: "array";
|
|
118
|
-
readonly items: {
|
|
119
|
-
readonly type: "object";
|
|
120
|
-
readonly additionalProperties: false;
|
|
121
|
-
readonly required: readonly ["name", "path"];
|
|
122
|
-
readonly properties: {
|
|
123
|
-
readonly name: {
|
|
124
|
-
readonly type: "string";
|
|
125
|
-
readonly minLength: 1;
|
|
126
|
-
};
|
|
127
|
-
readonly path: {
|
|
128
|
-
readonly type: "string";
|
|
129
|
-
readonly minLength: 1;
|
|
130
|
-
};
|
|
131
|
-
readonly role: {
|
|
132
|
-
readonly enum: readonly ["runtime-service", "shared-library"];
|
|
133
|
-
};
|
|
134
|
-
readonly sourcePreset: {
|
|
135
|
-
readonly enum: readonly ["hono-api", "ts-lib", "vue-app"];
|
|
136
|
-
};
|
|
137
|
-
};
|
|
138
|
-
};
|
|
139
|
-
};
|
|
140
|
-
readonly packageLinkIntents: {
|
|
141
|
-
readonly type: "array";
|
|
142
|
-
readonly items: {
|
|
143
|
-
readonly type: "object";
|
|
144
|
-
readonly additionalProperties: false;
|
|
145
|
-
readonly required: readonly ["consumerPackagePath", "providerPackagePath"];
|
|
146
|
-
readonly properties: {
|
|
147
|
-
readonly consumerPackagePath: {
|
|
148
|
-
readonly type: "string";
|
|
149
|
-
readonly minLength: 1;
|
|
150
|
-
};
|
|
151
|
-
readonly providerPackagePath: {
|
|
152
|
-
readonly type: "string";
|
|
153
|
-
readonly minLength: 1;
|
|
154
|
-
};
|
|
155
|
-
};
|
|
156
|
-
};
|
|
157
|
-
};
|
|
158
|
-
};
|
|
159
|
-
};
|
|
160
|
-
export declare const presetFileSchema: v.StrictObjectSchema<{
|
|
161
|
-
readonly schemaVersion: v.LiteralSchema<1, undefined>;
|
|
162
|
-
readonly name: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
163
|
-
readonly title: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
164
|
-
readonly description: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
165
|
-
readonly supportedPackageManagers: v.ArraySchema<v.PicklistSchema<["pnpm"], undefined>, undefined>;
|
|
166
|
-
readonly supportedProjectKinds: v.SchemaWithPipe<readonly [v.ArraySchema<v.PicklistSchema<["single-package", "multi-package"], undefined>, undefined>, v.MinLengthAction<("single-package" | "multi-package")[], 1, undefined>]>;
|
|
167
|
-
readonly features: v.ArraySchema<v.PicklistSchema<FeatureName[], undefined>, undefined>;
|
|
168
|
-
}, undefined>;
|
|
169
|
-
export declare const projectBlueprintSchema: v.StrictObjectSchema<{
|
|
170
|
-
readonly schemaVersion: v.LiteralSchema<1, undefined>;
|
|
171
|
-
readonly preset: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
172
|
-
readonly packageManager: v.OptionalSchema<v.PicklistSchema<["pnpm"], undefined>, undefined>;
|
|
173
|
-
readonly projectKind: v.PicklistSchema<["single-package", "multi-package"], undefined>;
|
|
174
|
-
readonly features: v.ArraySchema<v.PicklistSchema<FeatureName[], undefined>, undefined>;
|
|
175
|
-
readonly packages: v.OptionalSchema<v.ArraySchema<v.StrictObjectSchema<{
|
|
176
|
-
readonly name: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
177
|
-
readonly path: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
178
|
-
readonly role: v.OptionalSchema<v.PicklistSchema<["runtime-service", "shared-library"], undefined>, undefined>;
|
|
179
|
-
readonly sourcePreset: v.OptionalSchema<v.PicklistSchema<["hono-api", "ts-lib", "vue-app"], undefined>, undefined>;
|
|
180
|
-
}, undefined>, undefined>, undefined>;
|
|
181
|
-
readonly packageLinkIntents: v.OptionalSchema<v.ArraySchema<v.StrictObjectSchema<{
|
|
182
|
-
readonly consumerPackagePath: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
183
|
-
readonly providerPackagePath: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
184
|
-
}, undefined>, undefined>, undefined>;
|
|
185
|
-
}, undefined>;
|
|
186
|
-
export type ValidationIssue = {
|
|
187
|
-
path: string;
|
|
188
|
-
message: string;
|
|
189
|
-
};
|
|
190
|
-
export type ValidationResult<T> = {
|
|
191
|
-
ok: true;
|
|
192
|
-
value: T;
|
|
193
|
-
} | {
|
|
194
|
-
ok: false;
|
|
195
|
-
issues: ValidationIssue[];
|
|
196
|
-
};
|
|
197
|
-
export type PresetCatalogValidationOptions = {
|
|
198
|
-
readonly presets?: readonly BuiltInPreset[];
|
|
199
|
-
readonly presetLabel?: string;
|
|
200
|
-
};
|
|
201
|
-
export declare function validatePresetFile(input: unknown, options?: PresetCatalogValidationOptions): ValidationResult<PresetFile>;
|
|
202
|
-
export declare function findPreset(presets: readonly BuiltInPreset[], name: string): BuiltInPreset | undefined;
|
|
203
|
-
export declare function validateProjectBlueprint(input: unknown, options?: PresetCatalogValidationOptions): ValidationResult<ProjectBlueprint>;
|
|
1
|
+
export { blueprintJsonSchema, findPreset, presetFileJsonSchema, presetFileSchema, projectBlueprintSchema, validatePresetFile, validateProjectBlueprint, } from "@ykdz/template-shared";
|
|
2
|
+
export type { BuiltInPreset, FeatureName, PackageManager, PresetCatalogValidationOptions, PresetFile, ProjectBlueprint, ProjectKind, ProjectPackage, ValidationIssue, ValidationResult, } from "@ykdz/template-shared";
|
|
@@ -1,303 +1 @@
|
|
|
1
|
-
|
|
2
|
-
const featureNames = [
|
|
3
|
-
"pnpm-catalog",
|
|
4
|
-
"oxc-format-lint",
|
|
5
|
-
"strict-typescript",
|
|
6
|
-
"root-check",
|
|
7
|
-
"fix-command",
|
|
8
|
-
"devcontainer",
|
|
9
|
-
"github-actions",
|
|
10
|
-
"dependabot",
|
|
11
|
-
"rustfmt-clippy",
|
|
12
|
-
"cargo-test",
|
|
13
|
-
"native-binary-release",
|
|
14
|
-
];
|
|
15
|
-
export const presetFileJsonSchema = {
|
|
16
|
-
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
17
|
-
$id: "https://ykdz.dev/schemas/project-kit/preset-file.schema.json",
|
|
18
|
-
title: "Project Kit Preset File",
|
|
19
|
-
type: "object",
|
|
20
|
-
additionalProperties: false,
|
|
21
|
-
required: [
|
|
22
|
-
"schemaVersion",
|
|
23
|
-
"name",
|
|
24
|
-
"title",
|
|
25
|
-
"description",
|
|
26
|
-
"supportedPackageManagers",
|
|
27
|
-
"supportedProjectKinds",
|
|
28
|
-
"features",
|
|
29
|
-
],
|
|
30
|
-
properties: {
|
|
31
|
-
schemaVersion: { const: 1 },
|
|
32
|
-
name: { type: "string", minLength: 1 },
|
|
33
|
-
title: { type: "string", minLength: 1 },
|
|
34
|
-
description: { type: "string", minLength: 1 },
|
|
35
|
-
supportedPackageManagers: {
|
|
36
|
-
type: "array",
|
|
37
|
-
items: { enum: ["pnpm"] },
|
|
38
|
-
uniqueItems: true,
|
|
39
|
-
},
|
|
40
|
-
supportedProjectKinds: {
|
|
41
|
-
type: "array",
|
|
42
|
-
minItems: 1,
|
|
43
|
-
items: { enum: ["multi-package"] },
|
|
44
|
-
uniqueItems: true,
|
|
45
|
-
},
|
|
46
|
-
features: {
|
|
47
|
-
type: "array",
|
|
48
|
-
items: { enum: featureNames },
|
|
49
|
-
uniqueItems: true,
|
|
50
|
-
},
|
|
51
|
-
},
|
|
52
|
-
};
|
|
53
|
-
export const blueprintJsonSchema = {
|
|
54
|
-
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
55
|
-
$id: "https://ykdz.dev/schemas/project-kit/blueprint.schema.json",
|
|
56
|
-
title: "Project Kit Blueprint",
|
|
57
|
-
type: "object",
|
|
58
|
-
additionalProperties: false,
|
|
59
|
-
required: ["schemaVersion", "preset", "projectKind", "features"],
|
|
60
|
-
properties: {
|
|
61
|
-
schemaVersion: { const: 1 },
|
|
62
|
-
preset: { type: "string", minLength: 1 },
|
|
63
|
-
packageManager: { enum: ["pnpm"] },
|
|
64
|
-
projectKind: { enum: ["multi-package"] },
|
|
65
|
-
features: {
|
|
66
|
-
type: "array",
|
|
67
|
-
items: { enum: featureNames },
|
|
68
|
-
uniqueItems: true,
|
|
69
|
-
},
|
|
70
|
-
packages: {
|
|
71
|
-
type: "array",
|
|
72
|
-
items: {
|
|
73
|
-
type: "object",
|
|
74
|
-
additionalProperties: false,
|
|
75
|
-
required: ["name", "path"],
|
|
76
|
-
properties: {
|
|
77
|
-
name: { type: "string", minLength: 1 },
|
|
78
|
-
path: { type: "string", minLength: 1 },
|
|
79
|
-
role: { enum: ["runtime-service", "shared-library"] },
|
|
80
|
-
sourcePreset: { enum: ["hono-api", "ts-lib", "vue-app"] },
|
|
81
|
-
},
|
|
82
|
-
},
|
|
83
|
-
},
|
|
84
|
-
packageLinkIntents: {
|
|
85
|
-
type: "array",
|
|
86
|
-
items: {
|
|
87
|
-
type: "object",
|
|
88
|
-
additionalProperties: false,
|
|
89
|
-
required: ["consumerPackagePath", "providerPackagePath"],
|
|
90
|
-
properties: {
|
|
91
|
-
consumerPackagePath: { type: "string", minLength: 1 },
|
|
92
|
-
providerPackagePath: { type: "string", minLength: 1 },
|
|
93
|
-
},
|
|
94
|
-
},
|
|
95
|
-
},
|
|
96
|
-
},
|
|
97
|
-
};
|
|
98
|
-
const nonEmptyString = v.pipe(v.string(), v.minLength(1));
|
|
99
|
-
const packageManagerSchema = v.picklist(["pnpm"]);
|
|
100
|
-
const projectKindSchema = v.picklist([
|
|
101
|
-
"single-package",
|
|
102
|
-
"multi-package",
|
|
103
|
-
]);
|
|
104
|
-
const featureNameSchema = v.picklist(featureNames);
|
|
105
|
-
const packageRoleSchema = v.picklist([
|
|
106
|
-
"runtime-service",
|
|
107
|
-
"shared-library",
|
|
108
|
-
]);
|
|
109
|
-
const packageSourcePresetSchema = v.picklist([
|
|
110
|
-
"hono-api",
|
|
111
|
-
"ts-lib",
|
|
112
|
-
"vue-app",
|
|
113
|
-
]);
|
|
114
|
-
export const presetFileSchema = v.strictObject({
|
|
115
|
-
schemaVersion: v.literal(1),
|
|
116
|
-
name: nonEmptyString,
|
|
117
|
-
title: nonEmptyString,
|
|
118
|
-
description: nonEmptyString,
|
|
119
|
-
supportedPackageManagers: v.array(packageManagerSchema),
|
|
120
|
-
supportedProjectKinds: v.pipe(v.array(projectKindSchema), v.minLength(1)),
|
|
121
|
-
features: v.array(featureNameSchema),
|
|
122
|
-
});
|
|
123
|
-
export const projectBlueprintSchema = v.strictObject({
|
|
124
|
-
schemaVersion: v.literal(1),
|
|
125
|
-
preset: nonEmptyString,
|
|
126
|
-
packageManager: v.optional(packageManagerSchema),
|
|
127
|
-
projectKind: projectKindSchema,
|
|
128
|
-
features: v.array(featureNameSchema),
|
|
129
|
-
packages: v.optional(v.array(v.strictObject({
|
|
130
|
-
name: nonEmptyString,
|
|
131
|
-
path: nonEmptyString,
|
|
132
|
-
role: v.optional(packageRoleSchema),
|
|
133
|
-
sourcePreset: v.optional(packageSourcePresetSchema),
|
|
134
|
-
}))),
|
|
135
|
-
packageLinkIntents: v.optional(v.array(v.strictObject({
|
|
136
|
-
consumerPackagePath: nonEmptyString,
|
|
137
|
-
providerPackagePath: nonEmptyString,
|
|
138
|
-
}))),
|
|
139
|
-
});
|
|
140
|
-
function formatIssuePath(issue) {
|
|
141
|
-
if (!issue.path || issue.path.length === 0) {
|
|
142
|
-
return "$";
|
|
143
|
-
}
|
|
144
|
-
return issue.path.reduce((path, item) => `${path}.${String(item.key)}`, "$");
|
|
145
|
-
}
|
|
146
|
-
function shapeIssues(issues) {
|
|
147
|
-
return issues.map((issue) => ({
|
|
148
|
-
path: formatIssuePath(issue),
|
|
149
|
-
message: issue.message,
|
|
150
|
-
}));
|
|
151
|
-
}
|
|
152
|
-
function duplicateIssues(values, path) {
|
|
153
|
-
const seen = new Set();
|
|
154
|
-
const duplicates = new Set();
|
|
155
|
-
for (const value of values) {
|
|
156
|
-
if (seen.has(value)) {
|
|
157
|
-
duplicates.add(value);
|
|
158
|
-
}
|
|
159
|
-
seen.add(value);
|
|
160
|
-
}
|
|
161
|
-
return [...duplicates].map((value) => ({
|
|
162
|
-
path,
|
|
163
|
-
message: `Duplicate value: ${value}`,
|
|
164
|
-
}));
|
|
165
|
-
}
|
|
166
|
-
function generationSupportIssue(preset, path) {
|
|
167
|
-
if (preset.generation === "supported") {
|
|
168
|
-
return undefined;
|
|
169
|
-
}
|
|
170
|
-
return {
|
|
171
|
-
path,
|
|
172
|
-
message: `Preset ${preset.name} is not supported for generation in this version`,
|
|
173
|
-
};
|
|
174
|
-
}
|
|
175
|
-
function unsupportedSinglePackageProjectShapeIssue(path) {
|
|
176
|
-
return {
|
|
177
|
-
path,
|
|
178
|
-
message: "single-package Project Shape is unsupported in V1; use the workspace monorepo Project Shape",
|
|
179
|
-
};
|
|
180
|
-
}
|
|
181
|
-
export function validatePresetFile(input, options = {}) {
|
|
182
|
-
const result = v.safeParse(presetFileSchema, input);
|
|
183
|
-
if (!result.success) {
|
|
184
|
-
return { ok: false, issues: shapeIssues(result.issues) };
|
|
185
|
-
}
|
|
186
|
-
const semanticIssues = [
|
|
187
|
-
...duplicateIssues(result.output.supportedPackageManagers, "$.supportedPackageManagers"),
|
|
188
|
-
...duplicateIssues(result.output.supportedProjectKinds, "$.supportedProjectKinds"),
|
|
189
|
-
...duplicateIssues(result.output.features, "$.features"),
|
|
190
|
-
];
|
|
191
|
-
if (result.output.supportedProjectKinds.includes("single-package")) {
|
|
192
|
-
semanticIssues.push(unsupportedSinglePackageProjectShapeIssue("$.supportedProjectKinds"));
|
|
193
|
-
}
|
|
194
|
-
const catalogPreset = findPreset(options.presets ?? [], result.output.name);
|
|
195
|
-
const unsupportedGeneration = catalogPreset
|
|
196
|
-
? generationSupportIssue(catalogPreset, "$.name")
|
|
197
|
-
: undefined;
|
|
198
|
-
if (unsupportedGeneration) {
|
|
199
|
-
semanticIssues.push(unsupportedGeneration);
|
|
200
|
-
}
|
|
201
|
-
if (semanticIssues.length > 0) {
|
|
202
|
-
return { ok: false, issues: semanticIssues };
|
|
203
|
-
}
|
|
204
|
-
return { ok: true, value: result.output };
|
|
205
|
-
}
|
|
206
|
-
export function findPreset(presets, name) {
|
|
207
|
-
return presets.find((preset) => preset.name === name);
|
|
208
|
-
}
|
|
209
|
-
function normalizeProjectBlueprint(blueprint) {
|
|
210
|
-
return {
|
|
211
|
-
schemaVersion: blueprint.schemaVersion,
|
|
212
|
-
preset: blueprint.preset,
|
|
213
|
-
...(blueprint.packageManager === undefined
|
|
214
|
-
? {}
|
|
215
|
-
: { packageManager: blueprint.packageManager }),
|
|
216
|
-
projectKind: blueprint.projectKind,
|
|
217
|
-
features: [...blueprint.features],
|
|
218
|
-
...(blueprint.packages === undefined
|
|
219
|
-
? {}
|
|
220
|
-
: {
|
|
221
|
-
packages: blueprint.packages.map((projectPackage) => ({
|
|
222
|
-
name: projectPackage.name,
|
|
223
|
-
path: projectPackage.path,
|
|
224
|
-
...(projectPackage.role === undefined
|
|
225
|
-
? {}
|
|
226
|
-
: { role: projectPackage.role }),
|
|
227
|
-
...(projectPackage.sourcePreset === undefined
|
|
228
|
-
? {}
|
|
229
|
-
: { sourcePreset: projectPackage.sourcePreset }),
|
|
230
|
-
})),
|
|
231
|
-
}),
|
|
232
|
-
...(blueprint.packageLinkIntents === undefined
|
|
233
|
-
? {}
|
|
234
|
-
: {
|
|
235
|
-
packageLinkIntents: blueprint.packageLinkIntents.map((intent) => ({
|
|
236
|
-
consumerPackagePath: intent.consumerPackagePath,
|
|
237
|
-
providerPackagePath: intent.providerPackagePath,
|
|
238
|
-
})),
|
|
239
|
-
}),
|
|
240
|
-
};
|
|
241
|
-
}
|
|
242
|
-
export function validateProjectBlueprint(input, options = {}) {
|
|
243
|
-
const result = v.safeParse(projectBlueprintSchema, input);
|
|
244
|
-
if (!result.success) {
|
|
245
|
-
return { ok: false, issues: shapeIssues(result.issues) };
|
|
246
|
-
}
|
|
247
|
-
const blueprint = normalizeProjectBlueprint(result.output);
|
|
248
|
-
const preset = findPreset(options.presets ?? [], blueprint.preset);
|
|
249
|
-
const semanticIssues = [
|
|
250
|
-
...duplicateIssues(blueprint.features, "$.features"),
|
|
251
|
-
];
|
|
252
|
-
if (blueprint.projectKind === "single-package") {
|
|
253
|
-
semanticIssues.push(unsupportedSinglePackageProjectShapeIssue("$.projectKind"));
|
|
254
|
-
}
|
|
255
|
-
if (options.presets && !preset) {
|
|
256
|
-
semanticIssues.push({
|
|
257
|
-
path: "$.preset",
|
|
258
|
-
message: `Unknown ${options.presetLabel ?? "built-in"} preset: ${blueprint.preset}`,
|
|
259
|
-
});
|
|
260
|
-
}
|
|
261
|
-
else if (preset) {
|
|
262
|
-
const unsupportedGeneration = generationSupportIssue(preset, "$.preset");
|
|
263
|
-
if (unsupportedGeneration) {
|
|
264
|
-
semanticIssues.push(unsupportedGeneration);
|
|
265
|
-
}
|
|
266
|
-
if (blueprint.packageManager &&
|
|
267
|
-
!preset.supportedPackageManagers.includes(blueprint.packageManager)) {
|
|
268
|
-
semanticIssues.push({
|
|
269
|
-
path: "$.packageManager",
|
|
270
|
-
message: `${blueprint.packageManager} is not supported by preset ${preset.name}`,
|
|
271
|
-
});
|
|
272
|
-
}
|
|
273
|
-
if (!blueprint.packageManager &&
|
|
274
|
-
preset.supportedPackageManagers.length > 0) {
|
|
275
|
-
semanticIssues.push({
|
|
276
|
-
path: "$.packageManager",
|
|
277
|
-
message: `packageManager is required by preset ${preset.name}`,
|
|
278
|
-
});
|
|
279
|
-
}
|
|
280
|
-
if (!preset.supportedProjectKinds.includes(blueprint.projectKind)) {
|
|
281
|
-
semanticIssues.push({
|
|
282
|
-
path: "$.projectKind",
|
|
283
|
-
message: `${blueprint.projectKind} is not supported by preset ${preset.name}`,
|
|
284
|
-
});
|
|
285
|
-
}
|
|
286
|
-
const supportedFeatures = new Set(preset.features);
|
|
287
|
-
for (const feature of blueprint.features) {
|
|
288
|
-
if (!supportedFeatures.has(feature)) {
|
|
289
|
-
semanticIssues.push({
|
|
290
|
-
path: "$.features",
|
|
291
|
-
message: `${feature} is not supported by preset ${preset.name}`,
|
|
292
|
-
});
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
if (blueprint.packages) {
|
|
297
|
-
semanticIssues.push(...duplicateIssues(blueprint.packages.map((projectPackage) => projectPackage.name), "$.packages.name"), ...duplicateIssues(blueprint.packages.map((projectPackage) => projectPackage.path), "$.packages.path"));
|
|
298
|
-
}
|
|
299
|
-
if (semanticIssues.length > 0) {
|
|
300
|
-
return { ok: false, issues: semanticIssues };
|
|
301
|
-
}
|
|
302
|
-
return { ok: true, value: blueprint };
|
|
303
|
-
}
|
|
1
|
+
export { blueprintJsonSchema, findPreset, presetFileJsonSchema, presetFileSchema, projectBlueprintSchema, validatePresetFile, validateProjectBlueprint, } from "@ykdz/template-shared";
|
|
@@ -13,6 +13,21 @@ export type DevelopmentContainerRustLayer = {
|
|
|
13
13
|
readonly toolchain: string;
|
|
14
14
|
};
|
|
15
15
|
type DevelopmentContainerCapabilityLayer = DevelopmentContainerBrowserTestLayer | DevelopmentContainerRustLayer;
|
|
16
|
+
export type DevelopmentContainerDockerfileFragments = {
|
|
17
|
+
readonly sourceRoot: string;
|
|
18
|
+
readonly nodePnpm: {
|
|
19
|
+
readonly from: string;
|
|
20
|
+
readonly text: string;
|
|
21
|
+
};
|
|
22
|
+
readonly browserTest?: {
|
|
23
|
+
readonly from: string;
|
|
24
|
+
readonly text: string;
|
|
25
|
+
} | undefined;
|
|
26
|
+
readonly rust?: {
|
|
27
|
+
readonly from: string;
|
|
28
|
+
readonly text: string;
|
|
29
|
+
} | undefined;
|
|
30
|
+
};
|
|
16
31
|
export type DevelopmentContainerPlan = {
|
|
17
32
|
readonly devcontainer: Record<string, unknown>;
|
|
18
33
|
readonly dockerfile: string;
|
|
@@ -43,6 +58,7 @@ export declare function dockerfileFirstNodePnpmDevcontainer(options: {
|
|
|
43
58
|
export declare function checkedDockerfileFirstNodePnpmDevcontainer(options: {
|
|
44
59
|
readonly name: string;
|
|
45
60
|
readonly layer: DevelopmentContainerNodePnpmLayer;
|
|
61
|
+
readonly dockerfileFragments: DevelopmentContainerDockerfileFragments;
|
|
46
62
|
readonly additionalLayers?: readonly DevelopmentContainerCapabilityLayer[] | undefined;
|
|
47
63
|
readonly extensions: readonly string[];
|
|
48
64
|
readonly settings?: Record<string, unknown> | undefined;
|
|
@@ -52,6 +68,7 @@ export declare function dockerfileFirstRustPnpmDevcontainer(options: {
|
|
|
52
68
|
readonly name: string;
|
|
53
69
|
readonly nodeLayer: DevelopmentContainerNodePnpmLayer;
|
|
54
70
|
readonly rustLayer: DevelopmentContainerRustLayer;
|
|
71
|
+
readonly dockerfileFragments: DevelopmentContainerDockerfileFragments;
|
|
55
72
|
readonly extensions: readonly string[];
|
|
56
73
|
readonly settings?: Record<string, unknown> | undefined;
|
|
57
74
|
}): DevelopmentContainerPlan;
|
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
import { readFileSync } from "node:fs";
|
|
2
|
-
import path from "node:path";
|
|
3
|
-
import { fileURLToPath } from "node:url";
|
|
4
1
|
import { loadTemplateDependencyCatalog } from "./dependency-catalog.js";
|
|
5
|
-
|
|
2
|
+
function requireDockerfileFragment(fragments, name) {
|
|
3
|
+
const fragment = fragments[name];
|
|
4
|
+
if (fragment === undefined) {
|
|
5
|
+
throw new Error(`Development Container Dockerfile fragment is missing: ${name}`);
|
|
6
|
+
}
|
|
7
|
+
return fragment;
|
|
8
|
+
}
|
|
6
9
|
const runtimeDockerfileInstructions = new Set([
|
|
7
10
|
"CMD",
|
|
8
11
|
"ENTRYPOINT",
|
|
@@ -61,19 +64,13 @@ export function browserTestToolLayer() {
|
|
|
61
64
|
export function rustToolLayer(options = {}) {
|
|
62
65
|
return { kind: "rust", toolchain: options.toolchain ?? "stable" };
|
|
63
66
|
}
|
|
64
|
-
function
|
|
65
|
-
return packageTemplateRoot(path.dirname(fileURLToPath(import.meta.url)), "shared", "devcontainer");
|
|
66
|
-
}
|
|
67
|
-
function checkedDockerfileFragment(name) {
|
|
68
|
-
return readFileSync(path.join(sharedDevcontainerSourceRoot(), name), "utf8");
|
|
69
|
-
}
|
|
70
|
-
function checkedNodePnpmDockerfile(options = {}) {
|
|
67
|
+
function checkedNodePnpmDockerfile(options) {
|
|
71
68
|
return composeDevelopmentContainerDockerfile({
|
|
72
69
|
layers: [
|
|
73
70
|
{
|
|
74
71
|
kind: "base",
|
|
75
72
|
name: "node-pnpm",
|
|
76
|
-
text:
|
|
73
|
+
text: options.dockerfileFragments.nodePnpm.text,
|
|
77
74
|
},
|
|
78
75
|
...(options.additionalLayers ?? []).map((layer) => {
|
|
79
76
|
switch (layer.kind) {
|
|
@@ -81,36 +78,37 @@ function checkedNodePnpmDockerfile(options = {}) {
|
|
|
81
78
|
return {
|
|
82
79
|
kind: "capability",
|
|
83
80
|
name: "browser-test",
|
|
84
|
-
text:
|
|
81
|
+
text: requireDockerfileFragment(options.dockerfileFragments, "browserTest").text,
|
|
85
82
|
};
|
|
86
83
|
case "rust":
|
|
87
84
|
return {
|
|
88
85
|
kind: "capability",
|
|
89
86
|
name: "rust",
|
|
90
|
-
text:
|
|
87
|
+
text: requireDockerfileFragment(options.dockerfileFragments, "rust").text,
|
|
91
88
|
};
|
|
92
89
|
}
|
|
93
90
|
}),
|
|
94
91
|
],
|
|
95
92
|
});
|
|
96
93
|
}
|
|
97
|
-
function checkedNodePnpmDockerfileFragments(options
|
|
94
|
+
function checkedNodePnpmDockerfileFragments(options) {
|
|
98
95
|
return [
|
|
99
96
|
{
|
|
100
|
-
sourceRoot:
|
|
101
|
-
from:
|
|
97
|
+
sourceRoot: options.dockerfileFragments.sourceRoot,
|
|
98
|
+
from: options.dockerfileFragments.nodePnpm.from,
|
|
102
99
|
},
|
|
103
100
|
...(options.additionalLayers ?? []).map((layer) => {
|
|
104
101
|
switch (layer.kind) {
|
|
105
102
|
case "browser-test":
|
|
106
103
|
return {
|
|
107
|
-
sourceRoot:
|
|
108
|
-
from: "
|
|
104
|
+
sourceRoot: options.dockerfileFragments.sourceRoot,
|
|
105
|
+
from: requireDockerfileFragment(options.dockerfileFragments, "browserTest").from,
|
|
109
106
|
};
|
|
110
107
|
case "rust":
|
|
111
108
|
return {
|
|
112
|
-
sourceRoot:
|
|
113
|
-
from: "rust
|
|
109
|
+
sourceRoot: options.dockerfileFragments.sourceRoot,
|
|
110
|
+
from: requireDockerfileFragment(options.dockerfileFragments, "rust")
|
|
111
|
+
.from,
|
|
114
112
|
};
|
|
115
113
|
}
|
|
116
114
|
}),
|
|
@@ -175,12 +173,14 @@ export function checkedDockerfileFirstNodePnpmDevcontainer(options) {
|
|
|
175
173
|
...(options.mounts ? { mounts: options.mounts } : {}),
|
|
176
174
|
},
|
|
177
175
|
dockerfile: checkedNodePnpmDockerfile({
|
|
176
|
+
dockerfileFragments: options.dockerfileFragments,
|
|
178
177
|
additionalLayers: options.additionalLayers,
|
|
179
178
|
}),
|
|
180
179
|
dockerfileOperation: {
|
|
181
180
|
kind: "writeTextFromFragments",
|
|
182
181
|
to: ".devcontainer/Dockerfile",
|
|
183
182
|
fragments: checkedNodePnpmDockerfileFragments({
|
|
183
|
+
dockerfileFragments: options.dockerfileFragments,
|
|
184
184
|
additionalLayers: options.additionalLayers,
|
|
185
185
|
}),
|
|
186
186
|
},
|
|
@@ -190,6 +190,7 @@ export function dockerfileFirstRustPnpmDevcontainer(options) {
|
|
|
190
190
|
return checkedDockerfileFirstNodePnpmDevcontainer({
|
|
191
191
|
name: options.name,
|
|
192
192
|
layer: options.nodeLayer,
|
|
193
|
+
dockerfileFragments: options.dockerfileFragments,
|
|
193
194
|
additionalLayers: [options.rustLayer],
|
|
194
195
|
extensions: options.extensions,
|
|
195
196
|
settings: options.settings,
|
|
@@ -9,4 +9,13 @@ export type EditorCustomizationOptions = {
|
|
|
9
9
|
readonly formatter?: string;
|
|
10
10
|
};
|
|
11
11
|
};
|
|
12
|
-
|
|
12
|
+
type CapabilityProjection = {
|
|
13
|
+
readonly extensions: readonly string[];
|
|
14
|
+
readonly settings: Record<string, unknown>;
|
|
15
|
+
};
|
|
16
|
+
export type EditorCustomizationDeclarations = {
|
|
17
|
+
readonly capabilities: Record<EditorCustomizationCapability, CapabilityProjection>;
|
|
18
|
+
};
|
|
19
|
+
export declare function loadEditorCustomizationDeclarations(resourcePath: string): EditorCustomizationDeclarations;
|
|
20
|
+
export declare function editorCustomizationForCapabilities(capabilities: readonly EditorCustomizationCapability[], declarations: EditorCustomizationDeclarations, options?: EditorCustomizationOptions): EditorCustomization;
|
|
21
|
+
export {};
|