@metaobjectsdev/codegen-ts 0.20.9-rc.1 → 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.
Files changed (114) hide show
  1. package/dist/generators/api-model.d.ts.map +1 -1
  2. package/dist/generators/api-model.js +9 -5
  3. package/dist/generators/api-model.js.map +1 -1
  4. package/dist/generators/barrel.js +1 -1
  5. package/dist/generators/barrel.js.map +1 -1
  6. package/dist/generators/entity-file.d.ts.map +1 -1
  7. package/dist/generators/entity-file.js +7 -1
  8. package/dist/generators/entity-file.js.map +1 -1
  9. package/dist/generators/extractor-file.d.ts.map +1 -1
  10. package/dist/generators/extractor-file.js +6 -1
  11. package/dist/generators/extractor-file.js.map +1 -1
  12. package/dist/generators/output-parser-file.d.ts.map +1 -1
  13. package/dist/generators/output-parser-file.js +6 -1
  14. package/dist/generators/output-parser-file.js.map +1 -1
  15. package/dist/generators/queries-file.d.ts +1 -1
  16. package/dist/generators/queries-file.d.ts.map +1 -1
  17. package/dist/generators/queries-file.js +11 -6
  18. package/dist/generators/queries-file.js.map +1 -1
  19. package/dist/generators/routes-file-hono.d.ts +4 -0
  20. package/dist/generators/routes-file-hono.d.ts.map +1 -1
  21. package/dist/generators/routes-file-hono.js +6 -1
  22. package/dist/generators/routes-file-hono.js.map +1 -1
  23. package/dist/generators/routes-file.d.ts +4 -0
  24. package/dist/generators/routes-file.d.ts.map +1 -1
  25. package/dist/generators/routes-file.js +6 -1
  26. package/dist/generators/routes-file.js.map +1 -1
  27. package/dist/index.d.ts +1 -1
  28. package/dist/index.d.ts.map +1 -1
  29. package/dist/index.js +1 -1
  30. package/dist/index.js.map +1 -1
  31. package/dist/naming/collision-names.d.ts +19 -0
  32. package/dist/naming/collision-names.d.ts.map +1 -0
  33. package/dist/naming/collision-names.js +79 -0
  34. package/dist/naming/collision-names.js.map +1 -0
  35. package/dist/payload-codegen.d.ts.map +1 -1
  36. package/dist/payload-codegen.js +5 -71
  37. package/dist/payload-codegen.js.map +1 -1
  38. package/dist/render-context.d.ts +35 -3
  39. package/dist/render-context.d.ts.map +1 -1
  40. package/dist/render-context.js +23 -0
  41. package/dist/render-context.js.map +1 -1
  42. package/dist/runner.d.ts.map +1 -1
  43. package/dist/runner.js +36 -2
  44. package/dist/runner.js.map +1 -1
  45. package/dist/source-detect.d.ts +10 -0
  46. package/dist/source-detect.d.ts.map +1 -1
  47. package/dist/source-detect.js +22 -0
  48. package/dist/source-detect.js.map +1 -1
  49. package/dist/templates/drizzle-schema.d.ts.map +1 -1
  50. package/dist/templates/drizzle-schema.js +14 -3
  51. package/dist/templates/drizzle-schema.js.map +1 -1
  52. package/dist/templates/entity-file.d.ts +1 -1
  53. package/dist/templates/entity-file.d.ts.map +1 -1
  54. package/dist/templates/entity-file.js +13 -3
  55. package/dist/templates/entity-file.js.map +1 -1
  56. package/dist/templates/extract-delegate-emitter.d.ts +9 -4
  57. package/dist/templates/extract-delegate-emitter.d.ts.map +1 -1
  58. package/dist/templates/extract-delegate-emitter.js +46 -30
  59. package/dist/templates/extract-delegate-emitter.js.map +1 -1
  60. package/dist/templates/extractor.d.ts +2 -1
  61. package/dist/templates/extractor.d.ts.map +1 -1
  62. package/dist/templates/extractor.js +48 -33
  63. package/dist/templates/extractor.js.map +1 -1
  64. package/dist/templates/inferred-types.d.ts +1 -1
  65. package/dist/templates/inferred-types.d.ts.map +1 -1
  66. package/dist/templates/inferred-types.js +39 -16
  67. package/dist/templates/inferred-types.js.map +1 -1
  68. package/dist/templates/output-parser.d.ts +2 -1
  69. package/dist/templates/output-parser.d.ts.map +1 -1
  70. package/dist/templates/output-parser.js +37 -12
  71. package/dist/templates/output-parser.js.map +1 -1
  72. package/dist/templates/projection-decl.d.ts +1 -1
  73. package/dist/templates/projection-decl.d.ts.map +1 -1
  74. package/dist/templates/projection-decl.js +20 -9
  75. package/dist/templates/projection-decl.js.map +1 -1
  76. package/dist/templates/value-object-file.d.ts.map +1 -1
  77. package/dist/templates/value-object-file.js +5 -1
  78. package/dist/templates/value-object-file.js.map +1 -1
  79. package/dist/templates/view-decl.d.ts +12 -2
  80. package/dist/templates/view-decl.d.ts.map +1 -1
  81. package/dist/templates/view-decl.js +21 -15
  82. package/dist/templates/view-decl.js.map +1 -1
  83. package/dist/templates/zod-validators.d.ts +1 -1
  84. package/dist/templates/zod-validators.d.ts.map +1 -1
  85. package/dist/templates/zod-validators.js +35 -22
  86. package/dist/templates/zod-validators.js.map +1 -1
  87. package/package.json +6 -6
  88. package/src/generators/api-model.ts +9 -5
  89. package/src/generators/barrel.ts +1 -1
  90. package/src/generators/entity-file.ts +7 -1
  91. package/src/generators/extractor-file.ts +6 -1
  92. package/src/generators/output-parser-file.ts +6 -1
  93. package/src/generators/queries-file.ts +12 -7
  94. package/src/generators/routes-file-hono.ts +7 -1
  95. package/src/generators/routes-file.ts +6 -1
  96. package/src/index.ts +1 -1
  97. package/src/naming/collision-names.ts +87 -0
  98. package/src/payload-codegen.ts +4 -79
  99. package/src/reference/barrel.ts +1 -1
  100. package/src/reference/queries.ts +14 -6
  101. package/src/reference/routes.ts +8 -1
  102. package/src/render-context.ts +51 -3
  103. package/src/runner.ts +36 -4
  104. package/src/source-detect.ts +20 -0
  105. package/src/templates/drizzle-schema.ts +14 -3
  106. package/src/templates/entity-file.ts +14 -6
  107. package/src/templates/extract-delegate-emitter.ts +52 -27
  108. package/src/templates/extractor.ts +49 -32
  109. package/src/templates/inferred-types.ts +39 -17
  110. package/src/templates/output-parser.ts +40 -12
  111. package/src/templates/projection-decl.ts +20 -10
  112. package/src/templates/value-object-file.ts +5 -1
  113. package/src/templates/view-decl.ts +30 -18
  114. 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 ${obj.name}.extra.ts in this directory.\n`;
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, stripPackage,
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
- /** Resolve a value-object short name → its import module specifier. */
24
- readonly voModule: (refBase: string) => string;
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, voModule } = opts;
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
- const voTypeSym = imp(`${dtr.name}@${voModule(dtr.name)}`);
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
- dollarType = "scalar" in dtr.value
60
- ? `.$type<Record<string, ${dtr.value.scalar}>>()`
61
- : code`.$type<Record<string, ${imp(`${dtr.value.objectRef}@${voModule(dtr.value.objectRef)}`)}>>()`;
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, voModule } = opts;
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 refBase =
109
- f.subType === FIELD_SUBTYPE_OBJECT
110
- ? (() => {
111
- const ref = f.attr(FIELD_ATTR_OBJECT_REF);
112
- return typeof ref === "string" && ref.length > 0 ? stripPackage(ref) : undefined;
113
- })()
114
- : undefined;
115
- if (refBase) {
116
- const schemaSym = imp(`${refBase}InsertSchema@${voModule(refBase)}`);
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 { RenderContext } from "../render-context.js";
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 ${obj.name}Schema = ${z}.object({
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
- const insertSchemaName = `${obj.name}InsertSchema`;
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
- const insertSchemaName = `${obj.name}InsertSchema`;
373
- const updateSchemaName = `${obj.name}UpdateSchema`;
374
- const preservingSchemaName = `${obj.name}InsertPreservingSchema`;
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 ${obj.name}: identical to
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 ${obj.name}: every settable field, optional (FR-035 PATCH). A
402
- * renamed/dropped field is a compile error at every \`update${obj.name}\` call site. */
403
- export type ${obj.name}Patch = ${z}.input<typeof ${updateSchemaName}>;${preservingBlock}
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 referenced
450
- // <Ref>InsertSchema is named by the BARE short name. The import MODULE is
451
- // resolved via the shared layout/package/extStyle-aware helper (the SAME
452
- // one the field's TS type + Drizzle .$type<> use) so all three agree.
453
- // Without owner/ctx (bare unit-test calls) fall back to the flat same-dir.
454
- const refBase = stripPackage(ref);
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(refBase, ctx.packageOf, owner.package, ctx.outputLayout, ctx.extStyle)
457
- : `./${refBase}.js`;
458
- const refImp = imp(`${refBase}InsertSchema@${moduleSpec}`);
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 refBase = stripPackage(ref);
487
+ const refName = (ctx && owner) ? ctx.resolveValueObjectName(ref, fieldDeclaringPackage(field, owner.package)) : stripPackage(ref);
476
488
  const moduleSpec = (ctx && owner)
477
- ? valueObjectModuleSpecifier(refBase, ctx.packageOf, owner.package, ctx.outputLayout, ctx.extStyle)
478
- : `./${refBase}.js`;
479
- const refImp = imp(`${refBase}InsertSchema@${moduleSpec}`);
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);