@ykdz/template 0.0.13 → 0.0.15

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.
Files changed (32) hide show
  1. package/node_modules/@ykdz/template-builtin-source/dist/templates/hono-api/projection.js +7 -34
  2. package/node_modules/@ykdz/template-builtin-source/dist/templates/projection-plans.js +9 -8
  3. package/node_modules/@ykdz/template-builtin-source/dist/templates/rust-bin/projection.js +6 -4
  4. package/node_modules/@ykdz/template-builtin-source/dist/templates/ts-lib/projection.js +5 -32
  5. package/node_modules/@ykdz/template-builtin-source/dist/templates/vike-app/projection.js +4 -1
  6. package/node_modules/@ykdz/template-builtin-source/dist/templates/vue-app/projection.js +8 -36
  7. package/node_modules/@ykdz/template-builtin-source/dist/templates/vue-hono-app/projection.js +27 -74
  8. package/node_modules/@ykdz/template-builtin-source/templates/hono-api/.github/workflows/check.yml +1 -1
  9. package/node_modules/@ykdz/template-builtin-source/templates/hono-api/turbo.json +8 -0
  10. package/node_modules/@ykdz/template-builtin-source/templates/preset-source.json +22 -11
  11. package/node_modules/@ykdz/template-builtin-source/templates/rust-bin/.github/workflows/check.yml +1 -1
  12. package/node_modules/@ykdz/template-builtin-source/templates/rust-bin/turbo.json +3 -0
  13. package/node_modules/@ykdz/template-builtin-source/templates/ts-lib/.github/workflows/check.yml +1 -1
  14. package/node_modules/@ykdz/template-builtin-source/templates/ts-lib/turbo.json +3 -0
  15. package/node_modules/@ykdz/template-builtin-source/templates/vike-app/.github/workflows/check.yml +2 -2
  16. package/node_modules/@ykdz/template-builtin-source/templates/vue-app/.github/workflows/check.yml +1 -1
  17. package/node_modules/@ykdz/template-builtin-source/templates/vue-app/turbo.json +11 -0
  18. package/node_modules/@ykdz/template-builtin-source/templates/vue-hono-app/.github/workflows/check.yml +1 -1
  19. package/node_modules/@ykdz/template-builtin-source/templates/vue-hono-app/api/turbo.json +8 -0
  20. package/node_modules/@ykdz/template-builtin-source/templates/vue-hono-app/web/playwright.config.ts +1 -1
  21. package/node_modules/@ykdz/template-builtin-source/templates/vue-hono-app/web/turbo.json +11 -0
  22. package/node_modules/@ykdz/template-core/dist/module-graph.d.ts +4 -0
  23. package/node_modules/@ykdz/template-core/dist/module-graph.js +64 -4
  24. package/node_modules/@ykdz/template-core/dist/package-addition.js +23 -35
  25. package/node_modules/@ykdz/template-core/dist/package-linking.js +14 -8
  26. package/node_modules/@ykdz/template-core/dist/project-github.js +1 -1
  27. package/node_modules/@ykdz/template-core/dist/projection-capabilities.js +160 -167
  28. package/node_modules/@ykdz/template-shared/dist/index.d.ts +4 -4
  29. package/node_modules/@ykdz/template-shared/dist/index.js +21 -12
  30. package/package.json +3 -3
  31. /package/node_modules/@ykdz/template-builtin-source/templates/vike-app/{env.d.ts → types/env.d.ts} +0 -0
  32. /package/node_modules/@ykdz/template-builtin-source/templates/vike-app/{global.d.ts → types/global.d.ts} +0 -0
