@metaobjectsdev/codegen-ts 0.5.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (198) hide show
  1. package/LICENSE +189 -0
  2. package/README.md +101 -0
  3. package/dist/column-mapper.d.ts +38 -0
  4. package/dist/column-mapper.d.ts.map +1 -0
  5. package/dist/column-mapper.js +205 -0
  6. package/dist/column-mapper.js.map +1 -0
  7. package/dist/constants.d.ts +7 -0
  8. package/dist/constants.d.ts.map +1 -0
  9. package/dist/constants.js +8 -0
  10. package/dist/constants.js.map +1 -0
  11. package/dist/errors.d.ts +7 -0
  12. package/dist/errors.d.ts.map +1 -0
  13. package/dist/errors.js +11 -0
  14. package/dist/errors.js.map +1 -0
  15. package/dist/format.d.ts +2 -0
  16. package/dist/format.d.ts.map +1 -0
  17. package/dist/format.js +47 -0
  18. package/dist/format.js.map +1 -0
  19. package/dist/generator.d.ts +44 -0
  20. package/dist/generator.d.ts.map +1 -0
  21. package/dist/generator.js +17 -0
  22. package/dist/generator.js.map +1 -0
  23. package/dist/generators/barrel.d.ts +6 -0
  24. package/dist/generators/barrel.d.ts.map +1 -0
  25. package/dist/generators/barrel.js +17 -0
  26. package/dist/generators/barrel.js.map +1 -0
  27. package/dist/generators/entity-file.d.ts +8 -0
  28. package/dist/generators/entity-file.d.ts.map +1 -0
  29. package/dist/generators/entity-file.js +27 -0
  30. package/dist/generators/entity-file.js.map +1 -0
  31. package/dist/generators/index.d.ts +5 -0
  32. package/dist/generators/index.d.ts.map +1 -0
  33. package/dist/generators/index.js +5 -0
  34. package/dist/generators/index.js.map +1 -0
  35. package/dist/generators/queries-file.d.ts +8 -0
  36. package/dist/generators/queries-file.d.ts.map +1 -0
  37. package/dist/generators/queries-file.js +26 -0
  38. package/dist/generators/queries-file.js.map +1 -0
  39. package/dist/generators/routes-file.d.ts +12 -0
  40. package/dist/generators/routes-file.d.ts.map +1 -0
  41. package/dist/generators/routes-file.js +30 -0
  42. package/dist/generators/routes-file.js.map +1 -0
  43. package/dist/import-path.d.ts +41 -0
  44. package/dist/import-path.d.ts.map +1 -0
  45. package/dist/import-path.js +95 -0
  46. package/dist/import-path.js.map +1 -0
  47. package/dist/index.d.ts +29 -0
  48. package/dist/index.d.ts.map +1 -0
  49. package/dist/index.js +21 -0
  50. package/dist/index.js.map +1 -0
  51. package/dist/metaobjects-config.d.ts +56 -0
  52. package/dist/metaobjects-config.d.ts.map +1 -0
  53. package/dist/metaobjects-config.js +42 -0
  54. package/dist/metaobjects-config.js.map +1 -0
  55. package/dist/naming.d.ts +29 -0
  56. package/dist/naming.d.ts.map +1 -0
  57. package/dist/naming.js +67 -0
  58. package/dist/naming.js.map +1 -0
  59. package/dist/overwrite-policy.d.ts +8 -0
  60. package/dist/overwrite-policy.d.ts.map +1 -0
  61. package/dist/overwrite-policy.js +23 -0
  62. package/dist/overwrite-policy.js.map +1 -0
  63. package/dist/pk-resolver.d.ts +18 -0
  64. package/dist/pk-resolver.d.ts.map +1 -0
  65. package/dist/pk-resolver.js +36 -0
  66. package/dist/pk-resolver.js.map +1 -0
  67. package/dist/projection/extract-view-spec.d.ts +18 -0
  68. package/dist/projection/extract-view-spec.d.ts.map +1 -0
  69. package/dist/projection/extract-view-spec.js +272 -0
  70. package/dist/projection/extract-view-spec.js.map +1 -0
  71. package/dist/projection/index.d.ts +5 -0
  72. package/dist/projection/index.d.ts.map +1 -0
  73. package/dist/projection/index.js +5 -0
  74. package/dist/projection/index.js.map +1 -0
  75. package/dist/projection/projection-detector.d.ts +4 -0
  76. package/dist/projection/projection-detector.d.ts.map +1 -0
  77. package/dist/projection/projection-detector.js +13 -0
  78. package/dist/projection/projection-detector.js.map +1 -0
  79. package/dist/projection/view-ddl-emit.d.ts +10 -0
  80. package/dist/projection/view-ddl-emit.d.ts.map +1 -0
  81. package/dist/projection/view-ddl-emit.js +47 -0
  82. package/dist/projection/view-ddl-emit.js.map +1 -0
  83. package/dist/projection/view-spec.d.ts +56 -0
  84. package/dist/projection/view-spec.d.ts.map +1 -0
  85. package/dist/projection/view-spec.js +2 -0
  86. package/dist/projection/view-spec.js.map +1 -0
  87. package/dist/relation-resolver.d.ts +21 -0
  88. package/dist/relation-resolver.d.ts.map +1 -0
  89. package/dist/relation-resolver.js +62 -0
  90. package/dist/relation-resolver.js.map +1 -0
  91. package/dist/render-context.d.ts +65 -0
  92. package/dist/render-context.d.ts.map +1 -0
  93. package/dist/render-context.js +28 -0
  94. package/dist/render-context.js.map +1 -0
  95. package/dist/runner.d.ts +17 -0
  96. package/dist/runner.d.ts.map +1 -0
  97. package/dist/runner.js +135 -0
  98. package/dist/runner.js.map +1 -0
  99. package/dist/templates/barrel.d.ts +8 -0
  100. package/dist/templates/barrel.d.ts.map +1 -0
  101. package/dist/templates/barrel.js +12 -0
  102. package/dist/templates/barrel.js.map +1 -0
  103. package/dist/templates/drizzle-schema.d.ts +13 -0
  104. package/dist/templates/drizzle-schema.d.ts.map +1 -0
  105. package/dist/templates/drizzle-schema.js +251 -0
  106. package/dist/templates/drizzle-schema.js.map +1 -0
  107. package/dist/templates/entity-constants.d.ts +4 -0
  108. package/dist/templates/entity-constants.d.ts.map +1 -0
  109. package/dist/templates/entity-constants.js +215 -0
  110. package/dist/templates/entity-constants.js.map +1 -0
  111. package/dist/templates/entity-file.d.ts +4 -0
  112. package/dist/templates/entity-file.d.ts.map +1 -0
  113. package/dist/templates/entity-file.js +45 -0
  114. package/dist/templates/entity-file.js.map +1 -0
  115. package/dist/templates/field-meta.d.ts +24 -0
  116. package/dist/templates/field-meta.d.ts.map +1 -0
  117. package/dist/templates/field-meta.js +117 -0
  118. package/dist/templates/field-meta.js.map +1 -0
  119. package/dist/templates/filter-allowlist.d.ts +5 -0
  120. package/dist/templates/filter-allowlist.d.ts.map +1 -0
  121. package/dist/templates/filter-allowlist.js +86 -0
  122. package/dist/templates/filter-allowlist.js.map +1 -0
  123. package/dist/templates/filter-shared.d.ts +15 -0
  124. package/dist/templates/filter-shared.d.ts.map +1 -0
  125. package/dist/templates/filter-shared.js +30 -0
  126. package/dist/templates/filter-shared.js.map +1 -0
  127. package/dist/templates/filter-type.d.ts +4 -0
  128. package/dist/templates/filter-type.d.ts.map +1 -0
  129. package/dist/templates/filter-type.js +78 -0
  130. package/dist/templates/filter-type.js.map +1 -0
  131. package/dist/templates/inferred-types.d.ts +4 -0
  132. package/dist/templates/inferred-types.d.ts.map +1 -0
  133. package/dist/templates/inferred-types.js +14 -0
  134. package/dist/templates/inferred-types.js.map +1 -0
  135. package/dist/templates/projection-decl.d.ts +21 -0
  136. package/dist/templates/projection-decl.d.ts.map +1 -0
  137. package/dist/templates/projection-decl.js +116 -0
  138. package/dist/templates/projection-decl.js.map +1 -0
  139. package/dist/templates/queries-file.d.ts +4 -0
  140. package/dist/templates/queries-file.d.ts.map +1 -0
  141. package/dist/templates/queries-file.js +39 -0
  142. package/dist/templates/queries-file.js.map +1 -0
  143. package/dist/templates/queries.d.ts +9 -0
  144. package/dist/templates/queries.d.ts.map +1 -0
  145. package/dist/templates/queries.js +115 -0
  146. package/dist/templates/queries.js.map +1 -0
  147. package/dist/templates/relations-block.d.ts +9 -0
  148. package/dist/templates/relations-block.d.ts.map +1 -0
  149. package/dist/templates/relations-block.js +45 -0
  150. package/dist/templates/relations-block.js.map +1 -0
  151. package/dist/templates/routes-file.d.ts +4 -0
  152. package/dist/templates/routes-file.d.ts.map +1 -0
  153. package/dist/templates/routes-file.js +158 -0
  154. package/dist/templates/routes-file.js.map +1 -0
  155. package/dist/templates/zod-validators.d.ts +4 -0
  156. package/dist/templates/zod-validators.d.ts.map +1 -0
  157. package/dist/templates/zod-validators.js +129 -0
  158. package/dist/templates/zod-validators.js.map +1 -0
  159. package/package.json +59 -0
  160. package/src/column-mapper.ts +266 -0
  161. package/src/constants.ts +10 -0
  162. package/src/errors.ts +10 -0
  163. package/src/format.ts +50 -0
  164. package/src/generator.ts +73 -0
  165. package/src/generators/barrel.ts +28 -0
  166. package/src/generators/entity-file.ts +33 -0
  167. package/src/generators/index.ts +4 -0
  168. package/src/generators/queries-file.ts +32 -0
  169. package/src/generators/routes-file.ts +36 -0
  170. package/src/import-path.ts +153 -0
  171. package/src/index.ts +45 -0
  172. package/src/metaobjects-config.ts +95 -0
  173. package/src/naming.ts +84 -0
  174. package/src/overwrite-policy.ts +39 -0
  175. package/src/pk-resolver.ts +47 -0
  176. package/src/projection/extract-view-spec.ts +372 -0
  177. package/src/projection/index.ts +4 -0
  178. package/src/projection/projection-detector.ts +26 -0
  179. package/src/projection/view-ddl-emit.ts +66 -0
  180. package/src/projection/view-spec.ts +62 -0
  181. package/src/relation-resolver.ts +87 -0
  182. package/src/render-context.ts +93 -0
  183. package/src/runner.ts +178 -0
  184. package/src/templates/barrel.ts +23 -0
  185. package/src/templates/drizzle-schema.ts +286 -0
  186. package/src/templates/entity-constants.ts +248 -0
  187. package/src/templates/entity-file.ts +51 -0
  188. package/src/templates/field-meta.ts +150 -0
  189. package/src/templates/filter-allowlist.ts +104 -0
  190. package/src/templates/filter-shared.ts +30 -0
  191. package/src/templates/filter-type.ts +93 -0
  192. package/src/templates/inferred-types.ts +16 -0
  193. package/src/templates/projection-decl.ts +146 -0
  194. package/src/templates/queries-file.ts +56 -0
  195. package/src/templates/queries.ts +132 -0
  196. package/src/templates/relations-block.ts +65 -0
  197. package/src/templates/routes-file.ts +179 -0
  198. package/src/templates/zod-validators.ts +140 -0
