@metaobjectsdev/codegen-ts 0.7.0-rc.1 → 0.7.0-rc.3

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 (60) hide show
  1. package/README.md +30 -0
  2. package/dist/column-mapper.d.ts +16 -0
  3. package/dist/column-mapper.d.ts.map +1 -1
  4. package/dist/column-mapper.js +71 -1
  5. package/dist/column-mapper.js.map +1 -1
  6. package/dist/generators/entity-file.d.ts +15 -0
  7. package/dist/generators/entity-file.d.ts.map +1 -1
  8. package/dist/generators/entity-file.js +2 -1
  9. package/dist/generators/entity-file.js.map +1 -1
  10. package/dist/generators/prompt-render-file.d.ts.map +1 -1
  11. package/dist/generators/prompt-render-file.js +30 -12
  12. package/dist/generators/prompt-render-file.js.map +1 -1
  13. package/dist/generators/queries-file.d.ts +1 -1
  14. package/dist/generators/queries-file.d.ts.map +1 -1
  15. package/dist/generators/queries-file.js +11 -3
  16. package/dist/generators/queries-file.js.map +1 -1
  17. package/dist/index.d.ts +1 -1
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +1 -1
  20. package/dist/index.js.map +1 -1
  21. package/dist/payload-codegen.d.ts +8 -0
  22. package/dist/payload-codegen.d.ts.map +1 -1
  23. package/dist/payload-codegen.js +33 -3
  24. package/dist/payload-codegen.js.map +1 -1
  25. package/dist/source-detect.d.ts +10 -0
  26. package/dist/source-detect.d.ts.map +1 -0
  27. package/dist/source-detect.js +30 -0
  28. package/dist/source-detect.js.map +1 -0
  29. package/dist/templates/drizzle-schema.js +27 -3
  30. package/dist/templates/drizzle-schema.js.map +1 -1
  31. package/dist/templates/entity-file.d.ts +15 -1
  32. package/dist/templates/entity-file.d.ts.map +1 -1
  33. package/dist/templates/entity-file.js +15 -5
  34. package/dist/templates/entity-file.js.map +1 -1
  35. package/dist/templates/inferred-types.d.ts +9 -0
  36. package/dist/templates/inferred-types.d.ts.map +1 -1
  37. package/dist/templates/inferred-types.js +88 -2
  38. package/dist/templates/inferred-types.js.map +1 -1
  39. package/dist/templates/value-object-file.d.ts +3 -0
  40. package/dist/templates/value-object-file.d.ts.map +1 -0
  41. package/dist/templates/value-object-file.js +27 -0
  42. package/dist/templates/value-object-file.js.map +1 -0
  43. package/dist/templates/zod-validators.d.ts +10 -0
  44. package/dist/templates/zod-validators.d.ts.map +1 -1
  45. package/dist/templates/zod-validators.js +108 -30
  46. package/dist/templates/zod-validators.js.map +1 -1
  47. package/package.json +4 -4
  48. package/src/column-mapper.ts +84 -0
  49. package/src/generators/entity-file.ts +17 -1
  50. package/src/generators/prompt-render-file.ts +38 -12
  51. package/src/generators/queries-file.ts +13 -4
  52. package/src/index.ts +2 -2
  53. package/src/metaobjects-config.ts +9 -2
  54. package/src/payload-codegen.ts +34 -2
  55. package/src/source-detect.ts +28 -0
  56. package/src/templates/drizzle-schema.ts +27 -3
  57. package/src/templates/entity-file.ts +36 -5
  58. package/src/templates/inferred-types.ts +117 -3
  59. package/src/templates/value-object-file.ts +30 -0
  60. package/src/templates/zod-validators.ts +121 -35
