@metaobjectsdev/codegen-ts 0.20.9 → 0.20.10-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/generators/api-model.d.ts.map +1 -1
- package/dist/generators/api-model.js +9 -5
- package/dist/generators/api-model.js.map +1 -1
- package/dist/generators/barrel.js +1 -1
- package/dist/generators/barrel.js.map +1 -1
- package/dist/generators/entity-file.d.ts.map +1 -1
- package/dist/generators/entity-file.js +7 -1
- package/dist/generators/entity-file.js.map +1 -1
- package/dist/generators/extractor-file.d.ts.map +1 -1
- package/dist/generators/extractor-file.js +6 -1
- package/dist/generators/extractor-file.js.map +1 -1
- package/dist/generators/output-parser-file.d.ts.map +1 -1
- package/dist/generators/output-parser-file.js +6 -1
- package/dist/generators/output-parser-file.js.map +1 -1
- package/dist/generators/queries-file.d.ts +1 -1
- package/dist/generators/queries-file.d.ts.map +1 -1
- package/dist/generators/queries-file.js +11 -6
- package/dist/generators/queries-file.js.map +1 -1
- package/dist/generators/routes-file-hono.d.ts +4 -0
- package/dist/generators/routes-file-hono.d.ts.map +1 -1
- package/dist/generators/routes-file-hono.js +6 -1
- package/dist/generators/routes-file-hono.js.map +1 -1
- package/dist/generators/routes-file.d.ts +4 -0
- package/dist/generators/routes-file.d.ts.map +1 -1
- package/dist/generators/routes-file.js +6 -1
- package/dist/generators/routes-file.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/naming/collision-names.d.ts +19 -0
- package/dist/naming/collision-names.d.ts.map +1 -0
- package/dist/naming/collision-names.js +79 -0
- package/dist/naming/collision-names.js.map +1 -0
- package/dist/payload-codegen.d.ts.map +1 -1
- package/dist/payload-codegen.js +5 -71
- package/dist/payload-codegen.js.map +1 -1
- package/dist/render-context.d.ts +35 -3
- package/dist/render-context.d.ts.map +1 -1
- package/dist/render-context.js +23 -0
- package/dist/render-context.js.map +1 -1
- package/dist/runner.d.ts.map +1 -1
- package/dist/runner.js +36 -2
- package/dist/runner.js.map +1 -1
- package/dist/source-detect.d.ts +10 -0
- package/dist/source-detect.d.ts.map +1 -1
- package/dist/source-detect.js +22 -0
- package/dist/source-detect.js.map +1 -1
- package/dist/templates/drizzle-schema.d.ts.map +1 -1
- package/dist/templates/drizzle-schema.js +14 -3
- package/dist/templates/drizzle-schema.js.map +1 -1
- package/dist/templates/entity-file.d.ts +1 -1
- package/dist/templates/entity-file.d.ts.map +1 -1
- package/dist/templates/entity-file.js +13 -3
- package/dist/templates/entity-file.js.map +1 -1
- package/dist/templates/extract-delegate-emitter.d.ts +9 -4
- package/dist/templates/extract-delegate-emitter.d.ts.map +1 -1
- package/dist/templates/extract-delegate-emitter.js +46 -30
- package/dist/templates/extract-delegate-emitter.js.map +1 -1
- package/dist/templates/extractor.d.ts +2 -1
- package/dist/templates/extractor.d.ts.map +1 -1
- package/dist/templates/extractor.js +48 -33
- package/dist/templates/extractor.js.map +1 -1
- package/dist/templates/inferred-types.d.ts +1 -1
- package/dist/templates/inferred-types.d.ts.map +1 -1
- package/dist/templates/inferred-types.js +39 -16
- package/dist/templates/inferred-types.js.map +1 -1
- package/dist/templates/output-parser.d.ts +2 -1
- package/dist/templates/output-parser.d.ts.map +1 -1
- package/dist/templates/output-parser.js +37 -12
- package/dist/templates/output-parser.js.map +1 -1
- package/dist/templates/projection-decl.d.ts +1 -1
- package/dist/templates/projection-decl.d.ts.map +1 -1
- package/dist/templates/projection-decl.js +20 -9
- package/dist/templates/projection-decl.js.map +1 -1
- package/dist/templates/value-object-file.d.ts.map +1 -1
- package/dist/templates/value-object-file.js +5 -1
- package/dist/templates/value-object-file.js.map +1 -1
- package/dist/templates/view-decl.d.ts +12 -2
- package/dist/templates/view-decl.d.ts.map +1 -1
- package/dist/templates/view-decl.js +21 -15
- package/dist/templates/view-decl.js.map +1 -1
- package/dist/templates/zod-validators.d.ts +1 -1
- package/dist/templates/zod-validators.d.ts.map +1 -1
- package/dist/templates/zod-validators.js +35 -22
- package/dist/templates/zod-validators.js.map +1 -1
- package/package.json +6 -6
- package/src/generators/api-model.ts +9 -5
- package/src/generators/barrel.ts +1 -1
- package/src/generators/entity-file.ts +7 -1
- package/src/generators/extractor-file.ts +6 -1
- package/src/generators/output-parser-file.ts +6 -1
- package/src/generators/queries-file.ts +12 -7
- package/src/generators/routes-file-hono.ts +7 -1
- package/src/generators/routes-file.ts +6 -1
- package/src/index.ts +1 -1
- package/src/naming/collision-names.ts +87 -0
- package/src/payload-codegen.ts +4 -79
- package/src/reference/barrel.ts +1 -1
- package/src/reference/queries.ts +14 -6
- package/src/reference/routes.ts +8 -1
- package/src/render-context.ts +51 -3
- package/src/runner.ts +36 -4
- package/src/source-detect.ts +20 -0
- package/src/templates/drizzle-schema.ts +14 -3
- package/src/templates/entity-file.ts +14 -6
- package/src/templates/extract-delegate-emitter.ts +52 -27
- package/src/templates/extractor.ts +49 -32
- package/src/templates/inferred-types.ts +39 -17
- package/src/templates/output-parser.ts +40 -12
- package/src/templates/projection-decl.ts +20 -10
- package/src/templates/value-object-file.ts +5 -1
- package/src/templates/view-decl.ts +30 -18
- package/src/templates/zod-validators.ts +35 -23
|
@@ -63,9 +63,13 @@ export function renderValueObjectFile(obj: MetaObject, apiPrefix = "", ctx?: Ren
|
|
|
63
63
|
...(tphFilterType !== null ? [tphFilterType] : []),
|
|
64
64
|
];
|
|
65
65
|
const body = joinCode(sections, { on: "\n" }).toString();
|
|
66
|
+
// ADR-0044/#228 — the hand-edit sidecar name follows this value object's EMITTED
|
|
67
|
+
// module name (== the generated filename), so the `.extra.ts` hint is correct
|
|
68
|
+
// even for a collision-qualified value object. Byte-identical (bare) otherwise.
|
|
69
|
+
const emittedName = ctx ? ctx.valueObjectEmittedName(obj) : obj.name;
|
|
66
70
|
const header =
|
|
67
71
|
`// ${GENERATED_HEADER} — DO NOT EDIT.\n` +
|
|
68
72
|
`// Source metadata: ${obj.name} (${obj.fqn()})\n` +
|
|
69
|
-
`// Customize via ${
|
|
73
|
+
`// Customize via ${emittedName}.extra.ts in this directory.\n`;
|
|
70
74
|
return header + body;
|
|
71
75
|
}
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
import { code, imp, joinCode, type Code } from "ts-poet";
|
|
11
11
|
import {
|
|
12
|
-
type MetaField, FIELD_SUBTYPE_OBJECT, FIELD_ATTR_OBJECT_REF,
|
|
12
|
+
type MetaField, FIELD_SUBTYPE_OBJECT, FIELD_ATTR_OBJECT_REF,
|
|
13
13
|
} from "@metaobjectsdev/metadata";
|
|
14
14
|
import type { ColumnNamingStrategy } from "../metaobjects-config.js";
|
|
15
15
|
import { mapColumnType } from "../column-mapper.js";
|
|
@@ -20,8 +20,15 @@ export interface ViewDeclOpts {
|
|
|
20
20
|
readonly columnNamingStrategy: ColumnNamingStrategy;
|
|
21
21
|
/** Drives the timestamp column TS type (Date vs string) in the view declaration. */
|
|
22
22
|
readonly timestampMode: "date" | "string";
|
|
23
|
-
/**
|
|
24
|
-
|
|
23
|
+
/**
|
|
24
|
+
* ADR-0044/#228 — resolve a `field.object` / `field.map`'s `@objectRef` to the
|
|
25
|
+
* value object's EMITTED name (bare when unique in the run, package-qualified on
|
|
26
|
+
* a cross-package short-name collision) AND its import module, TOGETHER, so the
|
|
27
|
+
* imported symbol and its module can never diverge (a bare `Note` symbol pointing
|
|
28
|
+
* at an `./AcmeAlphaNote.js` module, or vice-versa). Callers build this from
|
|
29
|
+
* `RenderContext.resolveValueObjectName` + `valueObjectModuleSpecifier`.
|
|
30
|
+
*/
|
|
31
|
+
readonly voRef: (field: MetaField) => { name: string; module: string };
|
|
25
32
|
}
|
|
26
33
|
|
|
27
34
|
/**
|
|
@@ -31,7 +38,7 @@ export interface ViewDeclOpts {
|
|
|
31
38
|
* views carry type + physical name only (no PK/default/notNull DDL modifiers).
|
|
32
39
|
*/
|
|
33
40
|
function viewColumnLine(f: MetaField, opts: ViewDeclOpts): Code {
|
|
34
|
-
const { dialect, columnNamingStrategy, timestampMode
|
|
41
|
+
const { dialect, columnNamingStrategy, timestampMode } = opts;
|
|
35
42
|
const spec = mapColumnType(f, dialect, columnNamingStrategy, timestampMode);
|
|
36
43
|
const colSym = imp(`${spec.fnName}@${spec.importModule}`);
|
|
37
44
|
const optsArg =
|
|
@@ -53,12 +60,17 @@ function viewColumnLine(f: MetaField, opts: ViewDeclOpts): Code {
|
|
|
53
60
|
if (dtr?.kind === "scalar") {
|
|
54
61
|
dollarType = `.$type<${dtr.tsType}${dtr.array ? "[]" : ""}>()`;
|
|
55
62
|
} else if (dtr?.kind === "objectRef") {
|
|
56
|
-
|
|
63
|
+
// #228 — emitted name + module resolved together (lock-step) from the field's ref.
|
|
64
|
+
const vo = opts.voRef(f);
|
|
65
|
+
const voTypeSym = imp(`${vo.name}@${vo.module}`);
|
|
57
66
|
dollarType = dtr.array ? code`.$type<${voTypeSym}[]>()` : code`.$type<${voTypeSym}>()`;
|
|
58
67
|
} else if (dtr?.kind === "map") {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
68
|
+
if ("scalar" in dtr.value) {
|
|
69
|
+
dollarType = `.$type<Record<string, ${dtr.value.scalar}>>()`;
|
|
70
|
+
} else {
|
|
71
|
+
const vo = opts.voRef(f);
|
|
72
|
+
dollarType = code`.$type<Record<string, ${imp(`${vo.name}@${vo.module}`)}>>()`;
|
|
73
|
+
}
|
|
62
74
|
}
|
|
63
75
|
return code` ${f.name}: ${colSym}(${JSON.stringify(spec.dbName)}${optsArg})${dollarType}${viewModifiers}`;
|
|
64
76
|
}
|
|
@@ -98,22 +110,22 @@ ${joinCode(viewColumnLines, { on: ",\n" })}
|
|
|
98
110
|
* `voModule` resolves a value-object short name → its import module.
|
|
99
111
|
*/
|
|
100
112
|
export function renderViewReadZodObject(fields: readonly MetaField[], opts: ViewDeclOpts): Code {
|
|
101
|
-
const { dialect, columnNamingStrategy, timestampMode
|
|
113
|
+
const { dialect, columnNamingStrategy, timestampMode } = opts;
|
|
102
114
|
const z = imp("z@zod");
|
|
103
115
|
const lines: Code[] = fields.map((f) => {
|
|
104
116
|
const nullable =
|
|
105
117
|
mapColumnType(f, dialect, columnNamingStrategy, timestampMode).modifiers.includes(".notNull()")
|
|
106
118
|
? ""
|
|
107
119
|
: ".nullable()";
|
|
108
|
-
const
|
|
109
|
-
f.subType === FIELD_SUBTYPE_OBJECT
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
const schemaSym = imp(`${
|
|
120
|
+
const hasObjectRef =
|
|
121
|
+
f.subType === FIELD_SUBTYPE_OBJECT &&
|
|
122
|
+
typeof f.attr(FIELD_ATTR_OBJECT_REF) === "string" &&
|
|
123
|
+
(f.attr(FIELD_ATTR_OBJECT_REF) as string).length > 0;
|
|
124
|
+
if (hasObjectRef) {
|
|
125
|
+
// #228 — the <Ref>InsertSchema symbol + its module resolved together from the
|
|
126
|
+
// field's ref, so a cross-package collision qualifies both consistently.
|
|
127
|
+
const vo = opts.voRef(f);
|
|
128
|
+
const schemaSym = imp(`${vo.name}InsertSchema@${vo.module}`);
|
|
117
129
|
const base = f.resolvedIsArray() ? code`${z}.array(${schemaSym})` : code`${schemaSym}`;
|
|
118
130
|
return code` ${f.name}: ${base}${nullable}`;
|
|
119
131
|
}
|
|
@@ -35,7 +35,7 @@ import { renderDocsFor } from "./jsdoc.js";
|
|
|
35
35
|
import { sharedEnumForField } from "../enum-shared.js";
|
|
36
36
|
import { sharedEnumImportSpecifier } from "../enum-import.js";
|
|
37
37
|
import { sharedEnumZodConstName } from "./enums-file.js";
|
|
38
|
-
import type
|
|
38
|
+
import { fieldDeclaringPackage, type RenderContext } from "../render-context.js";
|
|
39
39
|
import { valueObjectModuleSpecifier } from "../import-path.js";
|
|
40
40
|
// FR-035: the SAME required-predicate that drives the Drizzle column's .notNull()
|
|
41
41
|
// drives the UpdateSchema's .nullable() exclusion — shared so they cannot drift.
|
|
@@ -117,10 +117,11 @@ export function renderTphSubtypeReadSchema(obj: MetaObject, ctx?: RenderContext)
|
|
|
117
117
|
);
|
|
118
118
|
}
|
|
119
119
|
|
|
120
|
+
const objName = ctx ? ctx.valueObjectEmittedName(obj) : obj.name;
|
|
120
121
|
const docs = renderDocsFor(obj);
|
|
121
122
|
const docsPrefix = docs ? `${docs}\n` : "";
|
|
122
123
|
return code`
|
|
123
|
-
${docsPrefix}export const ${
|
|
124
|
+
${docsPrefix}export const ${objName}Schema = ${z}.object({
|
|
124
125
|
${joinCode(fieldLines, { on: ",\n" })}
|
|
125
126
|
});
|
|
126
127
|
`;
|
|
@@ -199,7 +200,11 @@ export function renderInsertSchemaOnly(obj: MetaObject, ctx?: RenderContext): Co
|
|
|
199
200
|
}
|
|
200
201
|
}
|
|
201
202
|
|
|
202
|
-
|
|
203
|
+
// ADR-0044/#228 — the schema name follows the value object's EMITTED name
|
|
204
|
+
// (bare when unique in the run, package-qualified on a cross-package short-name
|
|
205
|
+
// collision) so importers (entity/extract tiers) resolve the same symbol.
|
|
206
|
+
const objName = ctx ? ctx.valueObjectEmittedName(obj) : obj.name;
|
|
207
|
+
const insertSchemaName = `${objName}InsertSchema`;
|
|
203
208
|
const docs = renderDocsFor(obj);
|
|
204
209
|
const docsPrefix = docs ? `${docs}\n` : "";
|
|
205
210
|
|
|
@@ -369,9 +374,13 @@ export function renderZodValidators(obj: MetaObject, ctx?: RenderContext): Code
|
|
|
369
374
|
}
|
|
370
375
|
}
|
|
371
376
|
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
377
|
+
// ADR-0044/#228 — schema + type-alias names follow the object's EMITTED name.
|
|
378
|
+
// For entities (never in the value-object collision set) and non-colliding value
|
|
379
|
+
// objects this equals `obj.name` (byte-identical).
|
|
380
|
+
const objName = ctx ? ctx.valueObjectEmittedName(obj) : obj.name;
|
|
381
|
+
const insertSchemaName = `${objName}InsertSchema`;
|
|
382
|
+
const updateSchemaName = `${objName}UpdateSchema`;
|
|
383
|
+
const preservingSchemaName = `${objName}InsertPreservingSchema`;
|
|
375
384
|
|
|
376
385
|
const docs = renderDocsFor(obj);
|
|
377
386
|
const docsPrefix = docs ? `${docs}\n` : "";
|
|
@@ -381,7 +390,7 @@ export function renderZodValidators(obj: MetaObject, ctx?: RenderContext): Code
|
|
|
381
390
|
const preservingBlock = emitPreserving
|
|
382
391
|
? code`
|
|
383
392
|
|
|
384
|
-
/** Insert-shape for import / restore / replication of ${
|
|
393
|
+
/** Insert-shape for import / restore / replication of ${objName}: identical to
|
|
385
394
|
* ${insertSchemaName}, but the @autoSet timestamp columns are written VERBATIM
|
|
386
395
|
* (no create-time now() stamp) so the caller's original values are preserved. */
|
|
387
396
|
export const ${preservingSchemaName} = ${z}.object({
|
|
@@ -398,9 +407,9 @@ ${docsPrefix}export const ${updateSchemaName} = ${z}.object({
|
|
|
398
407
|
${joinCode(updateFieldLines, { on: ",\n" })}
|
|
399
408
|
});
|
|
400
409
|
|
|
401
|
-
/** Typed patch shape for ${
|
|
402
|
-
* renamed/dropped field is a compile error at every \`update${
|
|
403
|
-
export type ${
|
|
410
|
+
/** Typed patch shape for ${objName}: every settable field, optional (FR-035 PATCH). A
|
|
411
|
+
* renamed/dropped field is a compile error at every \`update${objName}\` call site. */
|
|
412
|
+
export type ${objName}Patch = ${z}.input<typeof ${updateSchemaName}>;${preservingBlock}
|
|
404
413
|
`;
|
|
405
414
|
}
|
|
406
415
|
|
|
@@ -446,16 +455,19 @@ function zodFieldExpr(field: MetaField, owner?: MetaObject, ctx?: RenderContext)
|
|
|
446
455
|
if (field.subType === FIELD_SUBTYPE_OBJECT) {
|
|
447
456
|
const ref = field.attr(FIELD_ATTR_OBJECT_REF);
|
|
448
457
|
if (typeof ref === "string" && ref.length > 0) {
|
|
449
|
-
// @objectRef may be authored fully-qualified or bare — the
|
|
450
|
-
// <Ref>InsertSchema is named by the
|
|
451
|
-
//
|
|
452
|
-
//
|
|
453
|
-
//
|
|
454
|
-
|
|
458
|
+
// @objectRef may be authored fully-qualified or bare. ADR-0044/#228 — the
|
|
459
|
+
// referenced <Ref>InsertSchema is named by the value object's EMITTED name
|
|
460
|
+
// (bare when unique in the run, package-qualified on a cross-package
|
|
461
|
+
// short-name collision), resolved package-locally from the FIELD's declaring
|
|
462
|
+
// package. The import MODULE is resolved via the shared
|
|
463
|
+
// layout/package/extStyle-aware helper (the SAME one the field's TS type +
|
|
464
|
+
// Drizzle .$type<> use) so all three agree. Without owner/ctx (bare
|
|
465
|
+
// unit-test calls) fall back to the bare name + flat same-dir.
|
|
466
|
+
const refName = (ctx && owner) ? ctx.resolveValueObjectName(ref, fieldDeclaringPackage(field, owner.package)) : stripPackage(ref);
|
|
455
467
|
const moduleSpec = (ctx && owner)
|
|
456
|
-
? valueObjectModuleSpecifier(
|
|
457
|
-
: `./${
|
|
458
|
-
const refImp = imp(`${
|
|
468
|
+
? valueObjectModuleSpecifier(refName, ctx.packageOf, owner.package, ctx.outputLayout, ctx.extStyle)
|
|
469
|
+
: `./${refName}.js`;
|
|
470
|
+
const refImp = imp(`${refName}InsertSchema@${moduleSpec}`);
|
|
459
471
|
let base: Code = code`${refImp}`;
|
|
460
472
|
if (field.resolvedIsArray()) base = code`z.array(${base})`;
|
|
461
473
|
return appendValidatorChain(base, field);
|
|
@@ -472,11 +484,11 @@ function zodFieldExpr(field: MetaField, owner?: MetaObject, ctx?: RenderContext)
|
|
|
472
484
|
if (field.subType === FIELD_SUBTYPE_MAP) {
|
|
473
485
|
const ref = field.attr(FIELD_ATTR_OBJECT_REF);
|
|
474
486
|
if (typeof ref === "string" && ref.length > 0) {
|
|
475
|
-
const
|
|
487
|
+
const refName = (ctx && owner) ? ctx.resolveValueObjectName(ref, fieldDeclaringPackage(field, owner.package)) : stripPackage(ref);
|
|
476
488
|
const moduleSpec = (ctx && owner)
|
|
477
|
-
? valueObjectModuleSpecifier(
|
|
478
|
-
: `./${
|
|
479
|
-
const refImp = imp(`${
|
|
489
|
+
? valueObjectModuleSpecifier(refName, ctx.packageOf, owner.package, ctx.outputLayout, ctx.extStyle)
|
|
490
|
+
: `./${refName}.js`;
|
|
491
|
+
const refImp = imp(`${refName}InsertSchema@${moduleSpec}`);
|
|
480
492
|
return appendValidatorChain(code`z.record(z.string(), ${refImp})`, field);
|
|
481
493
|
}
|
|
482
494
|
const vt = field.attr(FIELD_ATTR_VALUE_TYPE);
|