@@ -5,8 +5,8 @@ import { normalizePresetProjectionDeclaration, projectionCapabilityIssues, valid
5
5
  import { collectGeneratedManifestCatalogDependencies, collectGeneratedManifestCatalogReferences, renderGeneratedPnpmWorkspaceYaml, } from "./dependency-catalog.js";
6
6
  import { browserTestToolLayer, checkedDockerfileFirstNodePnpmDevcontainer, dockerfileFirstRustPnpmDevcontainer, nodePnpmToolLayer, rustToolLayer, } from "./devcontainer.js";
7
7
  import { editorCustomizationForCapabilities, loadEditorCustomizationDeclarations, } from "./editor-customization.js";
8
- import { playwrightBrowserAssetsEnvironmentNeed, renderFixCommand, renderRootCheckCommand, } from "./module-graph.js";
9
- import { packageManifestExposureFields, planPackageLinks, } from "./package-linking.js";
8
+ import { playwrightBrowserAssetsEnvironmentNeed, renderCheckLeafCommand, renderFixCommand, renderFixLeafCommand, renderRootCheckCommand, } from "./module-graph.js";
9
+ import { packageManifestExposureFields, packageTurboTasks, planPackageLinks, } from "./package-linking.js";
10
10
  export { normalizePresetProjectionDeclaration, projectionCapabilityIssues, validateProjectionCapabilities, };
11
11
  const strictTypescriptRootBoundary = {
12
12
  kind: "workspace-orchestration",
@@ -78,11 +78,7 @@ const capabilityInterpreters = {
78
78
  state.nodeWorkspace = capability;
79
79
  state.sourceRoot = templateSourceRootForPreset(state, sourceRootPreset(capability));
80
80
  state.operationFactories.push(workspaceNodePackagesOperations);
81
- if (isRootNodeWorkspace(capability)) {
82
- state.rootScriptFragments.dev = "vike dev";
83
- state.rootCheckComponents.push({ kind: "build", owner: strictTypescriptRootBoundary }, { kind: "unit-test", owner: strictTypescriptRootBoundary }, { kind: "e2e-test", owner: strictTypescriptRootBoundary });
84
- }
85
- else if (capability.packages.length > 1) {
81
+ if (capability.packages.length > 1) {
86
82
  state.rootScriptFragments.dev = "turbo run dev --parallel";
87
83
  }
88
84
  const vuePackage = findVuePackage(capability);
@@ -133,13 +129,11 @@ const capabilityInterpreters = {
133
129
  kind: "typescript-typecheck",
134
130
  owner: strictTypescriptRootBoundary,
135
131
  });
136
- if (!isRootNodeWorkspace(state.nodeWorkspace)) {
137
- const workspaceBoundary = workspaceBoundaryForState(state);
138
- state.rootCheckComponents.push({
139
- kind: "turbo-package-check",
140
- owner: workspaceBoundary,
141
- });
142
- }
132
+ const workspaceBoundary = workspaceBoundaryForState(state);
133
+ state.rootCheckComponents.push({
134
+ kind: "turbo-package-check",
135
+ owner: workspaceBoundary,
136
+ });
143
137
  state.packageCheckComponents.push({
144
138
  kind: "typescript-typecheck",
145
139
  owner: workspacePackageBoundary,
@@ -173,14 +167,10 @@ const capabilityInterpreters = {
173
167
  }, {
174
168
  kind: "oxc-lint-fix",
175
169
  owner: strictTypescriptRootBoundary,
176
- }, ...(!isRootNodeWorkspace(state.nodeWorkspace)
177
- ? [
178
- {
179
- kind: "turbo-package-fix",
180
- owner: workspaceBoundaryForState(state),
181
- },
182
- ]
183
- : []));
170
+ }, {
171
+ kind: "turbo-package-fix",
172
+ owner: workspaceBoundaryForState(state),
173
+ });
184
174
  state.packageFixComponents.push({ kind: "oxc-format-write", owner: workspacePackageBoundary }, { kind: "oxc-lint-fix", owner: workspacePackageBoundary });
185
175
  state.rootScriptFragments["format:check"] =
186
176
  "oxfmt --check oxlint.config.ts oxfmt.config.ts";
@@ -468,11 +458,9 @@ function blueprintPackagesForCapabilities(capabilities, packageScope, projectNam
468
458
  }
469
459
  if (capability.kind === "workspace-node-packages") {
470
460
  return capability.packages.map((nodePackage) => {
471
- const leaf = nodePackage.path === "."
472
- ? projectName
473
- : (nodePackage.path.split("/").at(-1) ?? nodePackage.path);
461
+ const leaf = nodePackage.path.split("/").at(-1) ?? nodePackage.path;
474
462
  return {
475
- name: nodePackage.path === "." ? projectName : `@${packageScope}/${leaf}`,
463
+ name: `@${packageScope}/${leaf}`,
476
464
  path: nodePackage.path,
477
465
  };
478
466
  });
@@ -790,11 +778,6 @@ function workspaceGlobBoundary(workspacePackageGlob) {
790
778
  path: workspacePackageGlob,
791
779
  };
792
780
  }
793
- function isRootNodeWorkspace(workspace) {
794
- return (workspace?.workspacePackageGlob === "." &&
795
- workspace.packages.length === 1 &&
796
- workspace.packages[0]?.path === ".");
797
- }
798
781
  function hasVuePackage(capability) {
799
782
  return findVuePackage(capability) !== undefined;
800
783
  }
@@ -812,23 +795,102 @@ function sourceRootPreset(capability) {
812
795
  return "vue-hono-app";
813
796
  }
814
797
  function projectRootPackageScripts(checkPlan, fixPlan, fragments) {
798
+ const leafFragments = leafScriptFragments(fragments);
799
+ const directFragments = directScriptFragments(fragments);
815
800
  return {
816
801
  check: renderRootCheckCommand(checkPlan),
817
802
  fix: renderFixCommand(fixPlan),
818
- ...fragments,
803
+ ...rootTaskEntrypoints(checkPlan, fixPlan),
804
+ ...directFragments,
805
+ ...leafFragments,
806
+ "check:run": noopTaskCommand(),
807
+ "fix:run": noopTaskCommand(),
819
808
  };
820
809
  }
821
810
  function projectPackageScripts(checkPlan, fixPlan, fragments) {
811
+ void checkPlan;
812
+ void fixPlan;
822
813
  return {
823
- check: renderRootCheckCommand(checkPlan),
824
- fix: renderFixCommand(fixPlan),
825
- ...fragments,
814
+ ...directScriptFragments(fragments),
815
+ ...leafScriptFragments(fragments),
826
816
  };
827
817
  }
828
- function packageCollection(workspacePackageGlob) {
829
- if (workspacePackageGlob === ".") {
830
- return ".";
818
+ const leafEntrypointNames = new Set([
819
+ "format:check",
820
+ "format:write",
821
+ "lint",
822
+ "lint:fix",
823
+ "typecheck",
824
+ "build",
825
+ "test",
826
+ "test:e2e",
827
+ ]);
828
+ function leafScriptName(scriptName) {
829
+ return leafEntrypointNames.has(scriptName) ? `${scriptName}:run` : scriptName;
830
+ }
831
+ function leafScriptFragments(fragments) {
832
+ return Object.fromEntries(Object.entries(fragments)
833
+ .filter(([scriptName]) => leafEntrypointNames.has(scriptName))
834
+ .map(([scriptName, command]) => [leafScriptName(scriptName), command]));
835
+ }
836
+ function directScriptFragments(fragments) {
837
+ return Object.fromEntries(Object.entries(fragments).filter(([scriptName]) => !leafEntrypointNames.has(scriptName)));
838
+ }
839
+ function rootTaskEntrypoints(checkPlan, fixPlan) {
840
+ const taskNames = new Set([
841
+ ...checkPlan.components.map((component) => renderCheckLeafCommand(component).startsWith("turbo run ")
842
+ ? undefined
843
+ : leafEntrypointFromRunTask(component.kind)),
844
+ ...fixPlan.components.map((component) => renderFixLeafCommand(component).startsWith("turbo run ")
845
+ ? undefined
846
+ : leafEntrypointFromRunTask(component.kind)),
847
+ ]);
848
+ const entries = [];
849
+ for (const taskName of taskNames) {
850
+ if (taskName === undefined) {
851
+ continue;
852
+ }
853
+ entries.push([taskName, `turbo run ${taskName}:run`]);
854
+ }
855
+ return Object.fromEntries(entries);
856
+ }
857
+ function leafEntrypointFromRunTask(kind) {
858
+ switch (kind) {
859
+ case "oxc-format-check":
860
+ case "rustfmt-check":
861
+ return "format:check";
862
+ case "oxc-format-write":
863
+ case "rustfmt-write":
864
+ return "format:write";
865
+ case "oxc-lint":
866
+ case "cargo-clippy":
867
+ return "lint";
868
+ case "oxc-lint-fix":
869
+ return "lint:fix";
870
+ case "typescript-typecheck":
871
+ return "typecheck";
872
+ case "build":
873
+ return "build";
874
+ case "unit-test":
875
+ case "cargo-test":
876
+ return "test";
877
+ case "e2e-test":
878
+ return "test:e2e";
879
+ case "turbo-check":
880
+ case "turbo-package-typecheck":
881
+ case "turbo-package-build":
882
+ case "turbo-package-test":
883
+ case "turbo-package-e2e-test":
884
+ case "turbo-package-check":
885
+ case "turbo-fix":
886
+ case "turbo-package-fix":
887
+ return undefined;
831
888
  }
889
+ }
890
+ function noopTaskCommand() {
891
+ return 'node -e ""';
892
+ }
893
+ function packageCollection(workspacePackageGlob) {
832
894
  return workspacePackageGlob.slice(0, -"/*".length);
833
895
  }
834
896
  function workspacePackagePath(context, capability) {
@@ -882,9 +944,6 @@ function nodePackageName(context, nodePackage) {
882
944
  if (packageDefinition !== undefined) {
883
945
  return packageDefinition.name;
884
946
  }
885
- if (nodePackage.path === ".") {
886
- return context.projectName.value;
887
- }
888
947
  const leaf = nodePackage.path.split("/").at(-1) ?? nodePackage.path;
889
948
  return `@${context.projectName.value}/${leaf}`;
890
949
  }
@@ -1049,6 +1108,7 @@ function vikePackageJson(context, packageName, scripts) {
1049
1108
  oxlint: "catalog:",
1050
1109
  "oxlint-tsgolint": "catalog:",
1051
1110
  tailwindcss: "catalog:",
1111
+ turbo: "catalog:",
1052
1112
  typescript: "catalog:",
1053
1113
  vite: "catalog:",
1054
1114
  vitest: "catalog:",
@@ -1131,17 +1191,25 @@ function rustRootPackageJson(context, packageScripts, state) {
1131
1191
  packageManager: context.toolchain.packageManagerPin.value,
1132
1192
  };
1133
1193
  }
1134
- function rustWorkspacePackageJson(context, scripts) {
1194
+ function rustWorkspacePackageJson(context) {
1135
1195
  return {
1136
1196
  name: rustWorkspacePackageName(context),
1137
1197
  version: "0.0.0",
1138
1198
  private: true,
1139
- scripts,
1199
+ scripts: rustWorkspacePackageScripts(),
1140
1200
  engines: {
1141
1201
  node: context.toolchain.nodeLtsMajor.value,
1142
1202
  },
1143
1203
  };
1144
1204
  }
1205
+ function rustWorkspacePackageScripts() {
1206
+ return {
1207
+ "format:check:run": "cargo fmt --all -- --check",
1208
+ "format:write:run": "cargo fmt --all",
1209
+ "lint:run": "cargo clippy --workspace --all-targets -- -D warnings",
1210
+ "test:run": "cargo test --workspace",
1211
+ };
1212
+ }
1145
1213
  function workspaceLibraryPackageOperations({ context, state, packageScripts, packageScriptsByPath, }) {
1146
1214
  if (state.package === undefined) {
1147
1215
  throw new Error("workspace-library-package capability state is missing");
@@ -1177,14 +1245,7 @@ function workspaceLibraryPackageOperations({ context, state, packageScripts, pac
1177
1245
  to: "turbo.json",
1178
1246
  value: {
1179
1247
  tasks: {
1180
- build: packageLinkPlan.turboTasks.build,
1181
- check: packageLinkPlan.turboTasks.check,
1182
- typecheck: packageLinkPlan.turboTasks.typecheck,
1183
- test: packageLinkPlan.turboTasks.test,
1184
- "test:e2e": packageLinkPlan.turboTasks["test:e2e"],
1185
- fix: {
1186
- cache: false,
1187
- },
1248
+ ...packageLinkPlan.turboTasks,
1188
1249
  },
1189
1250
  },
1190
1251
  },
@@ -1223,18 +1284,14 @@ function workspaceLibraryPackageOperations({ context, state, packageScripts, pac
1223
1284
  },
1224
1285
  ];
1225
1286
  }
1226
- function rustBinaryWorkspaceOperations({ context, state, packageScripts, packageScriptsByPath, }) {
1287
+ function rustBinaryWorkspaceOperations({ context, state, packageScripts, }) {
1227
1288
  if (state.rustWorkspace === undefined) {
1228
1289
  throw new Error("rust-binary-workspace capability state is missing");
1229
1290
  }
1230
1291
  const capability = state.rustWorkspace;
1231
1292
  const packagePath = rustWorkspacePackagePath(context);
1232
- const workspacePackageScripts = packageScriptsByPath.get(capability.workspacePackageGlob);
1233
- if (workspacePackageScripts === undefined) {
1234
- throw new Error(`Missing package scripts for ${capability.workspacePackageGlob}`);
1235
- }
1236
1293
  const rootManifest = rustRootPackageJson(context, packageScripts, state);
1237
- const packageManifest = rustWorkspacePackageJson(context, workspacePackageScripts);
1294
+ const packageManifest = rustWorkspacePackageJson(context);
1238
1295
  const rustLayer = rustToolLayer();
1239
1296
  const dockerfileFragments = readDevelopmentContainerDockerfileFragments(state, ["rust"]);
1240
1297
  const editorCustomization = editorCustomizationForCapabilities(state.editorCustomizationCapabilities, editorCustomizationDeclarationsForState(state));
@@ -1270,12 +1327,7 @@ function rustBinaryWorkspaceOperations({ context, state, packageScripts, package
1270
1327
  kind: "writeJson",
1271
1328
  to: "turbo.json",
1272
1329
  value: {
1273
- tasks: {
1274
- check: {},
1275
- fix: {
1276
- cache: false,
1277
- },
1278
- },
1330
+ tasks: packageTurboTasks({ dependencyBuildsRequired: false }),
1279
1331
  },
1280
1332
  },
1281
1333
  {
@@ -1338,6 +1390,7 @@ function rustBinaryWorkspaceOperations({ context, state, packageScripts, package
1338
1390
  kind: "writeJson",
1339
1391
  to: ".devcontainer/devcontainer.json",
1340
1392
  value: developmentContainer.devcontainer,
1393
+ multilineArrays: ["customizations.vscode.extensions"],
1341
1394
  },
1342
1395
  {
1343
1396
  ...developmentContainer.dockerfileOperation,
@@ -1389,9 +1442,7 @@ function workspaceNodePackagesOperations({ context, state, packageScripts, }) {
1389
1442
  }
1390
1443
  return vuePackageJson(context, packageName, scripts, packageLinkPlan.manifestDependenciesByPackagePath.get(nodePackage.path));
1391
1444
  });
1392
- const rootManifest = isRootNodeWorkspace(capability)
1393
- ? packageManifests[0]
1394
- : rootPackageJson(context, packageScripts, state);
1445
+ const rootManifest = rootPackageJson(context, packageScripts, state);
1395
1446
  if (rootManifest === undefined) {
1396
1447
  throw new Error("workspace-node-packages rendered no package manifests");
1397
1448
  }
@@ -1429,11 +1480,7 @@ function workspaceNodePackagesOperations({ context, state, packageScripts, }) {
1429
1480
  to: "turbo.json",
1430
1481
  value: {
1431
1482
  tasks: {
1432
- build: packageLinkPlan.turboTasks.build,
1433
- check: packageLinkPlan.turboTasks.check,
1434
- typecheck: packageLinkPlan.turboTasks.typecheck,
1435
- test: packageLinkPlan.turboTasks.test,
1436
- "test:e2e": packageLinkPlan.turboTasks["test:e2e"],
1483
+ ...packageLinkPlan.turboTasks,
1437
1484
  ...(hasVuePackage(capability)
1438
1485
  ? {
1439
1486
  dev: {
@@ -1442,9 +1489,6 @@ function workspaceNodePackagesOperations({ context, state, packageScripts, }) {
1442
1489
  },
1443
1490
  }
1444
1491
  : {}),
1445
- fix: {
1446
- cache: false,
1447
- },
1448
1492
  },
1449
1493
  },
1450
1494
  },
@@ -1454,15 +1498,11 @@ function workspaceNodePackagesOperations({ context, state, packageScripts, }) {
1454
1498
  text: gitignoreForNodeWorkspace(capability),
1455
1499
  },
1456
1500
  ...capability.packages.flatMap((nodePackage, index) => [
1457
- ...(nodePackage.path === "."
1458
- ? []
1459
- : [
1460
- {
1461
- kind: "writeJson",
1462
- to: `${nodePackage.path}/package.json`,
1463
- value: packageManifests[index],
1464
- },
1465
- ]),
1501
+ {
1502
+ kind: "writeJson",
1503
+ to: `${nodePackage.path}/package.json`,
1504
+ value: packageManifests[index],
1505
+ },
1466
1506
  ...nodePackageTsconfigOperations(nodePackage, capability),
1467
1507
  ...nodePackage.sourceFiles.map((sourceFile) => ({
1468
1508
  kind: "copyFile",
@@ -1491,99 +1531,43 @@ function nodePackageScripts(nodePackage, workspace) {
1491
1531
  "lint:fix": "oxlint --config ../../oxlint.config.ts . --fix",
1492
1532
  };
1493
1533
  if (nodePackage.kind === "hono-api") {
1494
- const checks = {
1495
- components: [
1496
- { kind: "oxc-format-check", owner: workspacePackageBoundary },
1497
- { kind: "oxc-lint", owner: workspacePackageBoundary },
1498
- { kind: "typescript-typecheck", owner: workspacePackageBoundary },
1499
- { kind: "build", owner: workspacePackageBoundary },
1500
- { kind: "unit-test", owner: workspacePackageBoundary },
1501
- ],
1502
- environmentNeeds: [],
1503
- };
1504
- const fixes = {
1505
- components: [
1506
- { kind: "oxc-format-write", owner: workspacePackageBoundary },
1507
- { kind: "oxc-lint-fix", owner: workspacePackageBoundary },
1508
- ],
1509
- };
1510
1534
  return {
1511
- build: "tsc -p tsconfig.build.json && tsc-alias -p tsconfig.build.json",
1512
- check: renderRootCheckCommand(checks),
1535
+ "build:run": "tsc -p tsconfig.build.json && tsc-alias -p tsconfig.build.json",
1513
1536
  ...(workspace.packages.length > 1
1514
1537
  ? { dev: "tsx watch src/server.ts" }
1515
1538
  : {}),
1516
- fix: renderFixCommand(fixes),
1517
- ...oxcScripts,
1539
+ ...leafScriptFragments(oxcScripts),
1518
1540
  start: "node dist/server.js",
1519
- test: "vitest run",
1520
- typecheck: "tsc -p tsconfig.json --noEmit",
1541
+ "test:run": "vitest run",
1542
+ "typecheck:run": "tsc -p tsconfig.json --noEmit",
1521
1543
  };
1522
1544
  }
1523
1545
  if (nodePackage.kind === "vike-app") {
1524
- const checks = {
1525
- components: [
1526
- { kind: "oxc-format-check", owner: workspacePackageBoundary },
1527
- { kind: "oxc-lint", owner: workspacePackageBoundary },
1528
- { kind: "typescript-typecheck", owner: workspacePackageBoundary },
1529
- { kind: "build", owner: workspacePackageBoundary },
1530
- { kind: "unit-test", owner: workspacePackageBoundary },
1531
- { kind: "e2e-test", owner: workspacePackageBoundary },
1532
- ],
1533
- environmentNeeds: [],
1534
- };
1535
- const fixes = {
1536
- components: [
1537
- { kind: "oxc-format-write", owner: workspacePackageBoundary },
1538
- { kind: "oxc-lint-fix", owner: workspacePackageBoundary },
1539
- ],
1540
- };
1541
1546
  return {
1542
- build: "vike build",
1543
- check: renderRootCheckCommand(checks),
1547
+ "build:run": "vike build",
1544
1548
  dev: "vike dev",
1545
1549
  "drizzle:generate": "drizzle-kit generate",
1546
1550
  "drizzle:migrate": "drizzle-kit migrate",
1547
1551
  "drizzle:studio": "drizzle-kit studio",
1548
- fix: renderFixCommand(fixes),
1549
- "format:check": "oxfmt --check --config oxfmt.config.ts .",
1550
- "format:write": "oxfmt --write --config oxfmt.config.ts .",
1551
- lint: "oxlint --type-aware --config oxlint.config.ts .",
1552
- "lint:fix": "oxlint --type-aware --config oxlint.config.ts . --fix",
1552
+ "format:check:run": "oxfmt --check --config ../../oxfmt.config.ts .",
1553
+ "format:write:run": "oxfmt --write --config ../../oxfmt.config.ts .",
1554
+ "lint:run": "oxlint --type-aware --config ../../oxlint.config.ts .",
1555
+ "lint:fix:run": "oxlint --type-aware --config ../../oxlint.config.ts . --fix",
1553
1556
  preview: "vike preview",
1554
1557
  start: "node ./dist/server/index.mjs",
1555
- test: "vitest run",
1556
- "test:e2e": "playwright test --config playwright.config.ts",
1557
- typecheck: "vue-tsc --build --noEmit",
1558
+ "test:run": "vitest run",
1559
+ "test:e2e:run": "playwright test --config playwright.config.ts",
1560
+ "typecheck:run": "vue-tsc --build --noEmit",
1558
1561
  };
1559
1562
  }
1560
- const checks = {
1561
- components: [
1562
- { kind: "oxc-format-check", owner: workspacePackageBoundary },
1563
- { kind: "oxc-lint", owner: workspacePackageBoundary },
1564
- { kind: "typescript-typecheck", owner: workspacePackageBoundary },
1565
- { kind: "build", owner: workspacePackageBoundary },
1566
- { kind: "unit-test", owner: workspacePackageBoundary },
1567
- { kind: "e2e-test", owner: workspacePackageBoundary },
1568
- ],
1569
- environmentNeeds: [],
1570
- };
1571
- const fixes = {
1572
- components: [
1573
- { kind: "oxc-format-write", owner: workspacePackageBoundary },
1574
- { kind: "oxc-lint-fix", owner: workspacePackageBoundary },
1575
- ],
1576
- };
1577
1563
  return {
1578
- build: "vite build",
1579
- check: renderRootCheckCommand(checks),
1564
+ "build:run": "vite build",
1580
1565
  dev: "vite",
1581
- fix: renderFixCommand(fixes),
1582
- ...oxcScripts,
1566
+ ...leafScriptFragments(oxcScripts),
1583
1567
  preview: "vite preview",
1584
- test: "vitest run",
1585
- "test:e2e": "pnpm run build && node --experimental-strip-types scripts/run-playwright.ts",
1586
- typecheck: workspace.packages.length > 1
1568
+ "test:run": "vitest run",
1569
+ "test:e2e:run": "node --experimental-strip-types scripts/run-playwright.ts",
1570
+ "typecheck:run": workspace.packages.length > 1
1587
1571
  ? "vue-tsc --build"
1588
1572
  : "vue-tsc --build --noEmit",
1589
1573
  };
@@ -1593,7 +1577,19 @@ function nodePackageTsconfigOperations(nodePackage, workspace) {
1593
1577
  return [
1594
1578
  {
1595
1579
  kind: "writeJson",
1596
- to: "tsconfig.app.json",
1580
+ to: `${nodePackage.path}/tsconfig.json`,
1581
+ value: {
1582
+ files: [],
1583
+ references: [
1584
+ { path: "./tsconfig.app.json" },
1585
+ { path: "./tsconfig.test.json" },
1586
+ { path: "./tsconfig.node.json" },
1587
+ ],
1588
+ },
1589
+ },
1590
+ {
1591
+ kind: "writeJson",
1592
+ to: `${nodePackage.path}/tsconfig.app.json`,
1597
1593
  value: {
1598
1594
  extends: "@vue/tsconfig/tsconfig.dom.json",
1599
1595
  compilerOptions: {
@@ -1612,17 +1608,16 @@ function nodePackageTsconfigOperations(nodePackage, workspace) {
1612
1608
  "assets/**/*.svg",
1613
1609
  "components/**/*.vue",
1614
1610
  "database/**/*.ts",
1615
- "env.d.ts",
1616
- "global.d.ts",
1617
1611
  "pages/**/*.ts",
1618
1612
  "pages/**/*.vue",
1619
1613
  "server/**/*.ts",
1614
+ "types/**/*.d.ts",
1620
1615
  ],
1621
1616
  },
1622
1617
  },
1623
1618
  {
1624
1619
  kind: "writeJson",
1625
- to: "tsconfig.test.json",
1620
+ to: `${nodePackage.path}/tsconfig.test.json`,
1626
1621
  value: {
1627
1622
  extends: "./tsconfig.app.json",
1628
1623
  compilerOptions: {
@@ -1637,7 +1632,7 @@ function nodePackageTsconfigOperations(nodePackage, workspace) {
1637
1632
  },
1638
1633
  {
1639
1634
  kind: "writeJson",
1640
- to: "tsconfig.node.json",
1635
+ to: `${nodePackage.path}/tsconfig.node.json`,
1641
1636
  multilineArrays: ["include"],
1642
1637
  value: {
1643
1638
  compilerOptions: {
@@ -1813,9 +1808,6 @@ function sourcePathWithinNodePackage(sourceFile, workspace) {
1813
1808
  }
1814
1809
  function nodePackageTargetPath(nodePackage, sourceFile, workspace) {
1815
1810
  const packageRelativePath = sourcePathWithinNodePackage(sourceFile, workspace);
1816
- if (nodePackage.path === ".") {
1817
- return packageRelativePath;
1818
- }
1819
1811
  return `${nodePackage.path}/${packageRelativePath}`;
1820
1812
  }
1821
1813
  function gitignoreForNodeWorkspace(workspace) {
@@ -1900,9 +1892,9 @@ function rootTsconfigReferences(workspace) {
1900
1892
  }
1901
1893
  if (nodePackage.kind === "vike-app") {
1902
1894
  return [
1903
- { path: "./tsconfig.app.json" },
1904
- { path: "./tsconfig.test.json" },
1905
- { path: "./tsconfig.node.json" },
1895
+ { path: `./${nodePackage.path}/tsconfig.app.json` },
1896
+ { path: `./${nodePackage.path}/tsconfig.test.json` },
1897
+ { path: `./${nodePackage.path}/tsconfig.node.json` },
1906
1898
  ];
1907
1899
  }
1908
1900
  return [
@@ -1966,6 +1958,7 @@ function nodePnpmDevcontainerOperations({ context, state, }) {
1966
1958
  kind: "writeJson",
1967
1959
  to: ".devcontainer/devcontainer.json",
1968
1960
  value: developmentContainer.devcontainer,
1961
+ multilineArrays: ["customizations.vscode.extensions"],
1969
1962
  },
1970
1963
  {
1971
1964
  ...developmentContainer.dockerfileOperation,
@@ -78,7 +78,7 @@ export type WorkspaceLibraryPackageCapabilityDeclaration = {
78
78
  readonly sourceFiles: readonly string[];
79
79
  };
80
80
  export type WorkspaceNodePackageKind = "hono-api" | "vike-app" | "vue-app";
81
- export type WorkspaceNodePackagePath = "." | "apps/api" | "apps/web";
81
+ export type WorkspaceNodePackagePath = "apps/api" | "apps/web";
82
82
  export type WorkspaceNodePackageDeclaration = {
83
83
  readonly kind: WorkspaceNodePackageKind;
84
84
  readonly path: WorkspaceNodePackagePath;
@@ -86,7 +86,7 @@ export type WorkspaceNodePackageDeclaration = {
86
86
  };
87
87
  export type WorkspaceNodePackagesCapabilityDeclaration = {
88
88
  readonly kind: "workspace-node-packages";
89
- readonly workspacePackageGlob: "." | "apps/*";
89
+ readonly workspacePackageGlob: "apps/*";
90
90
  readonly packages: readonly WorkspaceNodePackageDeclaration[];
91
91
  readonly packageLinks?: readonly {
92
92
  readonly consumerPackagePath: "apps/web";
@@ -404,7 +404,7 @@ export declare const presetSourceManifestJsonSchema: {
404
404
  readonly const: "workspace-node-packages";
405
405
  };
406
406
  readonly workspacePackageGlob: {
407
- readonly enum: readonly [".", "apps/*"];
407
+ readonly const: "apps/*";
408
408
  };
409
409
  readonly packages: {
410
410
  readonly type: "array";
@@ -418,7 +418,7 @@ export declare const presetSourceManifestJsonSchema: {
418
418
  readonly enum: readonly ["hono-api", "vike-app", "vue-app"];
419
419
  };
420
420
  readonly path: {
421
- readonly enum: readonly [".", "apps/api", "apps/web"];
421
+ readonly enum: readonly ["apps/api", "apps/web"];
422
422
  };
423
423
  readonly sourceFiles: {
424
424
  readonly type: "array";
@@ -235,7 +235,7 @@ export const presetSourceManifestJsonSchema = {
235
235
  required: ["kind", "workspacePackageGlob", "packages"],
236
236
  properties: {
237
237
  kind: { const: "workspace-node-packages" },
238
- workspacePackageGlob: { enum: [".", "apps/*"] },
238
+ workspacePackageGlob: { const: "apps/*" },
239
239
  packages: {
240
240
  type: "array",
241
241
  minItems: 1,
@@ -247,7 +247,7 @@ export const presetSourceManifestJsonSchema = {
247
247
  kind: {
248
248
  enum: ["hono-api", "vike-app", "vue-app"],
249
249
  },
250
- path: { enum: [".", "apps/api", "apps/web"] },
250
+ path: { enum: ["apps/api", "apps/web"] },
251
251
  sourceFiles: {
252
252
  type: "array",
253
253
  minItems: 1,
@@ -849,11 +849,7 @@ const workspaceNodePackageKindSet = new Set([
849
849
  "vike-app",
850
850
  "vue-app",
851
851
  ]);
852
- const workspaceNodePackagePathSet = new Set([
853
- ".",
854
- "apps/api",
855
- "apps/web",
856
- ]);
852
+ const workspaceNodePackagePathSet = new Set(["apps/api", "apps/web"]);
857
853
  function isProjectionCapabilityKind(value) {
858
854
  return projectionCapabilityKindSet.has(value);
859
855
  }
@@ -979,7 +975,7 @@ function parseWorkspaceNodePackage(value, pathPrefix) {
979
975
  if (packagePath === undefined) {
980
976
  issues.push({
981
977
  path: `${pathPrefix}.path`,
982
- message: "workspace-node-packages package path must be ., apps/api, or apps/web",
978
+ message: "workspace-node-packages package path must be apps/api or apps/web",
983
979
  });
984
980
  }
985
981
  if (!Array.isArray(value.sourceFiles)) {
@@ -1083,14 +1079,13 @@ function parseWorkspaceNodePackageLinks(value, pathPrefix, declaredPackagePaths,
1083
1079
  }
1084
1080
  function parseWorkspaceNodePackagesCapability(capability, pathPrefix) {
1085
1081
  const issues = [];
1086
- const workspacePackageGlob = capability.workspacePackageGlob === "." ||
1087
- capability.workspacePackageGlob === "apps/*"
1082
+ const workspacePackageGlob = capability.workspacePackageGlob === "apps/*"
1088
1083
  ? capability.workspacePackageGlob
1089
1084
  : undefined;
1090
1085
  if (workspacePackageGlob === undefined) {
1091
1086
  issues.push({
1092
1087
  path: `${pathPrefix}.workspacePackageGlob`,
1093
- message: "workspace-node-packages currently supports workspacePackageGlob: . or apps/*",
1088
+ message: "workspace-node-packages currently supports workspacePackageGlob: apps/*",
1094
1089
  });
1095
1090
  }
1096
1091
  if (!Array.isArray(capability.packages) || capability.packages.length === 0) {
@@ -1591,6 +1586,17 @@ function normalizeProjectBlueprint(blueprint) {
1591
1586
  }),
1592
1587
  };
1593
1588
  }
1589
+ function packagePathIssue(packagePath, path) {
1590
+ const segments = packagePath.split("/");
1591
+ if (segments.length !== 2 ||
1592
+ segments.some((segment) => segment.length === 0 || segment === ".")) {
1593
+ return {
1594
+ path,
1595
+ message: "Package Path must be exactly two non-root path segments, such as apps/web or packages/ui",
1596
+ };
1597
+ }
1598
+ return undefined;
1599
+ }
1594
1600
  export function validateProjectBlueprint(input, options = {}) {
1595
1601
  const result = v.safeParse(projectBlueprintSchema, input);
1596
1602
  if (!result.success) {
@@ -1646,7 +1652,10 @@ export function validateProjectBlueprint(input, options = {}) {
1646
1652
  }
1647
1653
  }
1648
1654
  if (blueprint.packages) {
1649
- semanticIssues.push(...duplicateIssues(blueprint.packages.map((projectPackage) => projectPackage.name), "$.packages.name"), ...duplicateIssues(blueprint.packages.map((projectPackage) => projectPackage.path), "$.packages.path"));
1655
+ semanticIssues.push(...duplicateIssues(blueprint.packages.map((projectPackage) => projectPackage.name), "$.packages.name"), ...duplicateIssues(blueprint.packages.map((projectPackage) => projectPackage.path), "$.packages.path"), ...blueprint.packages.flatMap((projectPackage, index) => {
1656
+ const issue = packagePathIssue(projectPackage.path, `$.packages[${index}].path`);
1657
+ return issue === undefined ? [] : [issue];
1658
+ }));
1650
1659
  }
1651
1660
  if (semanticIssues.length > 0) {
1652
1661
  return { ok: false, issues: semanticIssues };