@metaobjectsdev/metadata 0.24.0-rc.1 → 0.24.1

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 (144) hide show
  1. package/dist/attr-schema-validate.d.ts.map +1 -1
  2. package/dist/attr-schema-validate.js +17 -2
  3. package/dist/attr-schema-validate.js.map +1 -1
  4. package/dist/core/field/field-constants.d.ts +18 -5
  5. package/dist/core/field/field-constants.d.ts.map +1 -1
  6. package/dist/core/field/field-constants.js +21 -5
  7. package/dist/core/field/field-constants.js.map +1 -1
  8. package/dist/core/field/field-definition.embedded.d.ts.map +1 -1
  9. package/dist/core/field/field-definition.embedded.js +8 -3
  10. package/dist/core/field/field-definition.embedded.js.map +1 -1
  11. package/dist/core/field/validate-field-mutability.d.ts +22 -0
  12. package/dist/core/field/validate-field-mutability.d.ts.map +1 -0
  13. package/dist/core/field/validate-field-mutability.js +208 -0
  14. package/dist/core/field/validate-field-mutability.js.map +1 -0
  15. package/dist/core/identity/identity-constants.d.ts +12 -0
  16. package/dist/core/identity/identity-constants.d.ts.map +1 -1
  17. package/dist/core/identity/identity-constants.js +15 -0
  18. package/dist/core/identity/identity-constants.js.map +1 -1
  19. package/dist/core/identity/identity-definition.embedded.js +2 -2
  20. package/dist/core/identity/identity-definition.embedded.js.map +1 -1
  21. package/dist/core/index/index-definition.embedded.js +2 -2
  22. package/dist/core/index/index-definition.embedded.js.map +1 -1
  23. package/dist/core/object/object-definition.embedded.js +2 -2
  24. package/dist/core/object/object-definition.embedded.js.map +1 -1
  25. package/dist/core/requirement/meta-requirement.d.ts +1 -2
  26. package/dist/core/requirement/meta-requirement.d.ts.map +1 -1
  27. package/dist/core/requirement/meta-requirement.js +2 -6
  28. package/dist/core/requirement/meta-requirement.js.map +1 -1
  29. package/dist/core/requirement/requirement-constants.d.ts +3 -8
  30. package/dist/core/requirement/requirement-constants.d.ts.map +1 -1
  31. package/dist/core/requirement/requirement-constants.js +2 -9
  32. package/dist/core/requirement/requirement-constants.js.map +1 -1
  33. package/dist/core/requirement/requirement-definition.embedded.d.ts.map +1 -1
  34. package/dist/core/requirement/requirement-definition.embedded.js +8 -46
  35. package/dist/core/requirement/requirement-definition.embedded.js.map +1 -1
  36. package/dist/core/requirement/resolve-claim.d.ts +37 -0
  37. package/dist/core/requirement/resolve-claim.d.ts.map +1 -0
  38. package/dist/core/requirement/resolve-claim.js +83 -0
  39. package/dist/core/requirement/resolve-claim.js.map +1 -0
  40. package/dist/core/vocabulary-rewrite-yaml.d.ts +21 -0
  41. package/dist/core/vocabulary-rewrite-yaml.d.ts.map +1 -0
  42. package/dist/core/vocabulary-rewrite-yaml.js +245 -0
  43. package/dist/core/vocabulary-rewrite-yaml.js.map +1 -0
  44. package/dist/core-types.d.ts.map +1 -1
  45. package/dist/core-types.js +10 -10
  46. package/dist/core-types.js.map +1 -1
  47. package/dist/errors.d.ts +2 -2
  48. package/dist/errors.d.ts.map +1 -1
  49. package/dist/errors.js +37 -4
  50. package/dist/errors.js.map +1 -1
  51. package/dist/index.d.ts +7 -1
  52. package/dist/index.d.ts.map +1 -1
  53. package/dist/index.js +13 -1
  54. package/dist/index.js.map +1 -1
  55. package/dist/library/library-sources.d.ts +11 -0
  56. package/dist/library/library-sources.d.ts.map +1 -1
  57. package/dist/library/library-sources.js +13 -0
  58. package/dist/library/library-sources.js.map +1 -1
  59. package/dist/loader/meta-data-loader.d.ts.map +1 -1
  60. package/dist/loader/meta-data-loader.js +14 -10
  61. package/dist/loader/meta-data-loader.js.map +1 -1
  62. package/dist/loader/validation-passes.d.ts +1 -0
  63. package/dist/loader/validation-passes.d.ts.map +1 -1
  64. package/dist/loader/validation-passes.js +263 -45
  65. package/dist/loader/validation-passes.js.map +1 -1
  66. package/dist/naming-refs.d.ts.map +1 -1
  67. package/dist/naming-refs.js +2 -3
  68. package/dist/naming-refs.js.map +1 -1
  69. package/dist/parser-core.d.ts.map +1 -1
  70. package/dist/parser-core.js +22 -5
  71. package/dist/parser-core.js.map +1 -1
  72. package/dist/persistence/origin/meta-origin.d.ts +0 -10
  73. package/dist/persistence/origin/meta-origin.d.ts.map +1 -1
  74. package/dist/persistence/origin/meta-origin.js +1 -15
  75. package/dist/persistence/origin/meta-origin.js.map +1 -1
  76. package/dist/persistence/origin/origin-constants.d.ts +2 -4
  77. package/dist/persistence/origin/origin-constants.d.ts.map +1 -1
  78. package/dist/persistence/origin/origin-constants.js +9 -7
  79. package/dist/persistence/origin/origin-constants.js.map +1 -1
  80. package/dist/persistence/origin/origin-definition.embedded.d.ts.map +1 -1
  81. package/dist/persistence/origin/origin-definition.embedded.js +5 -21
  82. package/dist/persistence/origin/origin-definition.embedded.js.map +1 -1
  83. package/dist/registry-manifest.d.ts +9 -4
  84. package/dist/registry-manifest.d.ts.map +1 -1
  85. package/dist/registry-manifest.js +9 -4
  86. package/dist/registry-manifest.js.map +1 -1
  87. package/dist/retired-vocabulary.d.ts +92 -0
  88. package/dist/retired-vocabulary.d.ts.map +1 -0
  89. package/dist/retired-vocabulary.js +204 -0
  90. package/dist/retired-vocabulary.js.map +1 -0
  91. package/dist/super-resolve.d.ts +33 -0
  92. package/dist/super-resolve.d.ts.map +1 -1
  93. package/dist/super-resolve.js +56 -1
  94. package/dist/super-resolve.js.map +1 -1
  95. package/dist/template/prompt-definition.embedded.js +1 -1
  96. package/dist/template/prompt-definition.embedded.js.map +1 -1
  97. package/dist/template/template-constants.d.ts +6 -0
  98. package/dist/template/template-constants.d.ts.map +1 -1
  99. package/dist/template/template-constants.js +24 -1
  100. package/dist/template/template-constants.js.map +1 -1
  101. package/dist/template/template-definition.embedded.d.ts.map +1 -1
  102. package/dist/template/template-definition.embedded.js +34 -21
  103. package/dist/template/template-definition.embedded.js.map +1 -1
  104. package/dist/vocabulary-rewrite.d.ts +33 -0
  105. package/dist/vocabulary-rewrite.d.ts.map +1 -0
  106. package/dist/vocabulary-rewrite.js +314 -0
  107. package/dist/vocabulary-rewrite.js.map +1 -0
  108. package/package.json +11 -1
  109. package/src/attr-schema-validate.ts +17 -2
  110. package/src/core/field/field-constants.ts +24 -5
  111. package/src/core/field/field-definition.embedded.ts +8 -3
  112. package/src/core/field/validate-field-mutability.ts +259 -0
  113. package/src/core/identity/identity-constants.ts +16 -0
  114. package/src/core/identity/identity-definition.embedded.ts +2 -2
  115. package/src/core/index/index-definition.embedded.ts +2 -2
  116. package/src/core/object/object-definition.embedded.ts +2 -2
  117. package/src/core/requirement/meta-requirement.ts +1 -7
  118. package/src/core/requirement/requirement-constants.ts +2 -9
  119. package/src/core/requirement/requirement-definition.embedded.ts +8 -46
  120. package/src/core/requirement/resolve-claim.ts +98 -0
  121. package/src/core/vocabulary-rewrite-yaml.ts +267 -0
  122. package/src/core-types.ts +9 -10
  123. package/src/errors.ts +37 -4
  124. package/src/index.ts +29 -1
  125. package/src/library/library-sources.ts +14 -0
  126. package/src/loader/meta-data-loader.ts +15 -10
  127. package/src/loader/validation-passes.ts +323 -50
  128. package/src/naming-refs.ts +1 -3
  129. package/src/parser-core.ts +27 -5
  130. package/src/persistence/origin/meta-origin.ts +0 -16
  131. package/src/persistence/origin/origin-constants.ts +9 -8
  132. package/src/persistence/origin/origin-definition.embedded.ts +5 -21
  133. package/src/registry-manifest.ts +9 -4
  134. package/src/retired-vocabulary.ts +280 -0
  135. package/src/super-resolve.ts +59 -1
  136. package/src/template/prompt-definition.embedded.ts +1 -1
  137. package/src/template/template-constants.ts +27 -1
  138. package/src/template/template-definition.embedded.ts +34 -21
  139. package/src/vocabulary-rewrite.ts +350 -0
  140. package/dist/core/field/validate-field-readonly.d.ts +0 -9
  141. package/dist/core/field/validate-field-readonly.d.ts.map +0 -1
  142. package/dist/core/field/validate-field-readonly.js +0 -128
  143. package/dist/core/field/validate-field-readonly.js.map +0 -1
  144. package/src/core/field/validate-field-readonly.ts +0 -154
