@ykdz/template 0.0.35 → 0.0.36

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 (80) hide show
  1. package/dist/application.d.ts +2 -1
  2. package/dist/application.js +64 -75
  3. package/dist/main.js +6 -2
  4. package/node_modules/@ykdz/template-builtin-presets/dist/src/foundation.d.ts +50 -36
  5. package/node_modules/@ykdz/template-builtin-presets/dist/src/foundation.js +968 -364
  6. package/node_modules/@ykdz/template-builtin-presets/dist/src/generation-record.d.ts +24 -0
  7. package/node_modules/@ykdz/template-builtin-presets/dist/src/generation-record.js +154 -0
  8. package/node_modules/@ykdz/template-builtin-presets/dist/src/index.d.ts +2 -2
  9. package/node_modules/@ykdz/template-builtin-presets/dist/src/index.js +1 -1
  10. package/node_modules/@ykdz/template-builtin-presets/dist/src/rust-bin/definition.d.ts +31 -2
  11. package/node_modules/@ykdz/template-builtin-presets/dist/src/rust-bin/definition.js +29 -33
  12. package/node_modules/@ykdz/template-builtin-presets/dist/src/shared/typescript.d.ts +4 -3
  13. package/node_modules/@ykdz/template-builtin-presets/dist/src/shared/typescript.js +9 -5
  14. package/node_modules/@ykdz/template-builtin-presets/dist/src/shared/vue.d.ts +1 -1
  15. package/node_modules/@ykdz/template-builtin-presets/dist/src/shared/vue.js +0 -1
  16. package/node_modules/@ykdz/template-builtin-presets/dist/src/ts-cli/definition.d.ts +31 -2
  17. package/node_modules/@ykdz/template-builtin-presets/dist/src/ts-cli/definition.js +79 -58
  18. package/node_modules/@ykdz/template-builtin-presets/dist/src/ts-lib/definition.d.ts +31 -2
  19. package/node_modules/@ykdz/template-builtin-presets/dist/src/ts-lib/definition.js +31 -23
  20. package/node_modules/@ykdz/template-builtin-presets/dist/src/vike-app/definition.d.ts +22 -2
  21. package/node_modules/@ykdz/template-builtin-presets/dist/src/vike-app/definition.js +53 -25
  22. package/node_modules/@ykdz/template-builtin-presets/dist/src/vue-app/definition.d.ts +26 -2
  23. package/node_modules/@ykdz/template-builtin-presets/dist/src/vue-app/definition.js +19 -7
  24. package/node_modules/@ykdz/template-builtin-presets/dist/src/vue-hono-app/definition.d.ts +22 -2
  25. package/node_modules/@ykdz/template-builtin-presets/dist/src/vue-hono-app/definition.js +31 -20
  26. package/node_modules/@ykdz/template-builtin-presets/package.json +12 -11
  27. package/node_modules/@ykdz/template-builtin-presets/templates/foundation/.github/workflows/check-deployment-diagnostics.yml +1 -1
  28. package/node_modules/@ykdz/template-builtin-presets/templates/foundation/.github/workflows/check-deployment.yml +1 -1
  29. package/node_modules/@ykdz/template-builtin-presets/templates/foundation/.pnpmfile.mjs +19 -0
  30. package/node_modules/@ykdz/template-builtin-presets/templates/foundation/tsconfig.packing-hook.json +8 -0
  31. package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication/CHANGELOG.md.template +17 -0
  32. package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication/RELEASING.md +17 -0
  33. package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication/artifact.ts +1271 -0
  34. package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication/changelog.ts +283 -0
  35. package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication/check-artifact.ts +99 -0
  36. package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication/check-readiness.ts +66 -0
  37. package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication/cli-command-identity.ts +4 -0
  38. package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication/handoff.ts +450 -0
  39. package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication/publish.ts +483 -0
  40. package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication/readiness.ts +1125 -0
  41. package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication/release.ts +819 -0
  42. package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication/release.yml +119 -0
  43. package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication/root-tsconfig.json +13 -0
  44. package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication/tsconfig.json +4 -0
  45. package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication/turbo.json +6 -0
  46. package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication-setup/README.md +48 -0
  47. package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication-setup/assets/CHANGELOG.md.template +17 -0
  48. package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication-setup/assets/LICENSE-APACHE-2.0.txt +202 -0
  49. package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication-setup/assets/LICENSE-MIT.txt +21 -0
  50. package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication-setup/assets/README.md.template +5 -0
  51. package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication-setup/bridge.ts +3336 -0
  52. package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication-setup/setup.sh +221 -0
  53. package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/src/cli-command-identity.ts +133 -0
  54. package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/src/cli.ts +4 -3
  55. package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/src/main.ts +5 -4
  56. package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/test/integration/command.test.ts +14 -13
  57. package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/test/unit/cli-command-identity.test.ts +76 -0
  58. package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/tsconfig.build.json +2 -0
  59. package/node_modules/@ykdz/template-core/dist/module-graph.d.ts +15 -53
  60. package/node_modules/@ykdz/template-core/dist/module-graph.js +134 -101
  61. package/node_modules/@ykdz/template-core/dist/package-contribution.d.ts +13 -1
  62. package/node_modules/@ykdz/template-core/dist/package-contribution.js +92 -0
  63. package/node_modules/@ykdz/template-core/dist/pnpm-workspace.yaml +14 -10
  64. package/node_modules/@ykdz/template-core/dist/preset-definition.d.ts +71 -13
  65. package/node_modules/@ykdz/template-core/dist/preset-definition.js +16 -1
  66. package/node_modules/@ykdz/template-core/dist/project-blueprint.d.ts +56 -0
  67. package/node_modules/@ykdz/template-core/dist/project-blueprint.js +271 -0
  68. package/node_modules/@ykdz/template-core/dist/project-linking-v2.d.ts +2 -2
  69. package/node_modules/@ykdz/template-core/dist/project-linking-v2.js +2 -2
  70. package/node_modules/@ykdz/template-core/dist/project-projection.d.ts +2 -1
  71. package/node_modules/@ykdz/template-core/dist/project-projection.js +107 -20
  72. package/node_modules/@ykdz/template-core/dist/renderer.d.ts +0 -2
  73. package/node_modules/@ykdz/template-core/dist/renderer.js +17 -38
  74. package/node_modules/@ykdz/template-core/dist/template-boundary-check.d.ts +2 -2
  75. package/node_modules/@ykdz/template-core/dist/template-boundary-check.js +6 -0
  76. package/node_modules/@ykdz/template-core/dist/toolchain-resolution.d.ts +2 -0
  77. package/node_modules/@ykdz/template-core/dist/toolchain-resolution.js +9 -3
  78. package/package.json +5 -5
  79. package/node_modules/@ykdz/template-core/dist/project-blueprint-v2.d.ts +0 -33
  80. package/node_modules/@ykdz/template-core/dist/project-blueprint-v2.js +0 -182
