@metaobjectsdev/codegen-ts 0.8.1 → 0.9.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 (97) hide show
  1. package/dist/column-mapper.d.ts.map +1 -1
  2. package/dist/column-mapper.js +123 -46
  3. package/dist/column-mapper.js.map +1 -1
  4. package/dist/generators/callable-file.d.ts +8 -0
  5. package/dist/generators/callable-file.d.ts.map +1 -0
  6. package/dist/generators/callable-file.js +32 -0
  7. package/dist/generators/callable-file.js.map +1 -0
  8. package/dist/generators/docs-data-builder.d.ts.map +1 -1
  9. package/dist/generators/docs-data-builder.js +5 -2
  10. package/dist/generators/docs-data-builder.js.map +1 -1
  11. package/dist/generators/extractor-file.d.ts +9 -0
  12. package/dist/generators/extractor-file.d.ts.map +1 -0
  13. package/dist/generators/extractor-file.js +45 -0
  14. package/dist/generators/extractor-file.js.map +1 -0
  15. package/dist/generators/index.d.ts +3 -0
  16. package/dist/generators/index.d.ts.map +1 -1
  17. package/dist/generators/index.js +3 -0
  18. package/dist/generators/index.js.map +1 -1
  19. package/dist/generators/render-helper-file.d.ts +9 -0
  20. package/dist/generators/render-helper-file.d.ts.map +1 -0
  21. package/dist/generators/render-helper-file.js +58 -0
  22. package/dist/generators/render-helper-file.js.map +1 -0
  23. package/dist/payload-codegen.d.ts.map +1 -1
  24. package/dist/payload-codegen.js +42 -8
  25. package/dist/payload-codegen.js.map +1 -1
  26. package/dist/projection/extract-view-spec.d.ts.map +1 -1
  27. package/dist/projection/extract-view-spec.js +11 -3
  28. package/dist/projection/extract-view-spec.js.map +1 -1
  29. package/dist/render-engine/framework-provider.d.ts +6 -5
  30. package/dist/render-engine/framework-provider.d.ts.map +1 -1
  31. package/dist/render-engine/framework-provider.js +53 -11
  32. package/dist/render-engine/framework-provider.js.map +1 -1
  33. package/dist/templates/callable-file.d.ts +8 -0
  34. package/dist/templates/callable-file.d.ts.map +1 -0
  35. package/dist/templates/callable-file.js +98 -0
  36. package/dist/templates/callable-file.js.map +1 -0
  37. package/dist/templates/extract-delegate-emitter.d.ts +42 -0
  38. package/dist/templates/extract-delegate-emitter.d.ts.map +1 -0
  39. package/dist/templates/extract-delegate-emitter.js +339 -0
  40. package/dist/templates/extract-delegate-emitter.js.map +1 -0
  41. package/dist/templates/{recover-schema-emitter.d.ts → extract-schema-emitter.d.ts} +2 -2
  42. package/dist/templates/extract-schema-emitter.d.ts.map +1 -0
  43. package/dist/templates/{recover-schema-emitter.js → extract-schema-emitter.js} +37 -20
  44. package/dist/templates/extract-schema-emitter.js.map +1 -0
  45. package/dist/templates/extractor.d.ts +9 -0
  46. package/dist/templates/extractor.d.ts.map +1 -0
  47. package/dist/templates/extractor.js +296 -0
  48. package/dist/templates/extractor.js.map +1 -0
  49. package/dist/templates/field-meta.d.ts.map +1 -1
  50. package/dist/templates/field-meta.js +2 -1
  51. package/dist/templates/field-meta.js.map +1 -1
  52. package/dist/templates/filter-type.d.ts.map +1 -1
  53. package/dist/templates/filter-type.js +8 -5
  54. package/dist/templates/filter-type.js.map +1 -1
  55. package/dist/templates/fr010-field-mapping.d.ts +22 -6
  56. package/dist/templates/fr010-field-mapping.d.ts.map +1 -1
  57. package/dist/templates/fr010-field-mapping.js +66 -21
  58. package/dist/templates/fr010-field-mapping.js.map +1 -1
  59. package/dist/templates/inferred-types.d.ts +15 -1
  60. package/dist/templates/inferred-types.d.ts.map +1 -1
  61. package/dist/templates/inferred-types.js +30 -17
  62. package/dist/templates/inferred-types.js.map +1 -1
  63. package/dist/templates/output-parser.d.ts.map +1 -1
  64. package/dist/templates/output-parser.js +98 -34
  65. package/dist/templates/output-parser.js.map +1 -1
  66. package/dist/templates/output-prompt.js +2 -2
  67. package/dist/templates/render-helper.d.ts +14 -0
  68. package/dist/templates/render-helper.d.ts.map +1 -0
  69. package/dist/templates/render-helper.js +180 -0
  70. package/dist/templates/render-helper.js.map +1 -0
  71. package/dist/templates/zod-validators.d.ts.map +1 -1
  72. package/dist/templates/zod-validators.js +59 -3
  73. package/dist/templates/zod-validators.js.map +1 -1
  74. package/package.json +10 -4
  75. package/src/column-mapper.ts +128 -45
  76. package/src/generators/callable-file.ts +44 -0
  77. package/src/generators/docs-data-builder.ts +5 -1
  78. package/src/generators/extractor-file.ts +57 -0
  79. package/src/generators/index.ts +3 -0
  80. package/src/generators/render-helper-file.ts +74 -0
  81. package/src/payload-codegen.ts +52 -7
  82. package/src/projection/extract-view-spec.ts +11 -3
  83. package/src/render-engine/framework-provider.ts +53 -16
  84. package/src/templates/callable-file.ts +122 -0
  85. package/src/templates/extract-delegate-emitter.ts +370 -0
  86. package/src/templates/{recover-schema-emitter.ts → extract-schema-emitter.ts} +39 -19
  87. package/src/templates/extractor.ts +333 -0
  88. package/src/templates/field-meta.ts +2 -0
  89. package/src/templates/filter-type.ts +7 -5
  90. package/src/templates/fr010-field-mapping.ts +71 -18
  91. package/src/templates/inferred-types.ts +32 -18
  92. package/src/templates/output-parser.ts +108 -35
  93. package/src/templates/output-prompt.ts +2 -2
  94. package/src/templates/render-helper.ts +244 -0
  95. package/src/templates/zod-validators.ts +51 -4
  96. package/dist/templates/recover-schema-emitter.d.ts.map +0 -1
  97. package/dist/templates/recover-schema-emitter.js.map +0 -1
