|
| 1 | +// #213 — the write-side codegen must exclude a derived (origin-bearing) field, in |
| 2 | +// lockstep with migrate-ts dropping it from the write-table DDL: otherwise the |
| 3 | +// generated Drizzle table declares a column, and the Insert/Update Zod schemas |
| 4 | +// accept a field, that no longer exists on the physical write table. |
| 5 | + |
| 6 | +import { describe, test, expect } from "bun:test"; |
| 7 | +import { MetaDataLoader, InMemoryStringSource } from "@metaobjectsdev/metadata"; |
| 8 | +import { renderDrizzleSchema } from "../../src/templates/drizzle-schema.js"; |
| 9 | +import { renderZodValidators } from "../../src/templates/zod-validators.js"; |
| 10 | +import { makeRenderContext } from "../../src/render-context.js"; |
| 11 | +import { buildPkMap } from "../../src/pk-resolver.js"; |
| 12 | +import { buildRelationMap } from "../../src/relation-resolver.js"; |
| 13 | + |
| 14 | +async function loadWriteThroughOrder() { |
| 15 | + const json = JSON.stringify({ |
| 16 | + "metadata.root": { |
| 17 | + package: "acme", |
| 18 | + children: [ |
| 19 | + { "object.entity": { name: "Customer", children: [ |
| 20 | + { "source.rdb": { "@table": "customers" } }, |
| 21 | + { "field.long": { name: "id" } }, |
| 22 | + { "field.string": { name: "name" } }, |
| 23 | + { "identity.primary": { name: "pk", "@fields": "id" } }, |
| 24 | + ] } }, |
| 25 | + { "object.entity": { name: "Order", children: [ |
| 26 | + { "source.rdb": { "@role": "primary", "@table": "orders" } }, |
| 27 | + { "source.rdb": { "@role": "replica", "@kind": "view", "@table": "v_order" } }, |
| 28 | + { "field.long": { name: "id" } }, |
| 29 | + { "field.long": { name: "customerId", "@required": true } }, |
| 30 | + { "field.string": { name: "customerName", children: [ |
| 31 | + { "origin.passthrough": { "@from": "Customer.name", "@via": "Order.customer" } } ] } }, |
| 32 | + { "relationship.association": { name: "customer", "@objectRef": "Customer", "@cardinality": "one" } }, |
| 33 | + { "identity.primary": { name: "pk", "@fields": "id" } }, |
| 34 | + { "identity.reference": { name: "ref_customer", "@fields": "customerId", "@references": "Customer" } }, |
| 35 | + ] } }, |
| 36 | + ], |
| 37 | + }, |
| 38 | + }); |
| 39 | + const { root, errors } = await new MetaDataLoader().load([new InMemoryStringSource(json)]); |
| 40 | + expect(errors).toEqual([]); |
| 41 | + const order = root.objects().find((o) => o.name === "Order")!; |
| 42 | + const ctx = makeRenderContext({ |
| 43 | + dialect: "postgres", loadedRoot: root, outDir: "/x", dbImport: "~/db", |
| 44 | + pkMap: buildPkMap(root), relationMap: buildRelationMap(root), |
| 45 | + }); |
| 46 | + return { order, ctx }; |
| 47 | +} |
| 48 | + |
| 49 | +describe("#213 — write-side codegen excludes derived fields", () => { |
| 50 | + test("Drizzle table def omits the derived customerName column", async () => { |
| 51 | + const { order, ctx } = await loadWriteThroughOrder(); |
| 52 | + const out = renderDrizzleSchema(order, ctx).toString(); |
| 53 | + expect(out).toContain("customerId"); // stored FK stays |
| 54 | + expect(out).not.toContain("customerName"); // derived join column excluded |
| 55 | + }); |
| 56 | + |
| 57 | + test("Insert + Update Zod schemas omit the derived customerName field", async () => { |
| 58 | + const { order, ctx } = await loadWriteThroughOrder(); |
| 59 | + const out = renderZodValidators(order, ctx).toString(); |
| 60 | + expect(out).toContain("OrderInsertSchema"); |
| 61 | + expect(out).toContain("customerId"); |
| 62 | + expect(out).not.toContain("customerName"); |
| 63 | + }); |
| 64 | +}); |
0 commit comments