@metaobjectsdev/codegen-ts 0.7.0 → 0.8.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 (67) hide show
  1. package/dist/generators/entity-file.d.ts.map +1 -1
  2. package/dist/generators/entity-file.js +7 -0
  3. package/dist/generators/entity-file.js.map +1 -1
  4. package/dist/generators/index.d.ts +1 -0
  5. package/dist/generators/index.d.ts.map +1 -1
  6. package/dist/generators/index.js +1 -0
  7. package/dist/generators/index.js.map +1 -1
  8. package/dist/generators/output-prompt-file.d.ts +9 -0
  9. package/dist/generators/output-prompt-file.d.ts.map +1 -0
  10. package/dist/generators/output-prompt-file.js +51 -0
  11. package/dist/generators/output-prompt-file.js.map +1 -0
  12. package/dist/index.d.ts +1 -0
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js +1 -0
  15. package/dist/index.js.map +1 -1
  16. package/dist/instance-artifacts.d.ts +29 -0
  17. package/dist/instance-artifacts.d.ts.map +1 -0
  18. package/dist/instance-artifacts.js +57 -0
  19. package/dist/instance-artifacts.js.map +1 -0
  20. package/dist/metaobjects-config.d.ts +10 -0
  21. package/dist/metaobjects-config.d.ts.map +1 -1
  22. package/dist/metaobjects-config.js +1 -0
  23. package/dist/metaobjects-config.js.map +1 -1
  24. package/dist/render-context.d.ts +4 -1
  25. package/dist/render-context.d.ts.map +1 -1
  26. package/dist/render-context.js +1 -0
  27. package/dist/render-context.js.map +1 -1
  28. package/dist/runner.d.ts.map +1 -1
  29. package/dist/runner.js +1 -0
  30. package/dist/runner.js.map +1 -1
  31. package/dist/templates/entity-file.d.ts.map +1 -1
  32. package/dist/templates/entity-file.js +12 -0
  33. package/dist/templates/entity-file.js.map +1 -1
  34. package/dist/templates/fr010-field-mapping.d.ts +28 -0
  35. package/dist/templates/fr010-field-mapping.d.ts.map +1 -0
  36. package/dist/templates/fr010-field-mapping.js +170 -0
  37. package/dist/templates/fr010-field-mapping.js.map +1 -0
  38. package/dist/templates/output-format-spec-emitter.d.ts +4 -0
  39. package/dist/templates/output-format-spec-emitter.d.ts.map +1 -0
  40. package/dist/templates/output-format-spec-emitter.js +60 -0
  41. package/dist/templates/output-format-spec-emitter.js.map +1 -0
  42. package/dist/templates/output-parser.d.ts.map +1 -1
  43. package/dist/templates/output-parser.js +69 -4
  44. package/dist/templates/output-parser.js.map +1 -1
  45. package/dist/templates/output-prompt.d.ts +10 -0
  46. package/dist/templates/output-prompt.d.ts.map +1 -0
  47. package/dist/templates/output-prompt.js +75 -0
  48. package/dist/templates/output-prompt.js.map +1 -0
  49. package/dist/templates/recover-schema-emitter.d.ts +8 -0
  50. package/dist/templates/recover-schema-emitter.d.ts.map +1 -0
  51. package/dist/templates/recover-schema-emitter.js +64 -0
  52. package/dist/templates/recover-schema-emitter.js.map +1 -0
  53. package/package.json +4 -4
  54. package/src/generators/entity-file.ts +7 -0
  55. package/src/generators/index.ts +1 -0
  56. package/src/generators/output-prompt-file.ts +66 -0
  57. package/src/index.ts +1 -0
  58. package/src/instance-artifacts.ts +61 -0
  59. package/src/metaobjects-config.ts +11 -0
  60. package/src/render-context.ts +5 -1
  61. package/src/runner.ts +1 -0
  62. package/src/templates/entity-file.ts +13 -0
  63. package/src/templates/fr010-field-mapping.ts +191 -0
  64. package/src/templates/output-format-spec-emitter.ts +97 -0
  65. package/src/templates/output-parser.ts +77 -2
  66. package/src/templates/output-prompt.ts +88 -0
  67. package/src/templates/recover-schema-emitter.ts +91 -0