@@ -0,0 +1,339 @@
1
+ // server/typescript/packages/codegen-ts/src/templates/extract-delegate-emitter.ts
2
+ //
3
+ // FR-010 Plan 2.1 (nested codegen gap) — the runtime-DELEGATING extract emitter.
4
+ //
5
+ // The self-contained extract<Name>(text) path (extract-schema-emitter + the baked
6
+ // ExtractSchema) covers scalars / enums / scalar-arrays but leaves nested-object and
7
+ // array-of-object components NULL — the historical FR-010 codegen gap. This module emits
8
+ // the additive delegating overload that CLOSES that gap by wrapping the runtime extract:
9
+ //
10
+ // extract<Name>(root: MetaRoot, text, opts?) -> ExtractionResult<<Name>Extracted>
11
+ //
12
+ // It resolves this payload's MetaObject by its baked simple name from the supplied MetaRoot,
13
+ // delegates to extractObject() in @metaobjectsdev/runtime-ts (which assembles the FULL nested
14
+ // object graph reflection-free via the Phase A object model — MetaObject.newInstance() + the
15
+ // MetaField SPI), then maps the assembled ValueObject graph into the typed nullable mirror
16
+ // graph via generated from<VO>(...) mapper functions (payload + every nested VO, deduped).
17
+ //
18
+ // This is the codegen-wrapping-runtime pattern (a generated DAO calling the dynamic-metadata
19
+ // runtime), mirroring the Java SpringOutputParserGenerator + Kotlin pilots. The generated
20
+ // mappers read the assembled graph through a tiny readProp() helper that mirrors the MetaField
21
+ // getValue SPI (ValueObject.get(name) else plain-property access), so the emitted code stays
22
+ // self-sufficient and reflection-free.
23
+ import { TYPE_OBJECT, TYPE_FIELD, FIELD_SUBTYPE_OBJECT, FIELD_SUBTYPE_ENUM, FIELD_ATTR_OBJECT_REF, PACKAGE_SEPARATOR, } from "@metaobjectsdev/metadata";
24
+ import { fields, isArray, scalarKind, jsonStringLiteral } from "./fr010-field-mapping.js";
25
+ function findObject(root, name) {
26
+ return root.ownChildren().find((c) => c.type === TYPE_OBJECT && c.name === name);
27
+ }
28
+ /** The @objectRef target VO for a nested-object field, or undefined when unresolvable. */
29
+ function refVo(field, root) {
30
+ const ref = field.ownAttr(FIELD_ATTR_OBJECT_REF);
31
+ if (typeof ref !== "string")
32
+ return undefined;
33
+ const direct = findObject(root, ref);
34
+ if (direct !== undefined)
35
+ return direct;
36
+ const sep = ref.lastIndexOf(PACKAGE_SEPARATOR);
37
+ if (sep >= 0)
38
+ return findObject(root, ref.slice(sep + PACKAGE_SEPARATOR.length));
39
+ return undefined;
40
+ }
41
+ /** True iff the field is a nested object reference (field.object — distinct from the
42
+ * string-backed field.enum, which is treated as a scalar). */
43
+ function isObjectField(field) {
44
+ return field.subType === FIELD_SUBTYPE_OBJECT;
45
+ }
46
+ /** The extracted-mirror interface name for a value-object (`<Name>Extracted`). */
47
+ export function mirrorName(vo) {
48
+ return `${vo.name}Extracted`;
49
+ }
50
+ /** The mapper function name for a value-object (`from<Name>Extracted`). */
51
+ function mapperName(vo) {
52
+ return `from${vo.name}Extracted`;
53
+ }
54
+ // =============================================================================
55
+ // Nested-aware mirror interfaces (payload + every reachable nested VO)
56
+ // =============================================================================
57
+ /** The nullable mirror TS type for one field — nested-aware (recurses into nested mirror names). */
58
+ function nestedMirrorType(field, root) {
59
+ if (isObjectField(field)) {
60
+ const target = refVo(field, root);
61
+ const base = target !== undefined ? mirrorName(target) : "unknown";
62
+ const elem = `${base} | null`;
63
+ return isArray(field) ? `(${elem})[] | null` : elem;
64
+ }
65
+ if (isArray(field))
66
+ return "(string | null)[] | null";
67
+ if (field.subType === FIELD_SUBTYPE_ENUM)
68
+ return "string | null";
69
+ switch (scalarKind(field.subType)) {
70
+ case "INT":
71
+ case "LONG":
72
+ case "DOUBLE":
73
+ return "number | null";
74
+ case "BOOLEAN":
75
+ return "boolean | null";
76
+ default:
77
+ return "string | null";
78
+ }
79
+ }
80
+ /**
81
+ * Emit the nested-aware mirror interface for `vo` and every value-object reachable from it
82
+ * (deduped by simple name; cycle-safe). The payload mirror keeps the canonical `<Payload>Extracted`
83
+ * name (passed in) so the existing self-contained extract<Name>() and the delegating overload
84
+ * share one mirror type. Returns the joined interface declarations in stable (BFS) order.
85
+ */
86
+ export function nestedMirrorInterfaces(vo, root, payloadMirror) {
87
+ const out = [];
88
+ const seen = new Set();
89
+ emitMirror(vo, root, payloadMirror, seen, out);
90
+ return out.join("\n\n");
91
+ }
92
+ function emitMirror(vo, root, interfaceName, seen, out) {
93
+ if (seen.has(vo.name))
94
+ return;
95
+ seen.add(vo.name);
96
+ const base = interfaceName.endsWith("Extracted")
97
+ ? interfaceName.slice(0, -"Extracted".length)
98
+ : interfaceName;
99
+ const lines = [];
100
+ lines.push(`/** Best-effort extracted twin of \`${base}\` — every field nullable (null where lost/malformed). */`);
101
+ lines.push(`export interface ${interfaceName} {`);
102
+ for (const f of fields(vo)) {
103
+ lines.push(` ${f.name}: ${nestedMirrorType(f, root)};`);
104
+ }
105
+ lines.push("}");
106
+ out.push(lines.join("\n"));
107
+ // Recurse into nested VOs (post-order via the shared seen set → dedupe + cycle guard).
108
+ for (const f of fields(vo)) {
109
+ if (isObjectField(f)) {
110
+ const target = refVo(f, root);
111
+ if (target !== undefined)
112
+ emitMirror(target, root, mirrorName(target), seen, out);
113
+ }
114
+ }
115
+ }
116
+ // =============================================================================
117
+ // Mapper functions (assembled ValueObject graph -> typed nullable mirror graph)
118
+ // =============================================================================
119
+ /**
120
+ * Emit one `from<VO>Extracted(o)` mapper per value-object reachable from `vo` (payload + nested,
121
+ * deduped). Each mapper reads the assembled object via readProp() and recurses into nested
122
+ * mappers for object/array-of-object components. Nested mappers use `from<NestedName>Extracted`
123
+ * returning `<NestedName>Extracted`. The ROOT mapper is overridden to the template-derived names
124
+ * (`rootMapperFn` / `rootMirror`) so it matches the canonically-named root mirror interface — the
125
+ * payload VO's own name may differ from the template name.
126
+ */
127
+ export function nestedMappers(vo, root, rootMapperFn, rootMirror) {
128
+ const out = [];
129
+ const seen = new Set();
130
+ emitMapper(vo, root, seen, out, { fn: rootMapperFn, mirror: rootMirror });
131
+ return out.join("\n\n");
132
+ }
133
+ /** The root mapper's name + mirror — derived from the template, not the payload VO. */
134
+ export function rootMapperName(template) {
135
+ return `from${template}Extracted`;
136
+ }
137
+ function emitMapper(vo, root, seen, out, override) {
138
+ if (seen.has(vo.name))
139
+ return;
140
+ seen.add(vo.name);
141
+ const fn = override?.fn ?? mapperName(vo);
142
+ const mir = override?.mirror ?? mirrorName(vo);
143
+ const assigns = fields(vo).map((f) => ` ${f.name}: ${mapperArg(f, root)},`);
144
+ const body = [
145
+ `/** Map an assembled ValueObject graph into a typed \`${mir}\` mirror. Generated; null-tolerant. */`,
146
+ `function ${fn}(o: unknown): ${mir} | null {`,
147
+ ` if (o == null) return null;`,
148
+ ` return {`,
149
+ ...assigns,
150
+ ` };`,
151
+ `}`,
152
+ ].join("\n");
153
+ out.push(body);
154
+ for (const f of fields(vo)) {
155
+ if (isObjectField(f)) {
156
+ const target = refVo(f, root);
157
+ if (target !== undefined)
158
+ emitMapper(target, root, seen, out);
159
+ }
160
+ }
161
+ }
162
+ /** The mirror-field initializer expression that reads `field` from the assembled object `o`. */
163
+ function mapperArg(field, root) {
164
+ const key = jsonStringLiteral(field.name);
165
+ if (isObjectField(field)) {
166
+ const target = refVo(field, root);
167
+ if (target === undefined)
168
+ return "null /* unresolved @objectRef */";
169
+ const fn = mapperName(target);
170
+ if (isArray(field)) {
171
+ return `mapObjectList(readProp(o, ${key}), ${fn})`;
172
+ }
173
+ return `${fn}(readProp(o, ${key}))`;
174
+ }
175
+ // Enum / scalar / scalar-array: the runtime already coerced; read + light-coerce to the
176
+ // mirror's nullable shape via the locally-defined dlg* readers. (These are distinct from the
177
+ // render ExtractMap helpers `asString(d, key)` etc., which the self-contained path imports — a
178
+ // local helper must NOT shadow those, so the delegate readers carry the `dlg` prefix.)
179
+ // An enum ARRAY is string-backed PER ELEMENT — it must use the list reader, NOT dlgString
180
+ // (which would String()-collapse the whole array into "A,B"). Check isArray before the enum
181
+ // scalar case. The mirror TYPE for an enum array is already `(string | null)[] | null` (see
182
+ // mirrorFieldType), so the list reader matches.
183
+ if (field.subType === FIELD_SUBTYPE_ENUM && isArray(field))
184
+ return `dlgStringList(readProp(o, ${key}))`;
185
+ if (field.subType === FIELD_SUBTYPE_ENUM)
186
+ return `dlgString(readProp(o, ${key}))`;
187
+ if (isArray(field))
188
+ return `dlgStringList(readProp(o, ${key}))`;
189
+ switch (scalarKind(field.subType)) {
190
+ case "INT":
191
+ case "LONG":
192
+ return `dlgInt(readProp(o, ${key}))`;
193
+ case "DOUBLE":
194
+ return `dlgNumber(readProp(o, ${key}))`;
195
+ case "BOOLEAN":
196
+ return `dlgBool(readProp(o, ${key}))`;
197
+ default:
198
+ return `dlgString(readProp(o, ${key}))`;
199
+ }
200
+ }
201
+ /**
202
+ * The set of generated-helper names the mappers for `vo` (+ reachable nested VOs) actually
203
+ * reference. Used to emit only the needed helpers (consumer projects may run noUnusedLocals).
204
+ * `readProp` + at least one dlg* reader are always present once any mapper is emitted.
205
+ */
206
+ export function usedHelpers(vo, root) {
207
+ const used = new Set(["readProp"]);
208
+ const seen = new Set();
209
+ const stack = [vo];
210
+ while (stack.length > 0) {
211
+ const cur = stack.pop();
212
+ if (seen.has(cur.name))
213
+ continue;
214
+ seen.add(cur.name);
215
+ for (const f of fields(cur)) {
216
+ if (isObjectField(f)) {
217
+ const target = refVo(f, root);
218
+ if (target === undefined)
219
+ continue;
220
+ stack.push(target);
221
+ if (isArray(f))
222
+ used.add("mapObjectList");
223
+ continue;
224
+ }
225
+ if (f.subType === FIELD_SUBTYPE_ENUM && isArray(f)) {
226
+ used.add("dlgStringList");
227
+ }
228
+ else if (f.subType === FIELD_SUBTYPE_ENUM) {
229
+ used.add("dlgString");
230
+ }
231
+ else if (isArray(f)) {
232
+ used.add("dlgStringList");
233
+ }
234
+ else {
235
+ switch (scalarKind(f.subType)) {
236
+ case "INT":
237
+ case "LONG":
238
+ used.add("dlgInt");
239
+ break;
240
+ case "DOUBLE":
241
+ used.add("dlgNumber");
242
+ break;
243
+ case "BOOLEAN":
244
+ used.add("dlgBool");
245
+ break;
246
+ default:
247
+ used.add("dlgString");
248
+ }
249
+ }
250
+ }
251
+ }
252
+ return used;
253
+ }
254
+ /** True iff the payload (or any reachable nested VO) has a nested-object / array-of-object field. */
255
+ export function hasNested(vo, root) {
256
+ const seen = new Set();
257
+ const stack = [vo];
258
+ while (stack.length > 0) {
259
+ const cur = stack.pop();
260
+ if (seen.has(cur.name))
261
+ continue;
262
+ seen.add(cur.name);
263
+ for (const f of cur.children().filter((c) => c.type === TYPE_FIELD)) {
264
+ if (isObjectField(f)) {
265
+ const target = refVo(f, root);
266
+ if (target !== undefined) {
267
+ stack.push(target);
268
+ }
269
+ // a nested object field exists regardless of resolvability → still "has nested"
270
+ if (f.subType === FIELD_SUBTYPE_OBJECT)
271
+ return true;
272
+ }
273
+ }
274
+ }
275
+ return false;
276
+ }
277
+ /**
278
+ * The shared runtime-side helper block the generated mappers rely on:
279
+ * • readProp — null-tolerant read mirroring the MetaField getValue SPI (ValueObject.get(name)
280
+ * else plain-property access); keeps the mappers reflection-free + backing-agnostic.
281
+ * • mapObjectList — map each element of an assembled array via a per-element mapper.
282
+ * • dlg* readers — light null-tolerant coercion to the mirror's nullable scalar shapes. The
283
+ * `dlg` prefix avoids shadowing the render ExtractMap helpers (`asString(d, key)` etc.) that
284
+ * the self-contained extract path imports into the SAME file — a collision would silently
285
+ * rebind those two-arg map readers to these one-arg readers.
286
+ * Emitted once per parser file.
287
+ */
288
+ export function delegateHelpers(used) {
289
+ const blocks = ["// ---- runtime-delegating extract helpers (generated) ----"];
290
+ // readProp is always needed once a mapper exists.
291
+ blocks.push(`/** Read a property from an assembled backing object, mirroring the MetaField getValue SPI. */
292
+ function readProp(o: unknown, name: string): unknown {
293
+ if (o == null) return undefined;
294
+ const vo = o as { get?: (n: string) => unknown };
295
+ if (typeof vo.get === "function") return vo.get(name);
296
+ return (o as Record<string, unknown>)[name];
297
+ }`);
298
+ if (used.has("mapObjectList")) {
299
+ blocks.push(`/** Map each element of an assembled array via \`fn\`; null/absent -> null; non-mappable -> filtered. */
300
+ function mapObjectList<T>(v: unknown, fn: (o: unknown) => T | null): (T | null)[] | null {
301
+ if (!Array.isArray(v)) return null;
302
+ return v.map((e) => fn(e));
303
+ }`);
304
+ }
305
+ if (used.has("dlgString")) {
306
+ blocks.push(`function dlgString(v: unknown): string | null {
307
+ return v == null ? null : String(v);
308
+ }`);
309
+ }
310
+ if (used.has("dlgInt")) {
311
+ blocks.push(`function dlgInt(v: unknown): number | null {
312
+ if (v == null) return null;
313
+ const n = typeof v === "number" ? v : Number(v);
314
+ return Number.isFinite(n) ? Math.trunc(n) : null;
315
+ }`);
316
+ }
317
+ if (used.has("dlgNumber")) {
318
+ blocks.push(`function dlgNumber(v: unknown): number | null {
319
+ if (v == null) return null;
320
+ const n = typeof v === "number" ? v : Number(v);
321
+ return Number.isFinite(n) ? n : null;
322
+ }`);
323
+ }
324
+ if (used.has("dlgBool")) {
325
+ blocks.push(`function dlgBool(v: unknown): boolean | null {
326
+ if (v == null) return null;
327
+ if (typeof v === "boolean") return v;
328
+ return String(v).toLowerCase() === "true";
329
+ }`);
330
+ }
331
+ if (used.has("dlgStringList")) {
332
+ blocks.push(`function dlgStringList(v: unknown): (string | null)[] | null {
333
+ if (!Array.isArray(v)) return null;
334
+ return v.map((e) => (e == null ? null : String(e)));
335
+ }`);
336
+ }
337
+ return blocks.join("\n\n");
338
+ }
339
+ //# sourceMappingURL=extract-delegate-emitter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extract-delegate-emitter.js","sourceRoot":"","sources":["../../src/templates/extract-delegate-emitter.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,8 @@
1
1
  import { type MetaData } from "@metaobjectsdev/metadata";
