@metaobjectsdev/render 0.8.1-rc.1 → 0.9.0-rc.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 (81) hide show
  1. package/dist/email-document.d.ts +7 -0
  2. package/dist/email-document.d.ts.map +1 -0
  3. package/dist/email-document.js +2 -0
  4. package/dist/email-document.js.map +1 -0
  5. package/dist/extract/coerce.d.ts +15 -0
  6. package/dist/extract/coerce.d.ts.map +1 -0
  7. package/dist/{recover → extract}/coerce.js +87 -13
  8. package/dist/extract/coerce.js.map +1 -0
  9. package/dist/{recover/recover-map.d.ts → extract/extract-map.d.ts} +1 -1
  10. package/dist/{recover/recover-map.d.ts.map → extract/extract-map.d.ts.map} +1 -1
  11. package/dist/{recover/recover-map.js → extract/extract-map.js} +3 -3
  12. package/dist/{recover/recover-map.js.map → extract/extract-map.js.map} +1 -1
  13. package/dist/extract/extract.d.ts +4 -0
  14. package/dist/extract/extract.d.ts.map +1 -0
  15. package/dist/extract/extract.js +157 -0
  16. package/dist/extract/extract.js.map +1 -0
  17. package/dist/{recover → extract}/json-forgiving-reader.d.ts.map +1 -1
  18. package/dist/{recover → extract}/json-forgiving-reader.js +1 -1
  19. package/dist/{recover → extract}/json-forgiving-reader.js.map +1 -1
  20. package/dist/{recover → extract}/locate.d.ts.map +1 -1
  21. package/dist/{recover → extract}/locate.js.map +1 -1
  22. package/dist/extract/normalize.d.ts +4 -0
  23. package/dist/extract/normalize.d.ts.map +1 -0
  24. package/dist/extract/normalize.js +22 -0
  25. package/dist/extract/normalize.js.map +1 -0
  26. package/dist/extract/strip.d.ts.map +1 -0
  27. package/dist/{recover → extract}/strip.js.map +1 -1
  28. package/dist/extract/types.d.ts +160 -0
  29. package/dist/extract/types.d.ts.map +1 -0
  30. package/dist/extract/types.js +221 -0
  31. package/dist/extract/types.js.map +1 -0
  32. package/dist/{recover → extract}/xml-forgiving-reader.d.ts.map +1 -1
  33. package/dist/{recover → extract}/xml-forgiving-reader.js +1 -1
  34. package/dist/{recover → extract}/xml-forgiving-reader.js.map +1 -1
  35. package/dist/index.d.ts +4 -3
  36. package/dist/index.d.ts.map +1 -1
  37. package/dist/index.js +4 -4
  38. package/dist/index.js.map +1 -1
  39. package/dist/prompt/output-format-renderer.d.ts.map +1 -1
  40. package/dist/prompt/output-format-renderer.js +113 -59
  41. package/dist/prompt/output-format-renderer.js.map +1 -1
  42. package/dist/prompt/output-format-spec.d.ts +1 -1
  43. package/dist/prompt/prompt-field.d.ts +1 -1
  44. package/package.json +1 -1
  45. package/src/email-document.ts +6 -0
  46. package/src/extract/KNOWN_GAPS.md +59 -0
  47. package/src/extract/coerce.ts +224 -0
  48. package/src/{recover/recover-map.ts → extract/extract-map.ts} +2 -2
  49. package/src/extract/extract.ts +187 -0
  50. package/src/{recover → extract}/json-forgiving-reader.ts +1 -1
  51. package/src/extract/normalize.ts +23 -0
  52. package/src/extract/types.ts +346 -0
  53. package/src/{recover → extract}/xml-forgiving-reader.ts +1 -1
  54. package/src/index.ts +17 -11
  55. package/src/prompt/output-format-renderer.ts +140 -61
  56. package/src/prompt/output-format-spec.ts +1 -1
  57. package/src/prompt/prompt-field.ts +1 -1
  58. package/dist/recover/coerce.d.ts +0 -5
  59. package/dist/recover/coerce.d.ts.map +0 -1
  60. package/dist/recover/coerce.js.map +0 -1
  61. package/dist/recover/recover.d.ts +0 -4
  62. package/dist/recover/recover.d.ts.map +0 -1
  63. package/dist/recover/recover.js +0 -115
  64. package/dist/recover/recover.js.map +0 -1
  65. package/dist/recover/strip.d.ts.map +0 -1
  66. package/dist/recover/types.d.ts +0 -117
  67. package/dist/recover/types.d.ts.map +0 -1
  68. package/dist/recover/types.js +0 -124
  69. package/dist/recover/types.js.map +0 -1
  70. package/src/recover/KNOWN_GAPS.md +0 -35
  71. package/src/recover/coerce.ts +0 -141
  72. package/src/recover/recover.ts +0 -146
  73. package/src/recover/types.ts +0 -217
  74. /package/dist/{recover → extract}/json-forgiving-reader.d.ts +0 -0
  75. /package/dist/{recover → extract}/locate.d.ts +0 -0
  76. /package/dist/{recover → extract}/locate.js +0 -0
  77. /package/dist/{recover → extract}/strip.d.ts +0 -0
  78. /package/dist/{recover → extract}/strip.js +0 -0
  79. /package/dist/{recover → extract}/xml-forgiving-reader.d.ts +0 -0
  80. /package/src/{recover → extract}/locate.ts +0 -0
  81. /package/src/{recover → extract}/strip.ts +0 -0