@@ -1 +1 @@
1
- {"version":3,"file":"zod-validators.js","sourceRoot":"","sources":["../../src/templates/zod-validators.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"zod-validators.js","sourceRoot":"","sources":["../../src/templates/zod-validators.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metaobjectsdev/codegen-ts",
3
- "version": "0.7.0-rc.1",
3
+ "version": "0.7.0-rc.3",
4
4
  "description": "TypeScript codegen engine for MetaObjects — emits Drizzle, Zod, and Fastify artifacts.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -38,7 +38,7 @@
38
38
  "access": "public"
39
39
  },
40
40
  "dependencies": {
41
- "@metaobjectsdev/metadata": "0.7.0-rc.1",
41
+ "@metaobjectsdev/metadata": "0.7.0-rc.3",
42
42
  "@biomejs/js-api": "^0.7.0",
43
43
  "@biomejs/wasm-nodejs": "^1.9.4",
44
44
  "ts-poet": "^6.10.0"
@@ -49,8 +49,8 @@
49
49
  },
50
50
  "devDependencies": {
51
51
  "@biomejs/biome": "^1.9.0",
52
- "@metaobjectsdev/codegen-ts-react": "0.7.0-rc.1",
53
- "@metaobjectsdev/render": "0.7.0-rc.1",
52
+ "@metaobjectsdev/codegen-ts-react": "0.7.0-rc.3",
53
+ "@metaobjectsdev/render": "0.7.0-rc.3",
54
54
  "bun-types": "latest",
55
55
  "drizzle-orm": "^0.36.0",
56
56
  "typescript": "^5.6.0",
@@ -23,6 +23,7 @@ import {
23
23
  FIELD_ATTR_REQUIRED,
24
24
  FIELD_ATTR_UNIQUE,
25
25
  FIELD_ATTR_DEFAULT,
26
+ FIELD_ATTR_OBJECT_REF,
26
27
  VALIDATOR_ATTR_MAX,
27
28
  } from "@metaobjectsdev/metadata";
28
29
  import { columnNameFromField } from "./naming.js";
@@ -63,6 +64,36 @@ function isSqlExprDefault(value: string): boolean {
63
64
  return SQL_EXPR_PATTERNS.some((re) => re.test(value));
64
65
  }
65
66
 
67
+ /**
68
+ * For an isArray:true field stored in SQLite as text(...,{mode:"json"}), return
69
+ * the TS element type used in the emitted .$type<E[]>() chain. Returns undefined
70
+ * when the field's subType doesn't have a stable scalar TS mapping (e.g.,
71
+ * field.object — leave the inferred `unknown[]` so the consumer can layer a
72
+ * richer schema on top).
73
+ */
74
+ function sqliteJsonArrayElementTsType(subType: string): string | undefined {
75
+ switch (subType) {
76
+ case FIELD_SUBTYPE_STRING:
77
+ case FIELD_SUBTYPE_ENUM:
78
+ case FIELD_SUBTYPE_CLASS:
79
+ case FIELD_SUBTYPE_DATE:
80
+ case FIELD_SUBTYPE_TIME:
81
+ case FIELD_SUBTYPE_TIMESTAMP:
82
+ case FIELD_SUBTYPE_DECIMAL:
83
+ return "string";
84
+ case FIELD_SUBTYPE_INT:
85
+ case FIELD_SUBTYPE_LONG:
86
+ case FIELD_SUBTYPE_CURRENCY:
87
+ case FIELD_SUBTYPE_DOUBLE:
88
+ case FIELD_SUBTYPE_FLOAT:
89
+ return "number";
90
+ case FIELD_SUBTYPE_BOOLEAN:
91
+ return "boolean";
92
+ default:
93
+ return undefined;
94
+ }
95
+ }
96
+
66
97
  /** Map a recognized SQL expression to its canonical raw form (uppercase keywords). */
67
98
  function canonicalizeSqlExpr(value: string): string {
68
99
  const lower = value.toLowerCase();
@@ -93,6 +124,17 @@ export interface ColumnSpec {
93
124
  leadingComment?: string;
94
125
  /** Optional CHECK constraint expression for the column (e.g., `status IN ('A', 'B')`). */
95
126
  checkConstraint?: string;
127
+ /**
128
+ * Optional `.$type<...>()` chain target. Renderer (drizzle-schema.ts) emits
129
+ * `.$type<TS[]>()` ahead of the modifiers chain, using ts-poet `imp()` for
130
+ * objectRef variants so the cross-module type import auto-hoists.
131
+ * `kind: "scalar"` covers string[]/number[]/boolean[] — no import needed.
132
+ * `kind: "objectRef"` covers SourceLens[]/Dissent[]/etc. — `module` is the
133
+ * relative import path to that entity's emitted module.
134
+ */
135
+ dollarTypeRef?:
136
+ | { kind: "scalar"; tsType: "string" | "number" | "boolean" }
137
+ | { kind: "objectRef"; name: string; module: string };
96
138
  }
97
139
 
98
140
  /** Resolve max length from validator.length child or @maxLength attr.
@@ -220,12 +262,36 @@ export function mapColumnType(
220
262
  }
221
263
  }
222
264
 
265
+ // Enum literal types: pass the values as `{ enum: [...] as const }` to
266
+ // Drizzle's text(...) so the inferred column type is a literal union
267
+ // ("a" | "b" | ...) instead of bare `string`. Skip when isArray — JSON
268
+ // arrays use { mode: "json" }, and the enum members go through Zod
269
+ // validation at the Insert/Update layer instead. Mirrors the Zod
270
+ // emission, which already uses z.enum([...]).
271
+ if (subType === FIELD_SUBTYPE_ENUM && !isArray && fnName === "text") {
272
+ const values = enumValues(field);
273
+ if (values !== undefined && values.length > 0) {
274
+ fnOptions = { ...(fnOptions ?? {}), enum: values };
275
+ }
276
+ }
277
+
223
278
  const modifiers: string[] = [];
224
279
 
225
280
  if (dialect === "postgres" && isArray) {
226
281
  modifiers.push(".array()");
227
282
  }
228
283
 
284
+ // SQLite stores arrays as JSON in a text column; Drizzle's text(...,{mode:"json"})
285
+ // infers the column as `unknown` without a $type<T>() annotation. Emit the
286
+ // chain via spec.dollarTypeRef so the renderer can hoist a type-only import
287
+ // for object refs (SourceLens[], Dissent[], etc.). Scalars (string/number/
288
+ // boolean) need no import. Postgres uses .array() above which is already
289
+ // element-typed by Drizzle.
290
+ // Determined ABOVE the modifiers chain so the renderer can position
291
+ // `.$type<>()` ahead of `.notNull()` etc.
292
+ // Note: dollarTypeRef is read alongside (and rendered ahead of) `modifiers`
293
+ // by `renderColumn` — see drizzle-schema.ts.
294
+
229
295
  if (isRequired(field)) {
230
296
  modifiers.push(".notNull()");
231
297
  }
@@ -258,6 +324,23 @@ export function mapColumnType(
258
324
  }
259
325
  }
260
326
 
327
+ // SQLite isArray columns route through {mode:"json"} above; compute the
328
+ // $type<E[]>() target so the renderer can hoist any cross-module imports.
329
+ let dollarTypeRef: ColumnSpec["dollarTypeRef"];
330
+ if (dialect === "sqlite" && isArray) {
331
+ if (subType === FIELD_SUBTYPE_OBJECT) {
332
+ const ref = field.ownAttr(FIELD_ATTR_OBJECT_REF);
333
+ if (typeof ref === "string" && ref.length > 0) {
334
+ dollarTypeRef = { kind: "objectRef", name: ref, module: `./${ref}.js` };
335
+ }
336
+ } else {
337
+ const scalar = sqliteJsonArrayElementTsType(subType);
338
+ if (scalar !== undefined) {
339
+ dollarTypeRef = { kind: "scalar", tsType: scalar as "string" | "number" | "boolean" };
340
+ }
341
+ }
342
+ }
343
+
261
344
  const result: ColumnSpec = {
262
345
  fnName,
263
346
  dbName,
@@ -267,6 +350,7 @@ export function mapColumnType(
267
350
  };
268
351
  if (fnOptions !== undefined) result.fnOptions = fnOptions;
269
352
  if (defaultExpr !== undefined) result.defaultExpr = defaultExpr;
353
+ if (dollarTypeRef !== undefined) result.dollarTypeRef = dollarTypeRef;
270
354
  if (leadingComment !== undefined) result.leadingComment = leadingComment;
271
355
 
272
356
  // Enum fields: emit a CHECK constraint listing the valid member values.
@@ -7,9 +7,25 @@ import { entityOutputPath } from "../import-path.js";
7
7
  export interface EntityFileOpts {
8
8
  filter?: (entity: MetaObject) => boolean;
9
9
  target?: string;
10
+ /**
11
+ * Whether generated entity files include the Fastify-flavored
12
+ * `<Entity>FilterAllowlist` + `<Entity>SortAllowlist` blocks (and the
13
+ * `@metaobjectsdev/runtime-ts/drizzle-fastify` type-only imports they
14
+ * require). Default `true` for back-compat.
15
+ *
16
+ * Set to `false` for Worker/Lambda-style consumers that don't mount
17
+ * Fastify-style server routes — the generated entity file then has no
18
+ * `runtime-ts/drizzle-fastify` imports at all and `@metaobjectsdev/runtime-ts`
19
+ * can be omitted from the consumer's dependency tree.
20
+ *
21
+ * The client-side `<Entity>Filter` type is always emitted — it's a pure
22
+ * client-side type with no runtime-ts dependency.
23
+ */
24
+ allowlists?: boolean;
10
25
  }
11
26
 
12
27
  export const entityFile = function entityFile(opts?: EntityFileOpts): Generator {
28
+ const allowlists = opts?.allowlists ?? true;
13
29
  const generator: Generator = {
14
30
  name: "entity-file",
15
31
  emitsEntityModule: true,
@@ -19,7 +35,7 @@ export const entityFile = function entityFile(opts?: EntityFileOpts): Generator
19
35
  }
20
36
  return {
21
37
  path: entityOutputPath(ctx.config.outputLayout ?? "flat", entity.package, `${entity.name}.ts`),
22
- content: await formatTs(renderEntityFile(entity, ctx.renderContext)),
38
+ content: await formatTs(renderEntityFile(entity, ctx.renderContext, { allowlists })),
23
39
  };
24
40
  }),
25
41
  };