@@ -0,0 +1,24 @@
1
+ import type { GenerationContext } from "#template-core/preset-definition";
2
+ import type { PackageDefinitionId } from "#template-core/project-blueprint";
3
+ export type GeneratedPackagePlanningRecord = {
4
+ readonly packageDefinitionId: PackageDefinitionId;
5
+ readonly path: string;
6
+ readonly definitionName: string;
7
+ readonly planningContribution: "foundationPlan" | "planInitialization" | "planPackageAddition";
8
+ readonly contributionIdentity: string;
9
+ };
10
+ export type GenerationRecord = {
11
+ readonly schemaVersion: 2;
12
+ readonly repositoryName: string;
13
+ readonly defaultPackageScope: string;
14
+ readonly preset: string;
15
+ readonly templateVersion: "0.0.0";
16
+ readonly toolchain: GenerationContext["toolchain"];
17
+ readonly packages: readonly GeneratedPackagePlanningRecord[];
18
+ };
19
+ /** Canonical durable Generation Record contract for a default npm scope. */
20
+ export declare function isValidDefaultPackageScope(value: string): boolean;
21
+ /** Strictly decodes the durable Record shape before semantic checks run. */
22
+ export declare function decodeGenerationRecordStructure(value: unknown): GenerationRecord;
23
+ /** Validates semantic invariants that are independent of a Project Blueprint. */
24
+ export declare function parseGenerationRecord(value: unknown): GenerationRecord;
@@ -0,0 +1,154 @@
1
+ import * as v from "valibot";
2
+ import { isValidNodeLtsMajor, isValidPackageManagerPin, } from "#template-core/toolchain-resolution";
3
+ /** Canonical durable Generation Record contract for a default npm scope. */
4
+ export function isValidDefaultPackageScope(value) {
5
+ return /^[a-z0-9][a-z0-9._-]*$/.test(value);
6
+ }
7
+ function strictObjectMessage(issue, objectMessage) {
8
+ if (issue.path?.at(-1)?.origin !== "key")
9
+ return objectMessage;
10
+ const unknownKey = typeof issue.input === "string" ? issue.input : "<unknown>";
11
+ return `contains unknown Generation Record field; contains unknown field: ${unknownKey}`;
12
+ }
13
+ const packagePlanningRecordSchema = v.strictObject({
14
+ packageDefinitionId: v.string("packageDefinitionId must use the package-<sha256> format"),
15
+ path: v.string("path must be a non-empty string"),
16
+ definitionName: v.string("definitionName must be a non-empty string"),
17
+ planningContribution: v.picklist(["foundationPlan", "planInitialization", "planPackageAddition"], "planningContribution is unsupported"),
18
+ contributionIdentity: v.string("contributionIdentity must be a non-empty string"),
19
+ }, (issue) => strictObjectMessage(issue, "package planning fact must be an object"));
20
+ const generationRecordSchema = v.strictObject({
21
+ schemaVersion: v.literal(2, (issue) => `Unsupported Generation Record schema version ${String(issue.input)}; expected 2`),
22
+ repositoryName: v.string("repositoryName must be a non-empty string"),
23
+ defaultPackageScope: v.string("defaultPackageScope must be a valid npm scope"),
24
+ preset: v.string("preset must be a non-empty string"),
25
+ templateVersion: v.literal("0.0.0", "templateVersion must be 0.0.0"),
26
+ toolchain: v.strictObject({
27
+ nodeLtsMajor: v.string("toolchain.nodeLtsMajor must be a numeric Node major"),
28
+ packageManagerPin: v.string("toolchain.packageManagerPin must be an exact pnpm version pin"),
29
+ }, (issue) => strictObjectMessage(issue, "toolchain must be an object")),
30
+ packages: v.array(packagePlanningRecordSchema, "packages must be an array"),
31
+ }, (issue) => strictObjectMessage(issue, "supported Generation Record must be an object"));
32
+ function issuePath(issue) {
33
+ let result = "";
34
+ for (const item of issue.path ?? []) {
35
+ if (typeof item.key === "number") {
36
+ result += `[${item.key}]`;
37
+ }
38
+ else if (typeof item.key === "string") {
39
+ result += `${result.length === 0 ? "" : "."}${item.key}`;
40
+ }
41
+ }
42
+ return result;
43
+ }
44
+ const missingFieldMessages = new Map([
45
+ [
46
+ "schemaVersion",
47
+ "Unsupported Generation Record schema version undefined; expected 2",
48
+ ],
49
+ ["repositoryName", "repositoryName must be a non-empty string"],
50
+ ["defaultPackageScope", "defaultPackageScope must be a valid npm scope"],
51
+ ["preset", "preset must be a non-empty string"],
52
+ ["templateVersion", "templateVersion must be 0.0.0"],
53
+ ["toolchain", "toolchain must be an object"],
54
+ ["packages", "packages must be an array"],
55
+ ]);
56
+ function missingFieldMessage(path, fallback) {
57
+ const exact = missingFieldMessages.get(path);
58
+ if (exact !== undefined)
59
+ return exact;
60
+ if (path.endsWith(".nodeLtsMajor")) {
61
+ return `${path} must be a numeric Node major`;
62
+ }
63
+ if (path.endsWith(".packageManagerPin")) {
64
+ return `${path} must be an exact pnpm version pin`;
65
+ }
66
+ if (path.endsWith(".packageDefinitionId")) {
67
+ return `${path} must use the package-<sha256> format`;
68
+ }
69
+ if (path.endsWith(".path") ||
70
+ path.endsWith(".definitionName") ||
71
+ path.endsWith(".contributionIdentity")) {
72
+ return `${path} must be a non-empty string`;
73
+ }
74
+ if (path.endsWith(".planningContribution")) {
75
+ return `${path} is unsupported`;
76
+ }
77
+ return fallback;
78
+ }
79
+ function structuralError(issues) {
80
+ return new Error(`Generation Record ${issues
81
+ .map((issue) => {
82
+ const path = issuePath(issue);
83
+ const last = issue.path?.at(-1);
84
+ if (issue.type === "strict_object" &&
85
+ last?.origin === "key" &&
86
+ issue.input !== undefined &&
87
+ !path.includes(".") &&
88
+ !path.includes("[")) {
89
+ const unknownKey = typeof issue.input === "string" ? issue.input : "<unknown>";
90
+ return `contains unknown field: ${unknownKey}; ${path}: contains unknown Generation Record field`;
91
+ }
92
+ let message = issue.message;
93
+ if (issue.type === "strict_object" &&
94
+ last?.origin === "key" &&
95
+ issue.input === undefined) {
96
+ message = missingFieldMessage(path, message);
97
+ }
98
+ const normalizedPath = path.length === 0 ? "." : path;
99
+ return message.startsWith(normalizedPath)
100
+ ? message
101
+ : `${normalizedPath}: ${message}`;
102
+ })
103
+ .join("; ")}`);
104
+ }
105
+ /** Strictly decodes the durable Record shape before semantic checks run. */
106
+ export function decodeGenerationRecordStructure(value) {
107
+ const parsed = v.safeParse(generationRecordSchema, value);
108
+ if (!parsed.success)
109
+ throw structuralError(parsed.issues);
110
+ return parsed.output;
111
+ }
112
+ /** Validates semantic invariants that are independent of a Project Blueprint. */
113
+ export function parseGenerationRecord(value) {
114
+ const record = decodeGenerationRecordStructure(value);
115
+ const issues = [];
116
+ if (record.repositoryName.length === 0 ||
117
+ record.repositoryName !== record.repositoryName.trim()) {
118
+ issues.push("repositoryName must be a non-empty string");
119
+ }
120
+ if (!isValidDefaultPackageScope(record.defaultPackageScope)) {
121
+ issues.push("defaultPackageScope must be a valid npm scope");
122
+ }
123
+ if (record.preset.length === 0 || record.preset !== record.preset.trim()) {
124
+ issues.push("preset must be a non-empty string");
125
+ }
126
+ if (!isValidNodeLtsMajor(record.toolchain.nodeLtsMajor)) {
127
+ issues.push("toolchain.nodeLtsMajor must be a numeric Node major");
128
+ }
129
+ if (!isValidPackageManagerPin(record.toolchain.packageManagerPin)) {
130
+ issues.push("toolchain.packageManagerPin must be an exact pnpm version pin");
131
+ }
132
+ for (const [index, item] of record.packages.entries()) {
133
+ if (!/^package-[a-f0-9]{64}$/.test(item.packageDefinitionId)) {
134
+ issues.push(`packages[${index}].packageDefinitionId must use the package-<sha256> format`);
135
+ }
136
+ if (item.path.length === 0) {
137
+ issues.push(`packages[${index}].path must be a non-empty string`);
138
+ }
139
+ if (item.definitionName.length === 0) {
140
+ issues.push(`packages[${index}].definitionName must be a non-empty string`);
141
+ }
142
+ if (item.contributionIdentity.length === 0) {
143
+ issues.push(`packages[${index}].contributionIdentity must be a non-empty string`);
144
+ }
145
+ }
146
+ const packageDefinitionIds = record.packages.map((item) => item.packageDefinitionId);
147
+ if (new Set(packageDefinitionIds).size !== packageDefinitionIds.length) {
148
+ issues.push("packages packageDefinitionId must be unique");
149
+ }
150
+ if (issues.length > 0) {
151
+ throw new Error(`Generation Record ${issues.join("; ")}`);
152
+ }
153
+ return record;
154
+ }
@@ -1,3 +1,3 @@
1
- export { builtInPresetRegistry, builtInPresetTemplateSourceCheckContexts, builtInPresetTemplateSourceContexts, createGenerationContext, planGeneratedRepositoryInitialization, planGeneratedRepositoryPackageAddition, resolveBuiltInTemplateSource, validateProjectBlueprintV2, } from "./foundation.ts";
1
+ export { builtInPresetRegistry, createGenerationContext, loadLocalTemplateMetadata, prepareGeneratedRepositoryInitialization, planGeneratedRepositoryInitialization, planGeneratedRepositoryPackageAddition, resolveBuiltInTemplateSource, validateProjectBlueprint, } from "./foundation.ts";
2
2
  export { templateSources } from "./template-sources.ts";