2
- /** Emit `recoverSchema(Format.X, "rootName", [ … ])`. */
2
+ /** Emit `extractSchema(Format.X, "rootName", [ … ])`. */
3
3
  export declare function schemaLiteral(vo: MetaData, format: string, rootName: string): string;
4
4
  /** Emit the all-nullable mirror interface declaration. */
5
5
  export declare function mirrorInterface(vo: MetaData, interfaceName: string): string;
6
6
  /** Emit `{ prop: asString(d, "prop"), … }` building the mirror from the forgiving map `d`. */
7
7
  export declare function mirrorInitializer(vo: MetaData): string;
8
- //# sourceMappingURL=recover-schema-emitter.d.ts.map
8
+ //# sourceMappingURL=extract-schema-emitter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extract-schema-emitter.d.ts","sourceRoot":"","sources":["../../src/templates/extract-schema-emitter.ts"],"names":[],"mappings":"AAcA,OAAO,EACL,KAAK,QAAQ,EAId,MAAM,0BAA0B,CAAC;AAkBlC,yDAAyD;AACzD,wBAAgB,aAAa,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAIpF;AA+CD,0DAA0D;AAC1D,wBAAgB,eAAe,CAAC,EAAE,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,GAAG,MAAM,CAc3E;AAED,8FAA8F;AAC9F,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,QAAQ,GAAG,MAAM,CAGtD"}
@@ -1,41 +1,58 @@
1
- // server/typescript/packages/codegen-ts/src/templates/recover-schema-emitter.ts
1
+ // server/typescript/packages/codegen-ts/src/templates/extract-schema-emitter.ts
2
2
  //