@@ -0,0 +1,314 @@
1
+ // server/typescript/packages/metadata/src/vocabulary-rewrite.ts
2
+ //
3
+ // The raw-document rewriter behind `meta upgrade`.
4
+ //
5
+ // WHY IT CANNOT USE THE LOADER — the constraint that shapes everything here. Once an
6
+ // attribute is deregistered, metadata carrying it FAILS THE LOAD; that is the point of a
7
+ // retirement. So load → transform → canonical-serialize is impossible: the input does not
8
+ // load, and the canonical serializer needs a loaded model. This operates on RAW TEXT.
9
+ //
10
+ // That is also what makes the upgrade path exist at all. An adopter installs the new CLI and
11
+ // runs this against metadata the new CLI REFUSES. A fixer that needed a successful load
12
+ // would be a chicken-and-egg with no exit.
13
+ //
14
+ // SURGICAL, NOT PARSE-AND-REPRINT. Adopters author JSONC with comments and meaningful key
15
+ // order — `meta gen`'s output order, review conventions, "do not reorder" notes. A
16
+ // round-trip through JSON.parse/stringify destroys all of it while reporting success. So
17
+ // every edit here is a span replacement on the original text, and any region we did not
18
+ // deliberately change comes back byte-identical.
19
+ //
20
+ // IT SCOPES EVERY OCCURRENCE, NOT EVERY FILE. Retirements are type-scoped — `@unique` is
21
+ // retired on `identity.secondary` and perfectly live on a field — so the governing type is
22
+ // a property of WHERE the attribute sits, not of the document it sits in. A file-level
23
+ // scope was the original shape and it was wrong in both directions: a caller that ran one
24
+ // pass per type key present in the file let the `identity.secondary` scope reach a
25
+ // `field.string`'s `@unique` (branding live vocabulary retired, and with a `dropAttr` entry
26
+ // DELETING it), and reported every wildcard-scoped refusal once per subtype key in the file.
27
+ // `scopeRanges` below recovers the enclosing `"<type>.<subType>"` for each occurrence, so
28
+ // one pass over the document answers both correctly.
29
+ //
30
+ // CANONICAL JSON ONLY — YAML lives in `core/vocabulary-rewrite-yaml.ts`, not here. This
31
+ // module is reachable from `src/index.ts`, which may not import the Node-only `yaml`
32
+ // package, so the YAML arm sits behind its own package subpath and `meta upgrade`
33
+ // dynamic-imports it. The split is a bundling constraint, not a difference in contract: both
34
+ // arms return the same result shape, scope every occurrence the same way, and refuse the
35
+ // same retirements.
36
+ //
37
+ // The reason YAML gets a parser and this arm does not: a hand-rolled YAML mode was tried
38
+ // here first and shipped a file-corrupting bug — a multi-item block sequence lost every item
39
+ // but the first, because a scanner stops at a newline — while the dominant authoring style
40
+ // (flow mappings, `{ name: x, readOnly: true }`) was not matched at all. YAML's value extent
41
+ // is not derivable by scanning; JSON's is.
42
+ //
43
+ // IT REFUSES WHAT IT CANNOT KNOW. A retirement with no `rewrite` (`@status: abandoned`) is
44
+ // reported, never guessed at. Deleting the node, retyping it, and fixing the residue it
45
+ // describes are all defensible, and a wrong guess emits metadata that LOADS and means
46
+ // something different — strictly worse than leaving it alone, because the adopter would
47
+ // believe the migration finished.
48
+ import { RETIRED_VOCABULARY, note, scopeMatches, } from "./retired-vocabulary.js";
49
+ /** `0.24.0` → `[0,24,0]`, for an ordered comparison rather than a string one. */
50
+ function parts(v) {
51
+ return v.split(".").map((n) => Number.parseInt(n, 10) || 0);
52
+ }
53
+ function atOrBefore(a, b) {
54
+ const [x, y] = [parts(a), parts(b)];
55
+ for (let i = 0; i < Math.max(x.length, y.length); i++) {
56
+ const d = (x[i] ?? 0) - (y[i] ?? 0);
57
+ if (d !== 0)
58
+ return d < 0;
59
+ }
60
+ return true;
61
+ }
62
+ /** 1-indexed line of `index` in `text`. */
63
+ function lineAt(text, index) {
64
+ let line = 1;
65
+ for (let i = 0; i < index && i < text.length; i++)
66
+ if (text[i] === "\n")
67
+ line++;
68
+ return line;
69
+ }
70
+ /**
71
+ * Offset just past the bracket closing the one at `open`, or undefined if unbalanced.
72
+ * String-aware, so a brace inside a JSON string literal cannot unbalance the scan.
73
+ */
74
+ function closingBracket(text, open) {
75
+ const close = text[open] === "[" ? "]" : "}";
76
+ const openCh = text[open];
77
+ let depth = 0;
78
+ let inStr = false;
79
+ for (let j = open; j < text.length; j++) {
80
+ const c = text[j];
81
+ if (inStr) {
82
+ if (c === "\\")
83
+ j++;
84
+ else if (c === '"')
85
+ inStr = false;
86
+ continue;
87
+ }
88
+ if (c === '"')
89
+ inStr = true;
90
+ else if (c === openCh)
91
+ depth++;
92
+ else if (c === close) {
93
+ depth--;
94
+ if (depth === 0)
95
+ return j + 1;
96
+ }
97
+ }
98
+ return undefined;
99
+ }
100
+ /**
101
+ * Every node body in the document, in source order.
102
+ *
103
+ * A canonical-JSON node is `{ "<type>.<subType>": { …body… } }`, so an attribute belongs to
104
+ * the INNERMOST body containing it — which is what makes per-occurrence scoping possible
105
+ * without a parser we deliberately do not have.
106
+ */
107
+ function scopeRanges(source) {
108
+ const ranges = [];
109
+ const re = /"([a-z][A-Za-z0-9]*)\.([A-Za-z0-9_*]+)"\s*:\s*\{/g;
110
+ let m;
111
+ while ((m = re.exec(source)) !== null) {
112
+ const bodyStart = m.index + m[0].length - 1;
113
+ const bodyEnd = closingBracket(source, bodyStart);
114
+ if (bodyEnd === undefined)
115
+ continue;
116
+ ranges.push({ typeKey: `${m[1]}.${m[2]}`, keyIndex: m.index, bodyStart, bodyEnd });
117
+ }
118
+ return ranges;
119
+ }
120
+ /** The type key governing `offset` — the innermost body containing it. */
121
+ function scopeAt(ranges, offset) {
122
+ let best;
123
+ for (const r of ranges) {
124
+ if (offset <= r.bodyStart || offset >= r.bodyEnd)
125
+ continue;
126
+ // Properly nested ranges: the innermost containing one starts last.
127
+ if (best === undefined || r.bodyStart > best.bodyStart)
128
+ best = r;
129
+ }
130
+ return best?.typeKey;
131
+ }
132
+ /**
133
+ * Matches `"@name"` at a key position, plus the separator that follows, capturing the key
134
+ * separately so a replacement can keep the original spacing.
135
+ *
136
+ * Deliberately NOT a full parser. A parser would have to reproduce the document to emit it,
137
+ * which is the thing this exists to avoid; matching a key occurrence lets every untouched
138
+ * byte survive by construction.
139
+ */
140
+ function keyPattern(attr) {
141
+ return new RegExp(`("@?${attr}")(\\s*:\\s*)`, "g");
142
+ }
143
+ /** The JSON value token starting at `from` — a scalar, or a bracketed array/object. */
144
+ function valueSpan(text, from) {
145
+ let i = from;
146
+ while (i < text.length && /\s/.test(text[i] ?? ""))
147
+ i++;
148
+ const open = text[i];
149
+ if (open === "[" || open === "{") {
150
+ const end = closingBracket(text, i);
151
+ return end === undefined ? undefined : { start: i, end, raw: text.slice(i, end) };
152
+ }
153
+ // Scalar: to the next comma, closing brace, or newline, whichever comes first.
154
+ let j = i;
155
+ let inStr = false;
156
+ for (; j < text.length; j++) {
157
+ const c = text[j];
158
+ if (inStr) {
159
+ if (c === "\\")
160
+ j++;
161
+ else if (c === '"')
162
+ inStr = false;
163
+ continue;
164
+ }
165
+ if (c === '"')
166
+ inStr = true;
167
+ else if (c === "," || c === "}" || c === "\n")
168
+ break;
169
+ }
170
+ return { start: i, end: j, raw: text.slice(i, j).trim() };
171
+ }
172
+ /** Does the raw token equal this literal? Compares JSON-decoded where possible so
173
+ * `"readOnly"` and `readOnly` both match a string literal. */
174
+ function rawEquals(raw, want) {
175
+ try {
176
+ return JSON.parse(raw) === want;
177
+ }
178
+ catch {
179
+ return raw === String(want);
180
+ }
181
+ }
182
+ /**
183
+ * The span to delete so that removing a key leaves loadable JSON.
184
+ *
185
+ * The arithmetic is fiddly and every branch is load-bearing, so it lives here with its
186
+ * steps named rather than inline in the dispatch below.
187
+ */
188
+ function dropSpan(source, keyStart, valueEnd) {
189
+ // 1. Absorb the value's trailing spaces, then its trailing comma if it has one.
190
+ let end = valueEnd;
191
+ while (end < source.length && /[ \t]/.test(source[end] ?? ""))
192
+ end++;
193
+ const hadTrailingComma = source[end] === ",";
194
+ if (hadTrailingComma)
195
+ end++;
196
+ // 2. Absorb the key's own indentation, so the removal does not leave a ragged line.
197
+ let start = keyStart;
198
+ while (start > 0 && /[ \t]/.test(source[start - 1] ?? ""))
199
+ start--;
200
+ // 3. THE LAST-KEY CASE, found by dogfooding rather than by a unit test: when the retired
201
+ // attr is last in its object there IS no trailing comma — the comma belongs to the
202
+ // PRECEDING key. Dropping without taking it leaves `"...",\n}`, which does not parse.
203
+ // A tool whose whole job is producing loadable metadata cannot emit invalid JSON.
204
+ if (!hadTrailingComma) {
205
+ let back = start;
206
+ while (back > 0 && /\s/.test(source[back - 1] ?? ""))
207
+ back--;
208
+ if (source[back - 1] === ",")
209
+ start = back - 1;
210
+ }
211
+ // 4. If the key owned its whole line, take the line terminator too rather than leaving a
212
+ // blank line. Otherwise the key shares a line with other content, so undo step 2's
213
+ // indentation trim — it would eat the separating space after the preceding key's comma.
214
+ if (source[start - 1] === "\n" && source[end] === "\n")
215
+ end++;
216
+ else if (start > 0 && source[start - 1] !== "\n" && hadTrailingComma)
217
+ start = keyStart;
218
+ return { start, end };
219
+ }
220
+ /**
221
+ * Rewrite retired vocabulary in one raw canonical-JSON metadata document.
222
+ *
223
+ * Pure: no filesystem, no loader, no registry. Returns the new text plus every change and
224
+ * every refusal, so a caller can print a diff and exit non-zero when work remains.
225
+ */
226
+ export function rewriteDocument(source, opts = {}) {
227
+ const changes = [];
228
+ const refusals = [];
229
+ // Edits are collected as spans against the ORIGINAL text and applied in one pass at the
230
+ // end, right-to-left. Rewriting incrementally would invalidate every later offset.
231
+ const edits = [];
232
+ const inWindow = (e) => opts.maxVersion === undefined || atOrBefore(e.since, opts.maxVersion);
233
+ const ranges = scopeRanges(source);
234
+ // A retired SUBTYPE has no attribute to rewrite — the node itself has to be re-modelled
235
+ // (`origin.collection` becomes `origin.aggregate @agg: collect`), which is a judgment the
236
+ // adopter makes. Reporting it is what keeps `meta upgrade` from exiting 0 on a document
237
+ // that still will not load; it used to be filtered out entirely and was invisible.
238
+ for (const r of ranges) {
239
+ for (const entry of RETIRED_VOCABULARY) {
240
+ if (entry.isSubTypeRetirement !== true || !inWindow(entry))
241
+ continue;
242
+ if (`${entry.type}.${entry.subType}` !== r.typeKey)
243
+ continue;
244
+ refusals.push({ ...note(entry), subject: r.typeKey, line: lineAt(source, r.keyIndex) });
245
+ }
246
+ }
247
+ for (const entry of RETIRED_VOCABULARY.filter((e) => e.attr !== undefined && inWindow(e))) {
248
+ const attr = entry.attr;
249
+ const re = keyPattern(attr);
250
+ let m;
251
+ while ((m = re.exec(source)) !== null) {
252
+ const keyStart = m.index;
253
+ const keyEnd = keyStart + (m[1]?.length ?? 0);
254
+ const afterKey = m.index + m[0].length;
255
+ // Scope is decided HERE, per occurrence, from the enclosing node.
256
+ const scope = scopeAt(ranges, keyStart);
257
+ if (scope === undefined || !scopeMatches(entry, scope))
258
+ continue;
259
+ const line = lineAt(source, keyStart);
260
+ const span = valueSpan(source, afterKey);
261
+ // A VALUE-scoped retirement only fires on the retired values. `@dbColumnType: jsonb`
262
+ // is live vocabulary on the same attribute; touching it would silently change the
263
+ // column type.
264
+ if (entry.attrValues !== undefined) {
265
+ if (!entry.attrValues.some((v) => rawEquals(span?.raw ?? "", v)))
266
+ continue;
267
+ }
268
+ const refuse = () => {
269
+ refusals.push({
270
+ ...note(entry),
271
+ subject: `@${attr}`,
272
+ ...(span?.raw !== undefined ? { value: span.raw } : {}),
273
+ line,
274
+ });
275
+ };
276
+ const drop = () => {
277
+ if (span === undefined)
278
+ return;
279
+ const { start, end } = dropSpan(source, keyStart, span.end);
280
+ edits.push({ start, end, text: "" });
281
+ changes.push({ attr, from: attr, to: "(removed)", line });
282
+ };
283
+ const rw = entry.rewrite;
284
+ if (rw === undefined)
285
+ refuse();
286
+ else if (rw.kind === "renameAttr") {
287
+ edits.push({ start: keyStart, end: keyEnd, text: `"@${rw.to}"` });
288
+ changes.push({ attr, from: attr, to: rw.to, line });
289
+ }
290
+ else if (rw.kind === "dropAttr")
291
+ drop();
292
+ else if (span === undefined)
293
+ continue;
294
+ else if (rawEquals(span.raw, rw.fromValue)) {
295
+ const valText = JSON.stringify(rw.toValue);
296
+ edits.push({ start: keyStart, end: keyEnd, text: `"@${rw.toAttr}"` });
297
+ edits.push({ start: span.start, end: span.end, text: valText });
298
+ changes.push({ attr, from: `${attr}: ${span.raw}`, to: `${rw.toAttr}: ${valText}`, line });
299
+ }
300
+ // Every other value of a retired attribute still has to go somewhere — the entry says
301
+ // which, and the type makes saying it mandatory.
302
+ else if (rw.otherwise === "drop")
303
+ drop();
304
+ else
305
+ refuse();
306
+ }
307
+ }
308
+ edits.sort((a, b) => b.start - a.start);
309
+ let text = source;
310
+ for (const e of edits)
311
+ text = text.slice(0, e.start) + e.text + text.slice(e.end);
312
+ return { text, changes, refusals };
313
+ }
314
+ //# sourceMappingURL=vocabulary-rewrite.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vocabulary-rewrite.js","sourceRoot":"","sources":["../src/vocabulary-rewrite.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metaobjectsdev/metadata",
3
- "version": "0.24.0-rc.1",
3
+ "version": "0.24.1",
4
4
  "description": "Metamodel loader, types, and constants for the MetaObjects standard.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -16,10 +16,20 @@
16
16
  "types": "./dist/core/index.d.ts",
17
17
  "default": "./dist/core/index.js"
18
18
  },