3
- export type { BuiltInPresetDefinition, BuiltInPresetTemplateSourceCheckContext, GeneratedRepositoryPlan, PackageContribution, ProjectBlueprintV2, BuiltInGenerationContext, } from "./foundation.ts";
3
+ export type { BuiltInPresetDefinition, GeneratedRepositoryPlan, PackageContribution, ProjectBlueprint, BuiltInGenerationContext, LocalTemplateMetadata, InitializationIdentityOverrides, PublicationSetupHandoff, ResolvedInitialization, } from "./foundation.ts";
@@ -1,2 +1,2 @@
1
- export { builtInPresetRegistry, builtInPresetTemplateSourceCheckContexts, builtInPresetTemplateSourceContexts, createGenerationContext, planGeneratedRepositoryInitialization, planGeneratedRepositoryPackageAddition, resolveBuiltInTemplateSource, validateProjectBlueprintV2, } from "./foundation.js";
1
+ export { builtInPresetRegistry, createGenerationContext, loadLocalTemplateMetadata, prepareGeneratedRepositoryInitialization, planGeneratedRepositoryInitialization, planGeneratedRepositoryPackageAddition, resolveBuiltInTemplateSource, validateProjectBlueprint, } from "./foundation.js";
2
2
  export { templateSources } from "./template-sources.js";
