@ykdz/template 0.0.8 → 0.0.9
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 +7 -7
- package/node_modules/@ykdz/template-builtin-source/dist/src/index.js +10 -6
- package/node_modules/@ykdz/template-builtin-source/dist/templates/hono-api/projection.js +15 -5
- package/node_modules/@ykdz/template-builtin-source/dist/templates/ts-lib/projection.js +15 -5
- package/node_modules/@ykdz/template-builtin-source/dist/templates/vue-app/projection.js +23 -4
- package/node_modules/@ykdz/template-builtin-source/dist/templates/vue-hono-app/projection.js +6 -6
- package/node_modules/@ykdz/template-builtin-source/package.json +15 -2
- package/node_modules/@ykdz/template-builtin-source/templates/preset-source.json +14 -2
- package/node_modules/@ykdz/template-builtin-source/templates/shared/oxc/node/oxlint.config.ts +25 -3
- package/node_modules/@ykdz/template-builtin-source/templates/shared/oxc/tsconfig.config.json +20 -0
- package/node_modules/@ykdz/template-builtin-source/templates/shared/oxc/vue/oxlint.config.ts +27 -3
- package/node_modules/@ykdz/template-builtin-source/templates/vue-app/env.d.ts +7 -0
- package/node_modules/@ykdz/template-builtin-source/templates/vue-hono-app/web/env.d.ts +7 -0
- package/node_modules/@ykdz/template-core/dist/declarations.js +34 -1
- package/node_modules/@ykdz/template-core/dist/dependency-catalog.js +11 -6
- package/node_modules/@ykdz/template-core/dist/devcontainer.d.ts +5 -5
- package/node_modules/@ykdz/template-core/dist/editor-customization.js +20 -29
- package/node_modules/@ykdz/template-core/dist/generated-scenarios.d.ts +4 -4
- package/node_modules/@ykdz/template-core/dist/generated-scenarios.js +29 -9
- package/node_modules/@ykdz/template-core/dist/generation-context.js +8 -3
- package/node_modules/@ykdz/template-core/dist/next-step-instructions.js +3 -0
- package/node_modules/@ykdz/template-core/dist/package-addition.d.ts +2 -2
- package/node_modules/@ykdz/template-core/dist/package-addition.js +22 -8
- package/node_modules/@ykdz/template-core/dist/pnpm-workspace.yaml +1 -0
- package/node_modules/@ykdz/template-core/dist/preset-projection.d.ts +3 -3
- package/node_modules/@ykdz/template-core/dist/preset-projection.js +1 -0
- package/node_modules/@ykdz/template-core/dist/preset-source.js +60 -45
- package/node_modules/@ykdz/template-core/dist/project-github.d.ts +3 -3
- package/node_modules/@ykdz/template-core/dist/project-github.js +1 -0
- package/node_modules/@ykdz/template-core/dist/projection-capabilities.d.ts +7 -3
- package/node_modules/@ykdz/template-core/dist/projection-capabilities.js +187 -120
- package/node_modules/@ykdz/template-core/dist/renderer.d.ts +2 -2
- package/node_modules/@ykdz/template-core/dist/renderer.js +2 -2
- package/node_modules/@ykdz/template-core/dist/template-boundary-check.d.ts +1 -1
- package/node_modules/@ykdz/template-core/dist/template-boundary-check.js +8 -10
- package/node_modules/@ykdz/template-core/dist/toolchain-resolution.d.ts +5 -5
- package/node_modules/@ykdz/template-core/dist/toolchain-resolution.js +9 -10
- package/node_modules/@ykdz/template-core/package.json +9 -2
- package/package.json +12 -5
|
@@ -15,6 +15,8 @@ const projectionCapabilityKinds = [
|
|
|
15
15
|
"github-maintenance",
|
|
16
16
|
];
|
|
17
17
|
const projectionCapabilityKindSet = new Set(projectionCapabilityKinds);
|
|
18
|
+
const workspaceNodePackageKindSet = new Set(["hono-api", "vue-app"]);
|
|
19
|
+
const workspaceNodePackagePathSet = new Set(["apps/api", "apps/web"]);
|
|
18
20
|
const strictTypescriptRootBoundary = {
|
|
19
21
|
kind: "workspace-orchestration",
|
|
20
22
|
path: ".",
|
|
@@ -71,6 +73,24 @@ const exactCapabilityKeys = {
|
|
|
71
73
|
"github-maintenance": ["kind"],
|
|
72
74
|
};
|
|
73
75
|
const dependencyMaintenanceEcosystems = ["npm", "github-actions", "docker"];
|
|
76
|
+
function strictTypeScriptCompilerOptions(options) {
|
|
77
|
+
return {
|
|
78
|
+
...options,
|
|
79
|
+
erasableSyntaxOnly: true,
|
|
80
|
+
exactOptionalPropertyTypes: true,
|
|
81
|
+
forceConsistentCasingInFileNames: true,
|
|
82
|
+
isolatedModules: true,
|
|
83
|
+
noEmitOnError: true,
|
|
84
|
+
noFallthroughCasesInSwitch: true,
|
|
85
|
+
noImplicitOverride: true,
|
|
86
|
+
noImplicitReturns: true,
|
|
87
|
+
noUncheckedIndexedAccess: true,
|
|
88
|
+
skipLibCheck: false,
|
|
89
|
+
strict: true,
|
|
90
|
+
target: "es2023",
|
|
91
|
+
verbatimModuleSyntax: true,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
74
94
|
const capabilityInterpreters = {
|
|
75
95
|
"workspace-library-package": {
|
|
76
96
|
kind: "workspace-library-package",
|
|
@@ -205,21 +225,23 @@ const capabilityInterpreters = {
|
|
|
205
225
|
state.rootScriptFragments["format:write"] =
|
|
206
226
|
"oxfmt --write --config oxfmt.config.ts oxlint.config.ts oxfmt.config.ts";
|
|
207
227
|
state.rootScriptFragments.lint =
|
|
208
|
-
"oxlint --config oxlint.config.ts oxlint.config.ts oxfmt.config.ts
|
|
228
|
+
"oxlint --config oxlint.config.ts oxlint.config.ts oxfmt.config.ts";
|
|
209
229
|
state.rootScriptFragments["lint:fix"] =
|
|
210
|
-
"oxlint --config oxlint.config.ts oxlint.config.ts oxfmt.config.ts --fix
|
|
230
|
+
"oxlint --config oxlint.config.ts oxlint.config.ts oxfmt.config.ts --fix";
|
|
211
231
|
state.packageScriptFragments["format:check"] =
|
|
212
232
|
"oxfmt --check --config ../../oxfmt.config.ts .";
|
|
213
233
|
state.packageScriptFragments["format:write"] =
|
|
214
234
|
"oxfmt --write --config ../../oxfmt.config.ts .";
|
|
215
235
|
state.packageScriptFragments.lint =
|
|
216
|
-
"oxlint --config ../../oxlint.config.ts .
|
|
236
|
+
"oxlint --config ../../oxlint.config.ts .";
|
|
217
237
|
state.packageScriptFragments["lint:fix"] =
|
|
218
|
-
"oxlint --config ../../oxlint.config.ts . --fix
|
|
238
|
+
"oxlint --config ../../oxlint.config.ts . --fix";
|
|
219
239
|
state.rootDevDependencies.add("oxfmt");
|
|
220
240
|
state.rootDevDependencies.add("oxlint");
|
|
241
|
+
state.rootDevDependencies.add("oxlint-tsgolint");
|
|
221
242
|
state.packageDevDependencies.add("oxfmt");
|
|
222
243
|
state.packageDevDependencies.add("oxlint");
|
|
244
|
+
state.packageDevDependencies.add("oxlint-tsgolint");
|
|
223
245
|
state.editorCustomizationCapabilities.push("oxc-format-lint");
|
|
224
246
|
state.flags.fixCommand = true;
|
|
225
247
|
state.operationFactories.push(oxcFormatLintOperations);
|
|
@@ -244,6 +266,52 @@ const capabilityInterpreters = {
|
|
|
244
266
|
},
|
|
245
267
|
},
|
|
246
268
|
};
|
|
269
|
+
function contributeProjectionCapability(capability, state) {
|
|
270
|
+
switch (capability.kind) {
|
|
271
|
+
case "workspace-library-package":
|
|
272
|
+
capabilityInterpreters["workspace-library-package"].contribute({
|
|
273
|
+
capability,
|
|
274
|
+
state,
|
|
275
|
+
});
|
|
276
|
+
return;
|
|
277
|
+
case "workspace-node-packages":
|
|
278
|
+
capabilityInterpreters["workspace-node-packages"].contribute({
|
|
279
|
+
capability,
|
|
280
|
+
state,
|
|
281
|
+
});
|
|
282
|
+
return;
|
|
283
|
+
case "rust-binary-workspace":
|
|
284
|
+
capabilityInterpreters["rust-binary-workspace"].contribute({
|
|
285
|
+
capability,
|
|
286
|
+
state,
|
|
287
|
+
});
|
|
288
|
+
return;
|
|
289
|
+
case "strict-typescript-root":
|
|
290
|
+
capabilityInterpreters["strict-typescript-root"].contribute({
|
|
291
|
+
capability,
|
|
292
|
+
state,
|
|
293
|
+
});
|
|
294
|
+
return;
|
|
295
|
+
case "oxc-format-lint":
|
|
296
|
+
capabilityInterpreters["oxc-format-lint"].contribute({
|
|
297
|
+
capability,
|
|
298
|
+
state,
|
|
299
|
+
});
|
|
300
|
+
return;
|
|
301
|
+
case "node-pnpm-devcontainer":
|
|
302
|
+
capabilityInterpreters["node-pnpm-devcontainer"].contribute({
|
|
303
|
+
capability,
|
|
304
|
+
state,
|
|
305
|
+
});
|
|
306
|
+
return;
|
|
307
|
+
case "github-maintenance":
|
|
308
|
+
capabilityInterpreters["github-maintenance"].contribute({
|
|
309
|
+
capability,
|
|
310
|
+
state,
|
|
311
|
+
});
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
247
315
|
export function validateProjectionCapabilities(input) {
|
|
248
316
|
if (!isRecord(input) || !Array.isArray(input.capabilities)) {
|
|
249
317
|
return {
|
|
@@ -274,7 +342,7 @@ export function validateProjectionCapabilities(input) {
|
|
|
274
342
|
});
|
|
275
343
|
return;
|
|
276
344
|
}
|
|
277
|
-
if (!
|
|
345
|
+
if (!isProjectionCapabilityKind(capability.kind)) {
|
|
278
346
|
issues.push({
|
|
279
347
|
path: `${pathPrefix}.kind`,
|
|
280
348
|
message: `Unknown Projection Capability kind: ${capability.kind}`,
|
|
@@ -282,7 +350,7 @@ export function validateProjectionCapabilities(input) {
|
|
|
282
350
|
return;
|
|
283
351
|
}
|
|
284
352
|
const kind = capability.kind;
|
|
285
|
-
issues.push(...unknownCapabilityPropertyIssues(capability, pathPrefix));
|
|
353
|
+
issues.push(...unknownCapabilityPropertyIssues(kind, capability, pathPrefix));
|
|
286
354
|
if (kind === "workspace-library-package") {
|
|
287
355
|
const workspaceCapability = parseWorkspaceLibraryPackageCapability(capability, pathPrefix);
|
|
288
356
|
if (Array.isArray(workspaceCapability)) {
|
|
@@ -358,10 +426,7 @@ export function interpretPresetProjectionDeclaration(options) {
|
|
|
358
426
|
}
|
|
359
427
|
const state = createProjectionCompositionState(options.sourceRoots);
|
|
360
428
|
for (const capability of validation.value.capabilities) {
|
|
361
|
-
|
|
362
|
-
capability: capability,
|
|
363
|
-
state,
|
|
364
|
-
});
|
|
429
|
+
contributeProjectionCapability(capability, state);
|
|
365
430
|
}
|
|
366
431
|
const checkPlan = {
|
|
367
432
|
components: state.rootCheckComponents,
|
|
@@ -405,10 +470,11 @@ export function interpretPresetProjectionDeclaration(options) {
|
|
|
405
470
|
export function blueprintForPresetSourcePreset(preset, options = { targetDir: process.cwd() }) {
|
|
406
471
|
const packageScope = options.scope ?? projectNameFromDir(options.targetDir);
|
|
407
472
|
const projectName = projectNameFromDir(options.targetDir);
|
|
473
|
+
const packageManager = preset.supportedPackageManagers[0];
|
|
408
474
|
const blueprint = {
|
|
409
475
|
schemaVersion: 1,
|
|
410
476
|
preset: preset.name,
|
|
411
|
-
packageManager:
|
|
477
|
+
...(packageManager === undefined ? {} : { packageManager }),
|
|
412
478
|
projectKind: preset.supportedProjectKinds[0] ?? "multi-package",
|
|
413
479
|
features: [...preset.features],
|
|
414
480
|
};
|
|
@@ -502,11 +568,29 @@ function createProjectionCompositionState(sourceRoots) {
|
|
|
502
568
|
function isRecord(value) {
|
|
503
569
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
504
570
|
}
|
|
571
|
+
function isProjectionCapabilityKind(value) {
|
|
572
|
+
return projectionCapabilityKindSet.has(value);
|
|
573
|
+
}
|
|
574
|
+
function isWorkspaceNodePackageKind(value) {
|
|
575
|
+
return typeof value === "string" && workspaceNodePackageKindSet.has(value);
|
|
576
|
+
}
|
|
577
|
+
function isWorkspaceNodePackagePath(value) {
|
|
578
|
+
return typeof value === "string" && workspaceNodePackagePathSet.has(value);
|
|
579
|
+
}
|
|
505
580
|
function isNonEmptyString(value) {
|
|
506
581
|
return typeof value === "string" && value.length > 0;
|
|
507
582
|
}
|
|
508
|
-
function
|
|
509
|
-
const
|
|
583
|
+
function nonEmptyStringArray(value) {
|
|
584
|
+
const strings = [];
|
|
585
|
+
for (const entry of value) {
|
|
586
|
+
if (!isNonEmptyString(entry)) {
|
|
587
|
+
return undefined;
|
|
588
|
+
}
|
|
589
|
+
strings.push(entry);
|
|
590
|
+
}
|
|
591
|
+
return strings.length === 0 ? undefined : strings;
|
|
592
|
+
}
|
|
593
|
+
function unknownCapabilityPropertyIssues(kind, capability, pathPrefix) {
|
|
510
594
|
const allowedKeys = new Set(exactCapabilityKeys[kind]);
|
|
511
595
|
return Object.keys(capability)
|
|
512
596
|
.filter((key) => !allowedKeys.has(key))
|
|
@@ -517,6 +601,7 @@ function unknownCapabilityPropertyIssues(capability, pathPrefix) {
|
|
|
517
601
|
}
|
|
518
602
|
function parseWorkspaceLibraryPackageCapability(capability, pathPrefix) {
|
|
519
603
|
const issues = [];
|
|
604
|
+
let sourceFiles = [];
|
|
520
605
|
if (capability.workspacePackageGlob !== "packages/*") {
|
|
521
606
|
issues.push({
|
|
522
607
|
path: `${pathPrefix}.workspacePackageGlob`,
|
|
@@ -541,12 +626,17 @@ function parseWorkspaceLibraryPackageCapability(capability, pathPrefix) {
|
|
|
541
626
|
message: "workspace-library-package sourceFiles must be a non-empty array",
|
|
542
627
|
});
|
|
543
628
|
}
|
|
544
|
-
else
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
629
|
+
else {
|
|
630
|
+
const parsedSourceFiles = nonEmptyStringArray(capability.sourceFiles);
|
|
631
|
+
if (parsedSourceFiles === undefined) {
|
|
632
|
+
issues.push({
|
|
633
|
+
path: `${pathPrefix}.sourceFiles`,
|
|
634
|
+
message: "workspace-library-package sourceFiles must be a non-empty array of paths",
|
|
635
|
+
});
|
|
636
|
+
}
|
|
637
|
+
else {
|
|
638
|
+
sourceFiles = parsedSourceFiles;
|
|
639
|
+
}
|
|
550
640
|
}
|
|
551
641
|
if (issues.length > 0) {
|
|
552
642
|
return issues;
|
|
@@ -556,7 +646,7 @@ function parseWorkspaceLibraryPackageCapability(capability, pathPrefix) {
|
|
|
556
646
|
workspacePackageGlob: "packages/*",
|
|
557
647
|
packageRole: "shared-library",
|
|
558
648
|
packageSourcePreset: "ts-lib",
|
|
559
|
-
sourceFiles
|
|
649
|
+
sourceFiles,
|
|
560
650
|
};
|
|
561
651
|
}
|
|
562
652
|
function parseWorkspaceNodePackagesCapability(capability, pathPrefix) {
|
|
@@ -607,13 +697,18 @@ function parseWorkspaceNodePackage(value, pathPrefix) {
|
|
|
607
697
|
},
|
|
608
698
|
];
|
|
609
699
|
}
|
|
610
|
-
|
|
700
|
+
const kind = isWorkspaceNodePackageKind(value.kind) ? value.kind : undefined;
|
|
701
|
+
const packagePath = isWorkspaceNodePackagePath(value.path)
|
|
702
|
+
? value.path
|
|
703
|
+
: undefined;
|
|
704
|
+
let sourceFiles = [];
|
|
705
|
+
if (kind === undefined) {
|
|
611
706
|
issues.push({
|
|
612
707
|
path: `${pathPrefix}.kind`,
|
|
613
708
|
message: "workspace-node-packages package kind must be hono-api or vue-app",
|
|
614
709
|
});
|
|
615
710
|
}
|
|
616
|
-
if (
|
|
711
|
+
if (packagePath === undefined) {
|
|
617
712
|
issues.push({
|
|
618
713
|
path: `${pathPrefix}.path`,
|
|
619
714
|
message: "workspace-node-packages package path must be apps/api or apps/web",
|
|
@@ -625,12 +720,17 @@ function parseWorkspaceNodePackage(value, pathPrefix) {
|
|
|
625
720
|
message: "workspace-node-packages package sourceFiles must be a non-empty array",
|
|
626
721
|
});
|
|
627
722
|
}
|
|
628
|
-
else
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
723
|
+
else {
|
|
724
|
+
const parsedSourceFiles = nonEmptyStringArray(value.sourceFiles);
|
|
725
|
+
if (parsedSourceFiles === undefined) {
|
|
726
|
+
issues.push({
|
|
727
|
+
path: `${pathPrefix}.sourceFiles`,
|
|
728
|
+
message: "workspace-node-packages package sourceFiles must be a non-empty array of paths",
|
|
729
|
+
});
|
|
730
|
+
}
|
|
731
|
+
else {
|
|
732
|
+
sourceFiles = parsedSourceFiles;
|
|
733
|
+
}
|
|
634
734
|
}
|
|
635
735
|
const allowedKeys = new Set(["kind", "path", "sourceFiles"]);
|
|
636
736
|
for (const key of Object.keys(value)) {
|
|
@@ -644,10 +744,13 @@ function parseWorkspaceNodePackage(value, pathPrefix) {
|
|
|
644
744
|
if (issues.length > 0) {
|
|
645
745
|
return issues;
|
|
646
746
|
}
|
|
747
|
+
if (kind === undefined || packagePath === undefined) {
|
|
748
|
+
throw new Error(`workspace-node-packages package validation failed without diagnostics at ${pathPrefix}`);
|
|
749
|
+
}
|
|
647
750
|
return {
|
|
648
|
-
kind
|
|
649
|
-
path:
|
|
650
|
-
sourceFiles
|
|
751
|
+
kind,
|
|
752
|
+
path: packagePath,
|
|
753
|
+
sourceFiles,
|
|
651
754
|
};
|
|
652
755
|
}
|
|
653
756
|
function parseWorkspaceNodePackageLinks(value, pathPrefix, declaredPackagePaths, issues) {
|
|
@@ -712,6 +815,7 @@ function parseWorkspaceNodePackageLinks(value, pathPrefix, declaredPackagePaths,
|
|
|
712
815
|
}
|
|
713
816
|
function parseRustBinaryWorkspaceCapability(capability, pathPrefix) {
|
|
714
817
|
const issues = [];
|
|
818
|
+
let sourceFiles = [];
|
|
715
819
|
if (capability.workspacePackageGlob !== "packages/*") {
|
|
716
820
|
issues.push({
|
|
717
821
|
path: `${pathPrefix}.workspacePackageGlob`,
|
|
@@ -724,12 +828,17 @@ function parseRustBinaryWorkspaceCapability(capability, pathPrefix) {
|
|
|
724
828
|
message: "rust-binary-workspace sourceFiles must be a non-empty array",
|
|
725
829
|
});
|
|
726
830
|
}
|
|
727
|
-
else
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
831
|
+
else {
|
|
832
|
+
const parsedSourceFiles = nonEmptyStringArray(capability.sourceFiles);
|
|
833
|
+
if (parsedSourceFiles === undefined) {
|
|
834
|
+
issues.push({
|
|
835
|
+
path: `${pathPrefix}.sourceFiles`,
|
|
836
|
+
message: "rust-binary-workspace sourceFiles must be a non-empty array of paths",
|
|
837
|
+
});
|
|
838
|
+
}
|
|
839
|
+
else {
|
|
840
|
+
sourceFiles = parsedSourceFiles;
|
|
841
|
+
}
|
|
733
842
|
}
|
|
734
843
|
if (issues.length > 0) {
|
|
735
844
|
return issues;
|
|
@@ -737,7 +846,7 @@ function parseRustBinaryWorkspaceCapability(capability, pathPrefix) {
|
|
|
737
846
|
return {
|
|
738
847
|
kind: "rust-binary-workspace",
|
|
739
848
|
workspacePackageGlob: "packages/*",
|
|
740
|
-
sourceFiles
|
|
849
|
+
sourceFiles,
|
|
741
850
|
};
|
|
742
851
|
}
|
|
743
852
|
function duplicateCapabilityIssues(capabilities) {
|
|
@@ -848,10 +957,7 @@ function stateForProjectionDeclaration(declaration, sourceRoots) {
|
|
|
848
957
|
}
|
|
849
958
|
const state = createProjectionCompositionState(sourceRoots);
|
|
850
959
|
for (const capability of validation.value.capabilities) {
|
|
851
|
-
|
|
852
|
-
capability: capability,
|
|
853
|
-
state,
|
|
854
|
-
});
|
|
960
|
+
contributeProjectionCapability(capability, state);
|
|
855
961
|
}
|
|
856
962
|
return state;
|
|
857
963
|
}
|
|
@@ -875,6 +981,9 @@ function packageAdditionCapabilityForState(presetName, state) {
|
|
|
875
981
|
throw new Error(`Preset ${presetName} is an initialization-only workspace and cannot be used for Package Addition`);
|
|
876
982
|
}
|
|
877
983
|
const nodePackage = state.nodeWorkspace.packages[0];
|
|
984
|
+
if (nodePackage === undefined) {
|
|
985
|
+
throw new Error(`Preset ${presetName} must declare one package for Package Addition`);
|
|
986
|
+
}
|
|
878
987
|
return {
|
|
879
988
|
sourcePreset: nodePackage.kind,
|
|
880
989
|
workspacePackageGlob: state.nodeWorkspace.workspacePackageGlob,
|
|
@@ -983,19 +1092,15 @@ function libraryPackageAdditionOperations(options) {
|
|
|
983
1092
|
}
|
|
984
1093
|
function libraryTsconfigJson() {
|
|
985
1094
|
return {
|
|
986
|
-
compilerOptions: {
|
|
1095
|
+
compilerOptions: strictTypeScriptCompilerOptions({
|
|
987
1096
|
composite: true,
|
|
988
1097
|
declaration: true,
|
|
989
1098
|
declarationMap: true,
|
|
990
|
-
module: "
|
|
991
|
-
moduleResolution: "
|
|
992
|
-
noEmitOnError: true,
|
|
1099
|
+
module: "nodenext",
|
|
1100
|
+
moduleResolution: "nodenext",
|
|
993
1101
|
rootDir: "src",
|
|
994
|
-
skipLibCheck: false,
|
|
995
|
-
strict: true,
|
|
996
|
-
target: "ES2022",
|
|
997
1102
|
types: ["node"],
|
|
998
|
-
},
|
|
1103
|
+
}),
|
|
999
1104
|
include: ["src/**/*.ts"],
|
|
1000
1105
|
};
|
|
1001
1106
|
}
|
|
@@ -1147,7 +1252,11 @@ function hasVuePackage(capability) {
|
|
|
1147
1252
|
}
|
|
1148
1253
|
function sourceRootPreset(capability) {
|
|
1149
1254
|
if (capability.packages.length === 1) {
|
|
1150
|
-
|
|
1255
|
+
const nodePackage = capability.packages[0];
|
|
1256
|
+
if (nodePackage === undefined) {
|
|
1257
|
+
throw new Error("Node package workspace must contain one package");
|
|
1258
|
+
}
|
|
1259
|
+
return nodePackage.kind;
|
|
1151
1260
|
}
|
|
1152
1261
|
return "vue-hono-app";
|
|
1153
1262
|
}
|
|
@@ -1297,6 +1406,7 @@ function honoApiPackageJson(context, packageName, scripts, exposureFields) {
|
|
|
1297
1406
|
"@types/node": "catalog:",
|
|
1298
1407
|
oxfmt: "catalog:",
|
|
1299
1408
|
oxlint: "catalog:",
|
|
1409
|
+
"oxlint-tsgolint": "catalog:",
|
|
1300
1410
|
"tsc-alias": "catalog:",
|
|
1301
1411
|
...(scripts.dev === undefined ? {} : { tsx: "catalog:" }),
|
|
1302
1412
|
typescript: "catalog:",
|
|
@@ -1338,6 +1448,7 @@ function vuePackageJson(context, packageName, scripts, packageLinkDependencies =
|
|
|
1338
1448
|
"@vue/tsconfig": "catalog:",
|
|
1339
1449
|
oxfmt: "catalog:",
|
|
1340
1450
|
oxlint: "catalog:",
|
|
1451
|
+
"oxlint-tsgolint": "catalog:",
|
|
1341
1452
|
tailwindcss: "catalog:",
|
|
1342
1453
|
typescript: "catalog:",
|
|
1343
1454
|
vite: "catalog:",
|
|
@@ -1350,7 +1461,7 @@ function vuePackageJson(context, packageName, scripts, packageLinkDependencies =
|
|
|
1350
1461
|
};
|
|
1351
1462
|
}
|
|
1352
1463
|
function catalogDependencies(dependencies) {
|
|
1353
|
-
return Object.fromEntries([...dependencies].
|
|
1464
|
+
return Object.fromEntries([...dependencies].toSorted().map((dependency) => [dependency, "catalog:"]));
|
|
1354
1465
|
}
|
|
1355
1466
|
function generationRecord(context) {
|
|
1356
1467
|
return {
|
|
@@ -1762,8 +1873,8 @@ function nodePackageScripts(nodePackage, workspace) {
|
|
|
1762
1873
|
const oxcScripts = {
|
|
1763
1874
|
"format:check": "oxfmt --check --config ../../oxfmt.config.ts .",
|
|
1764
1875
|
"format:write": "oxfmt --write --config ../../oxfmt.config.ts .",
|
|
1765
|
-
lint: "oxlint --config ../../oxlint.config.ts .
|
|
1766
|
-
"lint:fix": "oxlint --config ../../oxlint.config.ts . --fix
|
|
1876
|
+
lint: "oxlint --config ../../oxlint.config.ts .",
|
|
1877
|
+
"lint:fix": "oxlint --config ../../oxlint.config.ts . --fix",
|
|
1767
1878
|
};
|
|
1768
1879
|
if (nodePackage.kind === "hono-api") {
|
|
1769
1880
|
const checks = {
|
|
@@ -1833,19 +1944,15 @@ function nodePackageTsconfigOperations(nodePackage, workspace) {
|
|
|
1833
1944
|
kind: "writeJson",
|
|
1834
1945
|
to: `${nodePackage.path}/tsconfig.json`,
|
|
1835
1946
|
value: {
|
|
1836
|
-
compilerOptions: {
|
|
1947
|
+
compilerOptions: strictTypeScriptCompilerOptions({
|
|
1837
1948
|
composite: true,
|
|
1838
1949
|
...(workspace.packages.length > 1
|
|
1839
1950
|
? { declaration: true, declarationMap: true }
|
|
1840
1951
|
: {}),
|
|
1841
|
-
module: "
|
|
1842
|
-
moduleResolution: "
|
|
1843
|
-
noEmitOnError: true,
|
|
1844
|
-
skipLibCheck: false,
|
|
1845
|
-
strict: true,
|
|
1846
|
-
target: "ES2022",
|
|
1952
|
+
module: "nodenext",
|
|
1953
|
+
moduleResolution: "nodenext",
|
|
1847
1954
|
types: ["node", "vitest/globals"],
|
|
1848
|
-
},
|
|
1955
|
+
}),
|
|
1849
1956
|
include: ["src/**/*.ts", "test/**/*.ts", "vitest.config.ts"],
|
|
1850
1957
|
},
|
|
1851
1958
|
},
|
|
@@ -1882,17 +1989,13 @@ function nodePackageTsconfigOperations(nodePackage, workspace) {
|
|
|
1882
1989
|
to: `${nodePackage.path}/tsconfig.app.json`,
|
|
1883
1990
|
value: {
|
|
1884
1991
|
extends: "@vue/tsconfig/tsconfig.dom.json",
|
|
1885
|
-
compilerOptions: {
|
|
1992
|
+
compilerOptions: strictTypeScriptCompilerOptions({
|
|
1886
1993
|
composite: true,
|
|
1887
1994
|
module: "ESNext",
|
|
1888
1995
|
moduleResolution: "Bundler",
|
|
1889
|
-
noEmitOnError: true,
|
|
1890
|
-
skipLibCheck: false,
|
|
1891
|
-
strict: true,
|
|
1892
|
-
target: "ES2022",
|
|
1893
1996
|
tsBuildInfoFile: "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
|
|
1894
1997
|
types: ["web-bluetooth"],
|
|
1895
|
-
},
|
|
1998
|
+
}),
|
|
1896
1999
|
include: ["env.d.ts", "src/**/*.ts", "src/**/*.vue"],
|
|
1897
2000
|
},
|
|
1898
2001
|
},
|
|
@@ -1913,21 +2016,17 @@ function nodePackageTsconfigOperations(nodePackage, workspace) {
|
|
|
1913
2016
|
kind: "writeJson",
|
|
1914
2017
|
to: `${nodePackage.path}/tsconfig.node.json`,
|
|
1915
2018
|
value: {
|
|
1916
|
-
compilerOptions: {
|
|
2019
|
+
compilerOptions: strictTypeScriptCompilerOptions({
|
|
1917
2020
|
composite: true,
|
|
1918
2021
|
module: "ESNext",
|
|
1919
2022
|
moduleResolution: "Bundler",
|
|
1920
|
-
noEmitOnError: true,
|
|
1921
2023
|
lib: ["ESNext", "DOM", "DOM.Iterable"],
|
|
1922
2024
|
...(workspace.packages.length > 1
|
|
1923
2025
|
? { outDir: "./node_modules/.tmp/tsconfig.node" }
|
|
1924
2026
|
: {}),
|
|
1925
|
-
skipLibCheck: false,
|
|
1926
|
-
strict: true,
|
|
1927
|
-
target: "ES2022",
|
|
1928
2027
|
tsBuildInfoFile: "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
|
|
1929
2028
|
types: ["node"],
|
|
1930
|
-
},
|
|
2029
|
+
}),
|
|
1931
2030
|
include: ["playwright.config.ts", "vite.config.ts", "vitest.config.ts"],
|
|
1932
2031
|
},
|
|
1933
2032
|
},
|
|
@@ -2014,6 +2113,17 @@ function strictTypescriptOperations({ context, state, }) {
|
|
|
2014
2113
|
if (state.package === undefined && state.nodeWorkspace === undefined) {
|
|
2015
2114
|
throw new Error("strict-typescript-root requires a workspace package layout");
|
|
2016
2115
|
}
|
|
2116
|
+
const rootConfigTsconfigOperation = () => {
|
|
2117
|
+
if (state.sourceRoots.sharedOxc === undefined) {
|
|
2118
|
+
throw new Error("strict-typescript-root requires shared OXC source when rendering tsconfig.config.json");
|
|
2119
|
+
}
|
|
2120
|
+
return {
|
|
2121
|
+
kind: "copyFile",
|
|
2122
|
+
from: "tsconfig.config.json",
|
|
2123
|
+
to: "tsconfig.config.json",
|
|
2124
|
+
sourceRoot: "sharedOxc",
|
|
2125
|
+
};
|
|
2126
|
+
};
|
|
2017
2127
|
if (state.nodeWorkspace !== undefined) {
|
|
2018
2128
|
return [
|
|
2019
2129
|
{
|
|
@@ -2024,21 +2134,7 @@ function strictTypescriptOperations({ context, state, }) {
|
|
|
2024
2134
|
references: rootTsconfigReferences(state.nodeWorkspace),
|
|
2025
2135
|
},
|
|
2026
2136
|
},
|
|
2027
|
-
|
|
2028
|
-
kind: "writeJson",
|
|
2029
|
-
to: "tsconfig.config.json",
|
|
2030
|
-
value: {
|
|
2031
|
-
compilerOptions: {
|
|
2032
|
-
module: "NodeNext",
|
|
2033
|
-
moduleResolution: "NodeNext",
|
|
2034
|
-
noEmitOnError: true,
|
|
2035
|
-
skipLibCheck: false,
|
|
2036
|
-
strict: true,
|
|
2037
|
-
target: "ES2022",
|
|
2038
|
-
},
|
|
2039
|
-
include: ["oxlint.config.ts", "oxfmt.config.ts"],
|
|
2040
|
-
},
|
|
2041
|
-
},
|
|
2137
|
+
rootConfigTsconfigOperation(),
|
|
2042
2138
|
];
|
|
2043
2139
|
}
|
|
2044
2140
|
const libraryPackage = state.package;
|
|
@@ -2050,40 +2146,11 @@ function strictTypescriptOperations({ context, state, }) {
|
|
|
2050
2146
|
files: [],
|
|
2051
2147
|
},
|
|
2052
2148
|
},
|
|
2053
|
-
|
|
2054
|
-
kind: "writeJson",
|
|
2055
|
-
to: "tsconfig.config.json",
|
|
2056
|
-
value: {
|
|
2057
|
-
compilerOptions: {
|
|
2058
|
-
module: "NodeNext",
|
|
2059
|
-
moduleResolution: "NodeNext",
|
|
2060
|
-
noEmitOnError: true,
|
|
2061
|
-
skipLibCheck: false,
|
|
2062
|
-
strict: true,
|
|
2063
|
-
target: "ES2022",
|
|
2064
|
-
},
|
|
2065
|
-
include: ["oxlint.config.ts", "oxfmt.config.ts"],
|
|
2066
|
-
},
|
|
2067
|
-
},
|
|
2149
|
+
rootConfigTsconfigOperation(),
|
|
2068
2150
|
{
|
|
2069
2151
|
kind: "writeJson",
|
|
2070
2152
|
to: `${workspacePackagePath(context, libraryPackage)}/tsconfig.json`,
|
|
2071
|
-
value:
|
|
2072
|
-
compilerOptions: {
|
|
2073
|
-
composite: true,
|
|
2074
|
-
declaration: true,
|
|
2075
|
-
declarationMap: true,
|
|
2076
|
-
module: "NodeNext",
|
|
2077
|
-
moduleResolution: "NodeNext",
|
|
2078
|
-
noEmitOnError: true,
|
|
2079
|
-
rootDir: "src",
|
|
2080
|
-
skipLibCheck: false,
|
|
2081
|
-
strict: true,
|
|
2082
|
-
target: "ES2022",
|
|
2083
|
-
types: ["node"],
|
|
2084
|
-
},
|
|
2085
|
-
include: ["src/**/*.ts"],
|
|
2086
|
-
},
|
|
2153
|
+
value: libraryTsconfigJson(),
|
|
2087
2154
|
},
|
|
2088
2155
|
];
|
|
2089
2156
|
}
|
|
@@ -50,9 +50,9 @@ export type ReplaceAnchorsOperation = {
|
|
|
50
50
|
export type RenderOperation = CopyFileOperation | WriteJsonOperation | MergeJsonOperation | WriteTextOperation | WriteTextFromFragmentsOperation | WriteTextTemplateOperation | SetExecutableOperation | ReplaceAnchorsOperation;
|
|
51
51
|
export type RenderProjectOptions = {
|
|
52
52
|
sourceRoot: string;
|
|
53
|
-
sourceRoots?: Record<string, string
|
|
53
|
+
sourceRoots?: Record<string, string> | undefined;
|
|
54
54
|
targetRoot: string;
|
|
55
|
-
variables?: RenderVariables;
|
|
55
|
+
variables?: RenderVariables | undefined;
|
|
56
56
|
operations: RenderOperation[];
|
|
57
57
|
};
|
|
58
58
|
export declare function renderProject(options: RenderProjectOptions): Promise<void>;
|
|
@@ -65,7 +65,7 @@ function serializeJsonValue(value, indentation, pathSegments, multilineArrays, r
|
|
|
65
65
|
if (!isRecord(value)) {
|
|
66
66
|
return JSON.stringify(value);
|
|
67
67
|
}
|
|
68
|
-
const entries = Object.entries(value).
|
|
68
|
+
const entries = Object.entries(value).toSorted(([left], [right]) => compareJsonKeys(left, right, pathSegments, rootKeyOrder));
|
|
69
69
|
if (entries.length === 0) {
|
|
70
70
|
return "{}";
|
|
71
71
|
}
|
|
@@ -325,7 +325,7 @@ async function findTypeScriptAnchorRanges(sourceText) {
|
|
|
325
325
|
}
|
|
326
326
|
function replaceRanges(sourceText, ranges, replacements) {
|
|
327
327
|
let nextText = sourceText;
|
|
328
|
-
for (const range of
|
|
328
|
+
for (const range of ranges.toSorted((a, b) => b.start - a.start)) {
|
|
329
329
|
const replacement = replacements[range.name];
|
|
330
330
|
if (replacement === undefined) {
|
|
331
331
|
continue;
|
|
@@ -18,7 +18,7 @@ export type TemplateBoundaryCheckProjection = {
|
|
|
18
18
|
readonly sourceFilePath: string;
|
|
19
19
|
readonly plan: {
|
|
20
20
|
readonly sourceRoot: string;
|
|
21
|
-
readonly sourceRoots?: Record<string, string
|
|
21
|
+
readonly sourceRoots?: Record<string, string> | undefined;
|
|
22
22
|
readonly operations: readonly RenderOperation[];
|
|
23
23
|
};
|
|
24
24
|
};
|
|
@@ -233,14 +233,12 @@ function jsonValuesEqual(left, right) {
|
|
|
233
233
|
return false;
|
|
234
234
|
}
|
|
235
235
|
const leftEntries = Object.entries(left);
|
|
236
|
-
const
|
|
237
|
-
const
|
|
238
|
-
return (leftEntries.length ===
|
|
236
|
+
const rightEntries = Object.entries(right);
|
|
237
|
+
const rightValues = new Map(rightEntries);
|
|
238
|
+
return (leftEntries.length === rightEntries.length &&
|
|
239
239
|
leftEntries.every(([key, value]) => {
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
}) &&
|
|
243
|
-
rightKeys.size === 0);
|
|
240
|
+
return (rightValues.has(key) && jsonValuesEqual(value, rightValues.get(key)));
|
|
241
|
+
}));
|
|
244
242
|
}
|
|
245
243
|
function expressionMatchesJsonValue(expression, expectedValue) {
|
|
246
244
|
const literalValue = expressionLiteralJsonValue(expression);
|
|
@@ -383,12 +381,12 @@ function isStructuralTurboValue(value) {
|
|
|
383
381
|
});
|
|
384
382
|
}
|
|
385
383
|
const rootTsconfigConfigCompilerOptions = {
|
|
386
|
-
module: "
|
|
387
|
-
moduleResolution: "
|
|
384
|
+
module: "nodenext",
|
|
385
|
+
moduleResolution: "nodenext",
|
|
388
386
|
noEmitOnError: true,
|
|
389
387
|
skipLibCheck: false,
|
|
390
388
|
strict: true,
|
|
391
|
-
target: "
|
|
389
|
+
target: "es2023",
|
|
392
390
|
};
|
|
393
391
|
const rootTsconfigConfigIncludes = new Set([
|
|
394
392
|
"oxlint.config.ts",
|
|
@@ -14,15 +14,15 @@ export type ResolvedToolchainVersions = {
|
|
|
14
14
|
readonly diagnostics: string[];
|
|
15
15
|
};
|
|
16
16
|
export type ResolveToolchainVersionsOptions = {
|
|
17
|
-
readonly source?: ToolchainResolutionSource | "auto";
|
|
18
|
-
readonly fetchJson?: (url: string) => Promise<unknown
|
|
19
|
-
readonly nodeReleaseIndexUrl?: string;
|
|
20
|
-
readonly pnpmRegistryUrl?: string;
|
|
17
|
+
readonly source?: ToolchainResolutionSource | "auto" | undefined;
|
|
18
|
+
readonly fetchJson?: ((url: string) => Promise<unknown>) | undefined;
|
|
19
|
+
readonly nodeReleaseIndexUrl?: string | undefined;
|
|
20
|
+
readonly pnpmRegistryUrl?: string | undefined;
|
|
21
21
|
};
|
|
22
22
|
export declare const nodeReleaseIndexUrl = "https://nodejs.org/dist/index.json";
|
|
23
23
|
export declare const pnpmRegistryUrl = "https://registry.npmjs.org/pnpm";
|
|
24
24
|
type OnlineToolchainResolutionContractOptions = {
|
|
25
|
-
readonly fetchJson?: (url: string) => Promise<unknown
|
|
25
|
+
readonly fetchJson?: ((url: string) => Promise<unknown>) | undefined;
|
|
26
26
|
};
|
|
27
27
|
export type OnlineToolchainResolutionContractResult = {
|
|
28
28
|
readonly nodeLtsMajor: NodeLtsMajor;
|