@@ -0,0 +1,170 @@
1
+ // server/typescript/packages/codegen-ts/src/templates/fr010-field-mapping.ts
2
+ //
3
+ // Shared field-kind mapping for the FR-010 codegen emitters (recover-schema-emitter +
4
+ // output-format-spec-emitter). Maps a metadata field subtype onto the render engine's
5
+ // FieldKind member, the idiomatic nullable TS type used by the recover mirror interface,
6
+ // and the RecoverMap accessor that reads it from the forgiving outcome map.
7
+ //
8
+ // Mirrors the C# Fr010FieldMapping (adapted to TS syntax + the `| null` nullable mirror).
9
+ // Bounded scope (parity with Java/Kotlin/C#): scalar / enum / scalar-array. Nested object +
10
+ // array-of-enum are deferred.
11
+ import { TYPE_FIELD, FIELD_SUBTYPE_STRING, FIELD_SUBTYPE_CLASS, FIELD_SUBTYPE_DATE, FIELD_SUBTYPE_TIME, FIELD_SUBTYPE_TIMESTAMP, FIELD_SUBTYPE_INT, FIELD_SUBTYPE_SHORT, FIELD_SUBTYPE_BYTE, FIELD_SUBTYPE_LONG, FIELD_SUBTYPE_CURRENCY, FIELD_SUBTYPE_DOUBLE, FIELD_SUBTYPE_FLOAT, FIELD_SUBTYPE_DECIMAL, FIELD_SUBTYPE_BOOLEAN, FIELD_SUBTYPE_ENUM, FIELD_SUBTYPE_OBJECT, FIELD_ATTR_REQUIRED, FIELD_ATTR_VALUES, } from "@metaobjectsdev/metadata";
12
+ /** The render-engine FieldKind member name for a scalar field subtype, or null if non-scalar. */
13
+ export function scalarKind(subType) {
14
+ switch (subType) {
15
+ case FIELD_SUBTYPE_STRING:
16
+ case FIELD_SUBTYPE_CLASS:
17
+ case FIELD_SUBTYPE_DATE:
18
+ case FIELD_SUBTYPE_TIME:
19
+ case FIELD_SUBTYPE_TIMESTAMP:
20
+ return "STRING";
21
+ case FIELD_SUBTYPE_INT:
22
+ case FIELD_SUBTYPE_SHORT:
23
+ case FIELD_SUBTYPE_BYTE:
24
+ return "INT";
25
+ case FIELD_SUBTYPE_LONG:
26
+ case FIELD_SUBTYPE_CURRENCY:
27
+ return "LONG";
28
+ case FIELD_SUBTYPE_DOUBLE:
29
+ case FIELD_SUBTYPE_FLOAT:
30
+ case FIELD_SUBTYPE_DECIMAL:
31
+ return "DOUBLE";
32
+ case FIELD_SUBTYPE_BOOLEAN:
33
+ return "BOOLEAN";
34
+ default:
35
+ return null;
36
+ }
37
+ }
38
+ /** The field children of a payload value-object, in declaration order. */
39
+ export function fields(vo) {
40
+ return vo.children().filter((c) => c.type === TYPE_FIELD);
41
+ }
42
+ /** isArray is a native (reserved) property on MetaData, not an attr. */
43
+ export function isArray(field) {
44
+ return field.isArray === true;
45
+ }
46
+ /** True iff the field's @required is explicitly true (or the string "true"). */
47
+ export function isRequired(field) {
48
+ const v = field.ownAttr(FIELD_ATTR_REQUIRED);
49
+ if (v === true)
50
+ return true;
51
+ return typeof v === "string" && v.toLowerCase() === "true";
52
+ }
53
+ /** The string members of an enum field's @values attr (empty when absent). */
54
+ export function enumValues(field) {
55
+ const v = field.ownAttr(FIELD_ATTR_VALUES);
56
+ if (Array.isArray(v))
57
+ return v.map((e) => String(e));
58
+ return [];
59
+ }
60
+ /** The nullable TS type for a field in the recover mirror interface. */
61
+ export function mirrorType(field) {
62
+ // Matches asStringList's `(string | null)[] | null` return — a recovered array
63
+ // can contain null elements where individual items were lost.
64
+ if (isArray(field))
65
+ return "(string | null)[] | null";
66
+ if (field.subType === FIELD_SUBTYPE_OBJECT)
67
+ return "unknown"; // nested deferred
68
+ if (field.subType === FIELD_SUBTYPE_ENUM)
69
+ return "string | null"; // enum is string-backed
70
+ switch (scalarKind(field.subType)) {
71
+ case "INT":
72
+ case "LONG":
73
+ case "DOUBLE":
74
+ return "number | null";
75
+ case "BOOLEAN":
76
+ return "boolean | null";
77
+ default:
78
+ return "string | null";
79
+ }
80
+ }
81
+ /**
82
+ * The RecoverMap.as* helper name that reads this field from the forgiving map, or null
83
+ * for a nested object (which emits a null literal, not a helper call). Single source of
84
+ * truth for the per-field dispatch — both recoverMapCall and recoverMapHelpersUsed use it.
85
+ */
86
+ function recoverMapHelper(field) {
87
+ if (isArray(field))
88
+ return "asStringList";
89
+ if (field.subType === FIELD_SUBTYPE_OBJECT)
90
+ return null; // null literal, no helper
91
+ if (field.subType === FIELD_SUBTYPE_ENUM)
92
+ return "asString";
93
+ switch (scalarKind(field.subType)) {
94
+ case "INT":
95
+ return "asInt";
96
+ case "LONG":
97
+ return "asLong";
98
+ case "DOUBLE":
99
+ return "asDouble";
100
+ case "BOOLEAN":
101
+ return "asBool";
102
+ default:
103
+ return "asString";
104
+ }
105
+ }
106
+ /** The RecoverMap.as* helper name + call that reads this field from the forgiving map `d`. */
107
+ export function recoverMapCall(field) {
108
+ const helper = recoverMapHelper(field);
109
+ if (helper === null)
110
+ return "null /* FR-010: nested recover deferred */";
111
+ return `${helper}(d, ${jsonStringLiteral(field.name)})`;
112
+ }
113
+ /** Distinct RecoverMap helper names used across a value-object's fields (for the import). */
114
+ export function recoverMapHelpersUsed(vo) {
115
+ const used = new Set();
116
+ for (const f of fields(vo)) {
117
+ const helper = recoverMapHelper(f);
118
+ if (helper !== null)
119
+ used.add(helper);
120
+ }
121
+ return [...used].sort();
122
+ }
123
+ /** A TS double-quoted string literal for `value`, with the load-bearing chars escaped. */
124
+ export function jsonStringLiteral(value) {
125
+ let out = '"';
126
+ for (const ch of value) {
127
+ switch (ch) {
128
+ case "\\":
129
+ out += "\\\\";
130
+ break;
131
+ case '"':
132
+ out += '\\"';
133
+ break;
134
+ case "\t":
135
+ out += "\\t";
136
+ break;
137
+ case "\n":
138
+ out += "\\n";
139
+ break;
140
+ case "\r":
141
+ out += "\\r";
142
+ break;
143
+ default:
144
+ out += ch;
145
+ }
146
+ }
147
+ return out + '"';
148
+ }
149
+ /** A TS array literal `["a", "b"]` for the given members. */
150
+ export function stringArrayLiteral(values) {
151
+ return "[" + values.map((v) => jsonStringLiteral(v)).join(", ") + "]";
152
+ }
153
+ /**
154
+ * A TS object literal `{ "k": "v", … }` for a properties-shaped attr (e.g. @enumAlias /
155
+ * @enumDoc), or "null" when absent/empty. Null values are dropped; keys are sorted
156
+ * ordinally for deterministic output (matches the canonical-serializer properties sort).
157
+ */
158
+ export function propertiesMapLiteral(attr) {
159
+ if (attr == null || typeof attr !== "object" || Array.isArray(attr))
160
+ return "null";
161
+ const d = attr;
162
+ const entries = Object.keys(d)
163
+ .filter((k) => d[k] != null)
164
+ .sort()
165
+ .map((k) => `${jsonStringLiteral(k)}: ${jsonStringLiteral(String(d[k]))}`);
166
+ if (entries.length === 0)
167
+ return "null";
168
+ return "{ " + entries.join(", ") + " }";
169
+ }
170
+ //# sourceMappingURL=fr010-field-mapping.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fr010-field-mapping.js","sourceRoot":"","sources":["../../src/templates/fr010-field-mapping.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import { type MetaData } from "@metaobjectsdev/metadata";
2
+ /** Emit `{ format, rootName, style, fields: [ … ] } satisfies OutputFormatSpec`. */
3
+ export declare function specLiteral(vo: MetaData, template: MetaData, rootName: string): string;
4
+ //# sourceMappingURL=output-format-spec-emitter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output-format-spec-emitter.d.ts","sourceRoot":"","sources":["../../src/templates/output-format-spec-emitter.ts"],"names":[],"mappings":"AASA,OAAO,EACL,KAAK,QAAQ,EAUd,MAAM,0BAA0B,CAAC;AAYlC,oFAAoF;AACpF,wBAAgB,WAAW,CAAC,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAQtF"}
@@ -0,0 +1,60 @@
1
+ // server/typescript/packages/codegen-ts/src/templates/output-format-spec-emitter.ts
2
+ //
3
+ // Turns a payload value-object + its template.output node into a TS source literal for an
4
+ // OutputFormatSpec — the artifact-1 prompt descriptor used by the FR-010 output-prompt codegen.
5
+ //
6
+ // Emits an `{ format, rootName, style, fields: [ … ] } satisfies OutputFormatSpec` literal.
7
+ // Mirrors the C# OutputFormatSpecEmitter (adapted to TS syntax). Field-kind mapping is shared
8
+ // via fr010-field-mapping. Bounded scope: scalar / enum. Nested object → FieldKind.OBJECT placeholder.
9
+ import { FIELD_SUBTYPE_ENUM, FIELD_SUBTYPE_OBJECT, FIELD_ATTR_EXAMPLE, FIELD_ATTR_INSTRUCTION, FIELD_ATTR_ENUM_DOC, TEMPLATE_ATTR_FORMAT, TEMPLATE_ATTR_PROMPT_STYLE, PROMPT_STYLE_INLINE, PROMPT_STYLE_EXAMPLE_ONLY, } from "@metaobjectsdev/metadata";
10
+ import { fields, isRequired, isArray, scalarKind, enumValues, jsonStringLiteral, stringArrayLiteral, propertiesMapLiteral, } from "./fr010-field-mapping.js";
11
+ /** Emit `{ format, rootName, style, fields: [ … ] } satisfies OutputFormatSpec`. */
12
+ export function specLiteral(vo, template, rootName) {
13
+ const formatEnum = resolveFormat(template);
14
+ const styleEnum = resolvePromptStyle(template);
15
+ const fieldLits = fields(vo).map(promptFieldLiteral);
16
+ return (`{ format: ${formatEnum}, rootName: ${jsonStringLiteral(rootName)}, ` +
17
+ `style: ${styleEnum}, fields: [${fieldLits.join(", ")}] } satisfies OutputFormatSpec`);
18
+ }
19
+ function resolveFormat(template) {
20
+ const f = template.ownAttr(TEMPLATE_ATTR_FORMAT);
21
+ return typeof f === "string" && f.toLowerCase() === "xml" ? "Format.XML" : "Format.JSON";
22
+ }
23
+ function resolvePromptStyle(template) {
24
+ switch (template.ownAttr(TEMPLATE_ATTR_PROMPT_STYLE)) {
25
+ case PROMPT_STYLE_INLINE:
26
+ return "PromptStyle.INLINE";
27
+ case PROMPT_STYLE_EXAMPLE_ONLY:
28
+ return "PromptStyle.EXAMPLE_ONLY";
29
+ default:
30
+ return "PromptStyle.GUIDE";
31
+ }
32
+ }
33
+ /** A PromptField object literal. Field order matches the PromptField interface. */
34
+ function promptFieldLiteral(field) {
35
+ const name = jsonStringLiteral(field.name);
36
+ const required = isRequired(field);
37
+ const array = isArray(field);
38
+ if (field.subType === FIELD_SUBTYPE_OBJECT) {
39
+ return (`{ name: ${name}, kind: FieldKind.OBJECT, required: ${required}, array: ${array}, ` +
40
+ `enumValues: null, enumDoc: null, example: null, instruction: null, nested: null }` +
41
+ ` /* FR-010: nested prompt deferred */`);
42
+ }
43
+ const example = optStringAttr(field, FIELD_ATTR_EXAMPLE);
44
+ const instruction = optStringAttr(field, FIELD_ATTR_INSTRUCTION);
45
+ if (field.subType === FIELD_SUBTYPE_ENUM) {
46
+ const valuesLit = stringArrayLiteral(enumValues(field));
47
+ const enumDocLit = propertiesMapLiteral(field.ownAttr(FIELD_ATTR_ENUM_DOC));
48
+ return (`{ name: ${name}, kind: FieldKind.ENUM, required: ${required}, array: ${array}, ` +
49
+ `enumValues: ${valuesLit}, enumDoc: ${enumDocLit}, example: ${example}, ` +
50
+ `instruction: ${instruction}, nested: null }`);
51
+ }
52
+ const kind = scalarKind(field.subType) ?? "STRING";
53
+ return (`{ name: ${name}, kind: FieldKind.${kind}, required: ${required}, array: ${array}, ` +
54
+ `enumValues: null, enumDoc: null, example: ${example}, instruction: ${instruction}, nested: null }`);
55
+ }
56
+ function optStringAttr(field, attrName) {
57
+ const v = field.ownAttr(attrName);
58
+ return typeof v === "string" ? jsonStringLiteral(v) : "null";
59
+ }
60
+ //# sourceMappingURL=output-format-spec-emitter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output-format-spec-emitter.js","sourceRoot":"","sources":["../../src/templates/output-format-spec-emitter.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"output-parser.d.ts","sourceRoot":"","sources":["../../src/templates/output-parser.ts"],"names":[],"mappings":"AAUA,OAAO,EACL,KAAK,QAAQ,EAQd,MAAM,0BAA0B,CAAC;AAyDlC;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CA6D/E"}
1
+ {"version":3,"file":"output-parser.d.ts","sourceRoot":"","sources":["../../src/templates/output-parser.ts"],"names":[],"mappings":"AAUA,OAAO,EACL,KAAK,QAAQ,EASd,MAAM,0BAA0B,CAAC;AA+DlC;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAiI/E"}
@@ -7,7 +7,9 @@
7
7
  // `<TemplateName>Data`. Consumers wiring `promptRender()` get a structurally
