@metaobjectsdev/codegen-ts 0.19.1-rc.1 → 0.19.2-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.
- package/dist/payload-codegen.d.ts +9 -4
- package/dist/payload-codegen.d.ts.map +1 -1
- package/dist/payload-codegen.js +209 -75
- package/dist/payload-codegen.js.map +1 -1
- package/dist/runner.d.ts.map +1 -1
- package/dist/runner.js +11 -1
- package/dist/runner.js.map +1 -1
- package/dist/templates/render-helper.d.ts.map +1 -1
- package/dist/templates/render-helper.js +15 -7
- package/dist/templates/render-helper.js.map +1 -1
- package/package.json +6 -6
- package/src/payload-codegen.ts +219 -73
- package/src/runner.ts +11 -1
- package/src/templates/render-helper.ts +15 -6
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
import { type MetaData } from "@metaobjectsdev/metadata";
|
|
2
2
|
/** Emit the payload `interface` (+ nested element interfaces) for an object.value view-object.
|
|
3
|
-
* `referrerPkg` (ADR-0042) is the package a bare `voName` resolves in; pass an FQN and it is ignored.
|
|
3
|
+
* `referrerPkg` (ADR-0042) is the package a bare `voName` resolves in; pass an FQN and it is ignored.
|
|
4
|
+
* ADR-0044: a short-name collision within `voName`'s reference closure emits EVERY colliding
|
|
5
|
+
* member under its package-qualified derived name; a non-colliding closure emits byte-identical
|
|
6
|
+
* bare names (unchanged from pre-ADR-0044 output). */
|
|
4
7
|
export declare function generatePayloadInterfaces(root: MetaData, voName: string, referrerPkg?: string): string;
|
|
5
8
|
/**
|
|
6
|
-
* Emit interfaces for several payloads at once, using a
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
+
* Emit interfaces for several payloads at once, using a SINGLE shared reference
|
|
10
|
+
* closure (ADR-0044: the closure of ALL the given roots together is the collision
|
|
11
|
+
* domain for this call) so nested types (e.g. lens projections referenced by
|
|
12
|
+
* multiple payloads) appear exactly once, and a short-name collision anywhere
|
|
13
|
+
* across the whole batch is caught and qualified consistently.
|
|
9
14
|
*
|
|
10
15
|
* Returns the empty string when `voNames` is empty.
|
|
11
16
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"payload-codegen.d.ts","sourceRoot":"","sources":["../src/payload-codegen.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"payload-codegen.d.ts","sourceRoot":"","sources":["../src/payload-codegen.ts"],"names":[],"mappings":"AAyBA,OAAO,EACL,KAAK,QAAQ,EAcd,MAAM,0BAA0B,CAAC;AA0PlC;;;;uDAIuD;AACvD,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,SAAK,GAAG,MAAM,CAOlG;AAED;;;;;;;;GAQG;AACH,wBAAgB,8BAA8B,CAC5C,IAAI,EAAE,QAAQ,EACd,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,WAAW,SAAK,GACf,MAAM,CAWR;AAMD,iGAAiG;AACjG,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAyBjF"}
|
package/dist/payload-codegen.js
CHANGED
|
@@ -9,7 +9,20 @@
|
|
|
9
9
|
// should reuse codegen-ts's canonical field mapping + ts-poet emit + the
|
|
10
10
|
// Generator/runner integration. Assembler (RDB materialization + host overlay)
|
|
11
11
|
// is out of scope — this only emits the contract.
|
|
12
|
-
|
|
12
|
+
//
|
|
13
|
+
// ADR-0044 — collision-aware naming: emission is a THREE-PASS pipeline.
|
|
14
|
+
// 1. collectClosure — walk the reference closure (FQN-exact resolution),
|
|
15
|
+
// collecting resolved VOs keyed by resolutionKey()
|
|
16
|
+
// (never bare name — bare-keyed dedupe silently drops
|
|
17
|
+
// the second same-short-name VO; #219/#220).
|
|
18
|
+
// 2. assignEmittedNames — a PURE function of the closure: a bare short name
|
|
19
|
+
// unique in the closure emits bare; a collision emits
|
|
20
|
+
// EVERY member under its package-qualified derived
|
|
21
|
+
// name (PascalCase each package segment + short name).
|
|
22
|
+
// A still-colliding derived name fails loud.
|
|
23
|
+
// 3. emitClosureDeclarations — emit each declaration + every reference through
|
|
24
|
+
// the name map.
|
|
25
|
+
import { TYPE_FIELD, TYPE_TEMPLATE, FIELD_SUBTYPE_OBJECT, FIELD_SUBTYPE_ENUM, FIELD_ATTR_OBJECT_REF, FIELD_ATTR_REQUIRED, TEMPLATE_ATTR_PAYLOAD_REF, TEMPLATE_ATTR_TEXT_REF, TEMPLATE_ATTR_FORMAT, PACKAGE_SEPARATOR, resolveObjectRef, stripPackage, } from "@metaobjectsdev/metadata";
|
|
13
26
|
import { enumValues } from "./enum-meta.js";
|
|
14
27
|
import { enumUnionAliasName, enumUnionString } from "./templates/inferred-types.js";
|
|
15
28
|
const SCALAR_TS = {
|
|
@@ -28,35 +41,134 @@ const SCALAR_TS = {
|
|
|
28
41
|
time: "string",
|
|
29
42
|
timestamp: "string",
|
|
30
43
|
};
|
|
44
|
+
// ADR-0044 backstop error code — a codegen-time (not loader) error, peer of
|
|
45
|
+
// @metaobjectsdev/render's ERR_VAR_NOT_ON_PAYLOAD. Declared LOCALLY rather than
|
|
46
|
+
// added to packages/metadata/src/errors.ts's ERROR_CODES ledger: that ledger is
|
|
47
|
+
// checked for FULL cross-port agreement against fixtures/conformance/ERROR-CODES.json
|
|
48
|
+
// (packages/metadata/test/errors.test.ts) and, on the Python side, for corpus-code
|
|
49
|
+
// coverage — registering it there before every port implements the ADR-0044 fix
|
|
50
|
+
// would turn those OTHER ports' tests red. It moves into the shared ledger once the
|
|
51
|
+
// Java/Kotlin/Python follow-up (ADR-0044 §4, items 3-4) lands alongside this code.
|
|
52
|
+
const ERR_PAYLOAD_NAME_COLLISION = "ERR_PAYLOAD_NAME_COLLISION";
|
|
31
53
|
// ADR-0039: resolving — root has no super (children()==ownChildren()); a top-level object/template may itself extend, so resolve rather than work-by-accident.
|
|
32
54
|
// ADR-0042: resolveObjectRef gives package-local-before-root-level precedence for a bare ref, FQN-exact otherwise.
|
|
33
55
|
function findObject(root, name, referrerPkg = "") {
|
|
34
56
|
return resolveObjectRef(root, name, referrerPkg).node;
|
|
35
57
|
}
|
|
36
58
|
/**
|
|
37
|
-
*
|
|
38
|
-
*
|
|
59
|
+
* ADR-0044 pass 1 — walk `voRef`'s transitive `@objectRef` closure with FQN-exact
|
|
60
|
+
* resolution, collecting resolved VOs keyed by `resolutionKey()` (never bare name
|
|
61
|
+
* — the #219/#220 defect). `visited` accumulates across multiple root calls so a
|
|
62
|
+
* batch emission (`generatePayloadInterfacesBatch`) shares ONE collision domain,
|
|
63
|
+
* per the ADR-0044 "closure of the payload root(s) emitted into one artifact"
|
|
64
|
+
* definition. A VO already in `visited` is not re-walked (cycle/dedupe guard).
|
|
65
|
+
*/
|
|
66
|
+
function collectClosure(root, voRef, referrerPkg, visited) {
|
|
67
|
+
const vo = findObject(root, voRef, referrerPkg);
|
|
68
|
+
if (!vo)
|
|
69
|
+
return;
|
|
70
|
+
const fqn = vo.resolutionKey();
|
|
71
|
+
if (visited.has(fqn))
|
|
72
|
+
return;
|
|
73
|
+
visited.set(fqn, vo);
|
|
74
|
+
// ADR-0042: a nested @objectRef resolves in the FIELD's OWN declaring package —
|
|
75
|
+
// which may differ from this resolved VO's package when the field is inherited
|
|
76
|
+
// via extends from an abstract VO in another package (the bare ref was authored
|
|
77
|
+
// there). Fall back to this VO's package when a field has no parent package.
|
|
78
|
+
const voPkg = vo.package ?? vo.fileDefaultPackage ?? "";
|
|
79
|
+
for (const f of vo.children().filter((c) => c.type === TYPE_FIELD)) {
|
|
80
|
+
if (f.subType !== FIELD_SUBTYPE_OBJECT)
|
|
81
|
+
continue;
|
|
82
|
+
const ref = f.attr(FIELD_ATTR_OBJECT_REF);
|
|
83
|
+
if (typeof ref !== "string")
|
|
84
|
+
continue;
|
|
85
|
+
const fieldPkg = f.parent?.package ?? f.parent?.fileDefaultPackage ?? voPkg;
|
|
86
|
+
collectClosure(root, ref, fieldPkg, visited);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
function pascalSegment(s) {
|
|
90
|
+
return s.length > 0 ? s[0].toUpperCase() + s.slice(1) : s;
|
|
91
|
+
}
|
|
92
|
+
/** ADR-0044 — package-qualified derived name for a collision member: PascalCase
|
|
93
|
+
* each `::`-segment of the node's effective package, concatenated, then the
|
|
94
|
+
* bare short name (`acme::alpha::Note` -> `AcmeAlphaNote`). A root-level
|
|
95
|
+
* (no-package) node has nothing to qualify with and keeps its bare name — two
|
|
96
|
+
* root-level VOs can never share a name (the loader's own-package uniqueness
|
|
97
|
+
* already rejects that), so this can't silently under-qualify. */
|
|
98
|
+
function packageQualifiedName(pkg, shortName) {
|
|
99
|
+
if (pkg === "")
|
|
100
|
+
return shortName;
|
|
101
|
+
return (pkg
|
|
102
|
+
.split(PACKAGE_SEPARATOR)
|
|
103
|
+
.map(pascalSegment)
|
|
104
|
+
.join("") + shortName);
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* ADR-0044 pass 2 — assign the emitted TS name for every VO in the closure. A
|
|
108
|
+
* PURE function of the closure's (fqn, bareName, package) triples — never of
|
|
109
|
+
* traversal order: bare short name unique in the closure -> bare name; a
|
|
110
|
+
* collision -> EVERY member gets its package-qualified derived name. If two
|
|
111
|
+
* DISTINCT fqns still derive the same name after qualification, throws
|
|
112
|
+
* (ERR_PAYLOAD_NAME_COLLISION) — never silently wrong.
|
|
113
|
+
*/
|
|
114
|
+
function assignEmittedNames(closure) {
|
|
115
|
+
const byShortName = new Map();
|
|
116
|
+
for (const [fqn, node] of closure) {
|
|
117
|
+
const bucket = byShortName.get(node.name);
|
|
118
|
+
if (bucket)
|
|
119
|
+
bucket.push(fqn);
|
|
120
|
+
else
|
|
121
|
+
byShortName.set(node.name, [fqn]);
|
|
122
|
+
}
|
|
123
|
+
const nameMap = new Map();
|
|
124
|
+
for (const [shortName, fqns] of byShortName) {
|
|
125
|
+
if (fqns.length === 1) {
|
|
126
|
+
nameMap.set(fqns[0], shortName);
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
for (const fqn of fqns) {
|
|
130
|
+
const node = closure.get(fqn);
|
|
131
|
+
const pkg = node.package ?? node.fileDefaultPackage ?? "";
|
|
132
|
+
nameMap.set(fqn, packageQualifiedName(pkg, shortName));
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
// Backstop — sorted by fqn so which pair the message names (and whether the
|
|
136
|
+
// set of colliding names is non-empty) is a pure function of the closure, not
|
|
137
|
+
// of Map insertion/traversal order.
|
|
138
|
+
const ownerOf = new Map();
|
|
139
|
+
for (const fqn of [...nameMap.keys()].sort()) {
|
|
140
|
+
const emitted = nameMap.get(fqn);
|
|
141
|
+
const existing = ownerOf.get(emitted);
|
|
142
|
+
if (existing !== undefined && existing !== fqn) {
|
|
143
|
+
throw new Error(`${ERR_PAYLOAD_NAME_COLLISION}: payload record name collision: "${emitted}" derives from both "${existing}" and "${fqn}" — rename one value-object or move it to a package that derives a distinct name`);
|
|
144
|
+
}
|
|
145
|
+
ownerOf.set(emitted, fqn);
|
|
146
|
+
}
|
|
147
|
+
return nameMap;
|
|
148
|
+
}
|
|
149
|
+
/** Resolve `ref`'s emitted TS interface name under the ADR-0044 naming rule,
|
|
150
|
+
* scoped to `ref`'s OWN reference closure (the same closure
|
|
151
|
+
* `generatePayloadInterfaces(root, ref, referrerPkg)` would emit). Returns
|
|
152
|
+
* undefined when `ref` does not resolve to an object.value. */
|
|
153
|
+
function resolveEmittedName(root, ref, referrerPkg) {
|
|
154
|
+
const vo = findObject(root, ref, referrerPkg);
|
|
155
|
+
if (!vo)
|
|
156
|
+
return undefined;
|
|
157
|
+
const closure = new Map();
|
|
158
|
+
collectClosure(root, ref, referrerPkg, closure);
|
|
159
|
+
return assignEmittedNames(closure).get(vo.resolutionKey());
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Map a non-object payload field to its strict TS type.
|
|
39
163
|
* - `enumAlias`: a `{ name, decl }` for a `field.enum` — `name` is the union-alias
|
|
40
164
|
* type referenced inline; `decl` is the `export type <name> = "A" | "B";` line the
|
|
41
165
|
* caller hoists above the interface (deduped). Reuses the SAME naming + union
|
|
42
166
|
* logic as the entity inferred-types emitter (single source of truth).
|
|
167
|
+
* Object (`field.object`) fields are NOT handled here — their type comes from the
|
|
168
|
+
* ADR-0044 closure name map, resolved by the caller (the ref may need
|
|
169
|
+
* package-qualification the field alone can't determine).
|
|
43
170
|
*/
|
|
44
171
|
function fieldTsType(field, ownerName) {
|
|
45
|
-
if (field.subType === FIELD_SUBTYPE_OBJECT) {
|
|
46
|
-
const ref = field.attr(FIELD_ATTR_OBJECT_REF);
|
|
47
|
-
// FR-032/ADR-0041 — @objectRef canonicalizes to an FQN (`pkg::Name`), which is not
|
|
48
|
-
// a valid TS identifier. The emitted TYPE is the bare name; the FQN is retained as
|
|
49
|
-
// refVo for resolution/recursion (findObject matches FQN or bare).
|
|
50
|
-
const refName = typeof ref === "string" ? stripPackage(ref) : "unknown";
|
|
51
|
-
// isArray is a structural property on MetaData, not an attr.
|
|
52
|
-
const isArray = field.resolvedIsArray();
|
|
53
|
-
const result = {
|
|
54
|
-
type: isArray ? `${refName}[]` : refName,
|
|
55
|
-
};
|
|
56
|
-
if (typeof ref === "string")
|
|
57
|
-
result.refVo = ref;
|
|
58
|
-
return result;
|
|
59
|
-
}
|
|
60
172
|
// field.enum: a value-constrained string-literal union alias (NOT `unknown`).
|
|
61
173
|
// Field nodes are MetaField instances at runtime (MetaField extends MetaData),
|
|
62
174
|
// so the enum helpers (effective @values + super-resolving name) apply.
|
|
@@ -79,76 +191,98 @@ function fieldTsType(field, ownerName) {
|
|
|
79
191
|
function isFieldRequired(field) {
|
|
80
192
|
return field.attr(FIELD_ATTR_REQUIRED) === true;
|
|
81
193
|
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
194
|
+
/**
|
|
195
|
+
* ADR-0044 pass 3 — emit `export interface <emittedName> { ... }` for every VO in
|
|
196
|
+
* the closure, in closure-visitation order, using `nameMap` for both the
|
|
197
|
+
* declaration name and every nested `field.object` reference's type.
|
|
198
|
+
*/
|
|
199
|
+
function emitClosureDeclarations(root, closure, nameMap, out, enumAliases) {
|
|
200
|
+
for (const [, vo] of closure) {
|
|
201
|
+
const voName = nameMap.get(vo.resolutionKey());
|
|
202
|
+
const voPkg = vo.package ?? vo.fileDefaultPackage ?? "";
|
|
203
|
+
const aliasLines = [];
|
|
204
|
+
const lines = [`export interface ${voName} {`];
|
|
205
|
+
for (const f of vo.children().filter((c) => c.type === TYPE_FIELD)) {
|
|
206
|
+
let type;
|
|
207
|
+
let enumAlias;
|
|
208
|
+
if (f.subType === FIELD_SUBTYPE_OBJECT) {
|
|
209
|
+
const ref = f.attr(FIELD_ATTR_OBJECT_REF);
|
|
210
|
+
if (typeof ref === "string") {
|
|
211
|
+
// The nested ref resolves in the FIELD's declaring package (ADR-0042),
|
|
212
|
+
// not the resolved VO's — they differ when `f` is inherited from an
|
|
213
|
+
// abstract VO elsewhere.
|
|
214
|
+
const fieldPkg = f.parent?.package ?? f.parent?.fileDefaultPackage ?? voPkg;
|
|
215
|
+
const refNode = findObject(root, ref, fieldPkg);
|
|
216
|
+
// refNode was walked into the closure by collectClosure — the name map
|
|
217
|
+
// always has it. The stripPackage fallback only guards a defensive gap
|
|
218
|
+
// (e.g. a caller-constructed closure that skipped pass 1).
|
|
219
|
+
const refName = (refNode && nameMap.get(refNode.resolutionKey())) ?? stripPackage(ref);
|
|
220
|
+
type = f.resolvedIsArray() ? `${refName}[]` : refName;
|
|
221
|
+
}
|
|
222
|
+
else {
|
|
223
|
+
type = "unknown";
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
else {
|
|
227
|
+
const r = fieldTsType(f, voName);
|
|
228
|
+
type = r.type;
|
|
229
|
+
enumAlias = r.enumAlias;
|
|
230
|
+
}
|
|
231
|
+
// Hoist the enum union alias above the interface, deduped across the whole
|
|
232
|
+
// batch (multiple fields/objects can share one abstract enum's alias).
|
|
233
|
+
if (enumAlias && !enumAliases.has(enumAlias.name)) {
|
|
234
|
+
enumAliases.add(enumAlias.name);
|
|
235
|
+
aliasLines.push(enumAlias.decl);
|
|
236
|
+
}
|
|
237
|
+
// Required fields: `name: T;`
|
|
238
|
+
// Optional fields: `name?: T | null;` — the `| null` lets values from
|
|
239
|
+
// Drizzle entity rows (which return `null` for nullable columns) flow
|
|
240
|
+
// straight in. Without it, TS treats undefined-vs-null as a hard error
|
|
241
|
+
// at the entity → payload boundary.
|
|
242
|
+
const isRequired = isFieldRequired(f);
|
|
243
|
+
const tsType = isRequired ? type : `${type} | null`;
|
|
244
|
+
const optional = isRequired ? "" : "?";
|
|
245
|
+
lines.push(` ${f.name}${optional}: ${tsType};`);
|
|
108
246
|
}
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
// straight in. Without it, TS treats undefined-vs-null as a hard error
|
|
113
|
-
// at the entity → payload boundary.
|
|
114
|
-
const isRequired = isFieldRequired(f);
|
|
115
|
-
const tsType = isRequired ? type : `${type} | null`;
|
|
116
|
-
const optional = isRequired ? "" : "?";
|
|
117
|
-
lines.push(` ${f.name}${optional}: ${tsType};`);
|
|
118
|
-
// The nested ref resolves in the FIELD's declaring package (ADR-0042), not the
|
|
119
|
-
// resolved VO's — they differ when `f` is inherited from an abstract VO elsewhere.
|
|
120
|
-
if (refVo)
|
|
121
|
-
refs.push({ ref: refVo, pkg: f.parent?.package ?? f.parent?.fileDefaultPackage ?? voPkg });
|
|
247
|
+
lines.push("}");
|
|
248
|
+
const block = aliasLines.length > 0 ? `${aliasLines.join("\n")}\n${lines.join("\n")}` : lines.join("\n");
|
|
249
|
+
out.push(block);
|
|
122
250
|
}
|
|
123
|
-
lines.push("}");
|
|
124
|
-
const block = aliasLines.length > 0 ? `${aliasLines.join("\n")}\n${lines.join("\n")}` : lines.join("\n");
|
|
125
|
-
out.push(block);
|
|
126
|
-
for (const r of refs)
|
|
127
|
-
emitInterface(root, r.ref, r.pkg, emitted, out, enumAliases);
|
|
128
251
|
}
|
|
129
252
|
/** Emit the payload `interface` (+ nested element interfaces) for an object.value view-object.
|
|
130
|
-
* `referrerPkg` (ADR-0042) is the package a bare `voName` resolves in; pass an FQN and it is ignored.
|
|
253
|
+
* `referrerPkg` (ADR-0042) is the package a bare `voName` resolves in; pass an FQN and it is ignored.
|
|
254
|
+
* ADR-0044: a short-name collision within `voName`'s reference closure emits EVERY colliding
|
|
255
|
+
* member under its package-qualified derived name; a non-colliding closure emits byte-identical
|
|
256
|
+
* bare names (unchanged from pre-ADR-0044 output). */
|
|
131
257
|
export function generatePayloadInterfaces(root, voName, referrerPkg = "") {
|
|
258
|
+
const closure = new Map();
|
|
259
|
+
collectClosure(root, voName, referrerPkg, closure);
|
|
260
|
+
const nameMap = assignEmittedNames(closure);
|
|
132
261
|
const out = [];
|
|
133
|
-
|
|
262
|
+
emitClosureDeclarations(root, closure, nameMap, out, new Set());
|
|
134
263
|
return out.join("\n\n") + "\n";
|
|
135
264
|
}
|
|
136
265
|
/**
|
|
137
|
-
* Emit interfaces for several payloads at once, using a
|
|
138
|
-
*
|
|
139
|
-
*
|
|
266
|
+
* Emit interfaces for several payloads at once, using a SINGLE shared reference
|
|
267
|
+
* closure (ADR-0044: the closure of ALL the given roots together is the collision
|
|
268
|
+
* domain for this call) so nested types (e.g. lens projections referenced by
|
|
269
|
+
* multiple payloads) appear exactly once, and a short-name collision anywhere
|
|
270
|
+
* across the whole batch is caught and qualified consistently.
|
|
140
271
|
*
|
|
141
272
|
* Returns the empty string when `voNames` is empty.
|
|
142
273
|
*/
|
|
143
274
|
export function generatePayloadInterfacesBatch(root, voNames, referrerPkg = "") {
|
|
144
275
|
if (voNames.length === 0)
|
|
145
276
|
return "";
|
|
146
|
-
const
|
|
147
|
-
const emitted = new Set();
|
|
148
|
-
const enumAliases = new Set();
|
|
277
|
+
const closure = new Map();
|
|
149
278
|
for (const name of voNames) {
|
|
150
|
-
|
|
279
|
+
collectClosure(root, name, referrerPkg, closure);
|
|
151
280
|
}
|
|
281
|
+
if (closure.size === 0)
|
|
282
|
+
return "";
|
|
283
|
+
const nameMap = assignEmittedNames(closure);
|
|
284
|
+
const out = [];
|
|
285
|
+
emitClosureDeclarations(root, closure, nameMap, out, new Set());
|
|
152
286
|
return out.length === 0 ? "" : out.join("\n\n") + "\n";
|
|
153
287
|
}
|
|
154
288
|
function pascal(s) {
|
|
@@ -162,10 +296,10 @@ export function generateRenderHandle(root, templateName) {
|
|
|
162
296
|
// ADR-0039: resolving — a template may inherit its @* refs/format/kind via extends.
|
|
163
297
|
const payloadRef = tmpl.attr(TEMPLATE_ATTR_PAYLOAD_REF);
|
|
164
298
|
// FR-032 — @payloadRef is an FQN after the desugar/sweep; the generated TS
|
|
165
|
-
// TYPE NAME is the resolved value-object's
|
|
166
|
-
//
|
|
167
|
-
// `::`-segment when the VO is not in this root (defensive).
|
|
168
|
-
const payloadType = (typeof payloadRef === "string" ?
|
|
299
|
+
// TYPE NAME is the resolved value-object's ADR-0044 emitted name (bare when
|
|
300
|
+
// unique in its closure, package-qualified on a short-name collision). Fall
|
|
301
|
+
// back to the last `::`-segment when the VO is not in this root (defensive).
|
|
302
|
+
const payloadType = (typeof payloadRef === "string" ? resolveEmittedName(root, payloadRef, "") : undefined) ??
|
|
169
303
|
(typeof payloadRef === "string" ? stripPackage(payloadRef) : String(payloadRef));
|
|
170
304
|
// ADR-0039: resolving — a template may inherit its @* refs/format/kind via extends.
|
|
171
305
|
const textRef = tmpl.attr(TEMPLATE_ATTR_TEXT_REF);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"payload-codegen.js","sourceRoot":"","sources":["../src/payload-codegen.ts"],"names":[],"mappings":"AAAA,oFAAoF;AACpF,EAAE;AACF,+EAA+E;AAC/E,iFAAiF;AACjF,+EAA+E;AAC/E,sEAAsE;AACtE,EAAE;AACF,8EAA8E;AAC9E,yEAAyE;AACzE,+EAA+E;AAC/E,kDAAkD;
|
|
1
|
+
{"version":3,"file":"payload-codegen.js","sourceRoot":"","sources":["../src/payload-codegen.ts"],"names":[],"mappings":"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"}
|
package/dist/runner.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAc,MAAM,0BAA0B,CAAC;AAGrE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAMpE,OAAO,EAEL,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,YAAY,EAClB,MAAM,uBAAuB,CAAC;AAU/B,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,oBAAoB,CAAC;IAC7B,QAAQ,EAAE,QAAQ,CAAC;IACnB,0CAA0C;IAC1C,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,4EAA4E;IAC5E,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B;;4BAEwB;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;oDACgD;IAChD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;qBAEiB;IACjB,QAAQ,CAAC,EAAE,YAAY,CAAC;CACzB;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB;gDAC4C;IAC5C,SAAS,EAAE,WAAW,EAAE,CAAC;CAC1B;AAED,wBAAsB,MAAM,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,YAAY,CAAC,
|
|
1
|
+
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAc,MAAM,0BAA0B,CAAC;AAGrE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAMpE,OAAO,EAEL,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,YAAY,EAClB,MAAM,uBAAuB,CAAC;AAU/B,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,oBAAoB,CAAC;IAC7B,QAAQ,EAAE,QAAQ,CAAC;IACnB,0CAA0C;IAC1C,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,4EAA4E;IAC5E,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B;;4BAEwB;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;oDACgD;IAChD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;qBAEiB;IACjB,QAAQ,CAAC,EAAE,YAAY,CAAC;CACzB;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB;gDAC4C;IAC5C,SAAS,EAAE,WAAW,EAAE,CAAC;CAC1B;AAED,wBAAsB,MAAM,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,YAAY,CAAC,CAyNpE"}
|
package/dist/runner.js
CHANGED
|
@@ -106,6 +106,16 @@ export async function runGen(opts) {
|
|
|
106
106
|
continue;
|
|
107
107
|
}
|
|
108
108
|
const selfTarget = targetOf(generator);
|
|
109
|
+
// Resolve the WRITE-time location against projectRoot when outDir is
|
|
110
|
+
// relative and projectRoot is known — otherwise a relative outDir (the
|
|
111
|
+
// common, portable, `meta init`-scaffolded shape) silently resolves
|
|
112
|
+
// against the ambient process.cwd() instead of the project the CLI's
|
|
113
|
+
// `--cwd` flag says to run as. Import-path math below intentionally keeps
|
|
114
|
+
// using selfTarget.outDir as configured (relative paths between targets
|
|
115
|
+
// are compared to each other, not to projectRoot).
|
|
116
|
+
const writeOutDir = projectRoot !== undefined && !isAbsolute(selfTarget.outDir)
|
|
117
|
+
? resolve(projectRoot, selfTarget.outDir)
|
|
118
|
+
: selfTarget.outDir;
|
|
109
119
|
const renderContext = makeRenderContext({
|
|
110
120
|
dialect: config.dialect,
|
|
111
121
|
loadedRoot: root,
|
|
@@ -151,7 +161,7 @@ export async function runGen(opts) {
|
|
|
151
161
|
throw new Error(`[${generator.name}] ${msg}`);
|
|
152
162
|
}
|
|
153
163
|
for (const file of files) {
|
|
154
|
-
const fullPath = join(
|
|
164
|
+
const fullPath = join(writeOutDir, file.path);
|
|
155
165
|
const collision = emitted.find((prev) => prev.fullPath === fullPath);
|
|
156
166
|
if (collision) {
|
|
157
167
|
throw new Error(`Output path collision: "${fullPath}" emitted by both ` +
|
package/dist/runner.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner.js","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAChE,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAEjC,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAGpD,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAE/E,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EACL,cAAc,GAIf,MAAM,uBAAuB,CAAC;AAE/B;kFACkF;AAClF,MAAM,iBAAiB,GAAG,0BAA0B,CAAC;AAErD;kFACkF;AAClF,MAAM,yBAAyB,GAAG,IAAI,GAAG,CAAC,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC,CAAC;AA8BrE,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,IAAgB;IAC3C,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,IAAI,WAAW,CAAC;IACnD,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,SAAS,CAAC;IAC5C,yEAAyE;IACzE,wEAAwE;IACxE,yEAAyE;IACzE,0EAA0E;IAC1E,gEAAgE;IAChE,uEAAuE;IACvE,2DAA2D;IAC3D,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,KAAK,SAAS;QAChD,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAC/E,CAAC,CAAC,SAAS,CAAC;IACd,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,KAAK,SAAS;QAChD,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,WAAW,CAAC;YAC3B,CAAC,CAAC,IAAI,CAAC,WAAW;YAClB,CAAC,CAAC,OAAO,CAAC,WAAW,IAAI,OAAO,CAAC,GAAG,EAAE,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;QAC9D,CAAC,CAAC,CAAC,WAAW,KAAK,SAAS;YACxB,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,cAAc,EAAE,YAAY,CAAC;YACjD,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,kBAAkB,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IAEzD,8EAA8E;IAC9E,wEAAwE;IACxE,IAAI,CAAC,CAAC,IAAI,CAAC,QAAQ,YAAY,QAAQ,CAAC,EAAE,CAAC;QACzC,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;IACtE,CAAC;IACD,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC;IAE3B,+CAA+C;IAC/C,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;IAClC,MAAM,YAAY,GAAG,IAAI,CAAC,YAAY,CAAC;IACvC,MAAM,QAAQ,GAAG,YAAY;QAC3B,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACzD,CAAC,CAAC,UAAU,CAAC;IACf,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY;YAC9B,CAAC,CAAC,oDAAoD;YACtD,CAAC,CAAC,6BAA6B,CAAC;QAClC,QAAQ,CAAC,IAAI,CAAC,6BAA6B,MAAM,GAAG,CAAC,CAAC;QACtD,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC;IAChD,CAAC;IAED,MAAM,YAAY,GAAiB,EAAE,CAAC;IACtC,KAAK,MAAM,MAAM,IAAI,QAAQ,EAAE,CAAC;QAC9B,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;YACzC,QAAQ,CAAC,IAAI,CACX,qCAAqC,MAAM,CAAC,IAAI,4CAA4C,CAC7F,CAAC;YACF,SAAS;QACX,CAAC;QACD,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC5B,CAAC;IACD,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC9B,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC;IAChD,CAAC;IAED,6CAA6C;IAC7C,MAAM,MAAM,GAAG,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC5C,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;IAC/B,MAAM,QAAQ,GAAG,CAAC,CAAY,EAAkB,EAAE;QAChD,MAAM,IAAI,GAAG,CAAC,CAAC,MAAM,IAAI,mBAAmB,CAAC;QAC7C,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QACxB,IAAI,CAAC,CAAC,EAAE,CAAC;YACP,MAAM,IAAI,KAAK,CACb,cAAc,CAAC,CAAC,IAAI,gCAAgC,IAAI,KAAK;gBAC7D,kBAAkB,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CACrD,CAAC;QACJ,CAAC;QACD,OAAO,CAAC,CAAC;IACX,CAAC,CAAC;IACF,2CAA2C;IAC3C,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,UAAU;QAAE,QAAQ,CAAC,CAAC,CAAC,CAAC;IAE/C,MAAM,SAAS,GAAG,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC;IACrE,MAAM,kBAAkB,GAAG,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,mBAAmB,CAAE,CAAC;IAE3F,MAAM,gBAAgB,GAAG,MAAM,CAAC,UAAU,CAAC,IAAI,CAC7C,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,mBAAmB,CAAC,KAAK,kBAAkB,CAAC,IAAI,CACrE,CAAC;IACF,IAAI,gBAAgB,IAAI,kBAAkB,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;QACpE,MAAM,IAAI,KAAK,CACb,WAAW,kBAAkB,CAAC,IAAI,wCAAwC;YAC1E,oEAAoE;YACpE,kCAAkC,CACnC,CAAC;IACJ,CAAC;IAED,qCAAqC;IACrC,MAAM,KAAK,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;IAC/B,MAAM,WAAW,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;IAC3C,MAAM,SAAS,GAAG,IAAI,GAAG,CACvB,IAAI,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAC/C,CAAC;IAEF,+EAA+E;IAC/E,4EAA4E;IAC5E,qEAAqE;IACrE,MAAM,iBAAiB,GAAG,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,eAAe,KAAK,IAAI,CAAC,CAAC;IAEpF,kFAAkF;IAClF,MAAM,OAAO,GAAiE,EAAE,CAAC;IACjF,KAAK,MAAM,SAAS,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;QAC1C,0EAA0E;QAC1E,4EAA4E;QAC5E,oDAAoD;QACpD,IAAI,yBAAyB,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;YAClD,QAAQ,CAAC,IAAI,CACX,IAAI,SAAS,CAAC,IAAI,iDAAiD;gBACnE,UAAU,SAAS,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,YAAY,4BAA4B,CACrG,CAAC;YACF,SAAS;QACX,CAAC;QACD,MAAM,UAAU,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC;QACvC,MAAM,aAAa,GAAG,iBAAiB,CAAC;YACtC,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,UAAU,EAAE,IAAI;YAChB,MAAM,EAAE,UAAU,CAAC,MAAM;YACzB,QAAQ,EAAE,UAAU,CAAC,QAAQ;YAC7B,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,oBAAoB,EAAE,MAAM,CAAC,oBAAoB;YACjD,oBAAoB,EAAE,MAAM,CAAC,oBAAoB;YACjD,uBAAuB,EAAE,MAAM,CAAC,uBAAuB;YACvD,aAAa,EAAE,MAAM,CAAC,aAAa;YACnC,SAAS,EAAE,MAAM,CAAC,SAAS;YAC3B,kBAAkB,EAAE,MAAM,CAAC,kBAAkB;YAC7C,YAAY,EAAE,UAAU,CAAC,YAAY;YACrC,KAAK;YACL,WAAW;YACX,SAAS;YACT,UAAU;YACV,kBAAkB;YAClB,GAAG,CAAC,MAAM,CAAC,kBAAkB,KAAK,SAAS,IAAI,EAAE,kBAAkB,EAAE,MAAM,CAAC,kBAAkB,EAAE,CAAC;SAClG,CAAC,CAAC;QACH,MAAM,GAAG,GAAe;YACtB,QAAQ,EAAE,YAAY;YACtB,UAAU,EAAE,IAAI;YAChB,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI;YAC7C,MAAM,EAAE;gBACN,MAAM,EAAE,UAAU,CAAC,MAAM;gBACzB,QAAQ,EAAE,MAAM,CAAC,QAAQ;gBACzB,QAAQ,EAAE,UAAU,CAAC,QAAQ;gBAC7B,OAAO,EAAE,MAAM,CAAC,OAAO;gBACvB,YAAY,EAAE,UAAU,CAAC,YAAY;gBACrC,iBAAiB;aAClB;YACD,aAAa;YACb,GAAG,CAAC,WAAW,KAAK,SAAS,IAAI,EAAE,WAAW,EAAE,CAAC;YACjD,IAAI,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC,IAAI,KAAK,GAAG,EAAE,CAAC;SAC3D,CAAC;QAEF,IAAI,KAAoB,CAAC;QACzB,IAAI,CAAC;YACH,KAAK,GAAG,MAAM,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QACxC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAC7D,MAAM,IAAI,KAAK,CAAC,IAAI,SAAS,CAAC,IAAI,KAAK,GAAG,EAAE,CAAC,CAAC;QAChD,CAAC;QAED,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,QAAQ,GAAG,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"runner.js","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"render-helper.d.ts","sourceRoot":"","sources":["../../src/templates/render-helper.ts"],"names":[],"mappings":"AA2BA,OAAO,EACL,KAAK,QAAQ,
|
|
1
|
+
{"version":3,"file":"render-helper.d.ts","sourceRoot":"","sources":["../../src/templates/render-helper.ts"],"names":[],"mappings":"AA2BA,OAAO,EACL,KAAK,QAAQ,EAkBd,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAGL,KAAK,QAAQ,EAGd,MAAM,wBAAwB,CAAC;AAoFhC;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,QAAQ,EACd,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,QAAQ,GACjB,MAAM,CAqHR"}
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
// depend on the cli package; the walk is the same as cli's payload-field-tree).
|
|
25
25
|
// • PayloadField — the verify() field-tree shape; serialized into the emitted
|
|
26
26
|
// `verify:` literal so render()'s runtime drift check runs too.
|
|
27
|
-
import { TYPE_FIELD, TYPE_TEMPLATE, FIELD_SUBTYPE_OBJECT, FIELD_ATTR_OBJECT_REF, TEMPLATE_SUBTYPE_OUTPUT, TEMPLATE_ATTR_PAYLOAD_REF, TEMPLATE_ATTR_TEXT_REF, TEMPLATE_ATTR_FORMAT, TEMPLATE_ATTR_MAX_CHARS, TEMPLATE_ATTR_KIND, TEMPLATE_KIND_EMAIL, TEMPLATE_KIND_DEFAULT, TEMPLATE_ATTR_SUBJECT_REF, TEMPLATE_ATTR_HTML_BODY_REF, TEMPLATE_ATTR_TEXT_BODY_REF, resolveObjectRef, } from "@metaobjectsdev/metadata";
|
|
27
|
+
import { TYPE_FIELD, TYPE_TEMPLATE, FIELD_SUBTYPE_OBJECT, FIELD_ATTR_OBJECT_REF, TEMPLATE_SUBTYPE_OUTPUT, TEMPLATE_ATTR_PAYLOAD_REF, TEMPLATE_ATTR_TEXT_REF, TEMPLATE_ATTR_FORMAT, TEMPLATE_ATTR_MAX_CHARS, TEMPLATE_ATTR_KIND, TEMPLATE_KIND_EMAIL, TEMPLATE_KIND_DEFAULT, TEMPLATE_ATTR_SUBJECT_REF, TEMPLATE_ATTR_HTML_BODY_REF, TEMPLATE_ATTR_TEXT_BODY_REF, resolveObjectRef, stripPackage, } from "@metaobjectsdev/metadata";
|
|
28
28
|
import { verify, ERR_REQUIRED_SLOT_UNUSED, } from "@metaobjectsdev/render";
|
|
29
29
|
// ADR-0039: resolving — root has no super (children()==ownChildren()); a top-level object/template may itself extend, so resolve rather than work-by-accident.
|
|
30
30
|
// ADR-0042: package-local — resolveObjectRef binds a bare @objectRef in `referrerPkg` first (else root-level), an FQN exactly.
|
|
@@ -121,6 +121,14 @@ export function renderRenderHelper(root, templateName, provider) {
|
|
|
121
121
|
const fields = derivePayloadFieldTree(root, payloadRef, tmplPkg);
|
|
122
122
|
const ft = fieldTreeLiteral(fields);
|
|
123
123
|
const fnName = `render${templateName}`;
|
|
124
|
+
// @payloadRef may arrive package-qualified (FQN) once resolved — a bare
|
|
125
|
+
// `::`-free name is required everywhere it's emitted as a TS identifier /
|
|
126
|
+
// import specifier below (mirrors the same stripPackage() call every other
|
|
127
|
+
// TS-identifier-emitting generator makes on a resolved ref, e.g.
|
|
128
|
+
// payload-codegen.ts / entity-file.ts / drizzle-schema.ts). Package-scoped
|
|
129
|
+
// resolution above (findObject/derivePayloadFieldTree) intentionally keeps
|
|
130
|
+
// using the raw `payloadRef`.
|
|
131
|
+
const payloadTypeName = stripPackage(payloadRef);
|
|
124
132
|
// ADR-0039: resolving — a template may inherit its @* refs/format/kind via extends.
|
|
125
133
|
const kind = (tmpl.attr(TEMPLATE_ATTR_KIND) ?? TEMPLATE_KIND_DEFAULT)
|
|
126
134
|
.toLowerCase();
|
|
@@ -146,14 +154,14 @@ export function renderRenderHelper(root, templateName, provider) {
|
|
|
146
154
|
: "";
|
|
147
155
|
return `import { render } from "@metaobjectsdev/render";
|
|
148
156
|
import type { Provider, EmailDocument } from "@metaobjectsdev/render";
|
|
149
|
-
import type { ${
|
|
157
|
+
import type { ${payloadTypeName} } from "./${payloadTypeName}.js";
|
|
150
158
|
|
|
151
159
|
/**
|
|
152
160
|
* Render the ${templateName} email (subject + html body${typeof textBodyRef === "string" ? " + text body" : ""}) from a
|
|
153
|
-
* typed ${
|
|
161
|
+
* typed ${payloadTypeName} payload. Wraps the render() engine; the payload field tree is
|
|
154
162
|
* baked in so render()'s runtime drift check matches the build-time gate.
|
|
155
163
|
*/
|
|
156
|
-
export function ${fnName}(payload: ${
|
|
164
|
+
export function ${fnName}(payload: ${payloadTypeName}, provider: Provider): EmailDocument {
|
|
157
165
|
return {
|
|
158
166
|
subject: render({ ref: ${JSON.stringify(subjectRef)}, payload, format: "text", provider, verify: ${ft} }),
|
|
159
167
|
htmlBody: render({ ref: ${JSON.stringify(htmlBodyRef)}, payload, format: "html", provider, verify: ${ft} }),${textBodyLine}
|
|
@@ -180,14 +188,14 @@ export function ${fnName}(payload: ${payloadRef}, provider: Provider): EmailDocu
|
|
|
180
188
|
const maxCharsArg = maxChars !== undefined && Number.isFinite(maxChars) ? `, maxChars: ${maxChars}` : "";
|
|
181
189
|
return `import { render } from "@metaobjectsdev/render";
|
|
182
190
|
import type { Provider } from "@metaobjectsdev/render";
|
|
183
|
-
import type { ${
|
|
191
|
+
import type { ${payloadTypeName} } from "./${payloadTypeName}.js";
|
|
184
192
|
|
|
185
193
|
/**
|
|
186
|
-
* Render the ${templateName} document from a typed ${
|
|
194
|
+
* Render the ${templateName} document from a typed ${payloadTypeName} payload. Wraps the
|
|
187
195
|
* render() engine; the payload field tree is baked in so render()'s runtime drift
|
|
188
196
|
* check matches the build-time gate enforced when this file was generated.
|
|
189
197
|
*/
|
|
190
|
-
export function ${fnName}(payload: ${
|
|
198
|
+
export function ${fnName}(payload: ${payloadTypeName}, provider: Provider): string {
|
|
191
199
|
return render({ ref: ${JSON.stringify(textRef)}, payload, format: ${JSON.stringify(format)}, provider, verify: ${ft}${maxCharsArg} });
|
|
192
200
|
}
|
|
193
201
|
`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"render-helper.js","sourceRoot":"","sources":["../../src/templates/render-helper.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,EAAE;AACF,qFAAqF;AACrF,gFAAgF;AAChF,4DAA4D;AAC5D,EAAE;AACF,+BAA+B;AAC/B,qEAAqE;AACrE,0EAA0E;AAC1E,wEAAwE;AACxE,EAAE;AACF,+EAA+E;AAC/E,gFAAgF;AAChF,0EAA0E;AAC1E,iFAAiF;AACjF,4EAA4E;AAC5E,gFAAgF;AAChF,0CAA0C;AAC1C,EAAE;AACF,+BAA+B;AAC/B,qEAAqE;AACrE,6DAA6D;AAC7D,+EAA+E;AAC/E,oFAAoF;AACpF,gFAAgF;AAChF,oEAAoE;AAEpE,OAAO,EAEL,UAAU,EACV,aAAa,EACb,oBAAoB,EACpB,qBAAqB,EACrB,uBAAuB,EACvB,yBAAyB,EACzB,sBAAsB,EACtB,oBAAoB,EACpB,uBAAuB,EACvB,kBAAkB,EAClB,mBAAmB,EACnB,qBAAqB,EACrB,yBAAyB,EACzB,2BAA2B,EAC3B,2BAA2B,EAC3B,gBAAgB,
|
|
1
|
+
{"version":3,"file":"render-helper.js","sourceRoot":"","sources":["../../src/templates/render-helper.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.19.
|
|
3
|
+
"version": "0.19.2-rc.1",
|
|
4
4
|
"description": "TypeScript codegen engine for MetaObjects — emits Drizzle, Zod, and Fastify artifacts.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -111,8 +111,8 @@
|
|
|
111
111
|
"access": "public"
|
|
112
112
|
},
|
|
113
113
|
"dependencies": {
|
|
114
|
-
"@metaobjectsdev/metadata": "0.19.
|
|
115
|
-
"@metaobjectsdev/render": "0.19.
|
|
114
|
+
"@metaobjectsdev/metadata": "0.19.2-rc.1",
|
|
115
|
+
"@metaobjectsdev/render": "0.19.2-rc.1",
|
|
116
116
|
"@biomejs/js-api": "^0.7.0",
|
|
117
117
|
"@biomejs/wasm-nodejs": "^1.9.4",
|
|
118
118
|
"ts-poet": "^6.10.0"
|
|
@@ -123,9 +123,9 @@
|
|
|
123
123
|
},
|
|
124
124
|
"devDependencies": {
|
|
125
125
|
"@biomejs/biome": "^1.9.0",
|
|
126
|
-
"@metaobjectsdev/codegen-ts-react": "0.19.
|
|
127
|
-
"@metaobjectsdev/migrate-ts": "0.19.
|
|
128
|
-
"@metaobjectsdev/runtime-ts": "0.19.
|
|
126
|
+
"@metaobjectsdev/codegen-ts-react": "0.19.2-rc.1",
|
|
127
|
+
"@metaobjectsdev/migrate-ts": "0.19.2-rc.1",
|
|
128
|
+
"@metaobjectsdev/runtime-ts": "0.19.2-rc.1",
|
|
129
129
|
"bun-types": "latest",
|
|
130
130
|
"drizzle-orm": "^0.36.0",
|
|
131
131
|
"hono": "^4.6.0",
|
package/src/payload-codegen.ts
CHANGED
|
@@ -9,6 +9,19 @@
|
|
|
9
9
|
// should reuse codegen-ts's canonical field mapping + ts-poet emit + the
|
|
10
10
|
// Generator/runner integration. Assembler (RDB materialization + host overlay)
|
|
11
11
|
// is out of scope — this only emits the contract.
|
|
12
|
+
//
|
|
13
|
+
// ADR-0044 — collision-aware naming: emission is a THREE-PASS pipeline.
|
|
14
|
+
// 1. collectClosure — walk the reference closure (FQN-exact resolution),
|
|
15
|
+
// collecting resolved VOs keyed by resolutionKey()
|
|
16
|
+
// (never bare name — bare-keyed dedupe silently drops
|
|
17
|
+
// the second same-short-name VO; #219/#220).
|
|
18
|
+
// 2. assignEmittedNames — a PURE function of the closure: a bare short name
|
|
19
|
+
// unique in the closure emits bare; a collision emits
|
|
20
|
+
// EVERY member under its package-qualified derived
|
|
21
|
+
// name (PascalCase each package segment + short name).
|
|
22
|
+
// A still-colliding derived name fails loud.
|
|
23
|
+
// 3. emitClosureDeclarations — emit each declaration + every reference through
|
|
24
|
+
// the name map.
|
|
12
25
|
|
|
13
26
|
import {
|
|
14
27
|
type MetaData,
|
|
@@ -22,6 +35,7 @@ import {
|
|
|
22
35
|
TEMPLATE_ATTR_PAYLOAD_REF,
|
|
23
36
|
TEMPLATE_ATTR_TEXT_REF,
|
|
24
37
|
TEMPLATE_ATTR_FORMAT,
|
|
38
|
+
PACKAGE_SEPARATOR,
|
|
25
39
|
resolveObjectRef,
|
|
26
40
|
stripPackage,
|
|
27
41
|
} from "@metaobjectsdev/metadata";
|
|
@@ -45,6 +59,16 @@ const SCALAR_TS: Record<string, string> = {
|
|
|
45
59
|
timestamp: "string",
|
|
46
60
|
};
|
|
47
61
|
|
|
62
|
+
// ADR-0044 backstop error code — a codegen-time (not loader) error, peer of
|
|
63
|
+
// @metaobjectsdev/render's ERR_VAR_NOT_ON_PAYLOAD. Declared LOCALLY rather than
|
|
64
|
+
// added to packages/metadata/src/errors.ts's ERROR_CODES ledger: that ledger is
|
|
65
|
+
// checked for FULL cross-port agreement against fixtures/conformance/ERROR-CODES.json
|
|
66
|
+
// (packages/metadata/test/errors.test.ts) and, on the Python side, for corpus-code
|
|
67
|
+
// coverage — registering it there before every port implements the ADR-0044 fix
|
|
68
|
+
// would turn those OTHER ports' tests red. It moves into the shared ledger once the
|
|
69
|
+
// Java/Kotlin/Python follow-up (ADR-0044 §4, items 3-4) lands alongside this code.
|
|
70
|
+
const ERR_PAYLOAD_NAME_COLLISION = "ERR_PAYLOAD_NAME_COLLISION";
|
|
71
|
+
|
|
48
72
|
// ADR-0039: resolving — root has no super (children()==ownChildren()); a top-level object/template may itself extend, so resolve rather than work-by-accident.
|
|
49
73
|
// ADR-0042: resolveObjectRef gives package-local-before-root-level precedence for a bare ref, FQN-exact otherwise.
|
|
50
74
|
function findObject(root: MetaData, name: string, referrerPkg = ""): MetaData | undefined {
|
|
@@ -52,31 +76,131 @@ function findObject(root: MetaData, name: string, referrerPkg = ""): MetaData |
|
|
|
52
76
|
}
|
|
53
77
|
|
|
54
78
|
/**
|
|
55
|
-
*
|
|
56
|
-
*
|
|
79
|
+
* ADR-0044 pass 1 — walk `voRef`'s transitive `@objectRef` closure with FQN-exact
|
|
80
|
+
* resolution, collecting resolved VOs keyed by `resolutionKey()` (never bare name
|
|
81
|
+
* — the #219/#220 defect). `visited` accumulates across multiple root calls so a
|
|
82
|
+
* batch emission (`generatePayloadInterfacesBatch`) shares ONE collision domain,
|
|
83
|
+
* per the ADR-0044 "closure of the payload root(s) emitted into one artifact"
|
|
84
|
+
* definition. A VO already in `visited` is not re-walked (cycle/dedupe guard).
|
|
85
|
+
*/
|
|
86
|
+
function collectClosure(
|
|
87
|
+
root: MetaData,
|
|
88
|
+
voRef: string,
|
|
89
|
+
referrerPkg: string,
|
|
90
|
+
visited: Map<string, MetaData>,
|
|
91
|
+
): void {
|
|
92
|
+
const vo = findObject(root, voRef, referrerPkg);
|
|
93
|
+
if (!vo) return;
|
|
94
|
+
const fqn = vo.resolutionKey();
|
|
95
|
+
if (visited.has(fqn)) return;
|
|
96
|
+
visited.set(fqn, vo);
|
|
97
|
+
// ADR-0042: a nested @objectRef resolves in the FIELD's OWN declaring package —
|
|
98
|
+
// which may differ from this resolved VO's package when the field is inherited
|
|
99
|
+
// via extends from an abstract VO in another package (the bare ref was authored
|
|
100
|
+
// there). Fall back to this VO's package when a field has no parent package.
|
|
101
|
+
const voPkg = vo.package ?? vo.fileDefaultPackage ?? "";
|
|
102
|
+
for (const f of vo.children().filter((c) => c.type === TYPE_FIELD)) {
|
|
103
|
+
if (f.subType !== FIELD_SUBTYPE_OBJECT) continue;
|
|
104
|
+
const ref = f.attr(FIELD_ATTR_OBJECT_REF);
|
|
105
|
+
if (typeof ref !== "string") continue;
|
|
106
|
+
const fieldPkg = f.parent?.package ?? f.parent?.fileDefaultPackage ?? voPkg;
|
|
107
|
+
collectClosure(root, ref, fieldPkg, visited);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function pascalSegment(s: string): string {
|
|
112
|
+
return s.length > 0 ? s[0]!.toUpperCase() + s.slice(1) : s;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/** ADR-0044 — package-qualified derived name for a collision member: PascalCase
|
|
116
|
+
* each `::`-segment of the node's effective package, concatenated, then the
|
|
117
|
+
* bare short name (`acme::alpha::Note` -> `AcmeAlphaNote`). A root-level
|
|
118
|
+
* (no-package) node has nothing to qualify with and keeps its bare name — two
|
|
119
|
+
* root-level VOs can never share a name (the loader's own-package uniqueness
|
|
120
|
+
* already rejects that), so this can't silently under-qualify. */
|
|
121
|
+
function packageQualifiedName(pkg: string, shortName: string): string {
|
|
122
|
+
if (pkg === "") return shortName;
|
|
123
|
+
return (
|
|
124
|
+
pkg
|
|
125
|
+
.split(PACKAGE_SEPARATOR)
|
|
126
|
+
.map(pascalSegment)
|
|
127
|
+
.join("") + shortName
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* ADR-0044 pass 2 — assign the emitted TS name for every VO in the closure. A
|
|
133
|
+
* PURE function of the closure's (fqn, bareName, package) triples — never of
|
|
134
|
+
* traversal order: bare short name unique in the closure -> bare name; a
|
|
135
|
+
* collision -> EVERY member gets its package-qualified derived name. If two
|
|
136
|
+
* DISTINCT fqns still derive the same name after qualification, throws
|
|
137
|
+
* (ERR_PAYLOAD_NAME_COLLISION) — never silently wrong.
|
|
138
|
+
*/
|
|
139
|
+
function assignEmittedNames(closure: ReadonlyMap<string, MetaData>): Map<string, string> {
|
|
140
|
+
const byShortName = new Map<string, string[]>();
|
|
141
|
+
for (const [fqn, node] of closure) {
|
|
142
|
+
const bucket = byShortName.get(node.name);
|
|
143
|
+
if (bucket) bucket.push(fqn);
|
|
144
|
+
else byShortName.set(node.name, [fqn]);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const nameMap = new Map<string, string>();
|
|
148
|
+
for (const [shortName, fqns] of byShortName) {
|
|
149
|
+
if (fqns.length === 1) {
|
|
150
|
+
nameMap.set(fqns[0]!, shortName);
|
|
151
|
+
continue;
|
|
152
|
+
}
|
|
153
|
+
for (const fqn of fqns) {
|
|
154
|
+
const node = closure.get(fqn)!;
|
|
155
|
+
const pkg = node.package ?? node.fileDefaultPackage ?? "";
|
|
156
|
+
nameMap.set(fqn, packageQualifiedName(pkg, shortName));
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// Backstop — sorted by fqn so which pair the message names (and whether the
|
|
161
|
+
// set of colliding names is non-empty) is a pure function of the closure, not
|
|
162
|
+
// of Map insertion/traversal order.
|
|
163
|
+
const ownerOf = new Map<string, string>();
|
|
164
|
+
for (const fqn of [...nameMap.keys()].sort()) {
|
|
165
|
+
const emitted = nameMap.get(fqn)!;
|
|
166
|
+
const existing = ownerOf.get(emitted);
|
|
167
|
+
if (existing !== undefined && existing !== fqn) {
|
|
168
|
+
throw new Error(
|
|
169
|
+
`${ERR_PAYLOAD_NAME_COLLISION}: payload record name collision: "${emitted}" derives from both "${existing}" and "${fqn}" — rename one value-object or move it to a package that derives a distinct name`,
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
ownerOf.set(emitted, fqn);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
return nameMap;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/** Resolve `ref`'s emitted TS interface name under the ADR-0044 naming rule,
|
|
179
|
+
* scoped to `ref`'s OWN reference closure (the same closure
|
|
180
|
+
* `generatePayloadInterfaces(root, ref, referrerPkg)` would emit). Returns
|
|
181
|
+
* undefined when `ref` does not resolve to an object.value. */
|
|
182
|
+
function resolveEmittedName(root: MetaData, ref: string, referrerPkg: string): string | undefined {
|
|
183
|
+
const vo = findObject(root, ref, referrerPkg);
|
|
184
|
+
if (!vo) return undefined;
|
|
185
|
+
const closure = new Map<string, MetaData>();
|
|
186
|
+
collectClosure(root, ref, referrerPkg, closure);
|
|
187
|
+
return assignEmittedNames(closure).get(vo.resolutionKey());
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Map a non-object payload field to its strict TS type.
|
|
57
192
|
* - `enumAlias`: a `{ name, decl }` for a `field.enum` — `name` is the union-alias
|
|
58
193
|
* type referenced inline; `decl` is the `export type <name> = "A" | "B";` line the
|
|
59
194
|
* caller hoists above the interface (deduped). Reuses the SAME naming + union
|
|
60
195
|
* logic as the entity inferred-types emitter (single source of truth).
|
|
196
|
+
* Object (`field.object`) fields are NOT handled here — their type comes from the
|
|
197
|
+
* ADR-0044 closure name map, resolved by the caller (the ref may need
|
|
198
|
+
* package-qualification the field alone can't determine).
|
|
61
199
|
*/
|
|
62
200
|
function fieldTsType(
|
|
63
201
|
field: MetaData,
|
|
64
202
|
ownerName: string,
|
|
65
|
-
): { type: string;
|
|
66
|
-
if (field.subType === FIELD_SUBTYPE_OBJECT) {
|
|
67
|
-
const ref = field.attr(FIELD_ATTR_OBJECT_REF);
|
|
68
|
-
// FR-032/ADR-0041 — @objectRef canonicalizes to an FQN (`pkg::Name`), which is not
|
|
69
|
-
// a valid TS identifier. The emitted TYPE is the bare name; the FQN is retained as
|
|
70
|
-
// refVo for resolution/recursion (findObject matches FQN or bare).
|
|
71
|
-
const refName = typeof ref === "string" ? stripPackage(ref) : "unknown";
|
|
72
|
-
// isArray is a structural property on MetaData, not an attr.
|
|
73
|
-
const isArray = field.resolvedIsArray();
|
|
74
|
-
const result: { type: string; refVo?: string } = {
|
|
75
|
-
type: isArray ? `${refName}[]` : refName,
|
|
76
|
-
};
|
|
77
|
-
if (typeof ref === "string") result.refVo = ref;
|
|
78
|
-
return result;
|
|
79
|
-
}
|
|
203
|
+
): { type: string; enumAlias?: { name: string; decl: string } } {
|
|
80
204
|
// field.enum: a value-constrained string-literal union alias (NOT `unknown`).
|
|
81
205
|
// Field nodes are MetaField instances at runtime (MetaField extends MetaData),
|
|
82
206
|
// so the enum helpers (effective @values + super-resolving name) apply.
|
|
@@ -101,69 +225,89 @@ function isFieldRequired(field: MetaData): boolean {
|
|
|
101
225
|
return field.attr(FIELD_ATTR_REQUIRED) === true;
|
|
102
226
|
}
|
|
103
227
|
|
|
104
|
-
|
|
228
|
+
/**
|
|
229
|
+
* ADR-0044 pass 3 — emit `export interface <emittedName> { ... }` for every VO in
|
|
230
|
+
* the closure, in closure-visitation order, using `nameMap` for both the
|
|
231
|
+
* declaration name and every nested `field.object` reference's type.
|
|
232
|
+
*/
|
|
233
|
+
function emitClosureDeclarations(
|
|
105
234
|
root: MetaData,
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
emitted: Set<string>,
|
|
235
|
+
closure: ReadonlyMap<string, MetaData>,
|
|
236
|
+
nameMap: ReadonlyMap<string, string>,
|
|
109
237
|
out: string[],
|
|
110
238
|
enumAliases: Set<string>,
|
|
111
239
|
): void {
|
|
112
|
-
const vo
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
240
|
+
for (const [, vo] of closure) {
|
|
241
|
+
const voName = nameMap.get(vo.resolutionKey())!;
|
|
242
|
+
const voPkg = vo.package ?? vo.fileDefaultPackage ?? "";
|
|
243
|
+
const aliasLines: string[] = [];
|
|
244
|
+
const lines: string[] = [`export interface ${voName} {`];
|
|
245
|
+
for (const f of vo.children().filter((c) => c.type === TYPE_FIELD)) {
|
|
246
|
+
let type: string;
|
|
247
|
+
let enumAlias: { name: string; decl: string } | undefined;
|
|
248
|
+
if (f.subType === FIELD_SUBTYPE_OBJECT) {
|
|
249
|
+
const ref = f.attr(FIELD_ATTR_OBJECT_REF);
|
|
250
|
+
if (typeof ref === "string") {
|
|
251
|
+
// The nested ref resolves in the FIELD's declaring package (ADR-0042),
|
|
252
|
+
// not the resolved VO's — they differ when `f` is inherited from an
|
|
253
|
+
// abstract VO elsewhere.
|
|
254
|
+
const fieldPkg = f.parent?.package ?? f.parent?.fileDefaultPackage ?? voPkg;
|
|
255
|
+
const refNode = findObject(root, ref, fieldPkg);
|
|
256
|
+
// refNode was walked into the closure by collectClosure — the name map
|
|
257
|
+
// always has it. The stripPackage fallback only guards a defensive gap
|
|
258
|
+
// (e.g. a caller-constructed closure that skipped pass 1).
|
|
259
|
+
const refName = (refNode && nameMap.get(refNode.resolutionKey())) ?? stripPackage(ref);
|
|
260
|
+
type = f.resolvedIsArray() ? `${refName}[]` : refName;
|
|
261
|
+
} else {
|
|
262
|
+
type = "unknown";
|
|
263
|
+
}
|
|
264
|
+
} else {
|
|
265
|
+
const r = fieldTsType(f, voName);
|
|
266
|
+
type = r.type;
|
|
267
|
+
enumAlias = r.enumAlias;
|
|
268
|
+
}
|
|
269
|
+
// Hoist the enum union alias above the interface, deduped across the whole
|
|
270
|
+
// batch (multiple fields/objects can share one abstract enum's alias).
|
|
271
|
+
if (enumAlias && !enumAliases.has(enumAlias.name)) {
|
|
272
|
+
enumAliases.add(enumAlias.name);
|
|
273
|
+
aliasLines.push(enumAlias.decl);
|
|
274
|
+
}
|
|
275
|
+
// Required fields: `name: T;`
|
|
276
|
+
// Optional fields: `name?: T | null;` — the `| null` lets values from
|
|
277
|
+
// Drizzle entity rows (which return `null` for nullable columns) flow
|
|
278
|
+
// straight in. Without it, TS treats undefined-vs-null as a hard error
|
|
279
|
+
// at the entity → payload boundary.
|
|
280
|
+
const isRequired = isFieldRequired(f);
|
|
281
|
+
const tsType = isRequired ? type : `${type} | null`;
|
|
282
|
+
const optional = isRequired ? "" : "?";
|
|
283
|
+
lines.push(` ${f.name}${optional}: ${tsType};`);
|
|
135
284
|
}
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
// straight in. Without it, TS treats undefined-vs-null as a hard error
|
|
140
|
-
// at the entity → payload boundary.
|
|
141
|
-
const isRequired = isFieldRequired(f);
|
|
142
|
-
const tsType = isRequired ? type : `${type} | null`;
|
|
143
|
-
const optional = isRequired ? "" : "?";
|
|
144
|
-
lines.push(` ${f.name}${optional}: ${tsType};`);
|
|
145
|
-
// The nested ref resolves in the FIELD's declaring package (ADR-0042), not the
|
|
146
|
-
// resolved VO's — they differ when `f` is inherited from an abstract VO elsewhere.
|
|
147
|
-
if (refVo) refs.push({ ref: refVo, pkg: f.parent?.package ?? f.parent?.fileDefaultPackage ?? voPkg });
|
|
285
|
+
lines.push("}");
|
|
286
|
+
const block = aliasLines.length > 0 ? `${aliasLines.join("\n")}\n${lines.join("\n")}` : lines.join("\n");
|
|
287
|
+
out.push(block);
|
|
148
288
|
}
|
|
149
|
-
lines.push("}");
|
|
150
|
-
const block = aliasLines.length > 0 ? `${aliasLines.join("\n")}\n${lines.join("\n")}` : lines.join("\n");
|
|
151
|
-
out.push(block);
|
|
152
|
-
for (const r of refs) emitInterface(root, r.ref, r.pkg, emitted, out, enumAliases);
|
|
153
289
|
}
|
|
154
290
|
|
|
155
291
|
/** Emit the payload `interface` (+ nested element interfaces) for an object.value view-object.
|
|
156
|
-
* `referrerPkg` (ADR-0042) is the package a bare `voName` resolves in; pass an FQN and it is ignored.
|
|
292
|
+
* `referrerPkg` (ADR-0042) is the package a bare `voName` resolves in; pass an FQN and it is ignored.
|
|
293
|
+
* ADR-0044: a short-name collision within `voName`'s reference closure emits EVERY colliding
|
|
294
|
+
* member under its package-qualified derived name; a non-colliding closure emits byte-identical
|
|
295
|
+
* bare names (unchanged from pre-ADR-0044 output). */
|
|
157
296
|
export function generatePayloadInterfaces(root: MetaData, voName: string, referrerPkg = ""): string {
|
|
297
|
+
const closure = new Map<string, MetaData>();
|
|
298
|
+
collectClosure(root, voName, referrerPkg, closure);
|
|
299
|
+
const nameMap = assignEmittedNames(closure);
|
|
158
300
|
const out: string[] = [];
|
|
159
|
-
|
|
301
|
+
emitClosureDeclarations(root, closure, nameMap, out, new Set<string>());
|
|
160
302
|
return out.join("\n\n") + "\n";
|
|
161
303
|
}
|
|
162
304
|
|
|
163
305
|
/**
|
|
164
|
-
* Emit interfaces for several payloads at once, using a
|
|
165
|
-
*
|
|
166
|
-
*
|
|
306
|
+
* Emit interfaces for several payloads at once, using a SINGLE shared reference
|
|
307
|
+
* closure (ADR-0044: the closure of ALL the given roots together is the collision
|
|
308
|
+
* domain for this call) so nested types (e.g. lens projections referenced by
|
|
309
|
+
* multiple payloads) appear exactly once, and a short-name collision anywhere
|
|
310
|
+
* across the whole batch is caught and qualified consistently.
|
|
167
311
|
*
|
|
168
312
|
* Returns the empty string when `voNames` is empty.
|
|
169
313
|
*/
|
|
@@ -173,12 +317,14 @@ export function generatePayloadInterfacesBatch(
|
|
|
173
317
|
referrerPkg = "",
|
|
174
318
|
): string {
|
|
175
319
|
if (voNames.length === 0) return "";
|
|
176
|
-
const
|
|
177
|
-
const emitted = new Set<string>();
|
|
178
|
-
const enumAliases = new Set<string>();
|
|
320
|
+
const closure = new Map<string, MetaData>();
|
|
179
321
|
for (const name of voNames) {
|
|
180
|
-
|
|
322
|
+
collectClosure(root, name, referrerPkg, closure);
|
|
181
323
|
}
|
|
324
|
+
if (closure.size === 0) return "";
|
|
325
|
+
const nameMap = assignEmittedNames(closure);
|
|
326
|
+
const out: string[] = [];
|
|
327
|
+
emitClosureDeclarations(root, closure, nameMap, out, new Set<string>());
|
|
182
328
|
return out.length === 0 ? "" : out.join("\n\n") + "\n";
|
|
183
329
|
}
|
|
184
330
|
|
|
@@ -193,11 +339,11 @@ export function generateRenderHandle(root: MetaData, templateName: string): stri
|
|
|
193
339
|
// ADR-0039: resolving — a template may inherit its @* refs/format/kind via extends.
|
|
194
340
|
const payloadRef = tmpl.attr(TEMPLATE_ATTR_PAYLOAD_REF);
|
|
195
341
|
// FR-032 — @payloadRef is an FQN after the desugar/sweep; the generated TS
|
|
196
|
-
// TYPE NAME is the resolved value-object's
|
|
197
|
-
//
|
|
198
|
-
// `::`-segment when the VO is not in this root (defensive).
|
|
342
|
+
// TYPE NAME is the resolved value-object's ADR-0044 emitted name (bare when
|
|
343
|
+
// unique in its closure, package-qualified on a short-name collision). Fall
|
|
344
|
+
// back to the last `::`-segment when the VO is not in this root (defensive).
|
|
199
345
|
const payloadType =
|
|
200
|
-
(typeof payloadRef === "string" ?
|
|
346
|
+
(typeof payloadRef === "string" ? resolveEmittedName(root, payloadRef, "") : undefined) ??
|
|
201
347
|
(typeof payloadRef === "string" ? stripPackage(payloadRef) : String(payloadRef));
|
|
202
348
|
// ADR-0039: resolving — a template may inherit its @* refs/format/kind via extends.
|
|
203
349
|
const textRef = tmpl.attr(TEMPLATE_ATTR_TEXT_REF);
|
package/src/runner.ts
CHANGED
|
@@ -166,6 +166,16 @@ export async function runGen(opts: RunGenOpts): Promise<RunGenResult> {
|
|
|
166
166
|
continue;
|
|
167
167
|
}
|
|
168
168
|
const selfTarget = targetOf(generator);
|
|
169
|
+
// Resolve the WRITE-time location against projectRoot when outDir is
|
|
170
|
+
// relative and projectRoot is known — otherwise a relative outDir (the
|
|
171
|
+
// common, portable, `meta init`-scaffolded shape) silently resolves
|
|
172
|
+
// against the ambient process.cwd() instead of the project the CLI's
|
|
173
|
+
// `--cwd` flag says to run as. Import-path math below intentionally keeps
|
|
174
|
+
// using selfTarget.outDir as configured (relative paths between targets
|
|
175
|
+
// are compared to each other, not to projectRoot).
|
|
176
|
+
const writeOutDir = projectRoot !== undefined && !isAbsolute(selfTarget.outDir)
|
|
177
|
+
? resolve(projectRoot, selfTarget.outDir)
|
|
178
|
+
: selfTarget.outDir;
|
|
169
179
|
const renderContext = makeRenderContext({
|
|
170
180
|
dialect: config.dialect,
|
|
171
181
|
loadedRoot: root,
|
|
@@ -212,7 +222,7 @@ export async function runGen(opts: RunGenOpts): Promise<RunGenResult> {
|
|
|
212
222
|
}
|
|
213
223
|
|
|
214
224
|
for (const file of files) {
|
|
215
|
-
const fullPath = join(
|
|
225
|
+
const fullPath = join(writeOutDir, file.path);
|
|
216
226
|
const collision = emitted.find((prev) => prev.fullPath === fullPath);
|
|
217
227
|
if (collision) {
|
|
218
228
|
throw new Error(
|
|
@@ -43,6 +43,7 @@ import {
|
|
|
43
43
|
TEMPLATE_ATTR_HTML_BODY_REF,
|
|
44
44
|
TEMPLATE_ATTR_TEXT_BODY_REF,
|
|
45
45
|
resolveObjectRef,
|
|
46
|
+
stripPackage,
|
|
46
47
|
} from "@metaobjectsdev/metadata";
|
|
47
48
|
import {
|
|
48
49
|
verify,
|
|
@@ -175,6 +176,14 @@ export function renderRenderHelper(
|
|
|
175
176
|
const fields = derivePayloadFieldTree(root, payloadRef, tmplPkg);
|
|
176
177
|
const ft = fieldTreeLiteral(fields);
|
|
177
178
|
const fnName = `render${templateName}`;
|
|
179
|
+
// @payloadRef may arrive package-qualified (FQN) once resolved — a bare
|
|
180
|
+
// `::`-free name is required everywhere it's emitted as a TS identifier /
|
|
181
|
+
// import specifier below (mirrors the same stripPackage() call every other
|
|
182
|
+
// TS-identifier-emitting generator makes on a resolved ref, e.g.
|
|
183
|
+
// payload-codegen.ts / entity-file.ts / drizzle-schema.ts). Package-scoped
|
|
184
|
+
// resolution above (findObject/derivePayloadFieldTree) intentionally keeps
|
|
185
|
+
// using the raw `payloadRef`.
|
|
186
|
+
const payloadTypeName = stripPackage(payloadRef);
|
|
178
187
|
|
|
179
188
|
// ADR-0039: resolving — a template may inherit its @* refs/format/kind via extends.
|
|
180
189
|
const kind = ((tmpl.attr(TEMPLATE_ATTR_KIND) as string | undefined) ?? TEMPLATE_KIND_DEFAULT)
|
|
@@ -206,14 +215,14 @@ export function renderRenderHelper(
|
|
|
206
215
|
|
|
207
216
|
return `import { render } from "@metaobjectsdev/render";
|
|
208
217
|
import type { Provider, EmailDocument } from "@metaobjectsdev/render";
|
|
209
|
-
import type { ${
|
|
218
|
+
import type { ${payloadTypeName} } from "./${payloadTypeName}.js";
|
|
210
219
|
|
|
211
220
|
/**
|
|
212
221
|
* Render the ${templateName} email (subject + html body${typeof textBodyRef === "string" ? " + text body" : ""}) from a
|
|
213
|
-
* typed ${
|
|
222
|
+
* typed ${payloadTypeName} payload. Wraps the render() engine; the payload field tree is
|
|
214
223
|
* baked in so render()'s runtime drift check matches the build-time gate.
|
|
215
224
|
*/
|
|
216
|
-
export function ${fnName}(payload: ${
|
|
225
|
+
export function ${fnName}(payload: ${payloadTypeName}, provider: Provider): EmailDocument {
|
|
217
226
|
return {
|
|
218
227
|
subject: render({ ref: ${JSON.stringify(subjectRef)}, payload, format: "text", provider, verify: ${ft} }),
|
|
219
228
|
htmlBody: render({ ref: ${JSON.stringify(htmlBodyRef)}, payload, format: "html", provider, verify: ${ft} }),${textBodyLine}
|
|
@@ -246,14 +255,14 @@ export function ${fnName}(payload: ${payloadRef}, provider: Provider): EmailDocu
|
|
|
246
255
|
|
|
247
256
|
return `import { render } from "@metaobjectsdev/render";
|
|
248
257
|
import type { Provider } from "@metaobjectsdev/render";
|
|
249
|
-
import type { ${
|
|
258
|
+
import type { ${payloadTypeName} } from "./${payloadTypeName}.js";
|
|
250
259
|
|
|
251
260
|
/**
|
|
252
|
-
* Render the ${templateName} document from a typed ${
|
|
261
|
+
* Render the ${templateName} document from a typed ${payloadTypeName} payload. Wraps the
|
|
253
262
|
* render() engine; the payload field tree is baked in so render()'s runtime drift
|
|
254
263
|
* check matches the build-time gate enforced when this file was generated.
|
|
255
264
|
*/
|
|
256
|
-
export function ${fnName}(payload: ${
|
|
265
|
+
export function ${fnName}(payload: ${payloadTypeName}, provider: Provider): string {
|
|
257
266
|
return render({ ref: ${JSON.stringify(textRef)}, payload, format: ${JSON.stringify(format)}, provider, verify: ${ft}${maxCharsArg} });
|
|
258
267
|
}
|
|
259
268
|
`;
|