@@ -1,2 +1,31 @@
1
- import type { BuiltInPresetDefinition } from "#template-core/preset-definition";
2
- export declare const rustBinDefinition: BuiltInPresetDefinition;
1
+ import { type GenerationContext } from "#template-core/preset-definition";
2
+ export declare const rustBinDefinition: {
3
+ metadata: {
4
+ name: string;
5
+ title: string;
6
+ description: string;
7
+ };
8
+ source: import("@ykdz/template-core/renderer").TemplateSourceHandle;
9
+ plannerSourceFile: string;
10
+ packageContributionReplayAdapters: import("@ykdz/template-core/preset-definition").PackageContributionReplayAdapter[];
11
+ initialPrimaryPackage: {
12
+ defaultLeafName: string;
13
+ role: "native-package";
14
+ defaultPackagePath: ({ packageLeafName }: {
15
+ readonly packageLeafName: string;
16
+ }) => string;
17
+ planInitialContribution({ context, resolvedPackageIdentity }: {
18
+ readonly context: GenerationContext;
19
+ readonly resolvedPackageIdentity: import("@ykdz/template-core/preset-definition").ResolvedPrimaryPackageIdentity;
20
+ }): import("@ykdz/template-core/preset-definition").PlannedPackageContribution;
21
+ };
22
+ defaultPackagePath({ packageLeafName }: {
23
+ readonly context: GenerationContext;
24
+ readonly packageLeafName: string;
25
+ }): string;
26
+ planPackageAddition({ context, packageLeafName, packagePath }: {
27
+ readonly context: GenerationContext;
28
+ readonly packageLeafName: string;
29
+ readonly packagePath: string;
30
+ }): import("@ykdz/template-core/preset-definition").PlannedPackageContribution;
31
+ };
@@ -1,14 +1,9 @@
1
1
  import { fileURLToPath } from "node:url";