@@ -9,7 +9,7 @@
9
9
  // reference (com.metaobjects.render.prompt.OutputFormatRenderer). Do not change
10
10
  // the verbatim prose, skeleton shapes, or numeric-vs-quoted decision.
11
11
  import { ESCAPERS } from "../escapers.js";
12
- import { FieldKind, Format } from "../recover/types.js";
12
+ import { FieldKind, Format } from "../extract/types.js";
13
13
  import { PromptStyle } from "./prompt-style.js";
14
14
  const NUMERIC_KINDS = new Set([
15
15
  FieldKind.INT,
@@ -17,6 +17,8 @@ const NUMERIC_KINDS = new Set([
17
17
  FieldKind.DOUBLE,
18
18
  FieldKind.BOOLEAN,
19
19
  ]);
20
+ const INDENT = " ";
21
+ const MAX_NEST_DEPTH = 8;
20
22
  // The render engine OWNS format-keyed escaping; Format ("JSON"/"XML") maps to the
21
23
  // lowercase ESCAPERS keys.
22
24
  const escapeXml = (s) => ESCAPERS.xml(s);
@@ -39,20 +41,8 @@ export function renderOutputFormat(spec, overrides) {
39
41
  // ---- INLINE ----------------------------------------------------------------
40
42
  function renderInline(spec, overrides) {
41
43
  return spec.format === Format.XML
42
- ? renderXmlInline(spec, overrides)
43
- : renderJsonInline(spec, overrides);
44
- }
45
- function renderXmlInline(spec, overrides) {
46
- const lines = spec.fields.map((field) => {
47
- const escaped = escapeXml(inlineContent(field, overrides));
48
- return ` <${field.name}>${escaped}</${field.name}>\n`;
49
- });
50
- return `<${spec.rootName}>\n${lines.join("")}</${spec.rootName}>`;
51
- }
52
- function renderJsonInline(spec, overrides) {
53
- const lines = spec.fields.map((field) => ` "${field.name}": "${escapeJson(inlineContent(field, overrides))}"`);
54
- // Empty object is `{\n}` (Java/C# parity), not `{\n\n}` from join("") on no lines.
55
- return spec.fields.length === 0 ? "{\n}" : `{\n${lines.join(",\n")}\n}`;
44
+ ? renderXmlSkeleton(spec, overrides, "inline")
45
+ : renderJsonSkeleton(spec, overrides, "inline");
56
46
  }
57
47
  function inlineContent(field, overrides) {
58
48
  if (field.kind === FieldKind.ENUM && field.enumValues != null && field.enumValues.length > 0) {
@@ -74,59 +64,123 @@ function resolveInstruction(field, overrides) {
74
64
  // ---- GUIDE -----------------------------------------------------------------
75
65
  function renderGuide(spec, overrides) {
76
66
  let sb = "Fill in each field as described below:\n";
67
+ sb += guideFields(spec, overrides, "", new Set([spec]), 0);
68
+ sb += "\nRespond exactly like this:\n";
69
+ sb += renderExampleOnly(spec, overrides);
70
+ return sb;
71
+ }
72
+ function guideFields(spec, overrides, prefix, path, depth) {
73
+ let sb = "";
77
74
  for (const field of spec.fields) {
78
- const req = field.required ? "required" : "optional";
79
- sb += `- ${field.name} (${req})`;
80
- const instruction = resolveInstruction(field, overrides);
81
- if (instruction != null) {
82
- sb += `: ${instruction}`;
75
+ const displayName = prefix + field.name;
76
+ sb += guideEntry(field, overrides, displayName);
77
+ if (canExpand(field, path, depth)) {
78
+ const nested = field.nested;
79
+ const childPrefix = field.array ? `${displayName}[].` : `${displayName}.`;
80
+ path.add(nested);
81
+ sb += guideFields(nested, overrides, childPrefix, path, depth + 1);
82
+ path.delete(nested);
83
83
  }
84
- sb += "\n";
85
- if (field.kind === FieldKind.ENUM && field.enumValues != null && field.enumValues.length > 0) {
86
- sb += ` one of ${field.enumValues.join(", ")}\n`;
87
- const enumDoc = field.enumDoc;
88
- if (enumDoc != null) {
89
- for (const val of field.enumValues) {
90
- const doc = enumDoc[val];
91
- if (doc != null) {
92
- sb += ` ${val} = ${doc}\n`;
93
- }
94
- }
84
+ }
85
+ return sb;
86
+ }
87
+ function guideEntry(field, overrides, displayName) {
88
+ const req = field.required ? "required" : "optional";
89
+ let sb = `- ${displayName} (${req})`;
90
+ const instruction = resolveInstruction(field, overrides);
91
+ if (instruction != null)
92
+ sb += `: ${instruction}`;
93
+ sb += "\n";
94
+ if (field.kind === FieldKind.ENUM && field.enumValues != null && field.enumValues.length > 0) {
95
+ sb += ` one of ${field.enumValues.join(", ")}\n`;
96
+ const enumDoc = field.enumDoc;
97
+ if (enumDoc != null) {
98
+ for (const val of field.enumValues) {
99
+ const doc = enumDoc[val];
100
+ if (doc != null)
101
+ sb += ` ${val} = ${doc}\n`;
95
102
  }
96
103
  }
97
- const eg = exampleValueIfDeclared(field, overrides);
98
- if (eg != null) {
99
- sb += ` e.g. ${eg}\n`;
100
- }
101
104
  }
102
- sb += "\nRespond exactly like this:\n";
103
- sb += renderExampleOnly(spec, overrides);
105
+ const eg = exampleValueIfDeclared(field, overrides);
106
+ if (eg != null)
107
+ sb += ` e.g. ${eg}\n`;
104
108
  return sb;
105
109
  }
106
110
  // ---- EXAMPLE-ONLY (also the skeleton appended by GUIDE) ---------------------
107
111
  function renderExampleOnly(spec, overrides) {
108
112
  return spec.format === Format.XML
109
- ? renderXmlSkeleton(spec, overrides)
110
- : renderJsonSkeleton(spec, overrides);
111
- }
112
- function renderXmlSkeleton(spec, overrides) {
113
- const lines = spec.fields.map((field) => {
114
- const escaped = escapeXml(exampleValue(field, overrides));
115
- return ` <${field.name}>${escaped}</${field.name}>\n`;
116
- });
117
- return `<${spec.rootName}>\n${lines.join("")}</${spec.rootName}>`;
118
- }
119
- function renderJsonSkeleton(spec, overrides) {
120
- // NOTE: FieldKind.OBJECT / nested fields are not expanded here they render as
121
- // a "{fieldName}" placeholder. Nested-object expansion is a bounded deferral
122
- // (mirrors Java/C#).
123
- const lines = spec.fields.map((field) => {
124
- const value = exampleValue(field, overrides);
125
- const rendered = isNumericOrBoolean(field.kind, value) ? value : `"${escapeJson(value)}"`;
126
- return ` "${field.name}": ${rendered}`;
127
- });
128
- // Empty object is `{\n}` (Java/C# parity), not `{\n\n}` from join("") on no lines.
129
- return spec.fields.length === 0 ? "{\n}" : `{\n${lines.join(",\n")}\n}`;
113
+ ? renderXmlSkeleton(spec, overrides, "example")
114
+ : renderJsonSkeleton(spec, overrides, "example");
115
+ }
116
+ // ---- JSON skeleton (recursive) ---------------------------------------------
117
+ function renderJsonSkeleton(spec, overrides, mode) {
118
+ return jsonObject(spec, overrides, "", mode, new Set([spec]), 0);
119
+ }
120
+ function jsonObject(spec, overrides, braceIndent, mode, path, depth) {
121
+ if (spec.fields.length === 0)
122
+ return `{\n${braceIndent}}`;
123
+ const fieldIndent = braceIndent + INDENT;
124
+ const lines = spec.fields.map((field) => `${fieldIndent}"${field.name}": ${jsonValue(field, overrides, fieldIndent, mode, path, depth)}`);
125
+ return `{\n${lines.join(",\n")}\n${braceIndent}}`;
126
+ }
127
+ function jsonValue(field, overrides, indent, mode, path, depth) {
128
+ if (field.array)
129
+ return jsonArray(field, overrides, indent, mode, path, depth);
130
+ if (field.kind === FieldKind.OBJECT)
131
+ return jsonObjectField(field, overrides, indent, mode, path, depth);
132
+ return jsonLeaf(field, overrides, mode);
133
+ }
134
+ function jsonLeaf(field, overrides, mode) {
135
+ if (mode === "inline")
136
+ return `"${escapeJson(inlineContent(field, overrides))}"`;
137
+ const value = exampleValue(field, overrides);
138
+ return isNumericOrBoolean(field.kind, value) ? value : `"${escapeJson(value)}"`;
139
+ }
140
+ function canExpand(field, path, depth) {
141
+ return field.kind === FieldKind.OBJECT && field.nested != null
142
+ && depth < MAX_NEST_DEPTH && !path.has(field.nested);
143
+ }
144
+ function jsonObjectField(field, overrides, indent, mode, path, depth) {
145
+ if (!canExpand(field, path, depth))
146
+ return jsonLeaf(field, overrides, mode);
147
+ const nested = field.nested;
148
+ path.add(nested);
149
+ const out = jsonObject(nested, overrides, indent, mode, path, depth + 1);
150
+ path.delete(nested);
151
+ return out;
152
+ }
153
+ function jsonArray(field, overrides, indent, mode, path, depth) {
154
+ const elemIndent = indent + INDENT;
155
+ let elem;
156
+ if (canExpand(field, path, depth)) {
157
+ const nested = field.nested;
158
+ path.add(nested);
159
+ elem = jsonObject(nested, overrides, elemIndent, mode, path, depth + 1);
160
+ path.delete(nested);
161
+ }
162
+ else {
163
+ elem = jsonLeaf(field, overrides, mode);
164
+ }
165
+ return `[\n${elemIndent}${elem}\n${indent}]`;
166
+ }
167
+ // ---- XML skeleton (recursive) ----------------------------------------------
168
+ function renderXmlSkeleton(spec, overrides, mode) {
169
+ return `<${spec.rootName}>\n${xmlBody(spec, overrides, INDENT, mode, new Set([spec]), 0)}</${spec.rootName}>`;
170
+ }
171
+ function xmlBody(spec, overrides, indent, mode, path, depth) {
172
+ return spec.fields.map((field) => xmlField(field, overrides, indent, mode, path, depth)).join("");
173
+ }
174
+ function xmlField(field, overrides, indent, mode, path, depth) {
175
+ if (canExpand(field, path, depth)) {
176
+ const nested = field.nested;
177
+ path.add(nested);
178
+ const body = xmlBody(nested, overrides, indent + INDENT, mode, path, depth + 1);
179
+ path.delete(nested);
180
+ return `${indent}<${field.name}>\n${body}${indent}</${field.name}>\n`;
181
+ }
182
+ const content = mode === "inline" ? inlineContent(field, overrides) : exampleValue(field, overrides);
183
+ return `${indent}<${field.name}>${escapeXml(content)}</${field.name}>\n`;
130
184
  }
131
185
  function exampleValueIfDeclared(field, overrides) {
132
186
  const ov = overrides.examples?.[field.name];
@@ -155,7 +209,7 @@ function isNumericOrBoolean(kind, value) {
155
209
  // Finite-only: NaN/Infinity fall through to a quoted string so the emitted JSON
156
210
  // stays valid. Number("") is 0, so guard the empty/blank case explicitly. Reject
157
211
  // JS-only radix literals (0x../0b../0o..) that Number() accepts but Java/C# don't —
158
- // same guard as the recover engine's parseFiniteNumber (keeps the JSON valid + parity).
212
+ // same guard as the extract engine's parseFiniteNumber (keeps the JSON valid + parity).
159
213
  const t = value.trim();
160
214
  if (t === "" || /^[+-]?0[xXbBoO]/.test(t))
161
215
  return false;
@@ -1 +1 @@
1
- {"version":3,"file":"output-format-renderer.js","sourceRoot":"","sources":["../../src/prompt/output-format-renderer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"output-format-renderer.js","sourceRoot":"","sources":["../../src/prompt/output-format-renderer.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import type { Format } from "../recover/types.js";
1
+ import type { Format } from "../extract/types.js";
2
2
  import type { PromptField } from "./prompt-field.js";
3
3
  import type { PromptStyle } from "./prompt-style.js";
4
4
  /**
@@ -1,4 +1,4 @@
1
- import type { FieldKind } from "../recover/types.js";
1
+ import type { FieldKind } from "../extract/types.js";
2
2
  import type { OutputFormatSpec } from "./output-format-spec.js";
3
3
  /**
4
4
  * One field of an output-format fragment. `enumValues`/`enumDoc` are non-null
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metaobjectsdev/render",
3
- "version": "0.8.1-rc.1",
3
+ "version": "0.9.0-rc.1",
4
4
  "description": "Logic-less, deterministic text render engine (Mustache) for MetaObjects templates — provider-resolved partials, format-driven escaping, zero core dependency.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -0,0 +1,6 @@
1
+ /** A rendered email: subject + HTML body + optional plain-text alternative (MIME multipart/alternative). */
2
+ export interface EmailDocument {
3
+ subject: string;
4
+ htmlBody: string;
5
+ textBody?: string;
6
+ }
@@ -0,0 +1,59 @@
1
+ # FR-010 TypeScript extract engine — known gaps & intentional cross-port divergences
2
+
3
+ Scope: the tolerant `extract` pipeline (`src/extract/`). The Java engine
4
+ (`server/java/render/.../extract/`) is the cross-port reference; `fixtures/extract-conformance/`
5
+ is the oracle. All 10 corpus cases pass.
6
+
7
+ ## Additive capability (TS + C#, beyond Java/Kotlin)
8
+
9
+ - **Nested-object extract is implemented.** A `FieldSpec` with a non-null `nested` schema
10
+ (built via the `object(...)` factory) is descended into and its sub-fields classified. The
11
+ Java/Kotlin ports defer this (their codegen emits a scalar-STRING placeholder). The C# port
12
+ also carries the OBJECT branch, so TS and C# agree. This is **dormant** under both the
13
+ conformance corpus (no nested fixture; the runner's schema parser never sets `nested`) and the
14
+ FR-010 codegen (Phase 3 emits the scalar placeholder for cross-port parity), so it changes no
15
+ shared-corpus result. If a future shared fixture adds a nested case, Java/Kotlin catch up.
16
+
17
+ ## Intentional, documented divergence (NOT a bug)
18
+
19
+ The cross-port contract pins *classification + canonical value* (numbers within ±1e-9), not
20
+ byte-identical native parsing.
21
+
22
+ - **Java-style numeric suffixes / hex-float literals.** Java's `Double.parseDouble` accepts
23
+ `"42d"` / `"42f"` and hex-float forms (→ EXTRACTED); TS uses `Number(...)` + `Number.isFinite`,
24
+ which rejects them → **MALFORMED** (same accepted divergence the C# port records). The
25
+ load-bearing behavior — finite-only acceptance, `NaN`/`±Infinity` → MALFORMED — is identical.
26
+
27
+ - **JS-only radix-prefixed literals are GUARDED for parity.** `Number("0x10")` is `16` in JS, but
28
+ Java/C# reject `0x..`/`0b..`/`0o..` → MALFORMED. `parseFiniteNumber` rejects these prefixes
29
+ explicitly so TS matches Java/C# (→ MALFORMED) rather than over-accepting. (Not a divergence —
30
+ noted here because the guard exists precisely to prevent one.)
31
+
32
+ ## Bounded deferral (parity with all ports)
33
+
34
+ - Array-of-enum is not specialized (a scalar array extracts via `asStringList`).
35
+ - `asInt`/`asLong` both return `number | null` (JS has one number type) and truncate toward zero.
36
+
37
+ ## FR-011 extract hardening — current state
38
+
39
+ - **Enum coercion pipeline.** Enum extraction runs a fixed ladder: exact → normalize
40
+ (`@normalize` mode `none | collapse | strip`, default `strip`, per-field with an
41
+ `object.value`-level default) → `@enumAlias` → `@coerceDefault` → MALFORMED. `@default` fills
42
+ an absent enum (→ `DEFAULTED`, which satisfies `@required`); the `DEFAULTED` classification is
43
+ now emitted by the engine.
44
+ - **Nested/embedded-object extraction is supported** uniformly at the engine level (dotted child
45
+ paths, element-wise arrays) — this closes the FR-010 nested deferral noted above for the
46
+ *engine*. NOTE: the codegen schema-emitters still emit a scalar-STRING placeholder for nested
47
+ object fields (a deliberate, cross-port-consistent codegen deferral), so nested extraction is
48
+ reachable via a hand-built / engine-level schema but is not yet auto-emitted by codegen.
49
+ - **Fuzzy matching is deliberately DEFERRED.** A reserved no-op slot exists in the pipeline
50
+ (between `@enumAlias` and `@coerceDefault`). If added later it must be guarded integer
51
+ Levenshtein — never float / Jaro-Winkler — to preserve cross-port determinism.
52
+ - **`@normalize` `unicode` mode is intentionally NOT offered.** Normalization is ASCII-only (enum
53
+ members are ASCII identifiers), so it is byte-identical cross-port. A full Unicode / NFKC_Casefold
54
+ mode was rejected: cross-port byte-identity can't be guaranteed.
55
+ - **Known cross-port caveat (out of corpus).** The pre-normalization `trim` / `strip` step uses
56
+ each language's native trim, which differs on *non-ASCII* leading/trailing whitespace under
57
+ `collapse` mode — TS strips Unicode whitespace, Java trims only ≤U+0020. Unreachable via the
58
+ ASCII-only conformance corpus and irrelevant under `strip` / `none` modes; enum members and
59
+ typical LLM whitespace are ASCII. Documented for completeness.
@@ -0,0 +1,224 @@
1
+ // Stage 7: canonicalize a raw scalar string per its FieldSpec. Returns the MALFORMED
2
+ // sentinel when present-but-uncoercible. Mirrors Java Coerce.
3
+ //
4
+ // Tier-2 divergence (documented, parity with the C# port's KNOWN_GAPS): JS has one
5
+ // number type. INT/LONG both truncate toward zero via Math.trunc and return `number`.
6
+ // Coercion uses Number(...) + Number.isFinite, NOT Java's Double.parseDouble — so JS
7
+ // does NOT accept Java's numeric suffixes ("42d"/"42f") or hex-float literals. The
8
+ // load-bearing contract (finite-only acceptance; NaN/±Infinity → MALFORMED; numeric
9
+ // classification) is identical across ports.
10
+
11
+ import { FieldKind, Tolerance } from "./types.js";
12
+ import type { FieldSpec, ExtractOptions, ExtractionReport } from "./types.js";
13
+ import { normalizeEnum } from "./normalize.js";
14
+ import type { NormalizeMode } from "./normalize.js";
15
+
16
+ /** Sentinel: the value was present but could not be coerced to the declared kind/vocabulary. */
17
+ export const MALFORMED: unique symbol = Symbol("extract.coerce.MALFORMED");
18
+
19
+ export function coerceValue(
20
+ raw: string | null,
21
+ spec: FieldSpec,
22
+ opts: ExtractOptions,
23
+ fieldPath: string,
24
+ report: ExtractionReport,
25
+ ): unknown | typeof MALFORMED {
26
+ if (raw == null) return MALFORMED;
27
+
28
+ if (opts.onField != null) {
29
+ const hooked = opts.onField(fieldPath, raw, spec);
30
+ if (hooked != null) {
31
+ report.addCoercion({ fieldPath, from: raw, to: stringify(hooked), kind: "onField" });
32
+ return hooked;
33
+ }
34
+ }
35
+
36
+ // Per-field runtime normalizer (bounded 20% surface). Keyed by field path, then simple name.
37
+ const norm = opts.normalizers[fieldPath] ?? opts.normalizers[spec.name];
38
+ if (norm != null) {
39
+ const normalized = norm(raw);
40
+ if (normalized != null) {
41
+ report.addCoercion({ fieldPath, from: raw, to: stringify(normalized), kind: "normalizer" });
42
+ return normalized;
43
+ }
44
+ }
45
+
46
+ const ci = opts.tolerance !== Tolerance.STRICT;
47
+ switch (spec.kind) {
48
+ case FieldKind.ENUM:
49
+ return coerceEnum(raw, spec, opts, fieldPath, report, ci);
50
+ case FieldKind.INT:
51
+ case FieldKind.LONG:
52
+ return coerceInt(raw, spec, fieldPath, report);
53
+ case FieldKind.DOUBLE:
54
+ return coerceDouble(raw, spec, fieldPath, report);
55
+ case FieldKind.BOOLEAN:
56
+ return coerceBool(raw, ci);
57
+ default:
58
+ return raw;
59
+ }
60
+ }
61
+
62
+ /**
63
+ * Phase B (generalized `@default`): PURE coercion of a metadata-sourced string to the field's
64
+ * scalar kind, with NO side effects (no normalizer/onField hooks, no clamp logging) — the value
65
+ * originates from metadata, not the model response. Returns the coerced value or the MALFORMED
66
+ * sentinel. INT/LONG accept an integer or a truncatable finite number; DOUBLE accepts any finite
67
+ * number; BOOLEAN accepts `true|false|yes|no|1|0`; STRING (and any other kind) passes through
68
+ * verbatim. Mirrors Java `Coerce.scalar` (parse semantics of {@link coerceValue} without its
69
+ * range-clamp / report machinery).
70
+ */
71
+ export function scalarCoerce(raw: string | null, spec: FieldSpec): unknown | typeof MALFORMED {
72
+ if (raw == null) return MALFORMED;
73
+ switch (spec.kind) {
74
+ case FieldKind.INT:
75
+ case FieldKind.LONG: {
76
+ const n = parseFiniteNumber(raw);
77
+ return n === null ? MALFORMED : Math.trunc(n);
78
+ }
79
+ case FieldKind.DOUBLE: {
80
+ const n = parseFiniteNumber(raw);
81
+ return n === null ? MALFORMED : n;
82
+ }
83
+ case FieldKind.BOOLEAN:
84
+ return coerceBool(raw, true);
85
+ default:
86
+ return raw; // STRING / ENUM / OBJECT — verbatim
87
+ }
88
+ }
89
+
90
+ /**
91
+ * FR-011 enum coercion pipeline: exact → normalize → @enumAlias → (reserved fuzzy) →
92
+ * @coerceDefault → MALFORMED. Resolution mode is `spec.normalize` (default "strip"); under
93
+ * STRICT tolerance (ci === false) normalization is forced to "none" (exact-only), preserving
94
+ * the case-sensitive STRICT contract. The FR-010 case-insensitive default is now mode "strip".
95
+ */
96
+ function coerceEnum(
97
+ raw: string,
98
+ spec: FieldSpec,
99
+ opts: ExtractOptions,
100
+ path: string,
101
+ report: ExtractionReport,
102
+ ci: boolean,
103
+ ): unknown | typeof MALFORMED {
104
+ const mode: NormalizeMode = ci ? spec.normalize : "none";
105
+
106
+ // 1. exact match.
107
+ if (spec.enumValues != null) {
108
+ for (const v of spec.enumValues) if (v === raw) return v;
109
+ }
110
+
111
+ // 2. normalized match (skipped when mode === "none").
112
+ if (mode !== "none" && spec.enumValues != null) {
113
+ const normRaw = normalizeEnum(raw, mode);
114
+ for (const v of spec.enumValues) {
115
+ if (normalizeEnum(v, mode) === normRaw) {
116
+ report.addCoercion({ fieldPath: path, from: raw, to: v, kind: "normalize" });
117
+ return v;
118
+ }
119
+ }
120
+ }
121
+
122
+ // 3. @enumAlias — runtime aliases win over schema; alias keys normalized by the mode.
123
+ const aliasTarget = lookupAlias(raw, spec, opts, mode);
124
+ if (aliasTarget != null) {
125
+ const schemaTarget = lookupAliasIn(raw, spec.enumAlias ?? {}, mode);
126
+ const kind =
127
+ aliasTarget.fromRuntime && schemaTarget != null && schemaTarget !== aliasTarget.target
128
+ ? "runtime-alias-override"
129
+ : "alias";
130
+ report.addCoercion({ fieldPath: path, from: raw, to: aliasTarget.target, kind });
131
+ return aliasTarget.target;
132
+ }
133
+
134
+ // 4. reserved fuzzy slot — NOT implemented (see FR-011 spec "Out of scope").
135
+
136
+ // 5. @coerceDefault — present-but-uncoercible fallback to a valid member → DEFAULTED.
137
+ if (spec.coerceDefault != null && spec.enumValues != null && spec.enumValues.includes(spec.coerceDefault)) {
138
+ report.addCoercion({ fieldPath: path, from: raw, to: spec.coerceDefault, kind: "coerceDefault" });
139
+ return spec.coerceDefault;
140
+ }
141
+
142
+ // 6. MALFORMED.
143
+ return MALFORMED;
144
+ }
145
+
146
+ /**
147
+ * Resolve `raw` against the merged alias maps (runtime wins), comparing keys under `mode`.
148
+ * Returns the target member + whether the winning hit came from the runtime map.
149
+ */
150
+ function lookupAlias(
151
+ raw: string,
152
+ spec: FieldSpec,
153
+ opts: ExtractOptions,
154
+ mode: NormalizeMode,
155
+ ): { target: string; fromRuntime: boolean } | null {
156
+ const runtime = lookupAliasIn(raw, opts.aliases, mode);
157
+ if (runtime != null) return { target: runtime, fromRuntime: true };
158
+ const schema = lookupAliasIn(raw, spec.enumAlias ?? {}, mode);
159
+ if (schema != null) return { target: schema, fromRuntime: false };
160
+ return null;
161
+ }
162
+
163
+ /** Find `raw` in an alias map, matching keys exactly first then under `mode` normalization. */
164
+ function lookupAliasIn(raw: string, aliases: Readonly<Record<string, string>>, mode: NormalizeMode): string | null {
165
+ if (Object.prototype.hasOwnProperty.call(aliases, raw)) return aliases[raw]!;
166
+ if (mode === "none") return null;
167
+ const normRaw = normalizeEnum(raw, mode);
168
+ for (const key of Object.keys(aliases)) {
169
+ if (normalizeEnum(key, mode) === normRaw) return aliases[key]!;
170
+ }
171
+ return null;
172
+ }
173
+
174
+ function coerceInt(raw: string, spec: FieldSpec, path: string, report: ExtractionReport): unknown | typeof MALFORMED {
175
+ const n = parseFiniteNumber(raw);
176
+ if (n === null) return MALFORMED;
177
+ return clamp(Math.trunc(n), spec, path, report);
178
+ }
179
+
180
+ function coerceDouble(raw: string, spec: FieldSpec, path: string, report: ExtractionReport): unknown | typeof MALFORMED {
181
+ const n = parseFiniteNumber(raw);
182
+ if (n === null) return MALFORMED;
183
+ return clamp(n, spec, path, report);
184
+ }
185
+
186
+ /** Parse a trimmed numeric string; null if empty, non-numeric, or non-finite (NaN/±Infinity). */
187
+ function parseFiniteNumber(raw: string): number | null {
188
+ const t = raw.trim();
189
+ if (t.length === 0) return null;
190
+ // Reject JS-only radix-prefixed literals (0x.., 0b.., 0o..) that Number() would
191
+ // accept but Java/C# numeric parsing rejects → MALFORMED. Keeps cross-port parity.
192
+ if (/^[+-]?0[xXbBoO]/.test(t)) return null;
193
+ const n = Number(t); // Number("") === 0, hence the empty guard above
194
+ return Number.isFinite(n) ? n : null;
195
+ }
196
+
197
+ function clamp(n: number, spec: FieldSpec, path: string, report: ExtractionReport): number {
198
+ let c = n;
199
+ if (spec.min != null && c < spec.min) c = spec.min;
200
+ if (spec.max != null && c > spec.max) c = spec.max;
201
+ if (c !== n) report.addCoercion({ fieldPath: path, from: stringify(n), to: stringify(c), kind: "clamp" });
202
+ return c;
203
+ }
204
+
205
+ function coerceBool(raw: string, ci: boolean): boolean | typeof MALFORMED {
206
+ const t = ci ? raw.trim().toLowerCase() : raw.trim();
207
+ switch (t) {
208
+ case "true":
209
+ case "yes":
210
+ case "1":
211
+ return true;
212
+ case "false":
213
+ case "no":
214
+ case "0":
215
+ return false;
216
+ default:
217
+ return MALFORMED;
218
+ }
219
+ }
220
+
221
+ /** Canonical string form (locale-independent), mirroring Java String.valueOf for the corpus. */
222
+ function stringify(v: unknown): string {
223
+ return String(v);
224
+ }
@@ -1,5 +1,5 @@
1
- // Null-safe coercions from a RecoverOutcome data map onto typed values. Generated
2
- // recover(...) calls these. Mirrors Java RecoverMap.
1
+ // Null-safe coercions from a ExtractionOutcome data map onto typed values. Generated
2
+ // extract(...) calls these. Mirrors Java ExtractMap.
3
3
  //
4
4
  // Tier-2 divergence: JS has one number type, so asInt/asLong both return `number | null`
5
5
  // and truncate toward zero via Math.trunc (Java intValue()/longValue() also truncate).