3
- // Turns a payload value-object into TS source fragments for the FR-010 recover codegen:
4
- // • schemaLiteral — a `recoverSchema(Format.JSON, "root", [ … ])` baked descriptor
3
+ // Turns a payload value-object into TS source fragments for the FR-010 extract codegen:
4
+ // • schemaLiteral — a `extractSchema(Format.JSON, "root", [ … ])` baked descriptor
5
5
  // built from FieldSpec factories (scalar / enumField).
6
- // • mirrorInterface — an all-nullable mirror interface `<Payload>Recovered` (each
7
- // component `T | null`); recover returns this nullable twin rather
6
+ // • mirrorInterface — an all-nullable mirror interface `<Payload>Extracted` (each
7
+ // component `T | null`); extract returns this nullable twin rather
8
8
  // than the strict payload (same reasoning as the Java/C#/Kotlin ports).
9
9
  // • mirrorInitializer — `{ prop: asString(d, "prop"), … }` building the mirror from the
10
10
  // forgiving outcome map `d`.
11
11
  //
12
- // Mirrors the C# RecoverSchemaEmitter (adapted to TS syntax + the `| null` nullable mirror).
12
+ // Mirrors the C# ExtractSchemaEmitter (adapted to TS syntax + the `| null` nullable mirror).
13
13
  // Bounded scope: scalar / enum / scalar-array. Nested object + array-of-enum deferred.
