@nekostack/schema 1.0.0

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 (214) hide show
  1. package/CHANGELOG.md +422 -0
  2. package/LICENSE +202 -0
  3. package/README.md +656 -0
  4. package/dist/src/builders/array.d.ts +12 -0
  5. package/dist/src/builders/array.d.ts.map +1 -0
  6. package/dist/src/builders/array.js +29 -0
  7. package/dist/src/builders/array.js.map +1 -0
  8. package/dist/src/builders/object.d.ts +62 -0
  9. package/dist/src/builders/object.d.ts.map +1 -0
  10. package/dist/src/builders/object.js +263 -0
  11. package/dist/src/builders/object.js.map +1 -0
  12. package/dist/src/builders/primitives.d.ts +37 -0
  13. package/dist/src/builders/primitives.d.ts.map +1 -0
  14. package/dist/src/builders/primitives.js +125 -0
  15. package/dist/src/builders/primitives.js.map +1 -0
  16. package/dist/src/builders/s.d.ts +27 -0
  17. package/dist/src/builders/s.d.ts.map +1 -0
  18. package/dist/src/builders/s.js +39 -0
  19. package/dist/src/builders/s.js.map +1 -0
  20. package/dist/src/builders/schema.d.ts +70 -0
  21. package/dist/src/builders/schema.d.ts.map +1 -0
  22. package/dist/src/builders/schema.js +98 -0
  23. package/dist/src/builders/schema.js.map +1 -0
  24. package/dist/src/cli-integration.d.ts +43 -0
  25. package/dist/src/cli-integration.d.ts.map +1 -0
  26. package/dist/src/cli-integration.js +48 -0
  27. package/dist/src/cli-integration.js.map +1 -0
  28. package/dist/src/errors/issue.d.ts +34 -0
  29. package/dist/src/errors/issue.d.ts.map +1 -0
  30. package/dist/src/errors/issue.js +89 -0
  31. package/dist/src/errors/issue.js.map +1 -0
  32. package/dist/src/generators/errors.d.ts +31 -0
  33. package/dist/src/generators/errors.d.ts.map +1 -0
  34. package/dist/src/generators/errors.js +34 -0
  35. package/dist/src/generators/errors.js.map +1 -0
  36. package/dist/src/generators/header.d.ts +42 -0
  37. package/dist/src/generators/header.d.ts.map +1 -0
  38. package/dist/src/generators/header.js +43 -0
  39. package/dist/src/generators/header.js.map +1 -0
  40. package/dist/src/generators/json-schema-meta.d.ts +36 -0
  41. package/dist/src/generators/json-schema-meta.d.ts.map +1 -0
  42. package/dist/src/generators/json-schema-meta.js +35 -0
  43. package/dist/src/generators/json-schema-meta.js.map +1 -0
  44. package/dist/src/generators/json-schema.d.ts +26 -0
  45. package/dist/src/generators/json-schema.d.ts.map +1 -0
  46. package/dist/src/generators/json-schema.js +88 -0
  47. package/dist/src/generators/json-schema.js.map +1 -0
  48. package/dist/src/generators/openapi.d.ts +33 -0
  49. package/dist/src/generators/openapi.d.ts.map +1 -0
  50. package/dist/src/generators/openapi.js +61 -0
  51. package/dist/src/generators/openapi.js.map +1 -0
  52. package/dist/src/generators/schema-fragment.d.ts +55 -0
  53. package/dist/src/generators/schema-fragment.d.ts.map +1 -0
  54. package/dist/src/generators/schema-fragment.js +253 -0
  55. package/dist/src/generators/schema-fragment.js.map +1 -0
  56. package/dist/src/generators/ts.d.ts +19 -0
  57. package/dist/src/generators/ts.d.ts.map +1 -0
  58. package/dist/src/generators/ts.js +252 -0
  59. package/dist/src/generators/ts.js.map +1 -0
  60. package/dist/src/generators/types.d.ts +96 -0
  61. package/dist/src/generators/types.d.ts.map +1 -0
  62. package/dist/src/generators/types.js +10 -0
  63. package/dist/src/generators/types.js.map +1 -0
  64. package/dist/src/generators/version.d.ts +11 -0
  65. package/dist/src/generators/version.d.ts.map +1 -0
  66. package/dist/src/generators/version.js +11 -0
  67. package/dist/src/generators/version.js.map +1 -0
  68. package/dist/src/generators/zod-mapping.d.ts +90 -0
  69. package/dist/src/generators/zod-mapping.d.ts.map +1 -0
  70. package/dist/src/generators/zod-mapping.js +174 -0
  71. package/dist/src/generators/zod-mapping.js.map +1 -0
  72. package/dist/src/generators/zod.d.ts +17 -0
  73. package/dist/src/generators/zod.d.ts.map +1 -0
  74. package/dist/src/generators/zod.js +118 -0
  75. package/dist/src/generators/zod.js.map +1 -0
  76. package/dist/src/index.d.ts +21 -0
  77. package/dist/src/index.d.ts.map +1 -0
  78. package/dist/src/index.js +43 -0
  79. package/dist/src/index.js.map +1 -0
  80. package/dist/src/ir/hash.d.ts +19 -0
  81. package/dist/src/ir/hash.d.ts.map +1 -0
  82. package/dist/src/ir/hash.js +22 -0
  83. package/dist/src/ir/hash.js.map +1 -0
  84. package/dist/src/ir/nodes.d.ts +121 -0
  85. package/dist/src/ir/nodes.d.ts.map +1 -0
  86. package/dist/src/ir/nodes.js +14 -0
  87. package/dist/src/ir/nodes.js.map +1 -0
  88. package/dist/src/ir/serialize.d.ts +8 -0
  89. package/dist/src/ir/serialize.d.ts.map +1 -0
  90. package/dist/src/ir/serialize.js +23 -0
  91. package/dist/src/ir/serialize.js.map +1 -0
  92. package/dist/src/migrations/build-migration-registry.d.ts +46 -0
  93. package/dist/src/migrations/build-migration-registry.d.ts.map +1 -0
  94. package/dist/src/migrations/build-migration-registry.js +134 -0
  95. package/dist/src/migrations/build-migration-registry.js.map +1 -0
  96. package/dist/src/migrations/handlers/list.d.ts +35 -0
  97. package/dist/src/migrations/handlers/list.d.ts.map +1 -0
  98. package/dist/src/migrations/handlers/list.js +55 -0
  99. package/dist/src/migrations/handlers/list.js.map +1 -0
  100. package/dist/src/migrations/handlers/plan.d.ts +26 -0
  101. package/dist/src/migrations/handlers/plan.d.ts.map +1 -0
  102. package/dist/src/migrations/handlers/plan.js +28 -0
  103. package/dist/src/migrations/handlers/plan.js.map +1 -0
  104. package/dist/src/migrations/handlers/stub.d.ts +22 -0
  105. package/dist/src/migrations/handlers/stub.d.ts.map +1 -0
  106. package/dist/src/migrations/handlers/stub.js +24 -0
  107. package/dist/src/migrations/handlers/stub.js.map +1 -0
  108. package/dist/src/migrations/handlers/verify.d.ts +25 -0
  109. package/dist/src/migrations/handlers/verify.d.ts.map +1 -0
  110. package/dist/src/migrations/handlers/verify.js +27 -0
  111. package/dist/src/migrations/handlers/verify.js.map +1 -0
  112. package/dist/src/migrations/parse-provenance.d.ts +78 -0
  113. package/dist/src/migrations/parse-provenance.d.ts.map +1 -0
  114. package/dist/src/migrations/parse-provenance.js +157 -0
  115. package/dist/src/migrations/parse-provenance.js.map +1 -0
  116. package/dist/src/migrations/plan-migration.d.ts +50 -0
  117. package/dist/src/migrations/plan-migration.d.ts.map +1 -0
  118. package/dist/src/migrations/plan-migration.js +256 -0
  119. package/dist/src/migrations/plan-migration.js.map +1 -0
  120. package/dist/src/migrations/stub.d.ts +55 -0
  121. package/dist/src/migrations/stub.d.ts.map +1 -0
  122. package/dist/src/migrations/stub.js +201 -0
  123. package/dist/src/migrations/stub.js.map +1 -0
  124. package/dist/src/migrations/types.d.ts +297 -0
  125. package/dist/src/migrations/types.d.ts.map +1 -0
  126. package/dist/src/migrations/types.js +28 -0
  127. package/dist/src/migrations/types.js.map +1 -0
  128. package/dist/src/migrations/verify-provenance.d.ts +46 -0
  129. package/dist/src/migrations/verify-provenance.d.ts.map +1 -0
  130. package/dist/src/migrations/verify-provenance.js +158 -0
  131. package/dist/src/migrations/verify-provenance.js.map +1 -0
  132. package/dist/src/registry/build-registry.d.ts +65 -0
  133. package/dist/src/registry/build-registry.d.ts.map +1 -0
  134. package/dist/src/registry/build-registry.js +172 -0
  135. package/dist/src/registry/build-registry.js.map +1 -0
  136. package/dist/src/registry/diff.d.ts +25 -0
  137. package/dist/src/registry/diff.d.ts.map +1 -0
  138. package/dist/src/registry/diff.js +497 -0
  139. package/dist/src/registry/diff.js.map +1 -0
  140. package/dist/src/registry/handlers/check.d.ts +57 -0
  141. package/dist/src/registry/handlers/check.d.ts.map +1 -0
  142. package/dist/src/registry/handlers/check.js +181 -0
  143. package/dist/src/registry/handlers/check.js.map +1 -0
  144. package/dist/src/registry/handlers/diff.d.ts +33 -0
  145. package/dist/src/registry/handlers/diff.d.ts.map +1 -0
  146. package/dist/src/registry/handlers/diff.js +61 -0
  147. package/dist/src/registry/handlers/diff.js.map +1 -0
  148. package/dist/src/registry/handlers/generate.d.ts +87 -0
  149. package/dist/src/registry/handlers/generate.d.ts.map +1 -0
  150. package/dist/src/registry/handlers/generate.js +223 -0
  151. package/dist/src/registry/handlers/generate.js.map +1 -0
  152. package/dist/src/registry/handlers/list.d.ts +36 -0
  153. package/dist/src/registry/handlers/list.d.ts.map +1 -0
  154. package/dist/src/registry/handlers/list.js +84 -0
  155. package/dist/src/registry/handlers/list.js.map +1 -0
  156. package/dist/src/registry/parse-provenance.d.ts +63 -0
  157. package/dist/src/registry/parse-provenance.d.ts.map +1 -0
  158. package/dist/src/registry/parse-provenance.js +182 -0
  159. package/dist/src/registry/parse-provenance.js.map +1 -0
  160. package/dist/src/registry/source-hash.d.ts +28 -0
  161. package/dist/src/registry/source-hash.d.ts.map +1 -0
  162. package/dist/src/registry/source-hash.js +32 -0
  163. package/dist/src/registry/source-hash.js.map +1 -0
  164. package/dist/src/registry/types.d.ts +185 -0
  165. package/dist/src/registry/types.d.ts.map +1 -0
  166. package/dist/src/registry/types.js +22 -0
  167. package/dist/src/registry/types.js.map +1 -0
  168. package/dist/src/runtime/compile.d.ts +38 -0
  169. package/dist/src/runtime/compile.d.ts.map +1 -0
  170. package/dist/src/runtime/compile.js +45 -0
  171. package/dist/src/runtime/compile.js.map +1 -0
  172. package/dist/src/runtime/errors.d.ts +25 -0
  173. package/dist/src/runtime/errors.d.ts.map +1 -0
  174. package/dist/src/runtime/errors.js +43 -0
  175. package/dist/src/runtime/errors.js.map +1 -0
  176. package/dist/src/runtime/normalize-issues.d.ts +65 -0
  177. package/dist/src/runtime/normalize-issues.d.ts.map +1 -0
  178. package/dist/src/runtime/normalize-issues.js +208 -0
  179. package/dist/src/runtime/normalize-issues.js.map +1 -0
  180. package/dist/src/runtime/parse.d.ts +62 -0
  181. package/dist/src/runtime/parse.d.ts.map +1 -0
  182. package/dist/src/runtime/parse.js +107 -0
  183. package/dist/src/runtime/parse.js.map +1 -0
  184. package/dist/src/runtime/strip-defaults.d.ts +51 -0
  185. package/dist/src/runtime/strip-defaults.d.ts.map +1 -0
  186. package/dist/src/runtime/strip-defaults.js +81 -0
  187. package/dist/src/runtime/strip-defaults.js.map +1 -0
  188. package/dist/src/runtime/zod-compile.d.ts +27 -0
  189. package/dist/src/runtime/zod-compile.d.ts.map +1 -0
  190. package/dist/src/runtime/zod-compile.js +92 -0
  191. package/dist/src/runtime/zod-compile.js.map +1 -0
  192. package/dist/src/types.d.ts +116 -0
  193. package/dist/src/types.d.ts.map +1 -0
  194. package/dist/src/types.js +2 -0
  195. package/dist/src/types.js.map +1 -0
  196. package/docs/ABSENCE_SEMANTICS.md +37 -0
  197. package/docs/BENCHMARKS.md +64 -0
  198. package/docs/COMPOSITION.md +206 -0
  199. package/docs/DIFF_CLASSIFICATION.md +137 -0
  200. package/docs/EXAMPLES.md +221 -0
  201. package/docs/HEADER_FORMAT.md +66 -0
  202. package/docs/INVARIANTS.md +58 -0
  203. package/docs/IR_CONTRACT.md +67 -0
  204. package/docs/ISSUE_CODES.md +99 -0
  205. package/docs/JSON_SCHEMA_MAPPING.md +149 -0
  206. package/docs/MIGRATIONS.md +406 -0
  207. package/docs/MIGRATION_GUIDE.md +150 -0
  208. package/docs/OPENAPI_MAPPING.md +66 -0
  209. package/docs/REGISTRY.md +336 -0
  210. package/docs/RUNTIME.md +279 -0
  211. package/docs/SCOPE.md +119 -0
  212. package/docs/USAGE.md +376 -0
  213. package/docs/ZOD_MODIFIER_ORDERING.md +77 -0
  214. package/package.json +45 -0
