@ykdz/template 0.0.7 → 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.
Files changed (123) hide show
  1. package/dist/{src/cli.js → cli.js} +33 -21
  2. package/node_modules/@ykdz/template-builtin-source/dist/src/index.d.ts +22 -0
  3. package/node_modules/@ykdz/template-builtin-source/dist/src/index.js +96 -0
  4. package/node_modules/@ykdz/template-builtin-source/dist/templates/hono-api/projection.d.ts +6 -0
  5. package/node_modules/@ykdz/template-builtin-source/dist/templates/hono-api/projection.js +240 -0
  6. package/node_modules/@ykdz/template-builtin-source/dist/templates/projection-plans.d.ts +7 -0
  7. package/node_modules/@ykdz/template-builtin-source/dist/templates/projection-plans.js +94 -0
  8. package/node_modules/@ykdz/template-builtin-source/dist/templates/registry.d.ts +2 -0
  9. package/node_modules/@ykdz/template-builtin-source/dist/templates/registry.js +15 -0
  10. package/node_modules/@ykdz/template-builtin-source/dist/templates/rust-bin/projection.d.ts +9 -0
  11. package/node_modules/@ykdz/template-builtin-source/dist/templates/rust-bin/projection.js +103 -0
  12. package/node_modules/@ykdz/template-builtin-source/dist/templates/ts-lib/projection.d.ts +6 -0
  13. package/node_modules/@ykdz/template-builtin-source/dist/templates/ts-lib/projection.js +224 -0
  14. package/node_modules/@ykdz/template-builtin-source/dist/templates/vue-app/projection.d.ts +6 -0
  15. package/node_modules/@ykdz/template-builtin-source/dist/templates/vue-app/projection.js +372 -0
  16. package/node_modules/@ykdz/template-builtin-source/dist/templates/vue-hono-app/projection.d.ts +8 -0
  17. package/node_modules/@ykdz/template-builtin-source/dist/templates/vue-hono-app/projection.js +203 -0
  18. package/node_modules/@ykdz/template-builtin-source/package.json +59 -0
  19. package/{templates → node_modules/@ykdz/template-builtin-source/templates}/preset-source.json +14 -2
  20. package/node_modules/@ykdz/template-builtin-source/templates/shared/oxc/node/oxlint.config.ts +34 -0
  21. package/node_modules/@ykdz/template-builtin-source/templates/shared/oxc/tsconfig.config.json +20 -0
  22. package/node_modules/@ykdz/template-builtin-source/templates/shared/oxc/vue/oxlint.config.ts +36 -0
  23. package/node_modules/@ykdz/template-builtin-source/templates/vue-app/env.d.ts +8 -0
  24. package/node_modules/@ykdz/template-builtin-source/templates/vue-hono-app/web/env.d.ts +16 -0
  25. package/{dist/src → node_modules/@ykdz/template-core/dist}/declarations.d.ts +7 -4
  26. package/{dist/src → node_modules/@ykdz/template-core/dist}/declarations.js +45 -14
  27. package/{dist/src → node_modules/@ykdz/template-core/dist}/dependency-catalog.js +13 -6
  28. package/{dist/src → node_modules/@ykdz/template-core/dist}/devcontainer.d.ts +5 -5
  29. package/{dist/src → node_modules/@ykdz/template-core/dist}/editor-customization.js +23 -30
  30. package/{dist/src → node_modules/@ykdz/template-core/dist}/generated-scenarios.d.ts +6 -4
  31. package/{dist/src → node_modules/@ykdz/template-core/dist}/generated-scenarios.js +45 -14
  32. package/{dist/src → node_modules/@ykdz/template-core/dist}/generation-context.js +8 -3
  33. package/{dist/src → node_modules/@ykdz/template-core/dist}/next-step-instructions.js +3 -0
  34. package/node_modules/@ykdz/template-core/dist/package-addition.d.ts +12 -0
  35. package/{dist/src → node_modules/@ykdz/template-core/dist}/package-addition.js +33 -18
  36. package/{pnpm-workspace.yaml → node_modules/@ykdz/template-core/dist/pnpm-workspace.yaml} +4 -1
  37. package/{dist/src → node_modules/@ykdz/template-core/dist}/preset-projection.d.ts +3 -3
  38. package/{dist/src → node_modules/@ykdz/template-core/dist}/preset-projection.js +1 -0
  39. package/{dist/src → node_modules/@ykdz/template-core/dist}/preset-source.d.ts +1 -3
  40. package/{dist/src → node_modules/@ykdz/template-core/dist}/preset-source.js +73 -74
  41. package/{dist/src → node_modules/@ykdz/template-core/dist}/project-github.d.ts +3 -3
  42. package/{dist/src → node_modules/@ykdz/template-core/dist}/project-github.js +1 -0
  43. package/{dist/src → node_modules/@ykdz/template-core/dist}/projection-capabilities.d.ts +17 -5
  44. package/{dist/src → node_modules/@ykdz/template-core/dist}/projection-capabilities.js +209 -169
  45. package/{dist/src → node_modules/@ykdz/template-core/dist}/renderer.d.ts +2 -2
  46. package/{dist/src → node_modules/@ykdz/template-core/dist}/renderer.js +14 -6
  47. package/{dist/src → node_modules/@ykdz/template-core/dist}/runtime-paths.js +2 -0
  48. package/{dist/src → node_modules/@ykdz/template-core/dist}/template-boundary-check.d.ts +1 -1
  49. package/{dist/src → node_modules/@ykdz/template-core/dist}/template-boundary-check.js +8 -10
  50. package/{dist/src → node_modules/@ykdz/template-core/dist}/toolchain-resolution.d.ts +5 -5
  51. package/{dist/src → node_modules/@ykdz/template-core/dist}/toolchain-resolution.js +10 -11
  52. package/node_modules/@ykdz/template-core/package.json +34 -0
  53. package/package.json +18 -31
  54. package/README.md +0 -35
  55. package/dist/src/package-addition.d.ts +0 -8
  56. package/templates/shared/oxc/node/oxlint.config.ts +0 -9
  57. package/templates/shared/oxc/vue/oxlint.config.ts +0 -9
  58. package/templates/vue-app/env.d.ts +0 -1
  59. package/templates/vue-hono-app/web/env.d.ts +0 -9
  60. /package/dist/{src/cli.d.ts → cli.d.ts} +0 -0
  61. /package/{templates → node_modules/@ykdz/template-builtin-source/templates}/hono-api/.github/dependabot.yml +0 -0
  62. /package/{templates → node_modules/@ykdz/template-builtin-source/templates}/hono-api/.github/workflows/check.yml +0 -0
  63. /package/{templates → node_modules/@ykdz/template-builtin-source/templates}/hono-api/src/app.ts +0 -0
  64. /package/{templates → node_modules/@ykdz/template-builtin-source/templates}/hono-api/src/server.ts +0 -0
  65. /package/{templates → node_modules/@ykdz/template-builtin-source/templates}/hono-api/test/app.test.ts +0 -0
  66. /package/{templates → node_modules/@ykdz/template-builtin-source/templates}/hono-api/vitest.config.ts +0 -0
  67. /package/{templates → node_modules/@ykdz/template-builtin-source/templates}/rust-bin/.github/dependabot.yml +0 -0
  68. /package/{templates → node_modules/@ykdz/template-builtin-source/templates}/rust-bin/.github/workflows/check.yml +0 -0
  69. /package/{templates → node_modules/@ykdz/template-builtin-source/templates}/rust-bin/rust-toolchain.toml +0 -0
  70. /package/{templates → node_modules/@ykdz/template-builtin-source/templates}/rust-bin/rustfmt.toml +0 -0
  71. /package/{templates → node_modules/@ykdz/template-builtin-source/templates}/rust-bin/src/main.rs +0 -0
  72. /package/{templates → node_modules/@ykdz/template-builtin-source/templates}/shared/devcontainer/browser-test.Dockerfile +0 -0
  73. /package/{templates → node_modules/@ykdz/template-builtin-source/templates}/shared/devcontainer/node-pnpm.Dockerfile +0 -0
  74. /package/{templates → node_modules/@ykdz/template-builtin-source/templates}/shared/devcontainer/rust.Dockerfile +0 -0
  75. /package/{templates → node_modules/@ykdz/template-builtin-source/templates}/shared/editor-customization/capabilities.json +0 -0
  76. /package/{templates → node_modules/@ykdz/template-builtin-source/templates}/shared/oxc/oxfmt.config.ts +0 -0
  77. /package/{templates → node_modules/@ykdz/template-builtin-source/templates}/ts-lib/.github/dependabot.yml +0 -0
  78. /package/{templates → node_modules/@ykdz/template-builtin-source/templates}/ts-lib/.github/workflows/check.yml +0 -0
  79. /package/{templates → node_modules/@ykdz/template-builtin-source/templates}/ts-lib/src/index.ts +0 -0
  80. /package/{templates → node_modules/@ykdz/template-builtin-source/templates}/ts-lib/src/name-schema.ts +0 -0
  81. /package/{templates → node_modules/@ykdz/template-builtin-source/templates}/vue-app/.github/dependabot.yml +0 -0
  82. /package/{templates → node_modules/@ykdz/template-builtin-source/templates}/vue-app/.github/workflows/check.yml +0 -0
  83. /package/{templates → node_modules/@ykdz/template-builtin-source/templates}/vue-app/index.html +0 -0
  84. /package/{templates → node_modules/@ykdz/template-builtin-source/templates}/vue-app/playwright.config.ts +0 -0
  85. /package/{templates → node_modules/@ykdz/template-builtin-source/templates}/vue-app/playwright.package-addition.config.ts +0 -0
  86. /package/{templates → node_modules/@ykdz/template-builtin-source/templates}/vue-app/src/App.vue +0 -0
  87. /package/{templates → node_modules/@ykdz/template-builtin-source/templates}/vue-app/src/main.ts +0 -0
  88. /package/{templates → node_modules/@ykdz/template-builtin-source/templates}/vue-app/src/stores/counter.ts +0 -0
  89. /package/{templates → node_modules/@ykdz/template-builtin-source/templates}/vue-app/src/style.css +0 -0
  90. /package/{templates → node_modules/@ykdz/template-builtin-source/templates}/vue-app/test/app.test.ts +0 -0
  91. /package/{templates → node_modules/@ykdz/template-builtin-source/templates}/vue-app/test/e2e/app.spec.ts +0 -0
  92. /package/{templates → node_modules/@ykdz/template-builtin-source/templates}/vue-app/vite.config.ts +0 -0
  93. /package/{templates → node_modules/@ykdz/template-builtin-source/templates}/vue-app/vitest.config.ts +0 -0
  94. /package/{templates → node_modules/@ykdz/template-builtin-source/templates}/vue-hono-app/.github/dependabot.yml +0 -0
  95. /package/{templates → node_modules/@ykdz/template-builtin-source/templates}/vue-hono-app/.github/workflows/check.yml +0 -0
  96. /package/{templates → node_modules/@ykdz/template-builtin-source/templates}/vue-hono-app/api/src/index.ts +0 -0
  97. /package/{templates → node_modules/@ykdz/template-builtin-source/templates}/vue-hono-app/api/src/runtime.ts +0 -0
  98. /package/{templates → node_modules/@ykdz/template-builtin-source/templates}/vue-hono-app/api/src/server.ts +0 -0
  99. /package/{templates → node_modules/@ykdz/template-builtin-source/templates}/vue-hono-app/api/test/app.test.ts +0 -0
  100. /package/{templates → node_modules/@ykdz/template-builtin-source/templates}/vue-hono-app/api/vitest.config.ts +0 -0
  101. /package/{templates → node_modules/@ykdz/template-builtin-source/templates}/vue-hono-app/web/index.html +0 -0
  102. /package/{templates → node_modules/@ykdz/template-builtin-source/templates}/vue-hono-app/web/playwright.config.ts +0 -0
  103. /package/{templates → node_modules/@ykdz/template-builtin-source/templates}/vue-hono-app/web/src/App.vue +0 -0
  104. /package/{templates → node_modules/@ykdz/template-builtin-source/templates}/vue-hono-app/web/src/api.ts +0 -0
  105. /package/{templates → node_modules/@ykdz/template-builtin-source/templates}/vue-hono-app/web/src/main.ts +0 -0
  106. /package/{templates → node_modules/@ykdz/template-builtin-source/templates}/vue-hono-app/web/src/stores/counter.ts +0 -0
  107. /package/{templates → node_modules/@ykdz/template-builtin-source/templates}/vue-hono-app/web/src/style.css +0 -0
  108. /package/{templates → node_modules/@ykdz/template-builtin-source/templates}/vue-hono-app/web/test/app.test.ts +0 -0
  109. /package/{templates → node_modules/@ykdz/template-builtin-source/templates}/vue-hono-app/web/test/e2e/app.spec.ts +0 -0
  110. /package/{templates → node_modules/@ykdz/template-builtin-source/templates}/vue-hono-app/web/vite.config.ts +0 -0
  111. /package/{templates → node_modules/@ykdz/template-builtin-source/templates}/vue-hono-app/web/vitest.config.ts +0 -0
  112. /package/{dist/src → node_modules/@ykdz/template-core/dist}/dependency-catalog.d.ts +0 -0
  113. /package/{dist/src → node_modules/@ykdz/template-core/dist}/devcontainer.js +0 -0
  114. /package/{dist/src → node_modules/@ykdz/template-core/dist}/editor-customization.d.ts +0 -0
  115. /package/{dist/src → node_modules/@ykdz/template-core/dist}/generation-context.d.ts +0 -0
  116. /package/{dist/src → node_modules/@ykdz/template-core/dist}/module-graph.d.ts +0 -0
  117. /package/{dist/src → node_modules/@ykdz/template-core/dist}/module-graph.js +0 -0
  118. /package/{dist/src → node_modules/@ykdz/template-core/dist}/next-step-instructions.d.ts +0 -0
  119. /package/{dist/src → node_modules/@ykdz/template-core/dist}/package-addition-support.d.ts +0 -0
  120. /package/{dist/src → node_modules/@ykdz/template-core/dist}/package-addition-support.js +0 -0
  121. /package/{dist/src → node_modules/@ykdz/template-core/dist}/package-linking.d.ts +0 -0
  122. /package/{dist/src → node_modules/@ykdz/template-core/dist}/package-linking.js +0 -0
  123. /package/{dist/src → node_modules/@ykdz/template-core/dist}/runtime-paths.d.ts +0 -0