8
8
  // identical payload-VO interface in `prompts.ts`; either type can be used
9
9
  // interchangeably with parse results.
10
- import { TYPE_OBJECT, TYPE_FIELD, TYPE_TEMPLATE, TEMPLATE_SUBTYPE_OUTPUT, FIELD_SUBTYPE_OBJECT, FIELD_ATTR_OBJECT_REF, TEMPLATE_ATTR_PAYLOAD_REF, } from "@metaobjectsdev/metadata";
10
+ import { TYPE_OBJECT, TYPE_FIELD, TYPE_TEMPLATE, TEMPLATE_SUBTYPE_OUTPUT, FIELD_SUBTYPE_OBJECT, FIELD_ATTR_OBJECT_REF, TEMPLATE_ATTR_PAYLOAD_REF, TEMPLATE_ATTR_FORMAT, } from "@metaobjectsdev/metadata";
11
+ import { schemaLiteral, mirrorInterface, mirrorInitializer, } from "./recover-schema-emitter.js";
12
+ import { recoverMapHelpersUsed } from "./fr010-field-mapping.js";
11
13
  const SCALAR_ZOD = {
12
14
  string: "z.string()",
13
15
  class: "z.string()",
@@ -88,9 +90,13 @@ export function renderOutputParser(root, templateName) {
88
90
  const errorName = `${templateName}ValidationError`;
89
91
  const parseName = `parse${templateName}`;
90
92
  const safeParseName = `safeParse${templateName}`;
91
- return `import { z } from "zod";
92
-
93
- const ${schemaName} = ${schema};
93
+ // FR-010: emit the tolerant recover() API alongside the strict Zod parser when the
94
+ // template targets json/xml. The @payloadRef already resolved to a value-object above,
95
+ // so a RecoverSchema can always be baked. text-format outputs get no recover.
96
+ const format = tmpl.ownAttr(TEMPLATE_ATTR_FORMAT) ?? "text";
97
+ const lc = format.toLowerCase();
98
+ const emitRecover = lc === "json" || lc === "xml";
99
+ const strictBody = `const ${schemaName} = ${schema};
94
100
 
95
101
  export type ${dataName} = z.infer<typeof ${schemaName}>;
96
102
  export type ${errorName} = z.ZodError;
@@ -125,5 +131,64 @@ export function ${safeParseName}(
125
131
  : { success: false, error: result.error };
126
132
  }
127
133
  `;
134
+ if (!emitRecover) {
135
+ return `import { z } from "zod";\n\n${strictBody}`;
136
+ }
137
+ // ---- FR-010 tolerant recover block (json/xml only) ----
138
+ const recoveredName = `${templateName}Recovered`;
139
+ const recoverFnName = `recover${templateName}`;
140
+ const tryRecoverName = `tryRecover${templateName}`;
141
+ const schemaConstName = `${templateName}RecoverSchema`;
142
+ const schemaLit = schemaLiteral(vo, format, payloadRef);
143
+ const mirrorDecl = mirrorInterface(vo, recoveredName);
144
+ const initializer = mirrorInitializer(vo);
145
+ const mapHelpers = recoverMapHelpersUsed(vo);
146
+ // Render-package imports the recover block needs. Only pull in the names the emitted
147
+ // source actually references, so the file has no unused imports (tsc noUnusedLocals-safe).
148
+ const renderImports = ["recover", "recoverSchema", "Format"];
149
+ if (schemaLit.includes("scalar("))
150
+ renderImports.push("scalar");
151
+ if (schemaLit.includes("enumField("))
152
+ renderImports.push("enumField");
153
+ if (schemaLit.includes("FieldKind."))
154
+ renderImports.push("FieldKind");
155
+ renderImports.push("type RecoverSchema", "type RecoverOptions", "type RecoveryResult");
156
+ renderImports.push(...mapHelpers);
157
+ const recoverBody = `/** Baked recover descriptor for the ${templateName} output. */
158
+ const ${schemaConstName}: RecoverSchema = ${schemaLit};
159
+
160
+ ${mirrorDecl}
161
+
162
+ /**
163
+ * Tolerant best-effort recovery of a dirty LLM response; never throws. Returns a
164
+ * nullable mirror (\`${recoveredName}\`) with fields null where lost/malformed,
165
+ * plus the per-field recovery report.
166
+ */
167
+ export function ${recoverFnName}(
168
+ text: string,
169
+ opts?: RecoverOptions,
170
+ ): RecoveryResult<${recoveredName}> {
171
+ const outcome = recover(text, ${schemaConstName}, opts);
172
+ const d = outcome.data;
173
+ const data: ${recoveredName} = ${initializer};
174
+ return { data, report: outcome.report };
175
+ }
176
+
177
+ /**
178
+ * Recovery as a bool gate: \`true\` when the response was non-empty and no required
179
+ * field was lost. On success, \`result\` carries the recovered mirror + report.
180
+ */
181
+ export function ${tryRecoverName}(
182
+ text: string,
183
+ ): { ok: boolean; result: RecoveryResult<${recoveredName}> } {
184
+ const result = ${recoverFnName}(text);
185
+ const ok = !result.report.isEmpty() && !result.report.hasLostRequired();
186
+ return { ok, result };
187
+ }
188
+ `;
189
+ return (`import { z } from "zod";\n` +
190
+ `import {\n ${renderImports.join(",\n ")},\n} from "@metaobjectsdev/render";\n\n` +
191
+ `${strictBody}\n` +
192
+ `${recoverBody}`);
128
193
  }
129
194
  //# sourceMappingURL=output-parser.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"output-parser.js","sourceRoot":"","sources":["../../src/templates/output-parser.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"output-parser.js","sourceRoot":"","sources":["../../src/templates/output-parser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import { type MetaData } from "@metaobjectsdev/metadata";
2
+ /** True iff the template.output's @format is json or xml (the renderable structured formats). */
3
+ export declare function templateSupportsPrompt(tmpl: MetaData): boolean;
4
+ /**
5
+ * Render the full output-prompt file for one json/xml `template.output` node.
6
+ * Throws if the template isn't found, isn't a template.output, isn't json/xml,
7
+ * or its @payloadRef doesn't resolve to an object.value.
8
+ */
9
+ export declare function renderOutputPrompt(root: MetaData, templateName: string): string;
10
+ //# sourceMappingURL=output-prompt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output-prompt.d.ts","sourceRoot":"","sources":["../../src/templates/output-prompt.ts"],"names":[],"mappings":"AAYA,OAAO,EACL,KAAK,QAAQ,EAMd,MAAM,0BAA0B,CAAC;AAWlC,iGAAiG;AACjG,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAG9D;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CA8C/E"}
@@ -0,0 +1,75 @@
1
+ // server/typescript/packages/codegen-ts/src/templates/output-prompt.ts
2
+ //
3
+ // Per-template renderer for the FR-010 artifact-1 output-format prompt fragment
4
+ // ("produce your answer like this"). For each json/xml `template.output` whose
5
+ // @payloadRef resolves to a value-object, emits a `<TemplateName>.prompt.ts` file
6
+ // exporting `render<TemplateName>Format(overrides?)` backed by the render engine's
7
+ // renderOutputFormat(). The baked OutputFormatSpec's rootName is the payload name,
8
+ // so the prompt fragment and the recover() codegen agree on the root name.
9
+ //
10
+ // Mirrors the C# OutputPromptGenerator + OutputFormatSpecEmitter (split into a
11
+ // generator factory + this pure renderer, matching the TS output-parser shape).
12
+ import { TYPE_OBJECT, TYPE_TEMPLATE, TEMPLATE_SUBTYPE_OUTPUT, TEMPLATE_ATTR_PAYLOAD_REF, TEMPLATE_ATTR_FORMAT, } from "@metaobjectsdev/metadata";
13
+ import { specLiteral } from "./output-format-spec-emitter.js";
14
+ function findObject(root, name) {
15
+ return root.ownChildren().find((c) => c.type === TYPE_OBJECT && c.name === name);
16
+ }
17
+ function findTemplate(root, name) {
18
+ return root.ownChildren().find((c) => c.type === TYPE_TEMPLATE && c.name === name);
19
+ }
20
+ /** True iff the template.output's @format is json or xml (the renderable structured formats). */
21
+ export function templateSupportsPrompt(tmpl) {
22
+ const f = (tmpl.ownAttr(TEMPLATE_ATTR_FORMAT) ?? "text").toLowerCase();
23
+ return f === "json" || f === "xml";
24
+ }
25
+ /**
26
+ * Render the full output-prompt file for one json/xml `template.output` node.
27
+ * Throws if the template isn't found, isn't a template.output, isn't json/xml,
28
+ * or its @payloadRef doesn't resolve to an object.value.
29
+ */
30
+ export function renderOutputPrompt(root, templateName) {
31
+ const tmpl = findTemplate(root, templateName);
32
+ if (!tmpl) {
33
+ throw new Error(`template "${templateName}" not found in metadata root`);
34
+ }
35
+ if (tmpl.subType !== TEMPLATE_SUBTYPE_OUTPUT) {
36
+ throw new Error(`template "${templateName}" is not a template.output (got subtype "${tmpl.subType}")`);
37
+ }
38
+ if (!templateSupportsPrompt(tmpl)) {
39
+ throw new Error(`template "${templateName}" @format is not json/xml — no prompt fragment`);
40
+ }
41
+ const payloadRef = tmpl.ownAttr(TEMPLATE_ATTR_PAYLOAD_REF);
42
+ if (typeof payloadRef !== "string") {
43
+ throw new Error(`template "${templateName}" missing @payloadRef`);
44
+ }
45
+ const vo = findObject(root, payloadRef);
46
+ if (!vo) {
47
+ throw new Error(`template "${templateName}" @payloadRef "${payloadRef}" not found in metadata root`);
48
+ }
49
+ // rootName == payload name so the prompt fragment and recover() agree.
50
+ const spec = specLiteral(vo, tmpl, payloadRef);
51
+ const specName = `${templateName}FormatSpec`;
52
+ const fnName = `render${templateName}Format`;
53
+ return `import {
54
+ renderOutputFormat,
55
+ Format,
56
+ FieldKind,
57
+ PromptStyle,
58
+ type OutputFormatSpec,
59
+ type PromptOverrides,
60
+ } from "@metaobjectsdev/render";
61
+
62
+ const ${specName}: OutputFormatSpec = ${spec};
63
+
64
+ /**
65
+ * The output-format instruction fragment for the ${templateName} template.output
66
+ * ("produce your answer like this"). Comment-free — guidance lives in prose /
67
+ * inline placeholders / a filled skeleton. Pass \`overrides\` to override the style
68
+ * or per-field example/instruction at render time.
69
+ */
70
+ export function ${fnName}(overrides?: PromptOverrides): string {
71
+ return renderOutputFormat(${specName}, overrides ?? {});
72
+ }
73
+ `;
74
+ }
75
+ //# sourceMappingURL=output-prompt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output-prompt.js","sourceRoot":"","sources":["../../src/templates/output-prompt.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,EAAE;AACF,gFAAgF;AAChF,+EAA+E;AAC/E,kFAAkF;AAClF,mFAAmF;AACnF,mFAAmF;AACnF,2EAA2E;AAC3E,EAAE;AACF,+EAA+E;AAC/E,gFAAgF;AAEhF,OAAO,EAEL,WAAW,EACX,aAAa,EACb,uBAAuB,EACvB,yBAAyB,EACzB,oBAAoB,GACrB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAE9D,SAAS,UAAU,CAAC,IAAc,EAAE,IAAY;IAC9C,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,WAAW,IAAI,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;AACnF,CAAC;AAED,SAAS,YAAY,CAAC,IAAc,EAAE,IAAY;IAChD,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,aAAa,IAAI,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;AACrF,CAAC;AAED,iGAAiG;AACjG,MAAM,UAAU,sBAAsB,CAAC,IAAc;IACnD,MAAM,CAAC,GAAG,CAAE,IAAI,CAAC,OAAO,CAAC,oBAAoB,CAAwB,IAAI,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC;IAC/F,OAAO,CAAC,KAAK,MAAM,IAAI,CAAC,KAAK,KAAK,CAAC;AACrC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAAc,EAAE,YAAoB;IACrE,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;IAC9C,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,KAAK,CAAC,aAAa,YAAY,8BAA8B,CAAC,CAAC;IAC3E,CAAC;IACD,IAAI,IAAI,CAAC,OAAO,KAAK,uBAAuB,EAAE,CAAC;QAC7C,MAAM,IAAI,KAAK,CAAC,aAAa,YAAY,4CAA4C,IAAI,CAAC,OAAO,IAAI,CAAC,CAAC;IACzG,CAAC;IACD,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,EAAE,CAAC;QAClC,MAAM,IAAI,KAAK,CAAC,aAAa,YAAY,gDAAgD,CAAC,CAAC;IAC7F,CAAC;IACD,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,yBAAyB,CAAC,CAAC;IAC3D,IAAI,OAAO,UAAU,KAAK,QAAQ,EAAE,CAAC;QACnC,MAAM,IAAI,KAAK,CAAC,aAAa,YAAY,uBAAuB,CAAC,CAAC;IACpE,CAAC;IACD,MAAM,EAAE,GAAG,UAAU,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IACxC,IAAI,CAAC,EAAE,EAAE,CAAC;QACR,MAAM,IAAI,KAAK,CAAC,aAAa,YAAY,kBAAkB,UAAU,8BAA8B,CAAC,CAAC;IACvG,CAAC;IAED,uEAAuE;IACvE,MAAM,IAAI,GAAG,WAAW,CAAC,EAAE,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC;IAC/C,MAAM,QAAQ,GAAG,GAAG,YAAY,YAAY,CAAC;IAC7C,MAAM,MAAM,GAAG,SAAS,YAAY,QAAQ,CAAC;IAE7C,OAAO;;;;;;;;;QASD,QAAQ,wBAAwB,IAAI;;;oDAGQ,YAAY;;;;;kBAK9C,MAAM;8BACM,QAAQ;;CAErC,CAAC;AACF,CAAC"}
@@ -0,0 +1,8 @@
1
+ import { type MetaData } from "@metaobjectsdev/metadata";
2
+ /** Emit `recoverSchema(Format.X, "rootName", [ … ])`. */
3
+ export declare function schemaLiteral(vo: MetaData, format: string, rootName: string): string;
4
+ /** Emit the all-nullable mirror interface declaration. */
5
+ export declare function mirrorInterface(vo: MetaData, interfaceName: string): string;
6
+ /** Emit `{ prop: asString(d, "prop"), … }` building the mirror from the forgiving map `d`. */
7
+ export declare function mirrorInitializer(vo: MetaData): string;
8
+ //# sourceMappingURL=recover-schema-emitter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recover-schema-emitter.d.ts","sourceRoot":"","sources":["../../src/templates/recover-schema-emitter.ts"],"names":[],"mappings":"AAcA,OAAO,EACL,KAAK,QAAQ,EAId,MAAM,0BAA0B,CAAC;AAclC,yDAAyD;AACzD,wBAAgB,aAAa,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAIpF;AA+BD,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"}
@@ -0,0 +1,64 @@
1
+ // server/typescript/packages/codegen-ts/src/templates/recover-schema-emitter.ts
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
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
8
+ // than the strict payload (same reasoning as the Java/C#/Kotlin ports).
9
+ // • mirrorInitializer — `{ prop: asString(d, "prop"), … }` building the mirror from the
10
+ // forgiving outcome map `d`.
11
+ //
12
+ // Mirrors the C# RecoverSchemaEmitter (adapted to TS syntax + the `| null` nullable mirror).
13
+ // Bounded scope: scalar / enum / scalar-array. Nested object + array-of-enum deferred.
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", [ … ])`. */
17
+ export function schemaLiteral(vo, format, rootName) {
18
+ const formatEnum = format.toLowerCase() === "xml" ? "Format.XML" : "Format.JSON";
19
+ const specs = fields(vo).map(fieldSpecLiteral);
20
+ return `recoverSchema(${formatEnum}, ${jsonStringLiteral(rootName)}, [${specs.join(", ")}])`;
21
+ }
22
+ function fieldSpecLiteral(field) {
23
+ const name = jsonStringLiteral(field.name);
24
+ const required = isRequired(field);
25
+ if (field.subType === FIELD_SUBTYPE_ENUM) {
26
+ const valuesLit = stringArrayLiteral(enumValues(field));
27
+ const aliasLit = propertiesMapLiteral(field.ownAttr(FIELD_ATTR_ENUM_ALIAS));
28
+ // enumField() sets array:false; enum-array is a bounded deferral (parity with Java/C#).
29
+ return `enumField(${name}, ${required}, ${valuesLit}, ${aliasLit})`;
30
+ }
31
+ 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 */`;
34
+ }
35
+ const kind = scalarKind(field.subType) ?? "STRING";
36
+ // Scalar-array: the scalar() factory only builds singular specs (array:false), so emit a
37
+ // 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).
39
+ if (isArray(field)) {
40
+ return (`{ name: ${name}, kind: FieldKind.${kind}, required: ${required}, array: true, ` +
41
+ `enumValues: null, enumAlias: null, min: null, max: null, nested: null }`);
42
+ }
43
+ return `scalar(${name}, FieldKind.${kind}, ${required})`;
44
+ }
45
+ /** Emit the all-nullable mirror interface declaration. */
46
+ export function mirrorInterface(vo, interfaceName) {
47
+ const base = interfaceName.endsWith("Recovered")
48
+ ? interfaceName.slice(0, -"Recovered".length)
49
+ : interfaceName;
50
+ const lines = [];
51
+ lines.push(`/** Best-effort recovered twin of \`${base}\` — every field nullable (null where lost/malformed). */`);
52
+ lines.push(`export interface ${interfaceName} {`);
53
+ for (const f of fields(vo)) {
54
+ lines.push(` ${f.name}: ${mirrorType(f)};`);
55
+ }
56
+ lines.push("}");
57
+ return lines.join("\n");
58
+ }
59
+ /** Emit `{ prop: asString(d, "prop"), … }` building the mirror from the forgiving map `d`. */
60
+ export function mirrorInitializer(vo) {
61
+ const assigns = fields(vo).map((f) => `${f.name}: ${recoverMapCall(f)}`);
62
+ return `{ ${assigns.join(", ")} }`;
63
+ }
64
+ //# sourceMappingURL=recover-schema-emitter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recover-schema-emitter.js","sourceRoot":"","sources":["../../src/templates/recover-schema-emitter.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metaobjectsdev/codegen-ts",
3
- "version": "0.7.0",
3
+ "version": "0.8.0",
4
4
  "description": "TypeScript codegen engine for MetaObjects — emits Drizzle, Zod, and Fastify artifacts.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -38,8 +38,8 @@
38
38
  "access": "public"
39
39
  },
40
40
  "dependencies": {
41
- "@metaobjectsdev/metadata": "0.7.0",
42
- "@metaobjectsdev/render": "0.7.0",
41
+ "@metaobjectsdev/metadata": "0.8.0",
42
+ "@metaobjectsdev/render": "0.8.0",
43
43
  "@biomejs/js-api": "^0.7.0",
44
44
  "@biomejs/wasm-nodejs": "^1.9.4",
45
45
  "ts-poet": "^6.10.0"
@@ -50,7 +50,7 @@
50
50
  },
51
51
  "devDependencies": {
52
52
  "@biomejs/biome": "^1.9.0",
53
- "@metaobjectsdev/codegen-ts-react": "0.7.0",
53
+ "@metaobjectsdev/codegen-ts-react": "0.8.0",
54
54
  "bun-types": "latest",
55
55
  "drizzle-orm": "^0.36.0",
56
56
  "hono": "^4.6.0",
@@ -3,6 +3,7 @@ import { perEntity, type Generator, type GeneratorFactory } from "../generator.j
3
3
  import { renderEntityFile } from "../templates/entity-file.js";
4
4
  import { formatTs } from "../format.js";
5
5
  import { entityOutputPath } from "../import-path.js";
6
+ import { isAbstract } from "../instance-artifacts.js";
6
7
 
7
8
  export interface EntityFileOpts {
8
9
  filter?: (entity: MetaObject) => boolean;
@@ -33,6 +34,12 @@ export const entityFile = function entityFile(opts?: EntityFileOpts): Generator
33
34
  if (!ctx.renderContext) {
34
35
  throw new Error("entity-file: renderContext is required (provided by runGen)");
35
36
  }
37
+ // Abstract entities contribute shape only. When emitAbstractShapes is off
38
+ // (cross-port knob; default on) the entity-file generator emits nothing for
39
+ // them. Instance/write generators skip abstract unconditionally elsewhere.
40
+ if (isAbstract(entity) && !ctx.renderContext.emitAbstractShapes) {
41
+ return [];
42
+ }
36
43
  return {
37
44
  path: entityOutputPath(ctx.config.outputLayout ?? "flat", entity.package, `${entity.name}.ts`),
38
45
  content: await formatTs(renderEntityFile(entity, ctx.renderContext, { allowlists })),
@@ -6,6 +6,7 @@ export { barrel, type BarrelOpts } from "./barrel.js";
6
6
  export { mermaidErDiagram, type MermaidErOptions } from "./mermaid-er.js";
7
7
  export { promptRender, type PromptRenderOpts } from "./prompt-render-file.js";
8
8
  export { outputParser, type OutputParserOpts } from "./output-parser-file.js";
9
+ export { outputPrompt, type OutputPromptOpts } from "./output-prompt-file.js";
9
10
  export { docsFile, type DocsFileOpts } from "./docs-file.js";
10
11
  export {
11
12
  templateGenerator,