@@ -0,0 +1,157 @@
1
+ /**
2
+ * Provenance parser for `*.migration.ts` files (v0.8 Step 2).
3
+ *
4
+ * Reads the migration-header metadata out of an authored migration
5
+ * file so `buildMigrationRegistry` can index by
6
+ * `(schemaId, fromVersion, toVersion)` and `verifyMigrationProvenance`
7
+ * can compare the recorded hashes against the current schema
8
+ * registry. Migration files use **JSDoc-only** carriers — there is
9
+ * no JSON variant because migrations are TypeScript modules, not
10
+ * data documents.
11
+ *
12
+ * Expected header shape (generated by the v0.8 stub generator;
13
+ * humans edit the body, not the header):
14
+ *
15
+ * /**
16
+ * * @migration by @nekostack/schema
17
+ * * schemaId: com.x.User
18
+ * * fromVersion: 1.0.0
19
+ * * toVersion: 2.0.0
20
+ * * fromIrHash: sha256:<64-hex>
21
+ * * toIrHash: sha256:<64-hex>
22
+ * * fromSourceHash: sha256:<64-hex>
23
+ * * toSourceHash: sha256:<64-hex>
24
+ * * generator: neko-schema-migrate-stub
25
+ * * generatorVersion: @nekostack/schema@0.8.0
26
+ * *
27
+ * * DO NOT REMOVE THE HEADER. Authors EDIT THE BODY.
28
+ * * /
29
+ *
30
+ * The function is **pure**: no `fs.*`, no `import()`, no path
31
+ * argument, no module evaluation. The CLI reads the migration file
32
+ * text from disk and hands it in; this module parses and returns.
33
+ * Master plan Decision #1 boundary applies.
34
+ *
35
+ * **Fail-loud, never silent** (v0.8 Round-2 lock — intentional
36
+ * departure from v0.7 Decision #5). A `.migration.ts` file exists
37
+ * specifically to declare a `(schemaId, fromVersion, toVersion)`
38
+ * transition. Missing or malformed provenance is treated as an
39
+ * invalid declaration, not a "skip and continue" condition.
40
+ * Malformed input surfaces as `Result<...>` failure with one
41
+ * `integrity_error` `Issue` whose `metadata.reason` records the
42
+ * sub-mode (`missing_migration_provenance`, `missing_field`,
43
+ * `malformed_hash`, `malformed_field`, `unknown_format`).
44
+ *
45
+ * The shape of `reason` deliberately overlaps with the v0.7
46
+ * provenance-parser reasons where the failure mode is the same —
47
+ * a missing JSDoc block reads identically in both worlds, so
48
+ * `missing_provenance` would have worked, but the migration-specific
49
+ * `missing_migration_provenance` name lets downstream consumers
50
+ * disambiguate without parsing `message`.
51
+ */
52
+ const SHA256_PATTERN = /^sha256:[0-9a-f]{64}$/;
53
+ /**
54
+ * Parse the migration JSDoc header out of a migration file's text
55
+ * content. Returns `Result.success` with the parsed fields on a
56
+ * valid header, `Result.failure` with an `integrity_error` `Issue`
57
+ * on every failure mode.
58
+ */
59
+ export function parseMigrationProvenanceFromText(content) {
60
+ const trimmed = content.trimStart();
61
+ if (!trimmed.startsWith("/**")) {
62
+ return fail("unknown_format", "Migration file does not start with a `/** ... */` JSDoc header.");
63
+ }
64
+ return parseJsdocHeader(content);
65
+ }
66
+ // =============================================================================
67
+ // JSDoc header parsing
68
+ // =============================================================================
69
+ const JSDOC_BLOCK = /\/\*\*([\s\S]*?)\*\//;
70
+ const JSDOC_FIELD = /^\s*\*\s+(\w+):\s*(.+?)\s*$/;
71
+ function parseJsdocHeader(content) {
72
+ const block = JSDOC_BLOCK.exec(content);
73
+ if (!block) {
74
+ return fail("missing_migration_provenance", "No `/** ... */` JSDoc header found at the top of the migration file.");
75
+ }
76
+ const fields = new Map();
77
+ for (const line of block[1].split(/\r?\n/)) {
78
+ const m = JSDOC_FIELD.exec(line);
79
+ if (!m)
80
+ continue;
81
+ fields.set(m[1], m[2]);
82
+ }
83
+ return assembleMigrationProvenance(fields);
84
+ }
85
+ // =============================================================================
86
+ // Field assembly + validation
87
+ // =============================================================================
88
+ const REQUIRED_FIELDS = [
89
+ "generator",
90
+ "generatorVersion",
91
+ "schemaId",
92
+ "fromVersion",
93
+ "toVersion",
94
+ "fromIrHash",
95
+ "toIrHash",
96
+ "fromSourceHash",
97
+ "toSourceHash",
98
+ ];
99
+ const HASH_FIELDS = [
100
+ "fromIrHash",
101
+ "toIrHash",
102
+ "fromSourceHash",
103
+ "toSourceHash",
104
+ ];
105
+ function assembleMigrationProvenance(fields) {
106
+ // 1. Every required field must be present.
107
+ for (const name of REQUIRED_FIELDS) {
108
+ if (fields.get(name) === undefined) {
109
+ return fail("missing_field", `Migration provenance is missing required field \`${name}\`.`);
110
+ }
111
+ }
112
+ // 2. String-shape fields must be non-empty (the JSDoc regex
113
+ // already rejects whitespace-only values, but an empty value
114
+ // after a colon could still slip through on a malformed line —
115
+ // treat that as `malformed_field`).
116
+ for (const name of REQUIRED_FIELDS) {
117
+ const value = fields.get(name);
118
+ if (value.length === 0) {
119
+ return fail("malformed_field", `Migration provenance field \`${name}\` is empty.`);
120
+ }
121
+ }
122
+ // 3. Every hash field must match the sha256 shape.
123
+ for (const name of HASH_FIELDS) {
124
+ const value = fields.get(name);
125
+ if (!SHA256_PATTERN.test(value)) {
126
+ return fail("malformed_hash", `Migration provenance \`${name}\` must match \`sha256:<64 hex>\`; got "${value}".`);
127
+ }
128
+ }
129
+ return {
130
+ success: true,
131
+ data: {
132
+ generator: fields.get("generator"),
133
+ generatorVersion: fields.get("generatorVersion"),
134
+ schemaId: fields.get("schemaId"),
135
+ fromVersion: fields.get("fromVersion"),
136
+ toVersion: fields.get("toVersion"),
137
+ fromIrHash: fields.get("fromIrHash"),
138
+ toIrHash: fields.get("toIrHash"),
139
+ fromSourceHash: fields.get("fromSourceHash"),
140
+ toSourceHash: fields.get("toSourceHash"),
141
+ },
142
+ };
143
+ }
144
+ // =============================================================================
145
+ // Failure helper
146
+ // =============================================================================
147
+ function fail(reason, message) {
148
+ const issue = {
149
+ code: "integrity_error",
150
+ path: [],
151
+ message,
152
+ severity: "error",
153
+ metadata: { reason },
154
+ };
155
+ return { success: false, issues: [issue] };
156
+ }
157
+ //# sourceMappingURL=parse-provenance.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse-provenance.js","sourceRoot":"","sources":["../../../src/migrations/parse-provenance.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * `planMigration(opts)` — diff-aware migration planner (v0.8 Step 4).
3
+ *
4
+ * The v0.8 Round-3 lock: this primitive consumes BOTH the schema
5
+ * registry AND the migration registry. Without the schema registry
6
+ * it can't compute the diff that determines whether a missing
7
+ * migration is acceptable; without the migration registry it can't
8
+ * resolve a chain when one is required. The signature mirrors what
9
+ * the audit pinned in `PHASE_PLAN_v0.8.md`.
10
+ *
11
+ * Locked behavior (Round-3 contract — restated here so the
12
+ * implementation is easy to compare against the plan doc):
13
+ *
14
+ * 1. Resolve endpoints in `schemaRegistry`. If either is absent
15
+ * → `Result.failure` with `migration_missing_endpoint`. No
16
+ * diff is computed in this case.
17
+ * 2. Compute `diffNodes(from.schema.node, to.schema.node)`.
18
+ * `worstSeverity` is the max-severity over the change list
19
+ * (precedence `breaking > additive > cosmetic`; `null` when
20
+ * empty), exactly as `diffHandler` aggregates it in v0.7.
21
+ * 3. Look up the exact migration for `(schemaId, fromVersion,
22
+ * toVersion)` if any.
23
+ * 4. Dispatch on `worstSeverity`:
24
+ * - `null` / `"cosmetic"` → success with empty chain. If an
25
+ * exact migration exists for the pair, attach an
26
+ * `over_specified` `PlanNote`. The migration is NOT included
27
+ * in the chain — at this severity the diff says no
28
+ * transformation is needed.
29
+ * - `"additive"` → if an exact migration exists, include it
30
+ * in the chain. If not, success with empty chain plus an
31
+ * `additive_no_migration` note.
32
+ * - `"breaking"` → chain is **required**. Run DFS chain
33
+ * resolution over the schemaId's `from → to` adjacency map.
34
+ * 0 chains: `migration_not_found` (no migrations for the
35
+ * schemaId at all) or `migration_chain_broken` (some exist
36
+ * but can't bridge). 1 chain: success. 2+ chains:
37
+ * `migration_ambiguous_chain`.
38
+ *
39
+ * **Pure.** No `fs.*`, no `import()`, no `process.*`, no
40
+ * `console.*`. **Never invokes `migration.transform`** — chain
41
+ * resolution is structural; transform execution is v0.9+.
42
+ *
43
+ * `MigrationPlan.versionPath` always reflects the actual hop
44
+ * sequence: `[fromVersion, toVersion]` for empty chains;
45
+ * `[fromVersion, ...intermediateVersions, toVersion]` for non-empty
46
+ * chains derived from the chain entries.
47
+ */
48
+ import type { MigrationPlanOpts, MigrationPlanResult } from "./types.js";
49
+ export declare function planMigration(opts: MigrationPlanOpts): MigrationPlanResult;
50
+ //# sourceMappingURL=plan-migration.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan-migration.d.ts","sourceRoot":"","sources":["../../../src/migrations/plan-migration.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AAUH,OAAO,KAAK,EAGV,iBAAiB,EACjB,mBAAmB,EAGpB,MAAM,YAAY,CAAC;AAMpB,wBAAgB,aAAa,CAAC,IAAI,EAAE,iBAAiB,GAAG,mBAAmB,CAiG1E"}
@@ -0,0 +1,256 @@
1
+ /**
2
+ * `planMigration(opts)` — diff-aware migration planner (v0.8 Step 4).
3
+ *
4
+ * The v0.8 Round-3 lock: this primitive consumes BOTH the schema
5
+ * registry AND the migration registry. Without the schema registry
6
+ * it can't compute the diff that determines whether a missing
7
+ * migration is acceptable; without the migration registry it can't
8
+ * resolve a chain when one is required. The signature mirrors what
9
+ * the audit pinned in `PHASE_PLAN_v0.8.md`.
10
+ *
11
+ * Locked behavior (Round-3 contract — restated here so the
12
+ * implementation is easy to compare against the plan doc):
13
+ *
14
+ * 1. Resolve endpoints in `schemaRegistry`. If either is absent
15
+ * → `Result.failure` with `migration_missing_endpoint`. No
16
+ * diff is computed in this case.
17
+ * 2. Compute `diffNodes(from.schema.node, to.schema.node)`.
18
+ * `worstSeverity` is the max-severity over the change list
19
+ * (precedence `breaking > additive > cosmetic`; `null` when
20
+ * empty), exactly as `diffHandler` aggregates it in v0.7.
21
+ * 3. Look up the exact migration for `(schemaId, fromVersion,
22
+ * toVersion)` if any.
23
+ * 4. Dispatch on `worstSeverity`:
24
+ * - `null` / `"cosmetic"` → success with empty chain. If an
25
+ * exact migration exists for the pair, attach an
26
+ * `over_specified` `PlanNote`. The migration is NOT included
27
+ * in the chain — at this severity the diff says no
28
+ * transformation is needed.
29
+ * - `"additive"` → if an exact migration exists, include it
30
+ * in the chain. If not, success with empty chain plus an
31
+ * `additive_no_migration` note.
32
+ * - `"breaking"` → chain is **required**. Run DFS chain
33
+ * resolution over the schemaId's `from → to` adjacency map.
34
+ * 0 chains: `migration_not_found` (no migrations for the
35
+ * schemaId at all) or `migration_chain_broken` (some exist
36
+ * but can't bridge). 1 chain: success. 2+ chains:
37
+ * `migration_ambiguous_chain`.
38
+ *
39
+ * **Pure.** No `fs.*`, no `import()`, no `process.*`, no
40
+ * `console.*`. **Never invokes `migration.transform`** — chain
41
+ * resolution is structural; transform execution is v0.9+.
42
+ *
43
+ * `MigrationPlan.versionPath` always reflects the actual hop
44
+ * sequence: `[fromVersion, toVersion]` for empty chains;
45
+ * `[fromVersion, ...intermediateVersions, toVersion]` for non-empty
46
+ * chains derived from the chain entries.
47
+ */
48
+ import { findSchema } from "../registry/build-registry.js";
49
+ import { diffNodes } from "../registry/diff.js";
50
+ // =============================================================================
51
+ // Public entry
52
+ // =============================================================================
53
+ export function planMigration(opts) {
54
+ // 1. Resolve endpoints in the schema registry.
55
+ const fromEntry = findSchema(opts.schemaRegistry, opts.schemaId, opts.fromVersion);
56
+ const toEntry = findSchema(opts.schemaRegistry, opts.schemaId, opts.toVersion);
57
+ if (fromEntry === undefined || toEntry === undefined) {
58
+ return failure(missingEndpointIssue(opts.schemaId, opts.fromVersion, opts.toVersion, fromEntry === undefined, toEntry === undefined));
59
+ }
60
+ // 2. Compute the endpoint-to-endpoint diff and worst severity.
61
+ const changes = diffNodes(fromEntry.schema.node, toEntry.schema.node);
62
+ const worstSeverity = computeWorstSeverity(changes);
63
+ // 3. Look up the exact-pair migration (if any) for the
64
+ // over_specified / additive-with-migration branches.
65
+ const exact = findExactMigration(opts.migrationRegistry, opts.schemaId, opts.fromVersion, opts.toVersion);
66
+ // 4. Dispatch on severity.
67
+ if (worstSeverity === null || worstSeverity === "cosmetic") {
68
+ const notes = exact !== undefined ? [{ kind: "over_specified", migration: exact }] : [];
69
+ return success({
70
+ schemaId: opts.schemaId,
71
+ chain: [],
72
+ versionPath: [opts.fromVersion, opts.toVersion],
73
+ worstSeverity,
74
+ notes,
75
+ });
76
+ }
77
+ if (worstSeverity === "additive") {
78
+ if (exact !== undefined) {
79
+ return success({
80
+ schemaId: opts.schemaId,
81
+ chain: [exact],
82
+ versionPath: [opts.fromVersion, opts.toVersion],
83
+ worstSeverity,
84
+ notes: [],
85
+ });
86
+ }
87
+ return success({
88
+ schemaId: opts.schemaId,
89
+ chain: [],
90
+ versionPath: [opts.fromVersion, opts.toVersion],
91
+ worstSeverity,
92
+ notes: [{ kind: "additive_no_migration", worstSeverity }],
93
+ });
94
+ }
95
+ // worstSeverity === "breaking" — chain is required.
96
+ const adjacency = opts.migrationRegistry.get(opts.schemaId);
97
+ const noMigrationsForSchema = adjacency === undefined || adjacency.size === 0;
98
+ if (noMigrationsForSchema) {
99
+ return failure(notFoundIssue(opts.schemaId, opts.fromVersion, opts.toVersion));
100
+ }
101
+ const chains = enumerateChains(adjacency, opts.fromVersion, opts.toVersion);
102
+ if (chains.length === 0) {
103
+ return failure(chainBrokenIssue(opts.schemaId, opts.fromVersion, opts.toVersion));
104
+ }
105
+ if (chains.length > 1) {
106
+ return failure(ambiguousChainIssue(opts.schemaId, opts.fromVersion, opts.toVersion, chains));
107
+ }
108
+ const chain = chains[0];
109
+ return success({
110
+ schemaId: opts.schemaId,
111
+ chain,
112
+ versionPath: versionPathFromChain(opts.fromVersion, chain),
113
+ worstSeverity,
114
+ notes: [],
115
+ });
116
+ }
117
+ // =============================================================================
118
+ // Helpers — registry lookups
119
+ // =============================================================================
120
+ function findExactMigration(registry, schemaId, fromVersion, toVersion) {
121
+ return registry.get(schemaId)?.get(fromVersion)?.get(toVersion);
122
+ }
123
+ // =============================================================================
124
+ // Helpers — worstSeverity (same precedence as v0.7 diffHandler)
125
+ // =============================================================================
126
+ const SEVERITY_RANK = {
127
+ cosmetic: 0,
128
+ additive: 1,
129
+ breaking: 2,
130
+ };
131
+ function computeWorstSeverity(changes) {
132
+ if (changes.length === 0)
133
+ return null;
134
+ let worst = "cosmetic";
135
+ for (const c of changes) {
136
+ if (SEVERITY_RANK[c.severity] > SEVERITY_RANK[worst]) {
137
+ worst = c.severity;
138
+ }
139
+ }
140
+ return worst;
141
+ }
142
+ /**
143
+ * Enumerate every simple path of migration entries from `start` to
144
+ * `end` over the schemaId's adjacency map. "Simple" = no version
145
+ * is visited twice within a single chain (no cycles).
146
+ *
147
+ * v0.8 doesn't cap the number of enumerated chains — but it stops
148
+ * walking each path at the first revisit of any version it already
149
+ * entered on that path. The graph is the consumer's authored
150
+ * migrations, so practical depth is small.
151
+ */
152
+ function enumerateChains(adjacency, start, end) {
153
+ if (start === end)
154
+ return [];
155
+ const out = [];
156
+ const visited = new Set([start]);
157
+ const chain = [];
158
+ dfs(adjacency, start, end, visited, chain, out);
159
+ return out;
160
+ }
161
+ function dfs(adjacency, current, end, visited, chain, out) {
162
+ const outgoing = adjacency.get(current);
163
+ if (outgoing === undefined)
164
+ return;
165
+ for (const [toVer, entry] of outgoing) {
166
+ if (visited.has(toVer))
167
+ continue;
168
+ chain.push(entry);
169
+ if (toVer === end) {
170
+ out.push([...chain]);
171
+ }
172
+ else {
173
+ visited.add(toVer);
174
+ dfs(adjacency, toVer, end, visited, chain, out);
175
+ visited.delete(toVer);
176
+ }
177
+ chain.pop();
178
+ }
179
+ }
180
+ function versionPathFromChain(fromVersion, chain) {
181
+ if (chain.length === 0)
182
+ return [fromVersion, fromVersion];
183
+ const path = [fromVersion];
184
+ for (const entry of chain)
185
+ path.push(entry.toVersion);
186
+ return path;
187
+ }
188
+ // =============================================================================
189
+ // Result + Issue helpers
190
+ // =============================================================================
191
+ function success(data) {
192
+ return { success: true, data };
193
+ }
194
+ function failure(issue) {
195
+ return { success: false, issues: [issue] };
196
+ }
197
+ function missingEndpointIssue(schemaId, fromVersion, toVersion, fromMissing, toMissing) {
198
+ const missing = [];
199
+ if (fromMissing)
200
+ missing.push(`from=${fromVersion}`);
201
+ if (toMissing)
202
+ missing.push(`to=${toVersion}`);
203
+ return {
204
+ code: "migration_missing_endpoint",
205
+ path: [],
206
+ message: `Cannot plan migration for \`${schemaId}\`: ` +
207
+ `${missing.join(", ")} not in the schema registry.`,
208
+ severity: "error",
209
+ metadata: {
210
+ schemaId,
211
+ fromVersion,
212
+ toVersion,
213
+ missing: missing.map((s) => s.split("=")[0]),
214
+ },
215
+ };
216
+ }
217
+ function notFoundIssue(schemaId, fromVersion, toVersion) {
218
+ return {
219
+ code: "migration_not_found",
220
+ path: [],
221
+ message: `Breaking transition for \`${schemaId}\` requires a migration; ` +
222
+ `no migrations are registered for this schemaId.`,
223
+ severity: "error",
224
+ metadata: { schemaId, fromVersion, toVersion },
225
+ };
226
+ }
227
+ function chainBrokenIssue(schemaId, fromVersion, toVersion) {
228
+ return {
229
+ code: "migration_chain_broken",
230
+ path: [],
231
+ message: `Migrations exist for \`${schemaId}\` but no chain bridges ` +
232
+ `${fromVersion} → ${toVersion}.`,
233
+ severity: "error",
234
+ metadata: { schemaId, fromVersion, toVersion },
235
+ };
236
+ }
237
+ function ambiguousChainIssue(schemaId, fromVersion, toVersion, chains) {
238
+ return {
239
+ code: "migration_ambiguous_chain",
240
+ path: [],
241
+ message: `Multiple distinct migration chains bridge \`${schemaId}\` ` +
242
+ `${fromVersion} → ${toVersion}; the planner refuses to pick. ` +
243
+ `Remove one or constrain the registry.`,
244
+ severity: "error",
245
+ metadata: {
246
+ schemaId,
247
+ fromVersion,
248
+ toVersion,
249
+ chainCount: chains.length,
250
+ chainSummaries: chains.map((chain) => chain
251
+ .map((entry) => `${entry.fromVersion}→${entry.toVersion}`)
252
+ .join(", ")),
253
+ },
254
+ };
255
+ }
256
+ //# sourceMappingURL=plan-migration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan-migration.js","sourceRoot":"","sources":["../../../src/migrations/plan-migration.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * `stubMigration(opts)` — pure migration-stub generator (v0.8 Step 6).
3
+ *
4
+ * Produces a `MigrationStub` payload — a `suggestedPath` and the
5
+ * full file `content` for a new `*.migration.ts` file. The CLI is
6
+ * responsible for actually writing the file; this primitive is
7
+ * pure (no `fs.*`, no `import()`, no `process.*`, no `console.*`).
8
+ *
9
+ * The content follows the locked migration shape (Decision #5 +
10
+ * Decision #6):
11
+ *
12
+ * - JSDoc provenance header on top, generated by this function.
13
+ * - `import type { Migration } from "@nekostack/schema/cli";`
14
+ * (NOT root — Decision #6 keeps the v0.8 surface package-internal).
15
+ * - A `const migration: Migration<schemaId, from, to> = { ... }`
16
+ * with a skeleton `transform` that throws "Not yet implemented".
17
+ * Authors edit the body; v0.8 never invokes `transform`.
18
+ * - `export default migration;` so `buildMigrationRegistry` /
19
+ * `verifyMigrationProvenance` can find it via the
20
+ * `MigrationSourceEntry.migration` field.
21
+ *
22
+ * `suggestedPath` follows the locked path convention
23
+ * (Decision #5):
24
+ *
25
+ * <schema-dir>/migrations/<basename>.<from-slug>-to-<to-slug>.migration.ts
26
+ *
27
+ * with the slug rule reused verbatim from `v0.7 src/registry/handlers/generate.ts`:
28
+ * `lowercase → non-alphanumeric runs collapse to "-" → trim`.
29
+ *
30
+ * Reusing v0.7's `slugify` shape means one slug rule across the
31
+ * whole package — and it handles prerelease/build version markers
32
+ * (`1.0.0-beta.1`, `2.0.0+build.5`) cleanly.
33
+ *
34
+ * Failure path: if either operand version is absent from the schema
35
+ * registry → `Result.failure` with `migration_missing_endpoint`
36
+ * (same code as Step 4's planner uses for the same condition).
37
+ */
38
+ import type { MigrationStubOpts, MigrationStubResult } from "./types.js";
39
+ export declare function stubMigration(opts: MigrationStubOpts): MigrationStubResult;
40
+ /**
41
+ * Translate a schema's `sourcePath` plus a version pair into the
42
+ * locked migration-file path:
43
+ *
44
+ * <schema-dir>/migrations/<basename>.<from-slug>-to-<to-slug>.migration.ts
45
+ *
46
+ * `basename` strips a `.schema.{ts,js,mts,cts}` suffix when present;
47
+ * falls back to "filename minus last extension" otherwise. Forward
48
+ * slashes are canonical even on Windows — the CLI normalizes back
49
+ * to platform separators on write.
50
+ *
51
+ * Exported so the CLI's `stub` verb can advertise the same path
52
+ * without re-deriving the rule.
53
+ */
54
+ export declare function suggestedMigrationPathFor(sourcePath: string, fromVersion: string, toVersion: string): string;
55
+ //# sourceMappingURL=stub.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stub.d.ts","sourceRoot":"","sources":["../../../src/migrations/stub.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAKH,OAAO,KAAK,EAEV,iBAAiB,EACjB,mBAAmB,EACpB,MAAM,YAAY,CAAC;AAMpB,wBAAgB,aAAa,CAC3B,IAAI,EAAE,iBAAiB,GACtB,mBAAmB,CAuCrB;AAMD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,yBAAyB,CACvC,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,GAChB,MAAM,CAUR"}