14
14
  import { FIELD_SUBTYPE_ENUM, FIELD_SUBTYPE_OBJECT, FIELD_ATTR_ENUM_ALIAS, } from "@metaobjectsdev/metadata";
15
- import { fields, isRequired, isArray, scalarKind, mirrorType, recoverMapCall, enumValues, jsonStringLiteral, stringArrayLiteral, propertiesMapLiteral, } from "./fr010-field-mapping.js";
16
- /** Emit `recoverSchema(Format.X, "rootName", [ … ])`. */
15
+ import { fields, isRequired, isArray, scalarKind, mirrorType, extractMapCall, enumValues, coerceDefault, defaultValue, resolveNormalize, jsonStringLiteral, stringArrayLiteral, propertiesMapLiteral, } from "./fr010-field-mapping.js";
16
+ import { NORMALIZE_DEFAULT } from "@metaobjectsdev/metadata";
17
+ /** Emit `extractSchema(Format.X, "rootName", [ … ])`. */
17
18
  export function schemaLiteral(vo, format, rootName) {
18
19
  const formatEnum = format.toLowerCase() === "xml" ? "Format.XML" : "Format.JSON";
19
- const specs = fields(vo).map(fieldSpecLiteral);
20
- return `recoverSchema(${formatEnum}, ${jsonStringLiteral(rootName)}, [${specs.join(", ")}])`;
20
+ const specs = fields(vo).map((f) => fieldSpecLiteral(f, vo));
21
+ return `extractSchema(${formatEnum}, ${jsonStringLiteral(rootName)}, [${specs.join(", ")}])`;
21
22
  }