2
2
  import { rustToolchainEnvironmentNeed } from "#template-core/module-graph";
3
+ import { definePackageContributionReplayAdapter, } from "#template-core/preset-definition";
3
4
  import { templateSources } from "../template-sources.js";
4
- function cargoPackageName(projectName) {
5
- const slug = projectName
6
- .normalize("NFKD")
7
- .replace(/[\u0300-\u036f]/g, "")
8
- .toLowerCase()
9
- .replace(/[^a-z0-9]+/g, "-")
10
- .replace(/^-+|-+$/g, "");
11
- return slug || "rust-bin";
5
+ function packagePathForLeaf(packageLeafName) {
6
+ return `packages/${packageLeafName}`;
12
7
  }
13
8
  function packageScripts() {
14
9
  return {
@@ -19,8 +14,8 @@ function packageScripts() {
19
14
  };
20
15
  }
21
16
  function rustContribution(options) {
22
- const definition = {
23
- name: `@${options.context.scope}/${options.packageLeafName}`,
17
+ const definition = options.packageDefinition ?? {
18
+ name: `@${options.context.defaultPackageScope}/${options.packageLeafName}`,
24
19
  path: options.packagePath,
25
20
  role: "native-package",
26
21
  };
@@ -64,7 +59,6 @@ function rustContribution(options) {
64
59
  exposure: { exports: {}, imports: {} },
65
60
  manifest: {
66
61
  name: definition.name,
67
- version: "0.0.0",
68
62
  private: true,
69
63
  scripts: packageScripts(),
70
64
  engines: { node: options.context.toolchain.nodeLtsMajor },
@@ -133,6 +127,15 @@ function rustContribution(options) {
133
127
  },
134
128
  };
135
129
  }
130
+ const binaryReplayAdapter = definePackageContributionReplayAdapter({
131
+ identity: "binary",
132
+ replay: ({ context, packageDefinition, packageLeafName }) => rustContribution({
133
+ context,
134
+ packageLeafName,
135
+ packagePath: packageDefinition.path,
136
+ packageDefinition,
137
+ }),
138
+ });
136
139
  export const rustBinDefinition = {
137
140
  metadata: {
138
141
  name: "rust-bin",
@@ -141,31 +144,24 @@ export const rustBinDefinition = {
141
144
  },
142
145
  source: templateSources.rustBin,
143
146
  plannerSourceFile: fileURLToPath(import.meta.url),
144
- blueprint(context) {
145
- const packageLeafName = cargoPackageName(context.projectName);
146
- return {
147
- schemaVersion: 2,
148
- packages: [
149
- rustContribution({
150
- context,
151
- packageLeafName,
152
- packagePath: `packages/${packageLeafName}`,
153
- }).definition,
154
- ],
155
- };
156
- },
157
- planInitialization(context) {
158
- const packageLeafName = cargoPackageName(context.projectName);
159
- return rustContribution({
160
- context,
161
- packageLeafName,
162
- packagePath: `packages/${packageLeafName}`,
163
- });
147
+ packageContributionReplayAdapters: [binaryReplayAdapter],
148
+ initialPrimaryPackage: {
149
+ defaultLeafName: "app",
150
+ role: "native-package",
151
+ defaultPackagePath: ({ packageLeafName }) => packagePathForLeaf(packageLeafName),
152
+ planInitialContribution({ context, resolvedPackageIdentity }) {
153
+ return binaryReplayAdapter.identify(rustContribution({
154
+ context,
155
+ packageLeafName: resolvedPackageIdentity.leafName,
156
+ packagePath: resolvedPackageIdentity.definition.path,
157
+ packageDefinition: resolvedPackageIdentity.definition,
158
+ }));
159
+ },
164
160
  },
165
161
  defaultPackagePath({ packageLeafName }) {
166
- return `packages/${packageLeafName}`;
162
+ return packagePathForLeaf(packageLeafName);
167
163
  },
168
164
  planPackageAddition({ context, packageLeafName, packagePath }) {
169
- return rustContribution({ context, packageLeafName, packagePath });
165
+ return binaryReplayAdapter.identify(rustContribution({ context, packageLeafName, packagePath }));
170
166
  },
171
167
  };
@@ -1,6 +1,6 @@
1
1
  import type { PackageContribution } from "#template-core/package-contribution";
2
- import type { GenerationContext } from "#template-core/preset-definition";
3
- import type { PackageDefinition } from "#template-core/project-blueprint-v2";
2
+ import { type GenerationContext } from "#template-core/preset-definition";
3
+ import type { PackageDefinition } from "#template-core/project-blueprint";
4
4
  import type { RenderOperation, TemplateSourceHandle } from "#template-core/renderer";
5
5
  export declare function typescriptConfigPackageName(context: GenerationContext): string;
6
6
  export declare function typescriptConfigPackageDefinition(context: GenerationContext): PackageDefinition;
@@ -10,4 +10,5 @@ export declare function typescriptConfigSourceOperation(options: {
10
10
  readonly from: string;
11
11
  readonly to: string;
12
12
  }): RenderOperation;
13
- export declare function typescriptConfigContribution(context: GenerationContext): PackageContribution;
13
+ export declare function typescriptConfigContribution(context: GenerationContext, definition?: PackageDefinition): PackageContribution;
14
+ export declare const typescriptConfigReplayAdapter: import("@ykdz/template-core/preset-definition").PackageContributionReplayAdapter;
@@ -1,6 +1,8 @@
1
+ import { definePackageContributionReplayAdapter, } from "#template-core/preset-definition";
1
2
  import { templateSources } from "../template-sources.js";
3
+ const typescriptConfigPackageReplacement = "TYPESCRIPT_CONFIG_PACKAGE";
2
4
  export function typescriptConfigPackageName(context) {
3
- return `@${context.scope}/typescript-config`;
5
+ return context.foundationPackages.typescriptConfiguration.name;
4
6
  }
5
7
  export function typescriptConfigPackageDefinition(context) {
6
8
  return {
@@ -16,18 +18,16 @@ export function typescriptConfigSourceOperation(options) {
16
18
  from: options.from,
17
19
  to: options.to,
18
20
  replacements: {
19
- TYPESCRIPT_CONFIG_PACKAGE: typescriptConfigPackageName(options.context),
21
+ [typescriptConfigPackageReplacement]: typescriptConfigPackageName(options.context),
20
22
  },
21
23
  };
22
24
  }
23
- export function typescriptConfigContribution(context) {
24
- const definition = typescriptConfigPackageDefinition(context);
25
+ export function typescriptConfigContribution(context, definition = typescriptConfigPackageDefinition(context)) {
25
26
  return {
26
27
  definition,
27
28
  exposure: { exports: {}, imports: {} },
28
29
  manifest: {
29
30
  name: definition.name,
30
- version: "0.0.0",
31
31
  private: true,
32
32
  files: ["base.json"],
33
33
  scripts: {
@@ -68,3 +68,7 @@ export function typescriptConfigContribution(context) {
68
68
  },
69
69
  };
70
70
  }
71
+ export const typescriptConfigReplayAdapter = definePackageContributionReplayAdapter({
72
+ identity: "typescript-config",
73
+ replay: ({ context, packageDefinition }) => typescriptConfigContribution(context, packageDefinition),
74
+ });
@@ -1,6 +1,6 @@
1
1
  import type { PackageContribution } from "#template-core/package-contribution";
2
2
  import type { GenerationContext } from "#template-core/preset-definition";
3
- import type { PackageDefinition } from "#template-core/project-blueprint-v2";
3
+ import type { PackageDefinition } from "#template-core/project-blueprint";
4
4
  import type { RenderOperation } from "#template-core/renderer";
5
5
  /** Vue's tooling peers need these repository policy overrides, never Core defaults. */
6
6
  export declare const vuePnpmDependencyOverrides: {
@@ -76,7 +76,6 @@ export function vueApplicationDevelopmentContainerToolLayers() {
76
76
  export function vueApplicationManifest(options) {
77
77
  return {
78
78
  name: options.definition.name,
79
- version: "0.0.0",
80
79
  private: true,
81
80
  type: "module",
82
81
  ...vueApplicationExposure,
@@ -1,2 +1,31 @@
1
- import type { BuiltInPresetDefinition } from "#template-core/preset-definition";
2
- export declare const tsCliDefinition: BuiltInPresetDefinition;
1
+ import { type GenerationContext } from "#template-core/preset-definition";
2
+ export declare const tsCliDefinition: {
3
+ metadata: {
4
+ name: string;
5
+ title: string;
6
+ description: string;
7
+ };
8
+ source: import("@ykdz/template-core/renderer").TemplateSourceHandle;
9
+ plannerSourceFile: string;
10
+ packageContributionReplayAdapters: import("@ykdz/template-core/preset-definition").PackageContributionReplayAdapter[];
11
+ initialPrimaryPackage: {
12
+ defaultLeafName: string;
13
+ role: "cli-tool";
14
+ defaultPackagePath: ({ packageLeafName }: {
15
+ readonly packageLeafName: string;
16
+ }) => string;
17
+ planInitialContribution({ context, resolvedPackageIdentity }: {
18
+ readonly context: GenerationContext;
19
+ readonly resolvedPackageIdentity: import("@ykdz/template-core/preset-definition").ResolvedPrimaryPackageIdentity;
20
+ }): import("@ykdz/template-core/preset-definition").PlannedPackageContribution;
21
+ };
22
+ defaultPackagePath({ packageLeafName }: {
23
+ readonly context: GenerationContext;
24
+ readonly packageLeafName: string;
25
+ }): string;
26
+ planPackageAddition({ context, packageLeafName, packagePath }: {
27
+ readonly context: GenerationContext;
28
+ readonly packageLeafName: string;
29
+ readonly packagePath: string;
30
+ }): import("@ykdz/template-core/preset-definition").PlannedPackageContribution;
31
+ };
@@ -1,6 +1,10 @@
1
1
  import { fileURLToPath } from "node:url";
2
+ import { definePackageContributionReplayAdapter, } from "#template-core/preset-definition";
2
3
  import { typescriptConfigSourceOperation } from "../shared/typescript.js";
3
4
  import { templateSources } from "../template-sources.js";
5
+ function packagePathForLeaf(packageLeafName) {
6
+ return `packages/${packageLeafName}`;
7
+ }
4
8
  function packageScripts() {
5
9
  return {
6
10
  "format:check": "oxfmt --list-different --config ../../oxfmt.config.ts .",
@@ -16,27 +20,12 @@ function packageScripts() {
16
20
  };
17
21
  }
18
22
  function cliContribution(options) {
19
- const definition = {
20
- name: `@${options.context.scope}/${options.packageLeafName}`,
23
+ const definition = options.packageDefinition ?? {
24
+ name: `@${options.context.defaultPackageScope}/${options.packageLeafName}`,
21
25
  path: options.packagePath,
22
26
  role: "cli-tool",
23
27
  };
24
- const exposure = {
25
- exports: {
26
- ".": {
27
- source: "./src/main.ts",
28
- types: "./dist/main.d.ts",
29
- default: "./dist/main.js",
30
- },
31
- },
32
- imports: {
33
- "#main": {
34
- source: "./src/main.ts",
35
- types: "./src/main.ts",
36
- default: "./dist/main.js",
37
- },
38
- },
39
- };
28
+ const exposure = { exports: {}, imports: {} };
40
29
  const operations = [
41
30
  {
42
31
  kind: "writeJson",
@@ -71,16 +60,14 @@ function cliContribution(options) {
71
60
  {
72
61
  kind: "copyFile",
73
62
  source: templateSources.tsCli,
74
- from: "src/main.ts",
75
- to: `${definition.path}/src/main.ts`,
63
+ from: "src/cli-command-identity.ts",
64
+ to: `${definition.path}/src/cli-command-identity.ts`,
76
65
  },
77
66
  {
78
- kind: "replaceAnchors",
79
- path: `${definition.path}/src/main.ts`,
80
- language: "typescript",
81
- replacements: {
82
- "cli-command-name": `const commandName = ${JSON.stringify(options.packageLeafName)};`,
83
- },
67
+ kind: "copyFile",
68
+ source: templateSources.tsCli,
69
+ from: "src/main.ts",
70
+ to: `${definition.path}/src/main.ts`,
84
71
  },
85
72
  {
86
73
  kind: "copyFile",
@@ -91,16 +78,14 @@ function cliContribution(options) {
91
78
  {
92
79
  kind: "copyFile",
93
80
  source: templateSources.tsCli,
94
- from: "test/integration/command.test.ts",
95
- to: `${definition.path}/test/integration/command.test.ts`,
81
+ from: "test/unit/cli-command-identity.test.ts",
82
+ to: `${definition.path}/test/unit/cli-command-identity.test.ts`,
96
83
  },
97
84
  {
98
- kind: "replaceAnchors",
99
- path: `${definition.path}/test/integration/command.test.ts`,
100
- language: "typescript",
101
- replacements: {
102
- "cli-test-command-name": `commandName = ${JSON.stringify(options.packageLeafName)};`,
103
- },
85
+ kind: "copyFile",
86
+ source: templateSources.tsCli,
87
+ from: "test/integration/command.test.ts",
88
+ to: `${definition.path}/test/integration/command.test.ts`,
104
89
  },
105
90
  {
106
91
  kind: "copyFile",
@@ -126,12 +111,10 @@ function cliContribution(options) {
126
111
  exposure,
127
112
  manifest: {
128
113
  name: definition.name,
129
- version: "0.0.0",
130
- publishConfig: { access: "public" },
114
+ private: true,
131
115
  files: ["dist"],
132
116
  type: "module",
133
117
  bin: { [options.packageLeafName]: "./dist/cli.js" },
134
- ...exposure,
135
118
  scripts: packageScripts(),
136
119
  dependencies: { commander: "catalog:" },
137
120
  devDependencies: {
@@ -147,8 +130,12 @@ function cliContribution(options) {
147
130
  operations,
148
131
  environmentNeeds: [],
149
132
  foundation: {
133
+ ...(options.publicationCandidate
134
+ ? { npmPublication: { kind: "public-cli-candidate" } }
135
+ : {}),
150
136
  toolchains: {},
151
137
  editorCapabilities: ["oxc-format-lint"],
138
+ typescriptConfigurationPackage: { dependency: "required" },
152
139
  dependencyMaintenance: {
153
140
  ecosystems: ["npm", "github-actions", "docker"],
154
141
  interval: "weekly",
@@ -156,37 +143,71 @@ function cliContribution(options) {
156
143
  },
157
144
  };
158
145
  }
146
+ const cliPublicationCandidateReplayAdapter = definePackageContributionReplayAdapter({
147
+ identity: "cli-publication-candidate",
148
+ replay: ({ context, packageDefinition, packageLeafName, planningContribution, }) => {
149
+ if (planningContribution !== "planInitialization") {
150
+ throw new Error("cli-publication-candidate replay identity requires planInitialization provenance");
151
+ }
152
+ return cliContribution({
153
+ context,
154
+ packageLeafName,
155
+ packagePath: packageDefinition.path,
156
+ packageDefinition,
157
+ publicationCandidate: true,
158
+ });
159
+ },
160
+ });
161
+ const cliPackageAdditionReplayAdapter = definePackageContributionReplayAdapter({
162
+ identity: "cli-package-addition",
163
+ replay: ({ context, packageDefinition, packageLeafName, planningContribution, }) => {
164
+ if (planningContribution !== "planPackageAddition") {
165
+ throw new Error("cli-package-addition replay identity requires planPackageAddition provenance");
166
+ }
167
+ return cliContribution({
168
+ context,
169
+ packageLeafName,
170
+ packagePath: packageDefinition.path,
171
+ packageDefinition,
172
+ publicationCandidate: false,
173
+ });
174
+ },
175
+ });
159
176
  export const tsCliDefinition = {
160
177
  metadata: {
161
178
  name: "ts-cli",
162
179
  title: "TypeScript CLI",
163
- description: "Publishable TypeScript command-line package.",
180
+ description: "TypeScript command-line package.",
164
181
  },
165
182
  source: templateSources.tsCli,
166
183
  plannerSourceFile: fileURLToPath(import.meta.url),
167
- blueprint(context) {
168
- return {
169
- schemaVersion: 2,
170
- packages: [
171
- cliContribution({
172
- context,
173
- packageLeafName: context.projectName,
174
- packagePath: `packages/${context.projectName}`,
175
- }).definition,
176
- ],
177
- };
178
- },
179
- planInitialization(context) {
180
- return cliContribution({
181
- context,
182
- packageLeafName: context.projectName,
183
- packagePath: `packages/${context.projectName}`,
184
- });
184
+ packageContributionReplayAdapters: [
185
+ cliPublicationCandidateReplayAdapter,
186
+ cliPackageAdditionReplayAdapter,
187
+ ],
188
+ initialPrimaryPackage: {
189
+ defaultLeafName: "cli",
190
+ role: "cli-tool",
191
+ defaultPackagePath: ({ packageLeafName }) => packagePathForLeaf(packageLeafName),
192
+ planInitialContribution({ context, resolvedPackageIdentity }) {
193
+ return cliPublicationCandidateReplayAdapter.identify(cliContribution({
194
+ context,
195
+ packageLeafName: resolvedPackageIdentity.leafName,
196
+ packagePath: resolvedPackageIdentity.definition.path,
197
+ packageDefinition: resolvedPackageIdentity.definition,
198
+ publicationCandidate: true,
199
+ }));
200
+ },
185
201
  },
186
202
  defaultPackagePath({ packageLeafName }) {
187
- return `packages/${packageLeafName}`;
203
+ return packagePathForLeaf(packageLeafName);
188
204
  },
189
205
  planPackageAddition({ context, packageLeafName, packagePath }) {
190
- return cliContribution({ context, packageLeafName, packagePath });
206
+ return cliPackageAdditionReplayAdapter.identify(cliContribution({
207
+ context,
208
+ packageLeafName,
209
+ packagePath,
210
+ publicationCandidate: false,
211
+ }));
191
212
  },
192
213
  };