@@ -2,14 +2,15 @@
2
2
  import { readFile } from "node:fs/promises";
3
3
  import path from "node:path";
4
4
  import { createInterface } from "node:readline/promises";
5
- import { blueprintJsonSchema, builtInPresets, presetFileJsonSchema, validatePresetFile, validateProjectBlueprint, } from "./declarations.js";
6
- import { assembleGenerationContext, } from "./generation-context.js";
7
- import { addPackage } from "./package-addition.js";
8
- import { planNextStepInstructionsForProjection, } from "./preset-projection.js";
9
- import { findBuiltInPresetSourceManifestPreset, presetSourceManifestJsonSchema, validateBuiltInPresetSourceManifest, validatePresetSourceManifest, } from "./preset-source.js";
10
- import { blueprintForPresetSourcePreset, projectPresetSourcePreset, } from "./projection-capabilities.js";
11
- import { renderNewProject } from "./renderer.js";
12
- import { resolveToolchainVersions, } from "./toolchain-resolution.js";
5
+ import { builtInPresetProjectionSourceRoots, builtInPresets, findBuiltInPresetSourceManifestPreset, loadBuiltInPresetSourceManifest, projectBuiltInPresetSourcePreset, } from "@ykdz/template-builtin-source";
6
+ import { blueprintJsonSchema, presetFileJsonSchema, validatePresetFile, validateProjectBlueprint, } from "@ykdz/template-core/declarations";
7
+ import { assembleGenerationContext, } from "@ykdz/template-core/generation-context";
8
+ import { addPackage } from "@ykdz/template-core/package-addition";
9
+ import { planNextStepInstructionsForProjection, } from "@ykdz/template-core/preset-projection";
10
+ import { presetSourceManifestJsonSchema, validateBuiltInPresetSourceManifest, validatePresetSourceManifest, } from "@ykdz/template-core/preset-source";
11
+ import { blueprintForPresetSourcePreset } from "@ykdz/template-core/projection-capabilities";
12
+ import { renderNewProject } from "@ykdz/template-core/renderer";
13
+ import { resolveToolchainVersions, } from "@ykdz/template-core/toolchain-resolution";
13
14
  function usage() {
14
15
  return [
15
16
  "Project Kit template CLI",
@@ -51,7 +52,9 @@ async function readJsonDeclaration(filePath) {
51
52
  }
52
53
  catch (error) {
53
54
  if (error instanceof SyntaxError) {
54
- throw new Error(`Invalid JSON in ${filePath}: ${error.message}`);
55
+ throw new Error(`Invalid JSON in ${filePath}: ${error.message}`, {
56
+ cause: error,
57
+ });
55
58
  }
56
59
  throw error;
57
60
  }
@@ -246,7 +249,7 @@ async function generateInitProject(options, generationContext) {
246
249
  if (!generationContext) {
247
250
  throw new Error(`Missing Generation Context for Preset Projection: ${options.preset}`);
248
251
  }
249
- const plan = projectPresetSourcePreset({
252
+ const plan = projectBuiltInPresetSourcePreset({
250
253
  preset,
251
254
  context: generationContext,
252
255
  });
@@ -260,7 +263,7 @@ async function generateInitProject(options, generationContext) {
260
263
  function printInitComplete(options, blueprint, generationContext) {
261
264
  const preset = findBuiltInPresetSourceManifestPreset(blueprint.preset);
262
265
  const projectionPlan = generationContext && preset?.projection
263
- ? projectPresetSourcePreset({ preset, context: generationContext })
266
+ ? projectBuiltInPresetSourcePreset({ preset, context: generationContext })
264
267
  : undefined;
265
268
  if (!projectionPlan) {
266
269
  throw new Error(`Missing Preset Projection plan: ${blueprint.preset}`);
@@ -275,9 +278,9 @@ function printInitComplete(options, blueprint, generationContext) {
275
278
  dryRun: false,
276
279
  targetDir: options.dir,
277
280
  blueprint,
278
- toolchain: generationContext
279
- ? toolchainReport(generationContext.toolchain)
280
- : undefined,
281
+ ...(generationContext
282
+ ? { toolchain: toolchainReport(generationContext.toolchain) }
283
+ : {}),
281
284
  nextSteps,
282
285
  });
283
286
  return;
@@ -298,7 +301,7 @@ function printInitComplete(options, blueprint, generationContext) {
298
301
  console.log(formatProjectionNextSteps(options.dir, projectionPlan));
299
302
  }
300
303
  function isInteractiveTerminal() {
301
- return Boolean(process.stdin.isTTY && process.stdout.isTTY);
304
+ return process.stdin.isTTY && process.stdout.isTTY;
302
305
  }
303
306
  async function confirmInit(targetDir, blueprint) {
304
307
  console.log(formatBlueprintSummary(targetDir, blueprint));
@@ -395,7 +398,9 @@ async function main(args) {
395
398
  if (!filePath) {
396
399
  throw new Error("preset validate requires a path");
397
400
  }
398
- const result = validatePresetFile(await readJsonDeclaration(filePath));
401
+ const result = validatePresetFile(await readJsonDeclaration(filePath), {
402
+ presets: builtInPresets,
403
+ });
399
404
  if (!result.ok) {
400
405
  throw new Error(`Preset file is invalid:\n${formatValidationIssues(result.issues)}`);
401
406
  }
@@ -433,7 +438,9 @@ async function main(args) {
433
438
  if (!filePath) {
434
439
  throw new Error("blueprint validate requires a path");
435
440
  }
436
- const result = validateProjectBlueprint(await readJsonDeclaration(filePath));
441
+ const result = validateProjectBlueprint(await readJsonDeclaration(filePath), {
442
+ presets: builtInPresets,
443
+ });
437
444
  if (!result.ok) {
438
445
  throw new Error(`Blueprint is invalid:\n${formatValidationIssues(result.issues)}`);
439
446
  }
@@ -448,7 +455,10 @@ async function main(args) {
448
455
  const preset = findBuiltInPresetSourceManifestPreset(options.preset);
449
456
  const projectionPlan = generationContext
450
457
  ? preset?.projection
451
- ? projectPresetSourcePreset({ preset, context: generationContext })
458
+ ? projectBuiltInPresetSourcePreset({
459
+ preset,
460
+ context: generationContext,
461
+ })
452
462
  : undefined
453
463
  : undefined;
454
464
  if (!projectionPlan) {
@@ -464,9 +474,9 @@ async function main(args) {
464
474
  dryRun: true,
465
475
  targetDir: options.dir,
466
476
  blueprint,
467
- toolchain: generationContext
468
- ? toolchainReport(generationContext.toolchain)
469
- : undefined,
477
+ ...(generationContext
478
+ ? { toolchain: toolchainReport(generationContext.toolchain) }
479
+ : {}),
470
480
  nextSteps,
471
481
  });
472
482
  return;
@@ -499,6 +509,8 @@ async function main(args) {
499
509
  name: options.name,
500
510
  path: options.path,
501
511
  linkFrom: options.linkFrom,
512
+ presetSourceManifest: loadBuiltInPresetSourceManifest(),
513
+ projectionSourceRoots: builtInPresetProjectionSourceRoots(),
502
514
  });
503
515
  console.log([
504
516
  "Added package",
@@ -0,0 +1,22 @@
1
+ import type { BuiltInPreset } from "@ykdz/template-core/declarations";
2
+ import type { GenerationContext } from "@ykdz/template-core/generation-context";
3
+ import type { PresetPackageAdditionOptions } from "@ykdz/template-core/preset-projection";
4
+ import { type PresetSourceManifest, type PresetSourceManifestPreset } from "@ykdz/template-core/preset-source";
5
+ import { type PresetProjectionSourceRoots, type PresetProjectionDeclaration } from "@ykdz/template-core/projection-capabilities";
6
+ export { findPresetSourceManifestPreset, loadPresetSourceManifestFile, manifestReferencedSourceFiles, presetSourceManifestJsonSchema, validateBuiltInPresetSourceManifest, validatePresetSourceManifest, type PresetSourceManifest, type PresetSourceManifestPreset, } from "@ykdz/template-core/preset-source";
7
+ export declare function builtInPresetSourceRoot(...segments: string[]): string;
8
+ export declare function builtInPresetProjectionSourceRoots(): PresetProjectionSourceRoots;
9
+ export declare function loadBuiltInPresetSourceManifest(): PresetSourceManifest;
10
+ export declare const builtInPresets: readonly BuiltInPreset[];
11
+ export declare function findBuiltInPreset(name: string): BuiltInPreset | undefined;
12
+ export declare function findBuiltInPresetSourceManifestPreset(presetName: string): PresetSourceManifestPreset | undefined;
13
+ export declare function loadBuiltInPresetProjectionDeclaration(presetName: string): PresetProjectionDeclaration;
14
+ export declare function projectBuiltInPresetSourcePreset(options: {
15
+ readonly preset: PresetSourceManifestPreset;
16
+ readonly context: GenerationContext;
17
+ }): import("@ykdz/template-core/preset-projection").PresetProjectionPlan;
18
+ export declare function defaultPackagePathForBuiltInPackageAddition(preset: PresetSourceManifestPreset, packageLeafName: string): string;
19
+ export declare function planBuiltInPackageAddition(options: {
20
+ readonly preset: PresetSourceManifestPreset;
21
+ readonly addition: PresetPackageAdditionOptions;
22
+ }): Promise<import("@ykdz/template-core/preset-projection").PresetPackageAdditionPlan>;
@@ -0,0 +1,96 @@
1
+ import { readFileSync } from "node:fs";
2
+ import path from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ import { findPresetSourceManifestPreset, validateBuiltInPresetSourceManifest, } from "@ykdz/template-core/preset-source";
5
+ import { defaultPackagePathForPresetSourcePackageAddition, planPresetSourcePackageAddition, projectPresetSourcePreset, validateProjectionCapabilities, } from "@ykdz/template-core/projection-capabilities";
6
+ export { findPresetSourceManifestPreset, loadPresetSourceManifestFile, manifestReferencedSourceFiles, presetSourceManifestJsonSchema, validateBuiltInPresetSourceManifest, validatePresetSourceManifest, } from "@ykdz/template-core/preset-source";
7
+ export function builtInPresetSourceRoot(...segments) {
8
+ const moduleDir = path.dirname(fileURLToPath(import.meta.url));
9
+ const candidates = [
10
+ path.join(moduleDir, "..", "..", "templates", ...segments),
11
+ path.join(moduleDir, "..", "templates", ...segments),
12
+ path.join(moduleDir, "..", "..", "..", "template-builtin-source", "templates", ...segments),
13
+ ];
14
+ return (candidates.find((candidate) => readPathExists(candidate)) ?? candidates[0]);
15
+ }
16
+ function readPathExists(filePath) {
17
+ try {
18
+ readFileSync(filePath);
19
+ return true;
20
+ }
21
+ catch (error) {
22
+ if (errorCode(error) === "EISDIR") {
23
+ return true;
24
+ }
25
+ if (errorCode(error) === "ENOENT") {
26
+ return false;
27
+ }
28
+ return false;
29
+ }
30
+ }
31
+ function errorCode(error) {
32
+ if (error instanceof Error &&
33
+ "code" in error &&
34
+ typeof error.code === "string") {
35
+ return error.code;
36
+ }
37
+ return undefined;
38
+ }
39
+ export function builtInPresetProjectionSourceRoots() {
40
+ return {
41
+ preset(sourcePreset) {
42
+ return builtInPresetSourceRoot(sourcePreset);
43
+ },
44
+ sharedOxc() {
45
+ return builtInPresetSourceRoot("shared", "oxc");
46
+ },
47
+ sharedDevcontainer() {
48
+ return builtInPresetSourceRoot("shared", "devcontainer");
49
+ },
50
+ };
51
+ }
52
+ export function loadBuiltInPresetSourceManifest() {
53
+ const filePath = builtInPresetSourceRoot("preset-source.json");
54
+ const result = validateBuiltInPresetSourceManifest(JSON.parse(readFileSync(filePath, "utf8")), { sourceRoot: path.dirname(filePath) });
55
+ if (!result.ok) {
56
+ throw new Error(`Built-in Preset Source Manifest is invalid:\n${result.issues
57
+ .map((issue) => ` - ${issue.path}: ${issue.message}`)
58
+ .join("\n")}`);
59
+ }
60
+ return result.value;
61
+ }
62
+ export const builtInPresets = loadBuiltInPresetSourceManifest().presets;
63
+ export function findBuiltInPreset(name) {
64
+ return builtInPresets.find((preset) => preset.name === name);
65
+ }
66
+ export function findBuiltInPresetSourceManifestPreset(presetName) {
67
+ return findPresetSourceManifestPreset(loadBuiltInPresetSourceManifest(), presetName);
68
+ }
69
+ export function loadBuiltInPresetProjectionDeclaration(presetName) {
70
+ const preset = findBuiltInPresetSourceManifestPreset(presetName);
71
+ if (!preset?.projection) {
72
+ throw new Error(`Built-in Preset ${presetName} must declare a Projection Declaration`);
73
+ }
74
+ const result = validateProjectionCapabilities(preset.projection);
75
+ if (!result.ok) {
76
+ throw new Error(`Built-in Preset ${presetName} Projection Declaration is invalid:\n${result.issues
77
+ .map((issue) => ` - ${issue.path}: ${issue.message}`)
78
+ .join("\n")}`);
79
+ }
80
+ return result.value;
81
+ }
82
+ export function projectBuiltInPresetSourcePreset(options) {
83
+ return projectPresetSourcePreset({
84
+ ...options,
85
+ sourceRoots: builtInPresetProjectionSourceRoots(),
86
+ });
87
+ }
88
+ export function defaultPackagePathForBuiltInPackageAddition(preset, packageLeafName) {
89
+ return defaultPackagePathForPresetSourcePackageAddition(preset, packageLeafName, builtInPresetProjectionSourceRoots());
90
+ }
91
+ export function planBuiltInPackageAddition(options) {
92
+ return planPresetSourcePackageAddition({
93
+ ...options,
94
+ sourceRoots: builtInPresetProjectionSourceRoots(),
95
+ });
96
+ }
@@ -0,0 +1,6 @@
1
+ import type { BuiltInPreset, ProjectBlueprint } from "@ykdz/template-core/declarations";
2
+ import type { PresetBlueprintOptions, PresetProjection } from "@ykdz/template-core/preset-projection";
3
+ export declare const honoApiPresetMetadata: BuiltInPreset;
4
+ export declare function honoApiBlueprint(options?: PresetBlueprintOptions): ProjectBlueprint;
5
+ export declare function projectHonoApiPackageScripts(): Record<string, string>;
6
+ export declare const honoApiPresetProjection: PresetProjection;
@@ -0,0 +1,240 @@
1
+ import { existsSync } from "node:fs";
2
+ import path from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ import { builtInPresetProjectionSourceRoots, loadBuiltInPresetProjectionDeclaration, } from "@ykdz/template-builtin-source";
5
+ import { renderFixCommand, renderRootCheckCommand, } from "@ykdz/template-core/module-graph";
6
+ import { PackageAdditionSupport } from "@ykdz/template-core/package-addition-support";
7
+ import { packageManifestExposureFields, planPackageLinks, } from "@ykdz/template-core/package-linking";
8
+ import { interpretPresetProjectionDeclaration } from "@ykdz/template-core/projection-capabilities";
9
+ import { renderNewProject, } from "@ykdz/template-core/renderer";
10
+ export const honoApiPresetMetadata = {
11
+ name: "hono-api",
12
+ title: "Hono API",
13
+ description: "Hono Node API workspace with strict TypeScript tooling.",
14
+ generation: "supported",
15
+ supportedPackageManagers: ["pnpm"],
16
+ supportedProjectKinds: ["multi-package"],
17
+ packageAdditionSupport: PackageAdditionSupport.Supported,
18
+ features: [
19
+ "pnpm-catalog",
20
+ "oxc-format-lint",
21
+ "strict-typescript",
22
+ "root-check",
23
+ "fix-command",
24
+ "devcontainer",
25
+ "github-actions",
26
+ "dependabot",
27
+ ],
28
+ };
29
+ const apiPackageBoundary = {
30
+ kind: "package-boundary",
31
+ path: ".",
32
+ };
33
+ function planHonoApiPackageChecks() {
34
+ return {
35
+ components: [
36
+ { kind: "oxc-format-check", owner: apiPackageBoundary },
37
+ { kind: "oxc-lint", owner: apiPackageBoundary },
38
+ { kind: "typescript-typecheck", owner: apiPackageBoundary },
39
+ { kind: "build", owner: apiPackageBoundary },
40
+ { kind: "unit-test", owner: apiPackageBoundary },
41
+ ],
42
+ environmentNeeds: [],
43
+ };
44
+ }
45
+ function planHonoApiPackageFixes() {
46
+ return {
47
+ components: [
48
+ { kind: "oxc-format-write", owner: apiPackageBoundary },
49
+ { kind: "oxc-lint-fix", owner: apiPackageBoundary },
50
+ ],
51
+ };
52
+ }
53
+ function projectNameFromDir(targetDir) {
54
+ return path.basename(path.resolve(targetDir));
55
+ }
56
+ function packageScopeFromOptions(options) {
57
+ return options.scope ?? projectNameFromDir(options.targetDir);
58
+ }
59
+ function scopedPackageName(packageScope) {
60
+ return `@${packageScope}/api`;
61
+ }
62
+ export function honoApiBlueprint(options = { targetDir: process.cwd() }) {
63
+ const packageScope = packageScopeFromOptions(options);
64
+ return {
65
+ schemaVersion: 1,
66
+ preset: "hono-api",
67
+ packageManager: "pnpm",
68
+ projectKind: "multi-package",
69
+ features: [...honoApiPresetMetadata.features],
70
+ packages: [{ name: scopedPackageName(packageScope), path: "apps/api" }],
71
+ };
72
+ }
73
+ export function projectHonoApiPackageScripts() {
74
+ return {
75
+ build: "tsc -p tsconfig.build.json && tsc-alias -p tsconfig.build.json",
76
+ check: renderRootCheckCommand(planHonoApiPackageChecks()),
77
+ fix: renderFixCommand(planHonoApiPackageFixes()),
78
+ "format:check": "oxfmt --check --config ../../oxfmt.config.ts .",
79
+ "format:write": "oxfmt --write --config ../../oxfmt.config.ts .",
80
+ lint: "oxlint --config ../../oxlint.config.ts .",
81
+ "lint:fix": "oxlint --config ../../oxlint.config.ts . --fix",
82
+ start: "node dist/server.js",
83
+ test: "vitest run",
84
+ typecheck: "tsc -p tsconfig.json --noEmit",
85
+ };
86
+ }
87
+ function packageAdditionOperations(packagePath, packageNameValue, nodeVersion) {
88
+ const packageExposure = planPackageLinks([
89
+ {
90
+ name: packageNameValue,
91
+ path: packagePath,
92
+ role: "runtime-service",
93
+ sourcePreset: "hono-api",
94
+ },
95
+ ]).exposuresByPackagePath.get(packagePath);
96
+ if (packageExposure === undefined) {
97
+ throw new Error(`Missing Package Exposure for ${packagePath}`);
98
+ }
99
+ const exposureFields = packageManifestExposureFields(packageExposure);
100
+ return [
101
+ {
102
+ kind: "writeJson",
103
+ to: `${packagePath}/package.json`,
104
+ value: {
105
+ name: packageNameValue,
106
+ version: "0.0.0",
107
+ private: true,
108
+ type: "module",
109
+ types: exposureFields.types,
110
+ exports: exposureFields.exports,
111
+ imports: exposureFields.imports,
112
+ scripts: projectHonoApiPackageScripts(),
113
+ dependencies: {
114
+ "@hono/node-server": "catalog:",
115
+ hono: "catalog:",
116
+ },
117
+ devDependencies: {
118
+ "@types/node": "catalog:",
119
+ oxfmt: "catalog:",
120
+ oxlint: "catalog:",
121
+ "oxlint-tsgolint": "catalog:",
122
+ "tsc-alias": "catalog:",
123
+ typescript: "catalog:",
124
+ vitest: "catalog:",
125
+ },
126
+ engines: {
127
+ node: nodeVersion,
128
+ },
129
+ },
130
+ },
131
+ {
132
+ kind: "writeJson",
133
+ to: `${packagePath}/tsconfig.json`,
134
+ value: {
135
+ compilerOptions: {
136
+ composite: true,
137
+ erasableSyntaxOnly: true,
138
+ exactOptionalPropertyTypes: true,
139
+ forceConsistentCasingInFileNames: true,
140
+ isolatedModules: true,
141
+ module: "nodenext",
142
+ moduleResolution: "nodenext",
143
+ noEmitOnError: true,
144
+ noFallthroughCasesInSwitch: true,
145
+ noImplicitOverride: true,
146
+ noImplicitReturns: true,
147
+ noUncheckedIndexedAccess: true,
148
+ skipLibCheck: false,
149
+ strict: true,
150
+ target: "es2023",
151
+ types: ["node", "vitest/globals"],
152
+ verbatimModuleSyntax: true,
153
+ },
154
+ include: ["src/**/*.ts", "test/**/*.ts", "vitest.config.ts"],
155
+ },
156
+ },
157
+ {
158
+ kind: "writeJson",
159
+ to: `${packagePath}/tsconfig.build.json`,
160
+ value: {
161
+ extends: "./tsconfig.json",
162
+ compilerOptions: {
163
+ outDir: "dist",
164
+ rootDir: "src",
165
+ types: ["node"],
166
+ },
167
+ include: ["src/**/*.ts"],
168
+ },
169
+ },
170
+ { kind: "copyFile", from: "src/app.ts", to: `${packagePath}/src/app.ts` },
171
+ {
172
+ kind: "copyFile",
173
+ from: "src/server.ts",
174
+ to: `${packagePath}/src/server.ts`,
175
+ },
176
+ {
177
+ kind: "copyFile",
178
+ from: "test/app.test.ts",
179
+ to: `${packagePath}/test/app.test.ts`,
180
+ },
181
+ {
182
+ kind: "copyFile",
183
+ from: "vitest.config.ts",
184
+ to: `${packagePath}/vitest.config.ts`,
185
+ },
186
+ ];
187
+ }
188
+ function packageAdditionPlan(packageNameValue, packagePath, nodeVersion) {
189
+ const [workspaceCollection] = packagePath.split("/");
190
+ return {
191
+ packagePath,
192
+ workspacePackageGlob: `${workspaceCollection}/*`,
193
+ packageRole: "runtime-service",
194
+ packageSourcePreset: "hono-api",
195
+ sourceRoot: templateSourceRoot(),
196
+ sourceRoots: { sharedOxc: sharedOxcSourceRoot() },
197
+ operations: packageAdditionOperations(packagePath, packageNameValue, nodeVersion),
198
+ };
199
+ }
200
+ function templateSourceRoot() {
201
+ const projectionDir = path.dirname(fileURLToPath(import.meta.url));
202
+ const publishedTemplateRoot = path.join(projectionDir, "..", "..", "..", "templates", "hono-api");
203
+ return existsSync(path.join(publishedTemplateRoot, "src", "app.ts"))
204
+ ? publishedTemplateRoot
205
+ : projectionDir;
206
+ }
207
+ function sharedOxcSourceRoot() {
208
+ const projectionDir = path.dirname(fileURLToPath(import.meta.url));
209
+ const publishedSharedRoot = path.join(projectionDir, "..", "..", "..", "templates", "shared", "oxc");
210
+ return existsSync(path.join(publishedSharedRoot, "oxfmt.config.ts"))
211
+ ? publishedSharedRoot
212
+ : path.join(projectionDir, "..", "shared", "oxc");
213
+ }
214
+ export const honoApiPresetProjection = {
215
+ metadata: honoApiPresetMetadata,
216
+ capabilities: {
217
+ packageAddition: {
218
+ planPackageAddition({ packageName, packagePath, nodeVersion, }) {
219
+ return packageAdditionPlan(packageName, packagePath, nodeVersion);
220
+ },
221
+ },
222
+ },
223
+ blueprint: honoApiBlueprint,
224
+ project(context) {
225
+ return interpretPresetProjectionDeclaration({
226
+ preset: honoApiPresetMetadata,
227
+ declaration: loadBuiltInPresetProjectionDeclaration("hono-api"),
228
+ context,
229
+ sourceRoots: builtInPresetProjectionSourceRoots(),
230
+ });
231
+ },
232
+ async render({ targetDir, plan }) {
233
+ await renderNewProject({
234
+ sourceRoot: plan.sourceRoot,
235
+ sourceRoots: plan.sourceRoots,
236
+ targetRoot: targetDir,
237
+ operations: [...plan.operations],
238
+ });
239
+ },
240
+ };
@@ -0,0 +1,7 @@
1
+ import type { CheckComponent, CheckPlan, FixComponent, FixPlan } from "@ykdz/template-core/module-graph";
2
+ export type NodeCheckPlanTarget = "hono-api" | "vue-app" | "vue-hono-root" | "vue-hono-api" | "vue-hono-web";
3
+ export type NodeFixPlanTarget = "hono-api" | "vue-app" | "vue-hono-root" | "vue-hono-api" | "vue-hono-web";
4
+ export declare function selectNodeCheckComponents(target: NodeCheckPlanTarget): CheckComponent[];
5
+ export declare function selectNodeFixComponents(target: NodeFixPlanTarget): FixComponent[];
6
+ export declare function planNodeChecks(target: NodeCheckPlanTarget): CheckPlan;
7
+ export declare function planNodeFixes(target: NodeFixPlanTarget): FixPlan;
@@ -0,0 +1,94 @@
1
+ const rootPackageBoundary = {
2
+ kind: "package-boundary",
3
+ path: ".",
4
+ };
5
+ const apiPackageBoundary = {
6
+ kind: "package-boundary",
7
+ path: "apps/api",
8
+ };
9
+ const webPackageBoundary = {
10
+ kind: "package-boundary",
11
+ path: "apps/web",
12
+ };
13
+ function honoApiCheckComponents(owner) {
14
+ return [
15
+ { kind: "oxc-format-check", owner },
16
+ { kind: "oxc-lint", owner },
17
+ { kind: "typescript-typecheck", owner },
18
+ { kind: "build", owner },
19
+ { kind: "unit-test", owner },
20
+ ];
21
+ }
22
+ function vueAppCheckComponents(owner) {
23
+ return [
24
+ { kind: "oxc-format-check", owner },
25
+ { kind: "oxc-lint", owner },
26
+ { kind: "typescript-typecheck", owner },
27
+ { kind: "build", owner },
28
+ { kind: "unit-test", owner },
29
+ { kind: "e2e-test", owner },
30
+ ];
31
+ }
32
+ function nodeFixComponents(owner) {
33
+ return [
34
+ { kind: "oxc-format-write", owner },
35
+ { kind: "oxc-lint-fix", owner },
36
+ ];
37
+ }
38
+ export function selectNodeCheckComponents(target) {
39
+ switch (target) {
40
+ case "hono-api":
41
+ return honoApiCheckComponents(rootPackageBoundary);
42
+ case "vue-app":
43
+ return vueAppCheckComponents(rootPackageBoundary);
44
+ case "vue-hono-root":
45
+ return [{ kind: "turbo-check", owner: rootPackageBoundary }];
46
+ case "vue-hono-api":
47
+ return honoApiCheckComponents(apiPackageBoundary);
48
+ case "vue-hono-web":
49
+ return vueAppCheckComponents(webPackageBoundary);
50
+ }
51
+ }
52
+ export function selectNodeFixComponents(target) {
53
+ switch (target) {
54
+ case "hono-api":
55
+ case "vue-app":
56
+ return nodeFixComponents(rootPackageBoundary);
57
+ case "vue-hono-root":
58
+ return [{ kind: "turbo-fix", owner: rootPackageBoundary }];
59
+ case "vue-hono-api":
60
+ return nodeFixComponents(apiPackageBoundary);
61
+ case "vue-hono-web":
62
+ return nodeFixComponents(webPackageBoundary);
63
+ }
64
+ }
65
+ function checkEnvironmentNeeds(target) {
66
+ if (target === "vue-app") {
67
+ return [
68
+ {
69
+ kind: "playwright-browser-assets",
70
+ browser: "chromium",
71
+ owner: rootPackageBoundary,
72
+ },
73
+ ];
74
+ }
75
+ if (target === "vue-hono-root" || target === "vue-hono-web") {
76
+ return [
77
+ {
78
+ kind: "playwright-browser-assets",
79
+ browser: "chromium",
80
+ owner: webPackageBoundary,
81
+ },
82
+ ];
83
+ }
84
+ return [];
85
+ }
86
+ export function planNodeChecks(target) {
87
+ return {
88
+ components: selectNodeCheckComponents(target),
89
+ environmentNeeds: checkEnvironmentNeeds(target),
90
+ };
91
+ }
92
+ export function planNodeFixes(target) {
93
+ return { components: selectNodeFixComponents(target) };
94
+ }
@@ -0,0 +1,2 @@
1
+ import type { PresetProjection } from "@ykdz/template-core/preset-projection";
2
+ export declare function findBuiltInPresetProjection(name: string): PresetProjection | undefined;
@@ -0,0 +1,15 @@
1
+ import { honoApiPresetProjection } from "./hono-api/projection.js";
2
+ import { rustBinPresetProjection } from "./rust-bin/projection.js";
3
+ import { tsLibPresetProjection } from "./ts-lib/projection.js";
4
+ import { vueAppPresetProjection } from "./vue-app/projection.js";
5
+ import { vueHonoAppPresetProjection } from "./vue-hono-app/projection.js";
6
+ const testOnlyPresetProjections = [
7
+ tsLibPresetProjection,
8
+ honoApiPresetProjection,
9
+ vueAppPresetProjection,
10
+ vueHonoAppPresetProjection,
11
+ rustBinPresetProjection,
12
+ ];
13
+ export function findBuiltInPresetProjection(name) {
14
+ return testOnlyPresetProjections.find((projection) => projection.metadata.name === name);
15
+ }
@@ -0,0 +1,9 @@
1
+ import type { BuiltInPreset, ProjectBlueprint } from "@ykdz/template-core/declarations";
2
+ import { type CheckPlan, type FixPlan } from "@ykdz/template-core/module-graph";
3
+ import type { PresetBlueprintOptions, PresetProjection } from "@ykdz/template-core/preset-projection";
4
+ export declare const rustBinPresetMetadata: BuiltInPreset;
5
+ export declare function planRustBinChecks(): CheckPlan;
6
+ export declare function planRustBinFixes(): FixPlan;
7
+ export declare function rustBinBlueprint(options?: PresetBlueprintOptions): ProjectBlueprint;
8
+ export declare function projectRustBinPackageScripts(): Record<string, string>;
9
+ export declare const rustBinPresetProjection: PresetProjection;