22
- function fieldSpecLiteral(field) {
23
+ function fieldSpecLiteral(field, owner) {
23
24
  const name = jsonStringLiteral(field.name);
24
25
  const required = isRequired(field);
25
26
  if (field.subType === FIELD_SUBTYPE_ENUM) {
26
27
  const valuesLit = stringArrayLiteral(enumValues(field));
27
28
  const aliasLit = propertiesMapLiteral(field.ownAttr(FIELD_ATTR_ENUM_ALIAS));
29
+ // FR-011: extended enumField signature is (name, required, values, aliases,
30
+ // coerceDefault?, normalize="strip", defaultValue?). Resolve the three new args
31
+ // (field → object → "strip" for normalize) and emit only what's needed: keep the
32
+ // back-compat 4-arg form when nothing is set, else emit the positional tail up to
33
+ // the last meaningful arg.
34
+ const cd = coerceDefault(field);
35
+ const dv = defaultValue(field);
36
+ const normalize = resolveNormalize(field, owner);
28
37
  // enumField() sets array:false; enum-array is a bounded deferral (parity with Java/C#).
29
- return `enumField(${name}, ${required}, ${valuesLit}, ${aliasLit})`;
38
+ if (cd == null && dv == null && normalize === NORMALIZE_DEFAULT) {
39
+ return `enumField(${name}, ${required}, ${valuesLit}, ${aliasLit})`;
40
+ }
41
+ const cdLit = cd == null ? "null" : jsonStringLiteral(cd);
42
+ const normLit = jsonStringLiteral(normalize);
43
+ if (dv == null) {
44
+ return `enumField(${name}, ${required}, ${valuesLit}, ${aliasLit}, ${cdLit}, ${normLit})`;
45
+ }
46
+ return `enumField(${name}, ${required}, ${valuesLit}, ${aliasLit}, ${cdLit}, ${normLit}, ${jsonStringLiteral(dv)})`;
30
47
  }
31
48
  if (field.subType === FIELD_SUBTYPE_OBJECT) {
32
- // FR-010: nested recover deferred — treat as an opaque required/optional string slot.
33
- return `scalar(${name}, FieldKind.STRING, ${required}) /* FR-010: nested recover deferred */`;
49
+ // FR-010: nested extract deferred — treat as an opaque required/optional string slot.
50
+ return `scalar(${name}, FieldKind.STRING, ${required}) /* FR-010: nested extract deferred */`;
34
51
  }
35
52
  const kind = scalarKind(field.subType) ?? "STRING";
36
53
  // Scalar-array: the scalar() factory only builds singular specs (array:false), so emit a
37
54
  // FieldSpec object literal with array:true. Tier-2 win over the Roslyn proof: the emitted
38
- // recover() actually populates the array at runtime (RecoverMap.asStringList).
55
+ // extract() actually populates the array at runtime (ExtractMap.asStringList).
39
56
  if (isArray(field)) {
40
57
  return (`{ name: ${name}, kind: FieldKind.${kind}, required: ${required}, array: true, ` +
41
58
  `enumValues: null, enumAlias: null, min: null, max: null, nested: null }`);
@@ -44,11 +61,11 @@ function fieldSpecLiteral(field) {
44
61
  }
45
62
  /** Emit the all-nullable mirror interface declaration. */
46
63
  export function mirrorInterface(vo, interfaceName) {
47
- const base = interfaceName.endsWith("Recovered")
48
- ? interfaceName.slice(0, -"Recovered".length)
64
+ const base = interfaceName.endsWith("Extracted")
65
+ ? interfaceName.slice(0, -"Extracted".length)
49
66
  : interfaceName;
50
67
  const lines = [];
51
- lines.push(`/** Best-effort recovered twin of \`${base}\` — every field nullable (null where lost/malformed). */`);
68
+ lines.push(`/** Best-effort extracted twin of \`${base}\` — every field nullable (null where lost/malformed). */`);
52
69
  lines.push(`export interface ${interfaceName} {`);
53
70
  for (const f of fields(vo)) {
54
71
  lines.push(` ${f.name}: ${mirrorType(f)};`);
@@ -58,7 +75,7 @@ export function mirrorInterface(vo, interfaceName) {
58
75
  }
59
76
  /** Emit `{ prop: asString(d, "prop"), … }` building the mirror from the forgiving map `d`. */
60
77
  export function mirrorInitializer(vo) {
61
- const assigns = fields(vo).map((f) => `${f.name}: ${recoverMapCall(f)}`);
78
+ const assigns = fields(vo).map((f) => `${f.name}: ${extractMapCall(f)}`);
62
79
  return `{ ${assigns.join(", ")} }`;
63
80
  }
64
- //# sourceMappingURL=recover-schema-emitter.js.map
81
+ //# sourceMappingURL=extract-schema-emitter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extract-schema-emitter.js","sourceRoot":"","sources":["../../src/templates/extract-schema-emitter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import { type MetaData } from "@metaobjectsdev/metadata";
2
+ /**
3
+ * Render the full `<TemplateName>.extractor.ts` for one `template.output` node.
4
+ * Throws if the template isn't found / isn't a template.output / its @payloadRef doesn't resolve,
5
+ * or if the target format is not json/xml (the extract tier requires the extract<Name> API, which
6
+ * only the json/xml output-parsers emit).
7
+ */
8
+ export declare function renderExtractor(root: MetaData, templateName: string): string;
9
+ //# sourceMappingURL=extractor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extractor.d.ts","sourceRoot":"","sources":["../../src/templates/extractor.ts"],"names":[],"mappings":"AAsBA,OAAO,EACL,KAAK,QAAQ,EAYd,MAAM,0BAA0B,CAAC;AAyNlC;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CA0E5E"}