@@ -16,9 +16,10 @@ import {
16
16
  oncePerRun,
17
17
  } from "../generator.js";
18
18
  import {
19
- generatePayloadInterfaces,
19
+ generatePayloadInterfacesBatch,
20
20
  generateRenderHandle,
21
21
  } from "../payload-codegen.js";
22
+ import { GENERATED_HEADER } from "../constants.js";
22
23
 
23
24
  export interface PromptRenderOpts {
24
25
  /** Output file path relative to the target's outDir. Default: "prompts.ts". */
@@ -27,6 +28,17 @@ export interface PromptRenderOpts {
27
28
  target?: string;
28
29
  }
29
30
 
31
+ // Hoisted into the emitted file once. generateRenderHandle() emits this line
32
+ // per-handle (for the standalone scenario); we strip its per-handle copies.
33
+ const RENDER_IMPORT = `import { render, type Provider } from "@metaobjectsdev/render";`;
34
+
35
+ // Matches the `import type { ... } from "./payloads.js";` that generateRenderHandle
36
+ // emits for the standalone two-file scenario. In the single-file output here the
37
+ // payload interfaces are already defined above, so the import is dead.
38
+ function isStandalonePayloadImport(line: string): boolean {
39
+ return line.startsWith("import type {") && line.includes('"./payloads.js"');
40
+ }
41
+
30
42
  export const promptRender = function promptRender(opts?: PromptRenderOpts): Generator {
31
43
  const outFile = opts?.outFile ?? "prompts.ts";
32
44
  const generator: Generator = {
@@ -41,21 +53,35 @@ export const promptRender = function promptRender(opts?: PromptRenderOpts): Gene
41
53
  return [];
42
54
  }
43
55
 
44
- const parts: string[] = [];
45
- for (const p of payloads) {
46
- parts.push(generatePayloadInterfaces(ctx.loadedRoot, p.name));
56
+ const parts: string[] = [`// ${GENERATED_HEADER} — DO NOT EDIT.`];
57
+
58
+ // Hoist the @metaobjectsdev/render import once (only when prompts emit handles).
59
+ if (prompts.length > 0) {
60
+ parts.push(RENDER_IMPORT);
61
+ }
62
+
63
+ // Emit payload interfaces with a single shared dedupe set so a lens
64
+ // referenced by multiple payloads appears exactly once.
65
+ const payloadInterfaces = generatePayloadInterfacesBatch(
66
+ ctx.loadedRoot,
67
+ payloads.map((p) => p.name),
68
+ );
69
+ if (payloadInterfaces.length > 0) {
70
+ parts.push(payloadInterfaces);
47
71
  }
48
- // Strip the `import type { ... } from "./payloads.js"` line that
49
- // generateRenderHandle() emits for the standalone two-file scenario.
50
- // In the single-file output here the payload interfaces are already
51
- // defined above, so the import is a self-reference to a non-existent module.
72
+
73
+ // Append each render handle with its per-handle imports stripped — both
74
+ // the now-hoisted render/Provider import and the standalone payloads.js
75
+ // import. Also drop any leading blank lines left behind by the strip so
76
+ // the joined output doesn't accumulate double blank gaps between parts.
52
77
  for (const t of prompts) {
53
- const handle = generateRenderHandle(ctx.loadedRoot, t.name)
78
+ const lines = generateRenderHandle(ctx.loadedRoot, t.name)
54
79
  .split("\n")
55
- .filter((line) => !line.startsWith("import type {") || !line.includes("./payloads.js"))
56
- .join("\n");
57
- parts.push(handle);
80
+ .filter((line) => line !== RENDER_IMPORT && !isStandalonePayloadImport(line));
81
+ while (lines.length > 0 && lines[0]!.trim() === "") lines.shift();
82
+ parts.push(lines.join("\n"));
58
83
  }
84
+
59
85
  return [{
60
86
  path: outFile,
61
87
  content: parts.filter((s) => s.length > 0).map((s) => s.trimEnd()).join("\n\n") + "\n",
@@ -1,4 +1,4 @@
1
- import type { MetaObject } from "@metaobjectsdev/metadata";
1
+ import { OBJECT_SUBTYPE_VALUE, type MetaObject } from "@metaobjectsdev/metadata";
2
2
  import { perEntity, type Generator, type GeneratorFactory } from "../generator.js";
3
3
  import { renderQueriesFile } from "../templates/queries-file.js";
4
4
  import { formatTs } from "../format.js";
@@ -9,9 +9,21 @@ export interface QueriesFileOpts {
9
9
  target?: string;
10
10
  }
11
11
 
12
+ // object.value records have no primary identity, so the rendered queries module
13
+ // emits findById/updateById/deleteById against a non-existent column. Skipping
14
+ // value subtypes is unconditional — the user-supplied filter (if any) is applied
15
+ // on top via boolean AND.
16
+ const skipValueTypes = (e: MetaObject): boolean => e.subType !== OBJECT_SUBTYPE_VALUE;
17
+
12
18
  export const queriesFile = function queriesFile(opts?: QueriesFileOpts): Generator {
19
+ const userFilter = opts?.filter;
20
+ const filter: (e: MetaObject) => boolean = userFilter
21
+ ? (e) => skipValueTypes(e) && userFilter(e)
22
+ : skipValueTypes;
23
+
13
24
  const generator: Generator = {
14
25
  name: "queries-file",
26
+ filter,
15
27
  generate: perEntity(async (entity, ctx) => {
16
28
  if (!ctx.renderContext) {
17
29
  throw new Error("queries-file: renderContext is required (provided by runGen)");
@@ -22,9 +34,6 @@ export const queriesFile = function queriesFile(opts?: QueriesFileOpts): Generat
22
34
  };
23
35
  }),
24
36
  };
25
- if (opts?.filter) {
26
- generator.filter = opts.filter;
27
- }
28
37
  if (opts?.target) {
29
38
  generator.target = opts.target;
30
39
  }
package/src/index.ts CHANGED
@@ -9,7 +9,7 @@ export type { RunGenOpts, RunGenResult } from "./runner.js";
9
9
  export type { Generator, GenContext, EmittedFile, GeneratorFactory } from "./generator.js";
10
10
  export { perEntity, oncePerRun } from "./generator.js";
11
11
 
12
- export type { MetaobjectsGenConfig, NormalizedMetaobjectsGenConfig, ResolvedGenConfig, Dialect, ExtStyle, ColumnNamingStrategy } from "./metaobjects-config.js";
12
+ export type { MetaobjectsGenConfig, NormalizedMetaobjectsGenConfig, ResolvedGenConfig, Dialect, ExtStyle, ColumnNamingStrategy, MetaDataTypeProvider } from "./metaobjects-config.js";
13
13
  export { defineConfig, normalizeConfig } from "./metaobjects-config.js";
14
14
 
15
15
  export type { ColumnSpec, DefaultExpr } from "./column-mapper.js";
@@ -44,4 +44,4 @@ export { emitViewDdl } from "./projection/view-ddl-emit.js";
44
44
  export type { EmitOptions as ViewDdlEmitOptions } from "./projection/view-ddl-emit.js";
45
45
  export type { JoinNode, JoinTree, SelectColumn, SelectSpec, ViewSpec } from "./projection/view-spec.js";
46
46
  // Prompt construction (FR-004): typed payload + render-handle codegen.
47
- export { generatePayloadInterfaces, generateRenderHandle } from "./payload-codegen.js";
47
+ export { generatePayloadInterfaces, generatePayloadInterfacesBatch, generateRenderHandle } from "./payload-codegen.js";
@@ -1,11 +1,11 @@
1
- import { DEFAULT_COLUMN_NAMING_STRATEGY, type ColumnNamingStrategy } from "@metaobjectsdev/metadata";
1
+ import { DEFAULT_COLUMN_NAMING_STRATEGY, type ColumnNamingStrategy, type MetaDataTypeProvider } from "@metaobjectsdev/metadata";
2
2
  import type { Generator } from "./generator.js";
3
3
  import type { ExtStyle } from "./render-context.js";
4
4
  import type { OutputLayout, ResolvedTarget } from "./import-path.js";
5
5
 
6
6
  export type Dialect = "sqlite" | "postgres";
7
7
  /** Re-exported from metadata so codegen-ts consumers see one canonical type. */
8
- export type { ColumnNamingStrategy } from "@metaobjectsdev/metadata";
8
+ export type { ColumnNamingStrategy, MetaDataTypeProvider } from "@metaobjectsdev/metadata";
9
9
  export type { ExtStyle };
10
10
  export type { OutputLayout };
11
11
  export type { ResolvedTarget };
@@ -41,6 +41,13 @@ export interface MetaobjectsGenConfig extends ResolvedGenConfig {
41
41
  targets?: Record<string, TargetConfig>;
42
42
  /** importBase for the default target (top-level outDir). */
43
43
  importBase?: string;
44
+ /**
45
+ * Consumer-supplied {@link MetaDataTypeProvider}s. Threaded to `loadMemory`
46
+ * by the CLI's gen/migrate commands so a project can register its own
47
+ * subtypes/attrs (e.g. a `template.toolcall` subtype) without forking the
48
+ * loader. Composed AFTER the default core+forge bundle.
49
+ */
50
+ providers?: readonly MetaDataTypeProvider[];
44
51
  }
45
52
 
46
53
  /** MetaobjectsGenConfig after applying defaults. All fields required.
@@ -17,6 +17,7 @@ import {
17
17
  TYPE_TEMPLATE,
18
18
  FIELD_SUBTYPE_OBJECT,
19
19
  FIELD_ATTR_OBJECT_REF,
20
+ FIELD_ATTR_REQUIRED,
20
21
  TEMPLATE_ATTR_PAYLOAD_REF,
21
22
  TEMPLATE_ATTR_TEXT_REF,
22
23
  TEMPLATE_ATTR_FORMAT,
@@ -55,7 +56,13 @@ function fieldTsType(field: MetaData): { type: string; refVo?: string } {
55
56
  if (typeof ref === "string") result.refVo = ref;
56
57
  return result;
57
58
  }
58
- return { type: SCALAR_TS[field.subType] ?? "unknown" };
59
+ const scalar = SCALAR_TS[field.subType] ?? "unknown";
60
+ return { type: field.isArray ? `${scalar}[]` : scalar };
61
+ }
62
+
63
+ /** True iff the field's @required is explicitly set to true. */
64
+ function isFieldRequired(field: MetaData): boolean {
65
+ return field.ownAttr(FIELD_ATTR_REQUIRED) === true;
59
66
  }
60
67
 
61
68
  function emitInterface(root: MetaData, voName: string, emitted: Set<string>, out: string[]): void {
@@ -67,7 +74,15 @@ function emitInterface(root: MetaData, voName: string, emitted: Set<string>, out
67
74
  const refs: string[] = [];
68
75
  for (const f of vo.children().filter((c) => c.type === TYPE_FIELD)) {
69
76
  const { type, refVo } = fieldTsType(f);
70
- lines.push(` ${f.name}: ${type};`);
77
+ // Required fields: `name: T;`
78
+ // Optional fields: `name?: T | null;` — the `| null` lets values from
79
+ // Drizzle entity rows (which return `null` for nullable columns) flow
80
+ // straight in. Without it, TS treats undefined-vs-null as a hard error
81
+ // at the entity → payload boundary.
82
+ const isRequired = isFieldRequired(f);
83
+ const tsType = isRequired ? type : `${type} | null`;
84
+ const optional = isRequired ? "" : "?";
85
+ lines.push(` ${f.name}${optional}: ${tsType};`);
71
86
  if (refVo) refs.push(refVo);
72
87
  }
73
88
  lines.push("}");
@@ -82,6 +97,23 @@ export function generatePayloadInterfaces(root: MetaData, voName: string): strin
82
97
  return out.join("\n\n") + "\n";
83
98
  }
84
99
 
100
+ /**
101
+ * Emit interfaces for several payloads at once, using a single shared dedupe
102
+ * set so nested types (e.g. lens projections referenced by multiple payloads)
103
+ * appear exactly once in the combined output.
104
+ *
105
+ * Returns the empty string when `voNames` is empty.
106
+ */
107
+ export function generatePayloadInterfacesBatch(root: MetaData, voNames: readonly string[]): string {
108
+ if (voNames.length === 0) return "";
109
+ const out: string[] = [];
110
+ const emitted = new Set<string>();
111
+ for (const name of voNames) {
112
+ emitInterface(root, name, emitted, out);
113
+ }
114
+ return out.length === 0 ? "" : out.join("\n\n") + "\n";
115
+ }
116
+
85
117
  function pascal(s: string): string {
86
118
  return s.length > 0 ? s[0]!.toUpperCase() + s.slice(1) : s;
87
119
  }
@@ -0,0 +1,28 @@
1
+ // Source-detect helpers — discriminate table-backed entities from value-only
2
+ // objects (and other in-memory / transit shapes) by inspecting source.* children.
3
+ //
4
+ // Used by the entity-file composer to pick a streamlined "value-only" emission
5
+ // path for metaobjects that declare no writable relational source. Pure
6
+ // metadata-driven, not a typeId discriminator: any object subtype can opt out
7
+ // of Drizzle table emission simply by omitting source.rdb.
8
+
9
+ import { MetaSource } from "@metaobjectsdev/metadata";
10
+ import { TYPE_SOURCE, SOURCE_SUBTYPE_RDB } from "@metaobjectsdev/metadata";
11
+ import type { MetaObject } from "@metaobjectsdev/metadata";
12
+
13
+ /**
14
+ * True when the entity declares at least one writable source.rdb child.
15
+ * Discriminates table-backed entities (full Drizzle file: table + Insert/Update
16
+ * schemas + filter allowlists + constants) from value-only objects (TS
17
+ * interface + Zod schema only). Absence of source.rdb means in-memory /
18
+ * transit data — no migration, no ORM table to point at.
19
+ */
20
+ export function hasWritableRdbSource(entity: MetaObject): boolean {
21
+ for (const child of entity.ownChildren()) {
22
+ if (child.type !== TYPE_SOURCE) continue;
23
+ if (child.subType !== SOURCE_SUBTYPE_RDB) continue;
24
+ if (!(child instanceof MetaSource)) continue;
25
+ if (child.isWritable()) return true;
26
+ }
27
+ return false;
28
+ }
@@ -187,9 +187,17 @@ function buildCompositeKeyCallback(
187
187
  return code`${primaryKeySym}({ columns: [${columnRefs}] })`;
188
188
  }
189
189
 
190
- /** Build a JS-style object literal string (not JSON.stringify which uses quoted keys). */
190
+ /** Build a JS-style object literal string (not JSON.stringify which uses quoted keys).
191
+ * Array values get `as const` appended so Drizzle's text(...,{ enum: [...] })
192
+ * narrows the inferred column type to a literal union instead of bare `string`. */
191
193
  function inlineObjectLiteral(obj: Record<string, unknown>): string {
192
- const entries = Object.entries(obj).map(([k, v]) => `${k}: ${JSON.stringify(v)}`);
194
+ const entries = Object.entries(obj).map(([k, v]) => {
195
+ const lit = JSON.stringify(v);
196
+ if (Array.isArray(v)) {
197
+ return `${k}: ${lit} as const`;
198
+ }
199
+ return `${k}: ${lit}`;
200
+ });
193
201
  return `{ ${entries.join(", ")} }`;
194
202
  }
195
203
 
@@ -300,7 +308,23 @@ function renderColumn(
300
308
  ? `.$defaultFn(() => new Date().toISOString())`
301
309
  : "";
302
310
 
303
- const columnLine = code` ${field.name}: ${baseCall}${modifiersStr}${autoSetSuffix}${sqlDefaultSegment ?? ""}${fkRefSegment ?? ""}`;
311
+ // $type<E[]>() chain emitted as Code (not a string modifier) so ts-poet can
312
+ // hoist the cross-module type import for objectRef variants. Positioned
313
+ // immediately after the baseCall so the chain reads `.text(...).$type<...>().notNull()...`
314
+ // which Drizzle accepts in any order but is conventional for "type narrowing
315
+ // first."
316
+ let dollarTypeSegment: Code | string = "";
317
+ if (spec.dollarTypeRef !== undefined) {
318
+ const ref = spec.dollarTypeRef;
319
+ if (ref.kind === "scalar") {
320
+ dollarTypeSegment = `.$type<${ref.tsType}[]>()`;
321
+ } else {
322
+ const refSym = imp(`${ref.name}@${ref.module}`);
323
+ dollarTypeSegment = code`.$type<${refSym}[]>()`;
324
+ }
325
+ }
326
+
327
+ const columnLine = code` ${field.name}: ${baseCall}${dollarTypeSegment}${modifiersStr}${autoSetSuffix}${sqlDefaultSegment ?? ""}${fkRefSegment ?? ""}`;
304
328
  return spec.leadingComment !== undefined
305
329
  ? code` // ${spec.leadingComment}\n${columnLine}`
306
330
  : columnLine;
@@ -2,8 +2,9 @@
2
2
  // into one file with the @generated header. ts-poet deduplicates imports.
3
3
  //
4
4
  // Dispatch:
5
- // isProjection(entity) → renderProjectionDecl (read-only: view declaration + Zod + filter sections)
6
- // vanilla / write-through entity Drizzle table path
5
+ // isProjection(entity) → renderProjectionDecl (read-only: view declaration + Zod + filter sections)
6
+ // !hasWritableRdbSource(entity) → renderValueObjectFile (in-memory / transit shape: interface + Zod schema)
7
+ // vanilla / write-through entity → Drizzle table path
7
8
 
8
9
  import { joinCode, type Code } from "ts-poet";
9
10
  import type { MetaObject } from "@metaobjectsdev/metadata";
@@ -17,8 +18,31 @@ import { renderFilterType } from "./filter-type.js";
17
18
  import { GENERATED_HEADER } from "../constants.js";
18
19
  import { isProjection } from "../projection/projection-detector.js";
19
20
  import { renderProjectionDecl } from "./projection-decl.js";
21
+ import { hasWritableRdbSource } from "../source-detect.js";
22
+ import { renderValueObjectFile } from "./value-object-file.js";
23
+
24
+ /**
25
+ * Render-time options for the entity-file composer.
26
+ *
27
+ * `allowlists` (default `true`) controls whether the Fastify-flavored
28
+ * `<Entity>FilterAllowlist` + `<Entity>SortAllowlist` blocks (plus their
29
+ * `runtime-ts/drizzle-fastify` type-only imports) are emitted. Workers/Lambda
30
+ * consumers that don't mount Fastify-style server routes can pass `false` and
31
+ * drop `@metaobjectsdev/runtime-ts` from their deps entirely. The client-side
32
+ * `<Entity>Filter` type is always emitted — consumers still want it for typed
33
+ * client calls regardless of how the server is wired.
34
+ */
35
+ export interface RenderEntityFileOpts {
36
+ readonly allowlists?: boolean;
37
+ }
38
+
39
+ export function renderEntityFile(
40
+ entity: MetaObject,
41
+ ctx: RenderContext,
42
+ opts?: RenderEntityFileOpts,
43
+ ): string {
44
+ const allowlists = opts?.allowlists ?? true;
20
45
 
21
- export function renderEntityFile(entity: MetaObject, ctx: RenderContext): string {
22
46
  // --- Projection path (read-only: view-backed entity with no table source) ---
23
47
  // Projections intentionally get the z.enum() validator but NOT a named enum
24
48
  // type alias — emitting aliases here is a deliberate v1 scope decision.
@@ -30,6 +54,14 @@ export function renderEntityFile(entity: MetaObject, ctx: RenderContext): string
30
54
  });
31
55
  }
32
56
 
57
+ // --- Value-only path (no writable source.rdb: in-memory / transit shape) ---
58
+ // No Drizzle table, no migration footprint. Consumers that need to validate
59
+ // the shape (LLM tool_use input_schema, REST body parsing) use the Zod
60
+ // schema; consumers that need the type use the interface.
61
+ if (!hasWritableRdbSource(entity)) {
62
+ return renderValueObjectFile(entity);
63
+ }
64
+
33
65
  // --- Vanilla / write-through entity path ---
34
66
  const enumAliases = renderEnumTypeAliases(entity);
35
67
  const sections: Code[] = [
@@ -38,8 +70,7 @@ export function renderEntityFile(entity: MetaObject, ctx: RenderContext): string
38
70
  ...(enumAliases !== null ? [enumAliases] : []),
39
71
  renderZodValidators(entity),
40
72
  renderEntityConstants(entity, ctx.apiPrefix),
41
- renderFilterAllowlist(entity),
42
- renderSortAllowlist(entity),
73
+ ...(allowlists ? [renderFilterAllowlist(entity), renderSortAllowlist(entity)] : []),
43
74
  renderFilterType(entity),
44
75
  ];
45
76