@@ -0,0 +1,251 @@
1
+ // Drizzle schema template — emits a single sqliteTable() or pgTable() definition,
2
+ // with FK .references() on FK columns derived from relationship children,
3
+ // plus the relations() block auto-emitted at the end.
4
+ import { code, imp, joinCode } from "ts-poet";
5
+ import { MetaObject, MetaField } from "@metaobjectsdev/metadata";
6
+ import { IDENTITY_SUBTYPE_SECONDARY, FIELD_SUBTYPE_LONG, IDENTITY_ATTR_FIELDS, IDENTITY_ATTR_GENERATION, IDENTITY_ATTR_UNIQUE, GENERATION_INCREMENT, GENERATION_UUID, FIELD_ATTR_AUTO_SET, } from "@metaobjectsdev/metadata";
7
+ import {} from "../render-context.js";
8
+ import { crossEntitySpecifier } from "../import-path.js";
9
+ import { mapColumnType } from "../column-mapper.js";
10
+ import { tableNameFromEntity, variableNameFromEntity, columnNameFromField } from "../naming.js";
11
+ import { renderRelationsBlock } from "./relations-block.js";
12
+ /**
13
+ * Render the Drizzle table definition for one entity, including:
14
+ * - FK .references() on FK columns derived from relationship children
15
+ * - relations() block at the end of the section
16
+ *
17
+ * Returns a Code object so ts-poet can deduplicate imports when this composes
18
+ * with the rest of the entity file. Biome formatting runs after composition.
19
+ */
20
+ export function renderDrizzleSchema(obj, ctx) {
21
+ const dialect = ctx.dialect;
22
+ const tableFn = dialect === "sqlite" ? "sqliteTable" : "pgTable";
23
+ const importModule = dialect === "sqlite" ? "drizzle-orm/sqlite-core" : "drizzle-orm/pg-core";
24
+ const tableFnSym = imp(`${tableFn}@${importModule}`);
25
+ const tableName = obj.dbTable ?? tableNameFromEntity(obj.name, ctx.columnNamingStrategy);
26
+ const varName = variableNameFromEntity(obj.name);
27
+ const primary = obj.primaryIdentity();
28
+ const rawPkFields = primary?.ownAttr(IDENTITY_ATTR_FIELDS);
29
+ const pkFieldsList = Array.isArray(rawPkFields)
30
+ ? rawPkFields
31
+ : typeof rawPkFields === "string"
32
+ ? rawPkFields.split(",").map((f) => f.trim()).filter(Boolean)
33
+ : [];
34
+ const pkFieldNames = new Set(pkFieldsList);
35
+ const pkGeneration = primary?.ownAttr(IDENTITY_ATTR_GENERATION);
36
+ const fkMap = buildFkMapForEntity(obj, ctx);
37
+ const isComposite = pkFieldNames.size > 1;
38
+ // Collect secondary identities and the field names that need .unique() on
39
+ // their column. Only single-column UNIQUE identities propagate .unique() to
40
+ // the column — non-unique indexes emit a separate index() callback entry
41
+ // (handled below) and must not stamp .unique() on the underlying column.
42
+ const secondaryIdentities = obj.secondaryIdentities();
43
+ const uniqueFieldNames = new Set();
44
+ for (const sec of secondaryIdentities) {
45
+ const uniqueAttr = sec.ownAttr(IDENTITY_ATTR_UNIQUE);
46
+ if (uniqueAttr === false)
47
+ continue; // explicit non-unique → don't mark column
48
+ const fields = sec.ownAttr(IDENTITY_ATTR_FIELDS);
49
+ if (!Array.isArray(fields) || fields.length !== 1)
50
+ continue; // multi-col uniques use a callback index, not a column flag
51
+ uniqueFieldNames.add(fields[0]);
52
+ }
53
+ const columnLines = [];
54
+ for (const child of obj.fields()) {
55
+ const isPk = pkFieldNames.has(child.name);
56
+ const isUnique = uniqueFieldNames.has(child.name) && !isPk;
57
+ const fkInfo = fkMap.get(child.name);
58
+ columnLines.push(renderColumn(child, ctx, isPk, pkGeneration, fkInfo, isComposite, isUnique, obj.package));
59
+ }
60
+ // Build all table callback entries
61
+ const callbackEntries = [];
62
+ if (isComposite && primary !== undefined) {
63
+ callbackEntries.push(buildCompositeKeyCallback(pkFieldNames, importModule));
64
+ }
65
+ for (const sec of secondaryIdentities) {
66
+ const fields = sec.ownAttr(IDENTITY_ATTR_FIELDS);
67
+ if (!Array.isArray(fields) || fields.length === 0)
68
+ continue;
69
+ const indexName = `idx_${tableName}_${fields.map((f) => columnNameFromField(f, ctx.columnNamingStrategy)).join("_")}`;
70
+ // @unique on the identity defaults to true (preserves back-compat with
71
+ // foundations fixtures that assumed secondary identities were always
72
+ // unique). Explicit @unique: false → ordinary non-unique index.
73
+ const uniqueAttr = sec.ownAttr(IDENTITY_ATTR_UNIQUE);
74
+ const isUnique = uniqueAttr !== false;
75
+ const indexFn = isUnique ? "uniqueIndex" : "index";
76
+ const indexSym = imp(`${indexFn}@${importModule}`);
77
+ // Use the callback param `table` (not the outer varName) so TS doesn't see
78
+ // the table referencing itself inside its own initializer (TS7022/TS7024).
79
+ const cols = fields.map((f) => `table.${f}`).join(", ");
80
+ callbackEntries.push(code `${indexSym}(${JSON.stringify(indexName)}).on(${cols})`);
81
+ }
82
+ let tableBlock;
83
+ if (callbackEntries.length > 0) {
84
+ tableBlock = code `
85
+ export const ${varName} = ${tableFnSym}(${JSON.stringify(tableName)}, {
86
+ ${joinCode(columnLines, { on: ",\n", trim: false })}
87
+ }, (table) => [
88
+ ${joinCode(callbackEntries, { on: ",\n ", trim: false })}
89
+ ]);
90
+ `;
91
+ }
92
+ else {
93
+ tableBlock = code `
94
+ export const ${varName} = ${tableFnSym}(${JSON.stringify(tableName)}, {
95
+ ${joinCode(columnLines, { on: ",\n", trim: false })}
96
+ });
97
+ `;
98
+ }
99
+ // Emit the relations() block (returns null if no relations).
100
+ const relationsBlock = renderRelationsBlock(obj, ctx);
101
+ if (relationsBlock === null) {
102
+ return tableBlock;
103
+ }
104
+ return joinCode([tableBlock, relationsBlock], { on: "\n" });
105
+ }
106
+ /** Pre-pass: map fkFieldName → FkInfo for this entity's effective (own + inherited) identity.reference children. */
107
+ function buildFkMapForEntity(obj, ctx) {
108
+ const result = new Map();
109
+ for (const ref of obj.referenceIdentities()) {
110
+ // @enforce: false → logical-only reference. Skip the .references() emission;
111
+ // the column stays plain. Drizzle's relations() block (driven by
112
+ // relation-resolver) still includes the relationship for query navigation.
113
+ if (!ref.enforce)
114
+ continue;
115
+ const fkFieldNames = ref.fields;
116
+ if (fkFieldNames.length === 0)
117
+ continue;
118
+ const fkField = fkFieldNames[0];
119
+ const targetName = ref.targetEntity;
120
+ if (!targetName)
121
+ continue;
122
+ const targetObj = ctx.loadedRoot.findObject(targetName);
123
+ if (!targetObj)
124
+ continue;
125
+ const targetPkField = ref.resolvedTargetPkField(ctx.loadedRoot) ?? "id";
126
+ result.set(fkField, {
127
+ targetVarName: variableNameFromEntity(targetObj.name),
128
+ targetEntityName: targetObj.name,
129
+ targetPkField,
130
+ });
131
+ }
132
+ return result;
133
+ }
134
+ /**
135
+ * Build the `primaryKey({ columns: [table.f1, table.f2] })` Code expression
136
+ * for composite primary keys. Uses imp() so ts-poet tracks the import.
137
+ */
138
+ function buildCompositeKeyCallback(pkFieldNames, importModule) {
139
+ const primaryKeySym = imp(`primaryKey@${importModule}`);
140
+ const columnRefs = Array.from(pkFieldNames)
141
+ .map((f) => `table.${f}`)
142
+ .join(", ");
143
+ return code `${primaryKeySym}({ columns: [${columnRefs}] })`;
144
+ }
145
+ /** Build a JS-style object literal string (not JSON.stringify which uses quoted keys). */
146
+ function inlineObjectLiteral(obj) {
147
+ const entries = Object.entries(obj).map(([k, v]) => `${k}: ${JSON.stringify(v)}`);
148
+ return `{ ${entries.join(", ")} }`;
149
+ }
150
+ /** Render one column line (field name + Drizzle column expression). */
151
+ function renderColumn(field, ctx, isPk, pkGeneration, fkInfo, isComposite, isUnique = false, entityPackage = undefined) {
152
+ const spec = mapColumnType(field, ctx.dialect, ctx.columnNamingStrategy);
153
+ const fnSym = imp(`${spec.fnName}@${spec.importModule}`);
154
+ const dbNameLit = JSON.stringify(spec.dbName);
155
+ let baseCall;
156
+ if (spec.fnOptions !== undefined && Object.keys(spec.fnOptions).length > 0) {
157
+ baseCall = code `${fnSym}(${dbNameLit}, ${inlineObjectLiteral(spec.fnOptions)})`;
158
+ }
159
+ else {
160
+ baseCall = code `${fnSym}(${dbNameLit})`;
161
+ }
162
+ let pkSuffix = "";
163
+ if (isPk) {
164
+ if (pkGeneration === GENERATION_INCREMENT) {
165
+ if (ctx.dialect === "sqlite") {
166
+ // Composite PKs don't use .primaryKey() per-column; table callback owns it.
167
+ pkSuffix = isComposite ? "" : ".primaryKey({ autoIncrement: true })";
168
+ }
169
+ else {
170
+ // Postgres: bigserial for long (8-byte), serial for int (4-byte).
171
+ if (field.subType === FIELD_SUBTYPE_LONG) {
172
+ const bigserialSym = imp(`bigserial@${spec.importModule}`);
173
+ baseCall = code `${bigserialSym}(${dbNameLit}, { mode: "number" })`;
174
+ }
175
+ else {
176
+ const serialSym = imp(`serial@${spec.importModule}`);
177
+ baseCall = code `${serialSym}(${dbNameLit})`;
178
+ }
179
+ pkSuffix = isComposite ? "" : ".primaryKey()";
180
+ }
181
+ }
182
+ else if (pkGeneration === GENERATION_UUID) {
183
+ pkSuffix = isComposite
184
+ ? ""
185
+ : ctx.dialect === "sqlite"
186
+ ? ".primaryKey().$defaultFn(() => crypto.randomUUID())"
187
+ : ".primaryKey().defaultRandom()";
188
+ }
189
+ else {
190
+ // No generation: natural PK. Composite hands off to table callback.
191
+ pkSuffix = isComposite ? "" : ".primaryKey()";
192
+ }
193
+ }
194
+ let modifiersStr = pkSuffix;
195
+ // Append .unique() for secondary-identity fields (isPk guard already excluded PKs upstream).
196
+ if (isUnique)
197
+ modifiersStr += ".unique()";
198
+ for (const m of spec.modifiers) {
199
+ // Single-column PKs imply notNull/unique; avoid emitting them twice.
200
+ // Composite-PK columns are NOT declared with .primaryKey(), so they DO need .notNull().
201
+ if (isPk && !isComposite && (m === ".notNull()" || m === ".unique()"))
202
+ continue;
203
+ // Avoid double-emitting .unique() if it was already appended above.
204
+ if (isUnique && m === ".unique()")
205
+ continue;
206
+ modifiersStr += m;
207
+ }
208
+ // sqlDefaultSegment must be a Code segment (not a raw string) so ts-poet tracks
209
+ // the `sql` import via imp(); a raw `.default(sql`...`)` would leave `sql`
210
+ // unresolved in the generated file.
211
+ let sqlDefaultSegment = null;
212
+ if (spec.defaultExpr !== undefined && !isPk) {
213
+ if (spec.defaultExpr.kind === "now") {
214
+ if (ctx.dialect === "sqlite") {
215
+ const sqlSym = imp("sql@drizzle-orm");
216
+ sqlDefaultSegment = code `.default(${sqlSym}\`CURRENT_TIMESTAMP\`)`;
217
+ }
218
+ else {
219
+ modifiersStr += `.defaultNow()`;
220
+ }
221
+ }
222
+ else if (spec.defaultExpr.kind === "sqlExpr") {
223
+ const sqlSym = imp("sql@drizzle-orm");
224
+ // Raw SQL keyword/expression — emit as sql`<raw>` for both dialects.
225
+ sqlDefaultSegment = code `.default(${sqlSym}\`${spec.defaultExpr.raw}\`)`;
226
+ }
227
+ else {
228
+ // literal
229
+ modifiersStr += `.default(${JSON.stringify(spec.defaultExpr.value)})`;
230
+ }
231
+ }
232
+ // FK .references() uses imp() so ts-poet tracks the cross-entity import.
233
+ let fkRefSegment = null;
234
+ if (fkInfo !== undefined && !isPk) {
235
+ const targetSpec = crossEntitySpecifier(ctx.outputLayout, entityPackage, ctx.packageOf.get(fkInfo.targetEntityName), fkInfo.targetEntityName, ctx.extStyle);
236
+ const targetVarSym = imp(`${fkInfo.targetVarName}@${targetSpec}`);
237
+ fkRefSegment = code `.references(() => ${targetVarSym}.${fkInfo.targetPkField})`;
238
+ }
239
+ // @autoSet fields: emit .$defaultFn(() => new Date().toISOString()) so Drizzle
240
+ // inserts stamp the server-side timestamp automatically. This means callers don't
241
+ // need to supply createdAt / updatedAt in INSERT calls — Drizzle fills them in.
242
+ const autoSet = field.ownAttr(FIELD_ATTR_AUTO_SET);
243
+ const autoSetSuffix = (autoSet === "onCreate" || autoSet === "onUpdate")
244
+ ? `.$defaultFn(() => new Date().toISOString())`
245
+ : "";
246
+ const columnLine = code ` ${field.name}: ${baseCall}${modifiersStr}${autoSetSuffix}${sqlDefaultSegment ?? ""}${fkRefSegment ?? ""}`;
247
+ return spec.leadingComment !== undefined
248
+ ? code ` // ${spec.leadingComment}\n${columnLine}`
249
+ : columnLine;
250
+ }
251
+ //# sourceMappingURL=drizzle-schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"drizzle-schema.js","sourceRoot":"","sources":["../../src/templates/drizzle-schema.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import { type Code } from "ts-poet";
2
+ import { MetaObject } from "@metaobjectsdev/metadata";
3
+ export declare function renderEntityConstants(obj: MetaObject, apiPrefix?: string): Code;
4
+ //# sourceMappingURL=entity-constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entity-constants.d.ts","sourceRoot":"","sources":["../../src/templates/entity-constants.ts"],"names":[],"mappings":"AA8BA,OAAO,EAAQ,KAAK,IAAI,EAAE,MAAM,SAAS,CAAC;AAE1C,OAAO,EAAE,UAAU,EAAa,MAAM,0BAA0B,CAAC;AA+KjE,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,UAAU,EAAE,SAAS,SAAK,GAAG,IAAI,CAwC3E"}
@@ -0,0 +1,215 @@
1
+ // Entity-constants template — emits an `<Entity>` const with all the
2
+ // metadata-derived strings consumers should use INSTEAD of magic strings.
3
+ //
4
+ // Shape (each non-$-prefixed key is a per-field object):
5
+ //
6
+ // export const Subscriber = {
7
+ // $entity: "Subscriber",
8
+ // $table: "subscribers",
9
+ // $path: "/subscribers",
10
+ //
11
+ // email: {
12
+ // name: "email",
13
+ // label: "Email Address", // from @label on the view, falls back to humanized field name
14
+ // view: "text", // MetaView subtype
15
+ // htmlType: "email", // optional; only when it maps to a real HTML input type
16
+ // placeholder: "you@example.com", // optional; only when @placeholder is set on the view
17
+ // helpText: "We never share this.", // optional; only when @helpText is set
18
+ // rules: { // optional; derived from validator children
19
+ // required: "Email is required",
20
+ // maxLength: { value: 255, message: "Must be 255 characters or fewer" },
21
+ // pattern: { value: /.../, message: "Invalid email" },
22
+ // },
23
+ // },
24
+ // // ...
25
+ // } as const;
26
+ //
27
+ // Consumers spread `form.input.email` from useEntityForm and never touch
28
+ // per-attribute access (placeholder, rules, etc.) by hand — the helper
29
+ // picks them up from this object automatically.
30
+ import { code } from "ts-poet";
31
+ import { MetaObject, MetaField } from "@metaobjectsdev/metadata";
32
+ import { VIEW_SUBTYPE_TEXT, VIEW_SUBTYPE_TEXTAREA, VIEW_SUBTYPE_NUMBER, VIEW_SUBTYPE_CHECKBOX, VIEW_SUBTYPE_DATE, VIEW_SUBTYPE_PASSWORD, VIEW_SUBTYPE_HIDDEN, VIEW_SUBTYPE_DROPDOWN, VIEW_SUBTYPE_RADIO, VALIDATOR_SUBTYPE_REQUIRED, VALIDATOR_SUBTYPE_LENGTH, VALIDATOR_SUBTYPE_REGEX, VALIDATOR_ATTR_MIN, VALIDATOR_ATTR_MAX, VALIDATOR_ATTR_PATTERN, FIELD_ATTR_MAX_LENGTH, FIELD_ATTR_REQUIRED, } from "@metaobjectsdev/metadata";
33
+ import { resolveTableName, pluralize, toSnakeCase } from "@metaobjectsdev/metadata";
34
+ import { inferViewKind, currencyMetaFor, labelFor } from "./field-meta.js";
35
+ /** Convert a camelCase or PascalCase field name to a human-friendly label. */
36
+ function humanize(s) {
37
+ return s
38
+ .replace(/([a-z])([A-Z])/g, "$1 $2")
39
+ .replace(/_/g, " ")
40
+ .replace(/\b\w/g, (c) => c.toUpperCase())
41
+ .trim();
42
+ }
43
+ /**
44
+ * REST resource path for an entity. Pluralized + snake_cased + lowercased.
45
+ * "Subscriber" → "/subscribers"
46
+ * "WorkoutEvent" → "/workout_events"
47
+ */
48
+ function resourcePath(entity) {
49
+ const overrideAttr = entity.ownAttr("routePath");
50
+ if (typeof overrideAttr === "string" && overrideAttr.length > 0) {
51
+ return overrideAttr.startsWith("/") ? overrideAttr : `/${overrideAttr}`;
52
+ }
53
+ return `/${pluralize(toSnakeCase(entity.name))}`;
54
+ }
55
+ /** Resolve the view subtype: explicit `view` child (own or inherited) wins, else inferred from field subType. */
56
+ function resolveView(field) {
57
+ const viewChild = field.views()[0];
58
+ if (viewChild) {
59
+ return { view: viewChild.subType, viewNode: viewChild };
60
+ }
61
+ return { view: inferViewKind(field) };
62
+ }
63
+ /**
64
+ * Map a MetaView subtype to a real HTML <input type=...> value. Returns
65
+ * undefined for views that don't map to <input> at all (textarea, dropdown,
66
+ * radio) — consumers render the right element type themselves.
67
+ */
68
+ function htmlTypeFromView(view, override) {
69
+ if (typeof override === "string" && override.length > 0)
70
+ return override;
71
+ switch (view) {
72
+ case VIEW_SUBTYPE_TEXT:
73
+ return "text";
74
+ case VIEW_SUBTYPE_NUMBER:
75
+ return "number";
76
+ case VIEW_SUBTYPE_DATE:
77
+ return "date";
78
+ case VIEW_SUBTYPE_PASSWORD:
79
+ return "password";
80
+ case VIEW_SUBTYPE_CHECKBOX:
81
+ return "checkbox";
82
+ case VIEW_SUBTYPE_HIDDEN:
83
+ return "hidden";
84
+ case VIEW_SUBTYPE_RADIO:
85
+ return "radio";
86
+ case "month":
87
+ return "month";
88
+ case "email":
89
+ return "email";
90
+ case VIEW_SUBTYPE_TEXTAREA:
91
+ case VIEW_SUBTYPE_DROPDOWN:
92
+ return undefined;
93
+ default:
94
+ return undefined;
95
+ }
96
+ }
97
+ /**
98
+ * Build RHF rules JSON-ish code from a field's validator children plus
99
+ * field-level attrs (`@required`, `@maxLength`). Returns the code string
100
+ * (e.g. `{ required: "X", maxLength: { value: 255, message: "..." } }`)
101
+ * or undefined when there are no rules to emit.
102
+ */
103
+ function renderFieldRules(field) {
104
+ const ruleParts = [];
105
+ let hasRequired = false;
106
+ let hasMaxLength = false;
107
+ for (const child of field.validators()) {
108
+ if (child.subType === VALIDATOR_SUBTYPE_REQUIRED) {
109
+ const msg = child.ownAttr("message") ?? `${humanize(field.name)} is required`;
110
+ ruleParts.push(`required: ${JSON.stringify(msg)}`);
111
+ hasRequired = true;
112
+ }
113
+ else if (child.subType === VALIDATOR_SUBTYPE_LENGTH) {
114
+ const min = child.ownAttr(VALIDATOR_ATTR_MIN);
115
+ const max = child.ownAttr(VALIDATOR_ATTR_MAX);
116
+ if (typeof min === "number") {
117
+ const msg = child.ownAttr("minMessage") ?? `Must be at least ${min} characters`;
118
+ ruleParts.push(`minLength: { value: ${min}, message: ${JSON.stringify(msg)} }`);
119
+ }
120
+ if (typeof max === "number") {
121
+ const msg = child.ownAttr("maxMessage") ?? `Must be ${max} characters or fewer`;
122
+ ruleParts.push(`maxLength: { value: ${max}, message: ${JSON.stringify(msg)} }`);
123
+ hasMaxLength = true;
124
+ }
125
+ }
126
+ else if (child.subType === VALIDATOR_SUBTYPE_REGEX) {
127
+ const pattern = child.ownAttr(VALIDATOR_ATTR_PATTERN);
128
+ if (typeof pattern === "string") {
129
+ const msg = child.ownAttr("message") ?? "Invalid format";
130
+ // Emit as RegExp literal /.../ — `as const` preserves the value-ref.
131
+ // Forward-slash inside the pattern is escaped so the literal closes correctly.
132
+ const safe = pattern.replace(/\\/g, "\\\\").replace(/\//g, "\\/");
133
+ ruleParts.push(`pattern: { value: /${safe}/, message: ${JSON.stringify(msg)} }`);
134
+ }
135
+ }
136
+ }
137
+ // Field-level @required attr (if not already covered by validator).
138
+ if (!hasRequired && field.ownAttr(FIELD_ATTR_REQUIRED) === true) {
139
+ ruleParts.push(`required: ${JSON.stringify(`${humanize(field.name)} is required`)}`);
140
+ }
141
+ // Field-level @maxLength attr (if not already covered).
142
+ const maxLenAttr = field.ownAttr(FIELD_ATTR_MAX_LENGTH);
143
+ if (!hasMaxLength && typeof maxLenAttr === "number") {
144
+ ruleParts.push(`maxLength: { value: ${maxLenAttr}, message: ${JSON.stringify(`Must be ${maxLenAttr} characters or fewer`)} }`);
145
+ }
146
+ if (ruleParts.length === 0)
147
+ return undefined;
148
+ return `{ ${ruleParts.join(", ")} }`;
149
+ }
150
+ /** Build one nested field-object entry like `email: { name, label, ... },`. */
151
+ function renderFieldEntry(field) {
152
+ const { view, viewNode } = resolveView(field);
153
+ const label = labelFor(field);
154
+ const placeholder = viewNode?.ownAttr("placeholder");
155
+ const helpText = viewNode?.ownAttr("helpText");
156
+ const htmlType = htmlTypeFromView(view, viewNode?.ownAttr("htmlType"));
157
+ const rules = renderFieldRules(field);
158
+ const entries = [
159
+ `name: ${JSON.stringify(field.name)}`,
160
+ `label: ${JSON.stringify(label)}`,
161
+ `view: ${JSON.stringify(view)}`,
162
+ ];
163
+ if (htmlType !== undefined)
164
+ entries.push(`htmlType: ${JSON.stringify(htmlType)}`);
165
+ if (placeholder !== undefined)
166
+ entries.push(`placeholder: ${JSON.stringify(placeholder)}`);
167
+ if (helpText !== undefined)
168
+ entries.push(`helpText: ${JSON.stringify(helpText)}`);
169
+ if (rules !== undefined)
170
+ entries.push(`rules: ${rules}`);
171
+ // Currency-specific keys: only emitted for currency-subtype fields.
172
+ const currencyMeta = currencyMetaFor(field);
173
+ if (currencyMeta !== null) {
174
+ entries.push(`currency: ${JSON.stringify(currencyMeta.currency)}`);
175
+ entries.push(`locale: ${JSON.stringify(currencyMeta.locale)}`);
176
+ }
177
+ return ` ${field.name}: {\n ${entries.join(",\n ")},\n }`;
178
+ }
179
+ export function renderEntityConstants(obj, apiPrefix = "") {
180
+ const entityName = obj.name;
181
+ const tableName = resolveTableName(obj);
182
+ const path = resourcePath(obj);
183
+ const fieldEntries = [];
184
+ // Use fields() so inherited fields (from extends:/super:) appear in constants.
185
+ for (const child of obj.fields()) {
186
+ fieldEntries.push(renderFieldEntry(child));
187
+ }
188
+ const body = [
189
+ ` $entity: ${JSON.stringify(entityName)}`,
190
+ ` $table: ${JSON.stringify(tableName)}`,
191
+ ` $path: ${JSON.stringify(path)}`,
192
+ ` $apiPrefix: ${JSON.stringify(apiPrefix)}`,
193
+ ...fieldEntries,
194
+ ].join(",\n");
195
+ return code `
196
+ /**
197
+ * Metadata constants for ${entityName}.
198
+ *
199
+ * Use these instead of magic strings so TS catches typos and refactors stay
200
+ * coherent. Each non-dollar-prefixed key is a per-field object carrying
201
+ * name, label, view, optional htmlType/placeholder/helpText, and the
202
+ * RHF-shaped validation rules derived from the field's validator children.
203
+ *
204
+ * Typical usage with the metaobjects React form helper:
205
+ *
206
+ * import { useEntityForm } from '@metaobjectsdev/react';
207
+ * const form = useEntityForm(${entityName}, ${entityName}InsertSchema);
208
+ * <input {...form.input.${fieldEntries[0]?.match(/^\s*(\w+):/)?.[1] ?? "fieldName"}} />
209
+ */
210
+ export const ${entityName} = {
211
+ ${body},
212
+ } as const;
213
+ `;
214
+ }
215
+ //# sourceMappingURL=entity-constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entity-constants.js","sourceRoot":"","sources":["../../src/templates/entity-constants.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { MetaObject } from "@metaobjectsdev/metadata";
2
+ import type { RenderContext } from "../render-context.js";
3
+ export declare function renderEntityFile(entity: MetaObject, ctx: RenderContext): string;
4
+ //# sourceMappingURL=entity-file.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entity-file.d.ts","sourceRoot":"","sources":["../../src/templates/entity-file.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAW1D,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,UAAU,EAAE,GAAG,EAAE,aAAa,GAAG,MAAM,CA8B/E"}
@@ -0,0 +1,45 @@
1
+ // Entity file composer — combines drizzle-schema, inferred-types, and zod-validators
2
+ // into one file with the @generated header. ts-poet deduplicates imports.
3
+ //
4
+ // Dispatch:
5
+ // isProjection(entity) → renderProjectionDecl (read-only: view declaration + Zod + filter sections)
6
+ // vanilla / write-through entity → Drizzle table path
7
+ import { joinCode } from "ts-poet";
8
+ import { renderDrizzleSchema } from "./drizzle-schema.js";
9
+ import { renderInferredTypes } from "./inferred-types.js";
10
+ import { renderZodValidators } from "./zod-validators.js";
11
+ import { renderEntityConstants } from "./entity-constants.js";
12
+ import { renderFilterAllowlist, renderSortAllowlist } from "./filter-allowlist.js";
13
+ import { renderFilterType } from "./filter-type.js";
14
+ import { GENERATED_HEADER } from "../constants.js";
15
+ import { isProjection } from "../projection/projection-detector.js";
16
+ import { renderProjectionDecl } from "./projection-decl.js";
17
+ export function renderEntityFile(entity, ctx) {
18
+ // --- Projection path (read-only: view-backed entity with no table source) ---
19
+ if (isProjection(entity)) {
20
+ return renderProjectionDecl(entity, ctx.loadedRoot, {
21
+ columnNamingStrategy: ctx.columnNamingStrategy,
22
+ dialect: ctx.dialect,
23
+ apiPrefix: ctx.apiPrefix,
24
+ });
25
+ }
26
+ // --- Vanilla / write-through entity path ---
27
+ const sections = [
28
+ renderDrizzleSchema(entity, ctx),
29
+ renderInferredTypes(entity),
30
+ renderZodValidators(entity),
31
+ renderEntityConstants(entity, ctx.apiPrefix),
32
+ renderFilterAllowlist(entity),
33
+ renderSortAllowlist(entity),
34
+ renderFilterType(entity),
35
+ ];
36
+ // Render ts-poet body first (ts-poet hoists imp()-tracked imports to the top),
37
+ // then prepend the @generated header so it lands at line 1 — convention for
38
+ // generated files and what most tooling (overwrite-policy, IDEs) expects.
39
+ const body = joinCode(sections, { on: "\n" }).toString();
40
+ const header = `// ${GENERATED_HEADER} — DO NOT EDIT.\n` +
41
+ `// Source metadata: ${entity.name} (${entity.fqn()})\n` +
42
+ `// Customize via ${entity.name}.extra.ts in this directory.\n`;
43
+ return header + body;
44
+ }
45
+ //# sourceMappingURL=entity-file.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entity-file.js","sourceRoot":"","sources":["../../src/templates/entity-file.ts"],"names":[],"mappings":"AAAA,qFAAqF;AACrF,0EAA0E;AAC1E,EAAE;AACF,YAAY;AACZ,uGAAuG;AACvG,wDAAwD;AAExD,OAAO,EAAE,QAAQ,EAAa,MAAM,SAAS,CAAC;AAG9C,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AACnF,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,sCAAsC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAE5D,MAAM,UAAU,gBAAgB,CAAC,MAAkB,EAAE,GAAkB;IACrE,+EAA+E;IAC/E,IAAI,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC;QACzB,OAAO,oBAAoB,CAAC,MAAM,EAAE,GAAG,CAAC,UAAU,EAAE;YAClD,oBAAoB,EAAE,GAAG,CAAC,oBAAoB;YAC9C,OAAO,EAAE,GAAG,CAAC,OAAO;YACpB,SAAS,EAAE,GAAG,CAAC,SAAS;SACzB,CAAC,CAAC;IACL,CAAC;IAED,8CAA8C;IAC9C,MAAM,QAAQ,GAAW;QACvB,mBAAmB,CAAC,MAAM,EAAE,GAAG,CAAC;QAChC,mBAAmB,CAAC,MAAM,CAAC;QAC3B,mBAAmB,CAAC,MAAM,CAAC;QAC3B,qBAAqB,CAAC,MAAM,EAAE,GAAG,CAAC,SAAS,CAAC;QAC5C,qBAAqB,CAAC,MAAM,CAAC;QAC7B,mBAAmB,CAAC,MAAM,CAAC;QAC3B,gBAAgB,CAAC,MAAM,CAAC;KACzB,CAAC;IAEF,+EAA+E;IAC/E,4EAA4E;IAC5E,0EAA0E;IAC1E,MAAM,IAAI,GAAG,QAAQ,CAAC,QAAQ,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;IACzD,MAAM,MAAM,GACV,MAAM,gBAAgB,mBAAmB;QACzC,uBAAuB,MAAM,CAAC,IAAI,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK;QACxD,oBAAoB,MAAM,CAAC,IAAI,gCAAgC,CAAC;IAClE,OAAO,MAAM,GAAG,IAAI,CAAC;AACvB,CAAC"}
@@ -0,0 +1,24 @@
1
+ import { MetaField } from "@metaobjectsdev/metadata";
2
+ /**
3
+ * Resolve the cell-renderer key (view kind) for a field.
4
+ * Explicit view child wins; field subType determines default.
5
+ */
6
+ export declare function inferViewKind(field: MetaField): string;
7
+ /**
8
+ * Resolve the Zod validator expression for a field's storage type.
9
+ */
10
+ export declare function zodTypeFor(field: MetaField): string;
11
+ /**
12
+ * Resolve currency code + locale for a currency-subtype field.
13
+ * Returns null for non-currency fields.
14
+ */
15
+ export declare function currencyMetaFor(field: MetaField): {
16
+ currency: string;
17
+ locale: string;
18
+ } | null;
19
+ /**
20
+ * Resolve the human-readable label for a field.
21
+ * Uses @label attr on a view child if present; otherwise humanizes the field name.
22
+ */
23
+ export declare function labelFor(field: MetaField): string;
24
+ //# sourceMappingURL=field-meta.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"field-meta.d.ts","sourceRoot":"","sources":["../../src/templates/field-meta.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AA8BrD;;;GAGG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,CAMtD;AA6BD;;GAEG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,CAwBnD;AAMD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,SAAS,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAS7F;AAMD;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,CAMjD"}