19
+ "./library": {
20
+ "bun": "./src/library/library-sources.ts",
21
+ "types": "./dist/library/library-sources.d.ts",
22
+ "default": "./dist/library/library-sources.js"
23
+ },
19
24
  "./constants": {
20
25
  "bun": "./src/constants.ts",
21
26
  "types": "./dist/constants.d.ts",
22
27
  "default": "./dist/constants.js"
28
+ },
29
+ "./vocabulary-rewrite-yaml": {
30
+ "bun": "./src/core/vocabulary-rewrite-yaml.ts",
31
+ "types": "./dist/core/vocabulary-rewrite-yaml.d.ts",
32
+ "default": "./dist/core/vocabulary-rewrite-yaml.js"
23
33
  }
24
34
  },
25
35
  "files": [
@@ -47,6 +47,9 @@ import type { AttrSchema, TypeRegistry } from "./registry.js";
47
47
  import { childRuleMatches } from "./registry.js";
48
48
  import { TYPE_FIELD, TYPE_METADATA } from "./shared/base-types.js";
49
49
  import { ATTR_SUBTYPE_PROPERTIES } from "./core/attr/attr-constants.js";
50
+ // #337: turns "unknown X" into "retired in V — here is the migration". Changes no load
51
+ // outcome; retired vocabulary still fails with the same code.
52
+ import { retiredAttr, retiredAttrValue, retirementHint } from "./retired-vocabulary.js";
50
53
  import {
51
54
  FIELD_SUBTYPE_ENUM,
52
55
  FIELD_ATTR_VALUES,
@@ -164,10 +167,17 @@ function validateNode(
164
167
  // @-attr still fails — only the `properties` subtype is exempt.)
165
168
  if (inst.subType === ATTR_SUBTYPE_PROPERTIES) continue;
166
169
  if (!byName.has(inst.name)) {
170
+ // #337: if we RETIRED this name, say so. "Not declared by any registered
171
+ // provider" is true and reads as "your metadata is malformed", which sent one
172
+ // adopter to file a registration bug against a deliberate, documented breaking
173
+ // change. Unrecognised names still report generically — a typo is a typo.
174
+ const retired = retiredAttr(typeKey, inst.name);
167
175
  errors.push(
168
176
  new ParseError(
169
177
  `Unknown attribute '@${inst.name}' on ${nodeLabel(node)} — ` +
170
- `not declared by any registered provider for ${typeKey}`,
178
+ (retired !== undefined
179
+ ? retirementHint(retired)
180
+ : `not declared by any registered provider for ${typeKey}`),
171
181
  { code: "ERR_UNKNOWN_ATTR", source: node.source },
172
182
  ),
173
183
  );
@@ -290,11 +300,16 @@ function validateNode(
290
300
  ? []
291
301
  : [value];
292
302
  for (const bad of offenders) {
303
+ // #337: a member we REMOVED reads very differently from a member that never
304
+ // existed. `@status: abandoned` was valid one release ago, so "not one of the
305
+ // allowed values" invites the reader to conclude the enum is broken.
306
+ const retiredValue = retiredAttrValue(typeKey, inst.name, bad);
293
307
  errors.push(
294
308
  new ParseError(
295
309
  `${nodeLabel(node)} attribute '@${inst.name}' has value ` +
296
310
  `'${String(bad)}' which is not one of the allowed values: ` +
297
- `${allowed.map((v) => String(v)).join(", ")}`,
311
+ `${allowed.map((v) => String(v)).join(", ")}` +
312
+ (retiredValue !== undefined ? ` — ${retirementHint(retiredValue)}` : ""),
298
313
  { code: "ERR_BAD_ATTR_VALUE", source: node.source },
299
314
  ),
300
315
  );
@@ -64,11 +64,30 @@ export type FieldSubType = (typeof FIELD_SUBTYPES)[number];
64
64
  export const FIELD_ATTR_REQUIRED = "required";
65
65
  export const FIELD_ATTR_UNIQUE = "unique";
66
66
 
67
- /** FR-013: when true, the field is read-only from the application's perspective.
68
- * Codegen emits no setter; persistence skips the column on INSERT/UPDATE; Zod
69
- * create/update variants omit the field. Default false (writable). See ADR-0013
70
- * layer split — this is logical (no DB-introspection round-trip). */
71
- export const FIELD_ATTR_READ_ONLY = "readOnly";
67
+ /** FR-037 R1: who may write this field, and when. One axis, three mutually
68
+ * exclusive modes, so the illegal pair (`readOnly` + `writeOnce`) is
69
+ * unrepresentable and inheritance has a total order. Absent ⇒ `readWrite`.
70
+ * See ADR-0013 layer split — this is logical (no DB-introspection round-trip). */
71
+ export const FIELD_ATTR_MUTABILITY = "mutability";
72
+
73
+ /** `readWrite` — the caller may set it on create and change it on update. */
74
+ export const MUTABILITY_READ_WRITE = "readWrite";
75
+ /** `writeOnce` — set on create, then excluded from the update shape. A value
76
+ * presented on PATCH is IGNORED, not rejected (the uniform behaviour of every
77
+ * excluded-settable-set key, and the generated edit form submits every field). */
78
+ export const MUTABILITY_WRITE_ONCE = "writeOnce";
79
+ /** `readOnly` — nobody writes it: no setter, skipped on INSERT/UPDATE, omitted
80
+ * from every input variant. Populated by the DB, replication, or another owner. */
81
+ export const MUTABILITY_READ_ONLY = "readOnly";
82
+
83
+ /** Declaration order IS the tightening order — index in this array is the mode's
84
+ * rank, so "may only tighten" is an index comparison rather than a lookup table. */
85
+ export const MUTABILITY_MODES = [
86
+ MUTABILITY_READ_WRITE,
87
+ MUTABILITY_WRITE_ONCE,
88
+ MUTABILITY_READ_ONLY,
89
+ ] as const;
90
+ export type MutabilityMode = (typeof MUTABILITY_MODES)[number];
72
91
  export const FIELD_ATTR_DEFAULT = "default";
73
92
  export const FIELD_ATTR_MAX_LENGTH = "maxLength";
74
93
 
@@ -46,11 +46,16 @@ export const FIELD_DEFINITION: ProviderDefinition = {
46
46
  },
47
47
  {
48
48
  "type": "attr",
49
- "subType": "boolean",
50
- "name": "readOnly",
49
+ "subType": "string",
50
+ "name": "mutability",
51
51
  "min": 0,
52
52
  "max": 1,
53
- "description": "FR-013: when true, the field is read-only — codegen emits no setter / writable property, the persistence layer skips the column on INSERT/UPDATE, and Zod/Pydantic/class-validator schemas mark it read-only on input variants. The value is populated by the database (computed column, default expression, trigger), by replication, or by another external owner."
53
+ "allowedValues": [
54
+ "readWrite",
55
+ "writeOnce",
56
+ "readOnly"
57
+ ],
58
+ "description": "FR-037 R1: who may write this field, and when. 'readWrite' (the default when absent) — the caller may set it on create and change it on update. 'writeOnce' — the caller sets it on create; it is excluded from the update shape thereafter, so a value presented on PATCH is ignored rather than rejected. 'readOnly' — nobody writes it: codegen emits no setter / writable property, the persistence layer skips the column on INSERT/UPDATE, and Zod/Pydantic/class-validator schemas omit it from input variants; the value is populated by the database (computed column, default expression, trigger), by replication, or by another external owner. The three are mutually exclusive modes of ONE axis — who may write, and when — so the illegal pair is unrepresentable and inheritance has a total order: a subtype may TIGHTEN an inherited mode (readWrite < writeOnce < readOnly) and never loosen it (ERR_MUTABILITY_DOWNGRADE). Pairing a non-readWrite mode with @autoSet is ERR_MUTABILITY_AUTOSET_CONFLICT: @autoSet already says the SERVER supplies the value, which is a different axis from who may write it."
54
59
  },
55
60
  {
56
61
  "type": "attr",