@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,115 @@
1
+ // Queries template — individual CRUD function renderers.
2
+ // Each returns a ts-poet Code block; composed into a file by queries-file.ts.
3
+ import { code, imp } from "ts-poet";
4
+ import { IDENTITY_ATTR_FIELDS } from "@metaobjectsdev/metadata";
5
+ import { variableNameFromEntity, toSnakeCase, pluralize } from "../naming.js";
6
+ /** Derive a stable prepared statement name. Deterministic from entity + field names. */
7
+ function prepareName(prefix, entitySnakeName, fieldDbName) {
8
+ return `${prefix}_${entitySnakeName}_by_${fieldDbName}`;
9
+ }
10
+ /** Get the PK field name and its TS type for a given entity. */
11
+ function getPkInfo(entity, ctx) {
12
+ // Use primaryIdentity() to find the primary identity (may be inherited from extends:/super:).
13
+ const primary = entity.primaryIdentity();
14
+ const rawFields = primary?.ownAttr(IDENTITY_ATTR_FIELDS);
15
+ const fields = Array.isArray(rawFields) ? rawFields : (typeof rawFields === "string" ? [rawFields] : undefined);
16
+ const pkFieldName = fields?.[0] ?? "id";
17
+ const pkInfo = ctx.pkMap.get(entity.name);
18
+ const subType = pkInfo?.fieldSubType ?? "long";
19
+ const tsType = subType === "long" || subType === "int" || subType === "short" || subType === "byte"
20
+ ? "number"
21
+ : subType === "boolean"
22
+ ? "boolean"
23
+ : "string";
24
+ return { fieldName: pkFieldName, tsType };
25
+ }
26
+ export function renderFindByIdFn(entity, ctx) {
27
+ const varName = variableNameFromEntity(entity.name);
28
+ const entityName = entity.name;
29
+ const singularVar = entityName.charAt(0).toLowerCase() + entityName.slice(1);
30
+ const entitySnakeName = toSnakeCase(entityName);
31
+ const { fieldName: pkField, tsType: pkType } = getPkInfo(entity, ctx);
32
+ const pkSnakeName = toSnakeCase(pkField);
33
+ const prepName = prepareName("find", entitySnakeName, pkSnakeName);
34
+ const fnName = `find${entityName}ById`;
35
+ const prepVarName = `${fnName}Prepared`;
36
+ const eqSym = imp("eq@drizzle-orm");
37
+ const sqlSym = imp("sql@drizzle-orm");
38
+ const baseVarName = `${fnName}Base`;
39
+ // Drizzle's `.prepare()` signature differs by dialect:
40
+ // - Postgres: prepare(name) — the name is used by the pg driver to cache the plan
41
+ // - SQLite: prepare() — no name; the name arg was removed in drizzle-orm 0.41+
42
+ const prepArg = ctx.dialect === "postgres" ? `"${prepName}"` : "";
43
+ return code `
44
+ const ${baseVarName} = db
45
+ .select()
46
+ .from(${varName})
47
+ .where(${eqSym}(${varName}.${pkField}, ${sqlSym}.placeholder(${JSON.stringify(pkField)})));
48
+ const ${prepVarName} = ${baseVarName}.prepare(${prepArg});
49
+
50
+ export async function ${fnName}(${pkField}: ${pkType}): Promise<${entityName} | null> {
51
+ const [${singularVar}] = await ${prepVarName}.execute({ ${pkField} });
52
+ return ${singularVar} ?? null;
53
+ }
54
+ `;
55
+ }
56
+ export function renderListFn(entity, _ctx) {
57
+ const varName = variableNameFromEntity(entity.name);
58
+ const entityName = entity.name;
59
+ // Pluralize the PascalCase entity name, preserving capitalization
60
+ // (e.g., "Category" -> "Categories", not "Categorys").
61
+ const fnName = `list${pluralize(entityName)}`;
62
+ return code `
63
+ export async function ${fnName}(opts?: { limit?: number; offset?: number }): Promise<${entityName}[]> {
64
+ let q = db.select().from(${varName}).$dynamic();
65
+ if (opts?.limit !== undefined) q = q.limit(opts.limit);
66
+ if (opts?.offset !== undefined) q = q.offset(opts.offset);
67
+ return q;
68
+ }
69
+ `;
70
+ }
71
+ export function renderCreateFn(entity, _ctx) {
72
+ const varName = variableNameFromEntity(entity.name);
73
+ const entityName = entity.name;
74
+ const singularVar = entityName.charAt(0).toLowerCase() + entityName.slice(1);
75
+ const fnName = `create${entityName}`;
76
+ const schemaName = `${entityName}InsertSchema`;
77
+ return code `
78
+ export async function ${fnName}(data: unknown): Promise<${entityName}> {
79
+ const validated = ${schemaName}.parse(data);
80
+ const [${singularVar}] = await db.insert(${varName}).values(validated).returning();
81
+ return ${singularVar}!;
82
+ }
83
+ `;
84
+ }
85
+ export function renderUpdateFn(entity, ctx) {
86
+ const varName = variableNameFromEntity(entity.name);
87
+ const entityName = entity.name;
88
+ const singularVar = entityName.charAt(0).toLowerCase() + entityName.slice(1);
89
+ const { fieldName: pkField, tsType: pkType } = getPkInfo(entity, ctx);
90
+ const fnName = `update${entityName}`;
91
+ const schemaName = `${entityName}InsertSchema`;
92
+ const eqSym = imp("eq@drizzle-orm");
93
+ return code `
94
+ export async function ${fnName}(${pkField}: ${pkType}, data: unknown): Promise<${entityName} | null> {
95
+ const validated = ${schemaName}.partial().parse(data);
96
+ const [${singularVar}] = await db.update(${varName}).set(validated).where(${eqSym}(${varName}.${pkField}, ${pkField})).returning();
97
+ return ${singularVar} ?? null;
98
+ }
99
+ `;
100
+ }
101
+ export function renderDeleteByIdFn(entity, ctx) {
102
+ const varName = variableNameFromEntity(entity.name);
103
+ const entityName = entity.name;
104
+ const { fieldName: pkField, tsType: pkType } = getPkInfo(entity, ctx);
105
+ const fnName = `delete${entityName}ById`;
106
+ const eqSym = imp("eq@drizzle-orm");
107
+ return code `
108
+ export async function ${fnName}(${pkField}: ${pkType}): Promise<boolean> {
109
+ const result = await db.delete(${varName}).where(${eqSym}(${varName}.${pkField}, ${pkField}));
110
+ // SQLite (libsql/Turso) returns { rowsAffected }; postgres returns array from .returning()
111
+ return ('rowsAffected' in result ? result.rowsAffected : (result as unknown as unknown[]).length) > 0;
112
+ }
113
+ `;
114
+ }
115
+ //# sourceMappingURL=queries.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queries.js","sourceRoot":"","sources":["../../src/templates/queries.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import { type Code } from "ts-poet";
2
+ import type { MetaObject } from "@metaobjectsdev/metadata";
3
+ import { type RenderContext } from "../render-context.js";
4
+ /**
5
+ * Render the relations() block for one entity.
6
+ * Returns null if the entity has no relations to emit.
7
+ */
8
+ export declare function renderRelationsBlock(entity: MetaObject, ctx: RenderContext): Code | null;
9
+ //# sourceMappingURL=relations-block.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relations-block.d.ts","sourceRoot":"","sources":["../../src/templates/relations-block.ts"],"names":[],"mappings":"AAGA,OAAO,EAAuB,KAAK,IAAI,EAAE,MAAM,SAAS,CAAC;AACzD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAE3D,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAK1D;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,UAAU,EAAE,GAAG,EAAE,aAAa,GAAG,IAAI,GAAG,IAAI,CAyBxF"}
@@ -0,0 +1,45 @@
1
+ // Relations block template — emits the Drizzle relations() block for one entity.
2
+ // Derived from the RelationMap pre-pass (relation-resolver.ts).
3
+ import { code, imp, joinCode } from "ts-poet";
4
+ import { CARDINALITY_ONE, CARDINALITY_MANY } from "@metaobjectsdev/metadata";
5
+ import {} from "../render-context.js";
6
+ import { crossEntitySpecifier } from "../import-path.js";
7
+ import { variableNameFromEntity } from "../naming.js";
8
+ /**
9
+ * Render the relations() block for one entity.
10
+ * Returns null if the entity has no relations to emit.
11
+ */
12
+ export function renderRelationsBlock(entity, ctx) {
13
+ const entries = ctx.relationMap.get(entity.name);
14
+ if (!entries || entries.length === 0)
15
+ return null;
16
+ const varName = variableNameFromEntity(entity.name);
17
+ const relationsFn = imp("relations@drizzle-orm");
18
+ const relationsVarName = `${varName}Relations`;
19
+ const hasOne = entries.some((e) => e.cardinality === CARDINALITY_ONE);
20
+ const hasMany = entries.some((e) => e.cardinality === CARDINALITY_MANY);
21
+ const paramParts = [];
22
+ if (hasOne)
23
+ paramParts.push("one");
24
+ if (hasMany)
25
+ paramParts.push("many");
26
+ const params = `{ ${paramParts.join(", ")} }`;
27
+ const thisEntityPackage = entity.package;
28
+ const lines = entries.map((entry) => renderRelationEntry(entry, ctx, varName, thisEntityPackage));
29
+ return code `export const ${relationsVarName} = ${relationsFn}(${varName}, (${params}) => ({
30
+ ${joinCode(lines, { on: ",\n", trim: false })}
31
+ }));
32
+ `;
33
+ }
34
+ function renderRelationEntry(entry, ctx, thisVarName, thisEntityPackage) {
35
+ // Use imp() for cross-entity references so ts-poet tracks and emits the import.
36
+ const targetSpec = crossEntitySpecifier(ctx.outputLayout, thisEntityPackage, ctx.packageOf.get(entry.targetEntity), entry.targetEntity, ctx.extStyle);
37
+ const targetVarSym = imp(`${variableNameFromEntity(entry.targetEntity)}@${targetSpec}`);
38
+ if (entry.cardinality === CARDINALITY_ONE) {
39
+ const pkInfo = ctx.pkMap.get(entry.targetEntity);
40
+ const targetPkField = pkInfo?.fieldName ?? "id";
41
+ return code ` ${entry.name}: one(${targetVarSym}, { fields: [${thisVarName}.${entry.fkField ?? "id"}], references: [${targetVarSym}.${targetPkField}] })`;
42
+ }
43
+ return code ` ${entry.name}: many(${targetVarSym})`;
44
+ }
45
+ //# sourceMappingURL=relations-block.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relations-block.js","sourceRoot":"","sources":["../../src/templates/relations-block.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 renderRoutesFile(entity: MetaObject, ctx: RenderContext): string;
4
+ //# sourceMappingURL=routes-file.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routes-file.d.ts","sourceRoot":"","sources":["../../src/templates/routes-file.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAM1D,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,UAAU,EAAE,GAAG,EAAE,aAAa,GAAG,MAAM,CAyJ/E"}
@@ -0,0 +1,158 @@
1
+ // Fastify route template — emits a per-entity routes file that delegates
2
+ // CRUD verbs to helpers from @metaobjectsdev/runtime-ts/drizzle-fastify.
3
+ //
4
+ // Dispatch logic:
5
+ // isProjection(entity) → mountReadOnlyCrudRoutes (GET list + GET :id only)
6
+ // vanilla / write-through entity → mountCrudRoutes (all 5 CRUD verbs)
7
+ //
8
+ // apiPrefix behaviour:
9
+ // "" → flat mount: mountCrudRoutes({ fastify, ... })
10
+ // "/api" → wrapped: fastify.register(async (instance) => {
11
+ // mountCrudRoutes({ fastify: instance, ... });
12
+ // }, { prefix: "/api" });
13
+ //
14
+ // The user's Drizzle `db` instance is imported from ctx.dbImport (matching
15
+ // the existing queries-file template). The entity's Drizzle table const is
16
+ // imported alongside the Zod schemas + constants from the sibling Entity.ts.
17
+ import { code, imp } from "ts-poet";
18
+ import {} from "../render-context.js";
19
+ import { entityModuleSpecifier, relativeModuleSpecifier } from "../import-path.js";
20
+ import { GENERATED_HEADER } from "../constants.js";
21
+ import { variableNameFromEntity } from "../naming.js";
22
+ import { isProjection } from "../projection/projection-detector.js";
23
+ export function renderRoutesFile(entity, ctx) {
24
+ const entityName = entity.name;
25
+ const handlerName = `${entityName.charAt(0).toLowerCase()}${entityName.slice(1)}Routes`;
26
+ // Import the entity's own file. Same target → relative "./Entity"; cross
27
+ // target → importBase-qualified package path.
28
+ const entityFileSpec = entityModuleSpecifier(ctx.selfTarget, ctx.entityModuleTarget, entity.package, entityName, ctx.extStyle);
29
+ const dbImportSpec = relativeModuleSpecifier(ctx.outputLayout, entity.package, ctx.dbImport);
30
+ const header = `// ${GENERATED_HEADER} — DO NOT EDIT.\n` +
31
+ `// Source metadata: ${entityName} (${entity.fqn()})\n` +
32
+ `// Customize via ${entityName}.extra.ts in this directory (e.g., auth, additional handlers).\n`;
33
+ // --- Projection path: read-only routes (GET list + GET :id) ---
34
+ if (isProjection(entity)) {
35
+ const camelName = entityName.charAt(0).toLowerCase() + entityName.slice(1);
36
+ const FastifyInstanceSym = imp("t:FastifyInstance@fastify");
37
+ const mountReadOnlyCrudRoutesSym = imp("mountReadOnlyCrudRoutes@@metaobjectsdev/runtime-ts/drizzle-fastify");
38
+ const literalImports = code `
39
+ import { db } from ${JSON.stringify(dbImportSpec)};
40
+ import {
41
+ ${entityName},
42
+ ${camelName}View,
43
+ ${entityName}FilterAllowlist,
44
+ ${entityName}SortAllowlist,
45
+ } from ${JSON.stringify(entityFileSpec)};
46
+ `;
47
+ const body = ctx.apiPrefix
48
+ ? code `
49
+ /**
50
+ * Mount read-only REST endpoints for ${entityName} (projection — view-backed, no writes).
51
+ *
52
+ * Exposes GET list + GET :id only. POST/PATCH/DELETE return 405.
53
+ * Customize: register this as-is, or import individual route helpers from
54
+ * @metaobjectsdev/runtime-ts/drizzle-fastify.
55
+ */
56
+ export async function ${handlerName}(fastify: ${FastifyInstanceSym}) {
57
+ await fastify.register(async (instance) => {
58
+ ${mountReadOnlyCrudRoutesSym}({
59
+ fastify: instance,
60
+ path: ${entityName}.$path,
61
+ db,
62
+ view: ${camelName}View,
63
+ filterAllowlist: ${entityName}FilterAllowlist,
64
+ sortAllowlist: ${entityName}SortAllowlist,
65
+ dialect: ${JSON.stringify(ctx.dialect)},
66
+ });
67
+ }, { prefix: ${JSON.stringify(ctx.apiPrefix)} });
68
+ }
69
+ `
70
+ : code `
71
+ /**
72
+ * Mount read-only REST endpoints for ${entityName} (projection — view-backed, no writes).
73
+ *
74
+ * Exposes GET list + GET :id only. POST/PATCH/DELETE return 405.
75
+ * Customize: register this as-is, or import individual route helpers from
76
+ * @metaobjectsdev/runtime-ts/drizzle-fastify.
77
+ */
78
+ export async function ${handlerName}(fastify: ${FastifyInstanceSym}) {
79
+ ${mountReadOnlyCrudRoutesSym}({
80
+ fastify,
81
+ path: ${entityName}.$path,
82
+ db,
83
+ view: ${camelName}View,
84
+ filterAllowlist: ${entityName}FilterAllowlist,
85
+ sortAllowlist: ${entityName}SortAllowlist,
86
+ dialect: ${JSON.stringify(ctx.dialect)},
87
+ });
88
+ }
89
+ `;
90
+ return header + literalImports.toString() + body.toString();
91
+ }
92
+ // --- Vanilla / write-through entity path: full CRUD routes ---
93
+ const tableVar = variableNameFromEntity(entityName);
94
+ const FastifyInstanceSym = imp("t:FastifyInstance@fastify");
95
+ const mountCrudRoutesSym = imp("mountCrudRoutes@@metaobjectsdev/runtime-ts/drizzle-fastify");
96
+ const literalImports = code `
97
+ import { db } from ${JSON.stringify(dbImportSpec)};
98
+ import {
99
+ ${entityName},
100
+ ${tableVar},
101
+ ${entityName}InsertSchema,
102
+ ${entityName}UpdateSchema,
103
+ ${entityName}FilterAllowlist,
104
+ ${entityName}SortAllowlist,
105
+ } from ${JSON.stringify(entityFileSpec)};
106
+ `;
107
+ const body = ctx.apiPrefix
108
+ ? code `
109
+ /**
110
+ * Mount the 5 standard REST endpoints for ${entityName} using Drizzle directly.
111
+ *
112
+ * Customize: register this as-is for stock CRUD, OR import the per-verb
113
+ * helpers (mountListRoute, mountGetRoute, ...) from
114
+ * @metaobjectsdev/runtime-ts/drizzle-fastify and mix with your own handlers
115
+ * (auth, side effects, etc.).
116
+ */
117
+ export async function ${handlerName}(fastify: ${FastifyInstanceSym}) {
118
+ await fastify.register(async (instance) => {
119
+ ${mountCrudRoutesSym}({
120
+ fastify: instance,
121
+ path: ${entityName}.$path,
122
+ db,
123
+ table: ${tableVar},
124
+ insertSchema: ${entityName}InsertSchema,
125
+ updateSchema: ${entityName}UpdateSchema,
126
+ filterAllowlist: ${entityName}FilterAllowlist,
127
+ sortAllowlist: ${entityName}SortAllowlist,
128
+ dialect: ${JSON.stringify(ctx.dialect)},
129
+ });
130
+ }, { prefix: ${JSON.stringify(ctx.apiPrefix)} });
131
+ }
132
+ `
133
+ : code `
134
+ /**
135
+ * Mount the 5 standard REST endpoints for ${entityName} using Drizzle directly.
136
+ *
137
+ * Customize: register this as-is for stock CRUD, OR import the per-verb
138
+ * helpers (mountListRoute, mountGetRoute, ...) from
139
+ * @metaobjectsdev/runtime-ts/drizzle-fastify and mix with your own handlers
140
+ * (auth, side effects, etc.).
141
+ */
142
+ export async function ${handlerName}(fastify: ${FastifyInstanceSym}) {
143
+ ${mountCrudRoutesSym}({
144
+ fastify,
145
+ path: ${entityName}.$path,
146
+ db,
147
+ table: ${tableVar},
148
+ insertSchema: ${entityName}InsertSchema,
149
+ updateSchema: ${entityName}UpdateSchema,
150
+ filterAllowlist: ${entityName}FilterAllowlist,
151
+ sortAllowlist: ${entityName}SortAllowlist,
152
+ dialect: ${JSON.stringify(ctx.dialect)},
153
+ });
154
+ }
155
+ `;
156
+ return header + literalImports.toString() + body.toString();
157
+ }
158
+ //# sourceMappingURL=routes-file.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routes-file.js","sourceRoot":"","sources":["../../src/templates/routes-file.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 renderZodValidators(obj: MetaObject): Code;
4
+ //# sourceMappingURL=zod-validators.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"zod-validators.d.ts","sourceRoot":"","sources":["../../src/templates/zod-validators.ts"],"names":[],"mappings":"AAKA,OAAO,EAAa,KAAK,IAAI,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAa,MAAM,0BAA0B,CAAC;AAajE,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,UAAU,GAAG,IAAI,CA0DzD"}
@@ -0,0 +1,129 @@
1
+ // Zod validators template — emits InsertSchema (for create) and UpdateSchema (for update).
2
+ // Auto-generated PKs are EXCLUDED from InsertSchema (caller doesn't provide them).
3
+ // @autoSet fields: INSERT → .optional().transform(() => new Date().toISOString())
4
+ // UPDATE → onCreate fields omitted entirely; onUpdate gets same transform
5
+ import { code, imp } from "ts-poet";
6
+ import { MetaObject, MetaField } from "@metaobjectsdev/metadata";
7
+ import { FIELD_SUBTYPE_STRING, FIELD_SUBTYPE_INT, FIELD_SUBTYPE_LONG, FIELD_SUBTYPE_CURRENCY, FIELD_SUBTYPE_BOOLEAN, FIELD_SUBTYPE_DOUBLE, FIELD_SUBTYPE_FLOAT, FIELD_SUBTYPE_DATE, FIELD_SUBTYPE_TIME, FIELD_SUBTYPE_TIMESTAMP, VALIDATOR_SUBTYPE_REQUIRED, VALIDATOR_SUBTYPE_LENGTH, VALIDATOR_SUBTYPE_REGEX, IDENTITY_ATTR_FIELDS, IDENTITY_ATTR_GENERATION, FIELD_ATTR_REQUIRED, FIELD_ATTR_MAX_LENGTH, FIELD_ATTR_DEFAULT, FIELD_ATTR_AUTO_SET, AUTO_SET_ON_CREATE, AUTO_SET_ON_UPDATE, VALIDATOR_ATTR_MAX, VALIDATOR_ATTR_MIN, VALIDATOR_ATTR_PATTERN, GENERATION_INCREMENT, GENERATION_UUID, } from "@metaobjectsdev/metadata";
8
+ export function renderZodValidators(obj) {
9
+ const z = imp("z@zod");
10
+ const primary = obj.primaryIdentity();
11
+ const autoGenPkFields = new Set();
12
+ if (primary) {
13
+ const generation = primary.ownAttr(IDENTITY_ATTR_GENERATION);
14
+ if (generation === GENERATION_INCREMENT || generation === GENERATION_UUID) {
15
+ const fields = primary.ownAttr(IDENTITY_ATTR_FIELDS);
16
+ const fieldsList = Array.isArray(fields) ? fields : (typeof fields === "string" ? [fields] : []);
17
+ for (const f of fieldsList)
18
+ autoGenPkFields.add(String(f));
19
+ }
20
+ }
21
+ const insertFieldLines = [];
22
+ const updateFieldLines = [];
23
+ for (const child of obj.fields()) {
24
+ if (autoGenPkFields.has(child.name))
25
+ continue;
26
+ const autoSet = child.ownAttr(FIELD_ATTR_AUTO_SET);
27
+ // Insert schema: @autoSet fields use transform (always override client input).
28
+ // NOTE: use "z" as a literal string here — these lines are embedded in the
29
+ // `code` template tag below which resolves the imp("z@zod") import.
30
+ if (autoSet === AUTO_SET_ON_CREATE || autoSet === AUTO_SET_ON_UPDATE) {
31
+ insertFieldLines.push(` ${child.name}: z.string().optional().transform(() => new Date().toISOString())`);
32
+ }
33
+ else {
34
+ insertFieldLines.push(` ${child.name}: ${zodFieldExpr(child)}`);
35
+ }
36
+ // Update schema: @autoSet onCreate → omit entirely; onUpdate → transform
37
+ if (autoSet === AUTO_SET_ON_CREATE) {
38
+ // Omit: creation timestamps cannot be changed after creation
39
+ }
40
+ else if (autoSet === AUTO_SET_ON_UPDATE) {
41
+ updateFieldLines.push(` ${child.name}: z.string().optional().transform(() => new Date().toISOString())`);
42
+ }
43
+ else {
44
+ // All non-autoSet fields are optional in the update schema (PATCH semantics)
45
+ const expr = zodFieldExpr(child);
46
+ const optionalExpr = expr.endsWith(".optional()") ? expr : `${expr}.optional()`;
47
+ updateFieldLines.push(` ${child.name}: ${optionalExpr}`);
48
+ }
49
+ }
50
+ const insertSchemaName = `${obj.name}InsertSchema`;
51
+ const updateSchemaName = `${obj.name}UpdateSchema`;
52
+ return code `
53
+ export const ${insertSchemaName} = ${z}.object({
54
+ ${insertFieldLines.join(",\n")}
55
+ });
56
+
57
+ export const ${updateSchemaName} = ${z}.object({
58
+ ${updateFieldLines.join(",\n")}
59
+ });
60
+ `;
61
+ }
62
+ function zodFieldExpr(field) {
63
+ let base;
64
+ switch (field.subType) {
65
+ case FIELD_SUBTYPE_INT:
66
+ case FIELD_SUBTYPE_CURRENCY:
67
+ case FIELD_SUBTYPE_LONG:
68
+ base = "z.number().int()";
69
+ break;
70
+ case FIELD_SUBTYPE_DOUBLE:
71
+ case FIELD_SUBTYPE_FLOAT:
72
+ base = "z.number()";
73
+ break;
74
+ case FIELD_SUBTYPE_BOOLEAN:
75
+ base = "z.boolean()";
76
+ break;
77
+ case FIELD_SUBTYPE_DATE:
78
+ case FIELD_SUBTYPE_TIME:
79
+ case FIELD_SUBTYPE_TIMESTAMP:
80
+ base = "z.string()";
81
+ break;
82
+ case FIELD_SUBTYPE_STRING:
83
+ default:
84
+ base = "z.string()";
85
+ break;
86
+ }
87
+ if (field.isArray)
88
+ base = `z.array(${base})`;
89
+ let isRequired = field.ownAttr(FIELD_ATTR_REQUIRED) === true;
90
+ let maxLen = field.ownAttr(FIELD_ATTR_MAX_LENGTH);
91
+ let minLen;
92
+ let pattern;
93
+ for (const child of field.validators()) {
94
+ if (child.subType === VALIDATOR_SUBTYPE_REQUIRED)
95
+ isRequired = true;
96
+ if (child.subType === VALIDATOR_SUBTYPE_LENGTH) {
97
+ const max = child.ownAttr(VALIDATOR_ATTR_MAX);
98
+ const min = child.ownAttr(VALIDATOR_ATTR_MIN);
99
+ if (typeof max === "number")
100
+ maxLen = max;
101
+ if (typeof min === "number")
102
+ minLen = min;
103
+ }
104
+ if (child.subType === VALIDATOR_SUBTYPE_REGEX) {
105
+ const p = child.ownAttr(VALIDATOR_ATTR_PATTERN);
106
+ if (typeof p === "string")
107
+ pattern = p;
108
+ }
109
+ }
110
+ let chain = base;
111
+ if (field.subType === FIELD_SUBTYPE_STRING && !field.isArray) {
112
+ if (minLen !== undefined)
113
+ chain += `.min(${minLen})`;
114
+ else if (isRequired)
115
+ chain += `.min(1)`;
116
+ if (maxLen !== undefined)
117
+ chain += `.max(${maxLen})`;
118
+ if (pattern !== undefined)
119
+ chain += `.regex(new RegExp(${JSON.stringify(pattern)}))`;
120
+ }
121
+ // Fields with DB-level defaults are optional in the InsertSchema: the caller
122
+ // can omit them and the DB will fill in. Otherwise required-with-default
123
+ // would force callers to repeat the default at every call site.
124
+ const hasDefault = field.ownAttr(FIELD_ATTR_DEFAULT) !== undefined;
125
+ if (!isRequired || hasDefault)
126
+ chain += `.optional()`;
127
+ return chain;
128
+ }
129
+ //# sourceMappingURL=zod-validators.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"zod-validators.js","sourceRoot":"","sources":["../../src/templates/zod-validators.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,59 @@
1
+ {
2
+ "name": "@metaobjectsdev/codegen-ts",
3
+ "version": "0.5.0-rc.1",
4
+ "description": "TypeScript codegen engine for MetaObjects — emits Drizzle, Zod, and Fastify artifacts.",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "bun": "./src/index.ts",
11
+ "types": "./dist/index.d.ts",
12
+ "default": "./dist/index.js"
13
+ },
14
+ "./generators": {
15
+ "bun": "./src/generators/index.ts",
16
+ "types": "./dist/generators/index.d.ts",
17
+ "default": "./dist/generators/index.js"
18
+ }
19
+ },
20
+ "files": ["dist", "src", "README.md", "LICENSE"],
21
+ "scripts": {
22
+ "build": "tsc -p .",
23
+ "typecheck": "tsc -p tsconfig.typecheck.json"
24
+ },
25
+ "license": "Apache-2.0",
26
+ "author": "Doug Mealing <doug@dougmealing.com>",
27
+ "homepage": "https://metaobjects.dev",
28
+ "bugs": {
29
+ "url": "https://github.com/metaobjectsdev/metaobjects/issues"
30
+ },
31
+ "repository": {
32
+ "type": "git",
33
+ "url": "https://github.com/metaobjectsdev/metaobjects.git",
34
+ "directory": "server/typescript/packages/codegen-ts"
35
+ },
36
+ "keywords": ["metaobjects", "codegen", "drizzle", "zod", "fastify", "typescript"],
37
+ "publishConfig": {
38
+ "access": "public"
39
+ },
40
+ "dependencies": {
41
+ "@metaobjectsdev/metadata": "0.5.0",
42
+ "ts-poet": "^6.10.0"
43
+ },
44
+ "peerDependencies": {
45
+ "drizzle-orm": ">=0.36.0",
46
+ "zod": ">=3.23.0",
47
+ "@biomejs/biome": ">=1.9.0"
48
+ },
49
+ "devDependencies": {
50
+ "@biomejs/biome": "^1.9.0",
51
+ "@biomejs/js-api": "^0.7.0",
52
+ "@biomejs/wasm-nodejs": "^1.9.4",
53
+ "@metaobjectsdev/codegen-ts-react": "0.5.0",
54
+ "bun-types": "latest",
55
+ "drizzle-orm": "^0.36.0",
56
+ "typescript": "^5.6.0",
57
+ "zod": "^3.23.0"
58
+ }
59
+ }