@prisma-next/target-postgres 0.13.0 → 0.14.0-dev.2
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.
- package/dist/{codec-ids-CTikp1if.mjs → codec-ids-BvytN2P8.mjs} +3 -3
- package/dist/codec-ids-BvytN2P8.mjs.map +1 -0
- package/dist/{codec-ids-B1vOchLE.d.mts → codec-ids-CnXu9Qy3.d.mts} +3 -3
- package/dist/codec-ids-CnXu9Qy3.d.mts.map +1 -0
- package/dist/codec-ids.d.mts +2 -2
- package/dist/codec-ids.mjs +2 -2
- package/dist/{codec-types-CnFiNML4.d.mts → codec-types-DHCkwPKE.d.mts} +3 -3
- package/dist/{codec-types-CnFiNML4.d.mts.map → codec-types-DHCkwPKE.d.mts.map} +1 -1
- package/dist/codec-types.d.mts +1 -1
- package/dist/{codecs-CBpEv4s5.d.mts → codecs--0A5_4Bq.d.mts} +26 -23
- package/dist/codecs--0A5_4Bq.d.mts.map +1 -0
- package/dist/codecs.d.mts +2 -2
- package/dist/codecs.mjs +28 -35
- package/dist/codecs.mjs.map +1 -1
- package/dist/contract-free.d.mts +163 -15
- package/dist/contract-free.d.mts.map +1 -1
- package/dist/contract-free.mjs +4 -17
- package/dist/contract-free.mjs.map +1 -1
- package/dist/control.d.mts.map +1 -1
- package/dist/control.mjs +21 -27
- package/dist/control.mjs.map +1 -1
- package/dist/{data-transform-D25tLeYU.mjs → data-transform-BOWpliq8.mjs} +9 -17
- package/dist/data-transform-BOWpliq8.mjs.map +1 -0
- package/dist/{data-transform-DGOqcLrf.d.mts → data-transform-DDgWdB5o.d.mts} +2 -2
- package/dist/data-transform-DDgWdB5o.d.mts.map +1 -0
- package/dist/data-transform.d.mts +1 -1
- package/dist/data-transform.mjs +1 -1
- package/dist/ddl-QDyOSeLc.mjs +251 -0
- package/dist/ddl-QDyOSeLc.mjs.map +1 -0
- package/dist/ddl.d.mts +2 -2
- package/dist/ddl.mjs +2 -2
- package/dist/descriptor-meta-CpGygXpI.mjs +140 -0
- package/dist/descriptor-meta-CpGygXpI.mjs.map +1 -0
- package/dist/{issue-planner-Br0pt1Ea.mjs → issue-planner-DL6g3CmE.mjs} +52 -366
- package/dist/issue-planner-DL6g3CmE.mjs.map +1 -0
- package/dist/issue-planner.d.mts +8 -11
- package/dist/issue-planner.d.mts.map +1 -1
- package/dist/issue-planner.mjs +1 -1
- package/dist/migration.d.mts +5 -92
- package/dist/migration.d.mts.map +1 -1
- package/dist/migration.mjs +4 -4
- package/dist/{nodes-DZk2JZG3.mjs → nodes-Bbhs2rwj.mjs} +31 -2
- package/dist/nodes-Bbhs2rwj.mjs.map +1 -0
- package/dist/{nodes-779hmCfL.d.mts → nodes-pLeLgdis.d.mts} +30 -3
- package/dist/nodes-pLeLgdis.d.mts.map +1 -0
- package/dist/{op-factory-call-D2aAUhmS.mjs → op-factory-call-D_p5vxwt.mjs} +601 -418
- package/dist/op-factory-call-D_p5vxwt.mjs.map +1 -0
- package/dist/{op-factory-call-DMA86_2D.d.mts → op-factory-call-DmQEc3XV.d.mts} +119 -72
- package/dist/op-factory-call-DmQEc3XV.d.mts.map +1 -0
- package/dist/op-factory-call.d.mts +2 -2
- package/dist/op-factory-call.mjs +2 -2
- package/dist/pack.d.mts +36 -15
- package/dist/pack.d.mts.map +1 -1
- package/dist/pack.mjs +1 -1
- package/dist/{planner-CAYPJObw.mjs → planner-Bs_baQax.mjs} +25 -45
- package/dist/planner-Bs_baQax.mjs.map +1 -0
- package/dist/{planner-ddl-builders-Cw2n2llW.mjs → planner-ddl-builders-B2wOwLqI.mjs} +2 -2
- package/dist/planner-ddl-builders-B2wOwLqI.mjs.map +1 -0
- package/dist/planner-ddl-builders.d.mts +4 -4
- package/dist/planner-ddl-builders.d.mts.map +1 -1
- package/dist/planner-ddl-builders.mjs +1 -1
- package/dist/{planner-identity-values-BIpa5p2I.mjs → planner-identity-values-CJPha2Sz.mjs} +3 -9
- package/dist/planner-identity-values-CJPha2Sz.mjs.map +1 -0
- package/dist/planner-identity-values.d.mts +1 -1
- package/dist/planner-identity-values.d.mts.map +1 -1
- package/dist/planner-identity-values.mjs +1 -1
- package/dist/{planner-produced-postgres-migration-NSEhWL0L.mjs → planner-produced-postgres-migration-Cji5vxUf.mjs} +6 -4
- package/dist/planner-produced-postgres-migration-Cji5vxUf.mjs.map +1 -0
- package/dist/{planner-produced-postgres-migration-B4EDvLdz.d.mts → planner-produced-postgres-migration-QqHa2C2l.d.mts} +5 -6
- package/dist/planner-produced-postgres-migration-QqHa2C2l.d.mts.map +1 -0
- package/dist/planner-produced-postgres-migration.d.mts +1 -1
- package/dist/planner-produced-postgres-migration.mjs +1 -1
- package/dist/planner-sql-checks-jqUUGyQR.mjs +152 -0
- package/dist/planner-sql-checks-jqUUGyQR.mjs.map +1 -0
- package/dist/planner-sql-checks.d.mts +3 -49
- package/dist/planner-sql-checks.d.mts.map +1 -1
- package/dist/planner-sql-checks.mjs +2 -2
- package/dist/{planner-type-resolution-836DExFN.mjs → planner-type-resolution-Bt2f_q-F.mjs} +1 -6
- package/dist/planner-type-resolution-Bt2f_q-F.mjs.map +1 -0
- package/dist/planner.d.mts +4 -4
- package/dist/planner.d.mts.map +1 -1
- package/dist/planner.mjs +1 -1
- package/dist/{postgres-contract-serializer-DYTyXjPf.mjs → postgres-contract-serializer-k3TAcPMY.mjs} +30 -37
- package/dist/postgres-contract-serializer-k3TAcPMY.mjs.map +1 -0
- package/dist/postgres-migration-B5jKrXv3.mjs +145 -0
- package/dist/postgres-migration-B5jKrXv3.mjs.map +1 -0
- package/dist/postgres-migration-Y4YBJqkS.d.mts +181 -0
- package/dist/postgres-migration-Y4YBJqkS.d.mts.map +1 -0
- package/dist/{postgres-schema-BuxCxbvB.mjs → postgres-schema-COGZ1ark.mjs} +82 -23
- package/dist/postgres-schema-COGZ1ark.mjs.map +1 -0
- package/dist/{render-ops-BpjstrKQ.mjs → render-ops-BREh1kHe.mjs} +10 -5
- package/dist/render-ops-BREh1kHe.mjs.map +1 -0
- package/dist/render-ops.d.mts +2 -2
- package/dist/render-ops.d.mts.map +1 -1
- package/dist/render-ops.mjs +1 -1
- package/dist/runtime.d.mts +1 -0
- package/dist/runtime.d.mts.map +1 -1
- package/dist/runtime.mjs +2 -2
- package/dist/table-source-BvFo7gVs.d.mts +15 -0
- package/dist/table-source-BvFo7gVs.d.mts.map +1 -0
- package/dist/types.d.mts +34 -19
- package/dist/types.d.mts.map +1 -1
- package/dist/types.mjs +2 -3
- package/package.json +17 -18
- package/src/contract-free/checks.ts +363 -0
- package/src/contract-free/ddl.ts +28 -1
- package/src/core/authoring.ts +43 -44
- package/src/core/codec-helpers.ts +0 -17
- package/src/core/codec-ids.ts +1 -1
- package/src/core/codec-type-map.ts +2 -2
- package/src/core/codecs.ts +43 -48
- package/src/core/ddl/nodes.ts +59 -1
- package/src/core/migrations/control-policy.ts +17 -47
- package/src/core/migrations/issue-planner.ts +34 -70
- package/src/core/migrations/op-factory-call.ts +486 -215
- package/src/core/migrations/operations/columns.ts +175 -140
- package/src/core/migrations/operations/constraints.ts +79 -108
- package/src/core/migrations/operations/data-transform.ts +15 -18
- package/src/core/migrations/operations/dependencies.ts +16 -14
- package/src/core/migrations/operations/indexes.ts +31 -28
- package/src/core/migrations/operations/shared.ts +2 -2
- package/src/core/migrations/operations/tables.ts +13 -14
- package/src/core/migrations/planner-ddl-builders.ts +3 -4
- package/src/core/migrations/planner-identity-values.ts +4 -28
- package/src/core/migrations/planner-produced-postgres-migration.ts +15 -7
- package/src/core/migrations/planner-recipes.ts +44 -39
- package/src/core/migrations/planner-sql-checks.ts +3 -178
- package/src/core/migrations/planner-strategies.ts +76 -449
- package/src/core/migrations/planner-type-resolution.ts +2 -20
- package/src/core/migrations/planner.ts +6 -6
- package/src/core/migrations/postgres-migration.ts +287 -7
- package/src/core/migrations/render-ops.ts +26 -13
- package/src/core/migrations/runner.ts +26 -20
- package/src/core/postgres-contract-serializer.ts +37 -54
- package/src/core/postgres-enum-type-schema.ts +17 -0
- package/src/core/postgres-schema.ts +86 -46
- package/src/exports/codecs.ts +2 -2
- package/src/exports/contract-free.ts +22 -1
- package/src/exports/control.ts +0 -22
- package/src/exports/ddl.ts +4 -0
- package/src/exports/migration.ts +1 -29
- package/src/exports/op-factory-call.ts +0 -4
- package/src/exports/planner-sql-checks.ts +0 -7
- package/src/exports/types.ts +0 -1
- package/dist/codec-ids-B1vOchLE.d.mts.map +0 -1
- package/dist/codec-ids-CTikp1if.mjs.map +0 -1
- package/dist/codecs-CBpEv4s5.d.mts.map +0 -1
- package/dist/data-transform-D25tLeYU.mjs.map +0 -1
- package/dist/data-transform-DGOqcLrf.d.mts.map +0 -1
- package/dist/ddl-77SyXgFt.mjs +0 -30
- package/dist/ddl-77SyXgFt.mjs.map +0 -1
- package/dist/descriptor-meta-DKmj-IMN.mjs +0 -14
- package/dist/descriptor-meta-DKmj-IMN.mjs.map +0 -1
- package/dist/descriptor-meta-runtime-My8_s4cs.mjs +0 -130
- package/dist/descriptor-meta-runtime-My8_s4cs.mjs.map +0 -1
- package/dist/enum-planning-BCyvlFHk.mjs +0 -0
- package/dist/enum-planning-BCyvlFHk.mjs.map +0 -1
- package/dist/enum-planning.d.mts +0 -86
- package/dist/enum-planning.d.mts.map +0 -1
- package/dist/enum-planning.mjs +0 -2
- package/dist/issue-planner-Br0pt1Ea.mjs.map +0 -1
- package/dist/nodes-779hmCfL.d.mts.map +0 -1
- package/dist/nodes-DZk2JZG3.mjs.map +0 -1
- package/dist/op-factory-call-D2aAUhmS.mjs.map +0 -1
- package/dist/op-factory-call-DMA86_2D.d.mts.map +0 -1
- package/dist/planner-CAYPJObw.mjs.map +0 -1
- package/dist/planner-ddl-builders-Cw2n2llW.mjs.map +0 -1
- package/dist/planner-identity-values-BIpa5p2I.mjs.map +0 -1
- package/dist/planner-produced-postgres-migration-B4EDvLdz.d.mts.map +0 -1
- package/dist/planner-produced-postgres-migration-NSEhWL0L.mjs.map +0 -1
- package/dist/planner-sql-checks-DAdhnI2c.mjs +0 -272
- package/dist/planner-sql-checks-DAdhnI2c.mjs.map +0 -1
- package/dist/planner-type-resolution-836DExFN.mjs.map +0 -1
- package/dist/postgres-contract-serializer-DYTyXjPf.mjs.map +0 -1
- package/dist/postgres-enum-type-BVn63a89.d.mts +0 -72
- package/dist/postgres-enum-type-BVn63a89.d.mts.map +0 -1
- package/dist/postgres-enum-type-DPKqCBem.mjs +0 -62
- package/dist/postgres-enum-type-DPKqCBem.mjs.map +0 -1
- package/dist/postgres-migration-COore9Mz.mjs +0 -71
- package/dist/postgres-migration-COore9Mz.mjs.map +0 -1
- package/dist/postgres-migration-DZ_gLUOW.d.mts +0 -72
- package/dist/postgres-migration-DZ_gLUOW.d.mts.map +0 -1
- package/dist/postgres-schema-BuxCxbvB.mjs.map +0 -1
- package/dist/render-ops-BpjstrKQ.mjs.map +0 -1
- package/dist/shared-DarONYBZ.d.mts +0 -43
- package/dist/shared-DarONYBZ.d.mts.map +0 -1
- package/src/core/migrations/enum-planning.ts +0 -213
- package/src/core/migrations/operations/enums.ts +0 -114
- package/src/core/postgres-enum-type.ts +0 -89
- package/src/exports/enum-planning.ts +0 -11
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"postgres-schema-BuxCxbvB.mjs","names":[],"sources":["../src/core/postgres-schema.ts"],"sourcesContent":["import {\n freezeNode,\n NamespaceBase,\n UNBOUND_NAMESPACE_ID,\n} from '@prisma-next/framework-components/ir';\nimport {\n type PostgresEnumStorageEntry,\n type SqlNamespaceTablesInput,\n type SqlStorage,\n StorageTable,\n type StorageTableInput,\n} from '@prisma-next/sql-contract/types';\nimport { PostgresEnumType, type PostgresEnumTypeInput } from './postgres-enum-type';\nimport { escapeLiteral } from './sql-utils';\n\nexport interface PostgresSchemaInput {\n readonly id: string;\n readonly entries: {\n readonly table: Record<string, StorageTable | StorageTableInput>;\n readonly type: Record<string, PostgresEnumType | PostgresEnumTypeInput>;\n };\n}\n\n/**\n * Postgres target `Namespace` concretion — a Postgres schema (`CREATE\n * SCHEMA …`). Each Postgres `SqlStorage` carries a\n * `namespaces: Record<NamespaceId, PostgresSchema>` map populated by\n * the Postgres PSL interpreter from `namespace { … }` AST buckets.\n *\n * `entries` holds entity-kind slot maps (`table`, `type`). Qualifier\n * emission is the rendering seam: DDL / SQL emission asks the namespace\n * for its qualifier (`\"<schema>\"`) or for a qualified table name\n * (`\"<schema>\".\"<table>\"`) and consumes the result polymorphically.\n * The unbound singleton below overrides these methods to elide the\n * prefix entirely — call sites stay polymorphic and never branch on\n * `id === UNBOUND_NAMESPACE_ID`.\n */\nexport class PostgresSchema extends NamespaceBase {\n /**\n * Stable singleton reference for the late-bound slot. Materialised\n * lazily below the singleton subclass declaration so the static\n * initialiser sees the subclass before assigning. Consumers always\n * reach for `PostgresSchema.unbound` (or `PostgresUnboundSchema.instance`\n * — same identity).\n */\n static unbound: PostgresUnboundSchema;\n\n declare readonly kind: 'schema';\n readonly id: string;\n readonly entries: Readonly<{\n readonly table: Readonly<Record<string, StorageTable>>;\n readonly type: Readonly<Record<string, PostgresEnumType>>;\n }>;\n\n constructor(input: PostgresSchemaInput) {\n super();\n this.id = input.id;\n this.entries = Object.freeze({\n table: Object.freeze(\n Object.fromEntries(\n Object.entries(input.entries.table).map(([k, v]) => [\n k,\n v instanceof StorageTable ? v : new StorageTable(v as StorageTableInput),\n ]),\n ),\n ),\n type: Object.freeze(\n Object.fromEntries(\n Object.entries(input.entries.type).map(([k, v]) => [\n k,\n v instanceof PostgresEnumType ? v : new PostgresEnumType(v as PostgresEnumTypeInput),\n ]),\n ),\n ),\n });\n Object.defineProperty(this, 'kind', {\n value: 'schema',\n writable: false,\n enumerable: false,\n configurable: true,\n });\n freezeNode(this);\n }\n\n /**\n * The bare schema qualifier as it would appear in a rendered SQL\n * fragment (already quoted). The unbound-schema singleton overrides\n * this to return `''`.\n */\n qualifier(): string {\n return `\"${this.id}\"`;\n }\n\n /**\n * Qualify a table name with the schema prefix\n * (`\"<schema>\".\"<table>\"`). The unbound-schema singleton overrides\n * this to emit just `\"<table>\"` so the resolved DDL is unqualified\n * and `search_path` decides where the object lands at runtime.\n */\n qualifyTable(tableName: string): string {\n return `\"${this.id}\".\"${tableName}\"`;\n }\n\n /**\n * Render a SQL string-literal containing the qualified-name form\n * suitable for `to_regclass(...)` arguments (e.g. `'\"public\".\"user\"'`).\n * The unbound singleton overrides this to elide the schema prefix\n * (`'\"user\"'`) so `search_path` resolves the object at runtime.\n */\n regclassLiteral(name: string): string {\n return `'${escapeLiteral(this.qualifyTable(name))}'`;\n }\n\n /**\n * Render a SQL expression that evaluates to this namespace's schema\n * name at runtime, ready to drop into a `WHERE table_schema = …` /\n * `WHERE n.nspname = …` clause. Named schemas emit a quoted SQL\n * literal (`'public'`); the unbound singleton overrides this to emit\n * `current_schema()` so catalog queries match whichever schema the\n * connection's `search_path` resolved at runtime.\n */\n schemaSqlExpression(): string {\n return `'${escapeLiteral(this.id)}'`;\n }\n\n /**\n * The bare schema name a DDL planner should target when emitting\n * statements that need to identify this namespace in the live\n * database (e.g. `CREATE TABLE \"<ddlSchemaName>\".\"<table>\" …`,\n * catalog filters, planner conflict lookups). Named schemas resolve\n * to their own id. The `PostgresUnboundSchema` singleton inherits\n * this and returns `UNBOUND_NAMESPACE_ID` — callers that dispatch\n * through `qualifyTableName` / `toRegclassLiteral` route through the\n * polymorphic `PostgresUnboundSchema` overrides and produce\n * unqualified (search-path-resolved) output automatically.\n */\n ddlSchemaName(_storage: SqlStorage): string {\n return this.id;\n }\n}\n\n/**\n * Singleton subclass for the reserved sentinel namespace id\n * (`UNBOUND_NAMESPACE_ID`) — the late-bound Postgres slot whose binding\n * the connection's `search_path` resolves at runtime. Overrides\n * qualifier emission to elide the schema prefix; call sites that consume\n * `qualifier()` / `qualifyTable()` get unqualified output without\n * branching on the namespace id.\n *\n * This is the target-side materialization of \"the framework provides\n * affordances; targets implement specifics\": the framework names the\n * sentinel; Postgres decides what late-bound means here (the table\n * name, naked — the schema is supplied by the live connection's\n * `search_path`).\n *\n * `ddlSchemaName` is inherited from `PostgresSchema` and returns\n * `UNBOUND_NAMESPACE_ID`. Downstream helpers (`qualifyTableName`,\n * `toRegclassLiteral`) route through the polymorphic factory and\n * produce unqualified output automatically.\n */\nexport class PostgresUnboundSchema extends PostgresSchema {\n static readonly instance: PostgresUnboundSchema = new PostgresUnboundSchema();\n\n constructor(input?: PostgresSchemaInput) {\n super(input ?? { id: UNBOUND_NAMESPACE_ID, entries: { table: {}, type: {} } });\n }\n\n override qualifier(): string {\n return '';\n }\n\n override qualifyTable(tableName: string): string {\n return `\"${tableName}\"`;\n }\n\n override schemaSqlExpression(): string {\n return 'current_schema()';\n }\n}\n\nPostgresSchema.unbound = PostgresUnboundSchema.instance;\n\n/**\n * Narrow an arbitrary namespace (or `undefined`) to `PostgresSchema`\n * so callers can dispatch to the polymorphic emission methods without\n * branching at the call site. Uses the structural `kind` discriminator\n * (`'schema'`) rather than `instanceof` so the check survives realm /\n * bundle / hot-reload boundaries — matching the rest of the IR's\n * narrowing convention. `PostgresUnboundSchema` passes through because\n * it inherits the same `kind: 'schema'` from `PostgresSchema`.\n */\nexport function isPostgresSchema(ns: unknown): ns is PostgresSchema {\n return (ns as { kind?: unknown } | null | undefined)?.kind === 'schema';\n}\n\n/**\n * Target-supplied `Namespace` factory the Postgres target plumbs\n * through `defineContract({ createNamespace })` and the SQL PSL\n * interpreter. Returns the unbound singleton for the framework\n * sentinel and a fresh `PostgresSchema` for any other coordinate.\n *\n * The factory has no per-call state — every named id deterministically\n * maps to a distinct schema instance — so callers can pass it through\n * by reference and trust the resulting `SqlStorage.namespaces` map to\n * be value-stable for a given input set.\n */\nexport function postgresCreateNamespace(\n input: SqlNamespaceTablesInput,\n enumTypes?: Readonly<Record<string, PostgresEnumStorageEntry>>,\n): PostgresSchema {\n const schemaInput: PostgresSchemaInput = {\n id: input.id,\n entries: {\n table: input.entries.table,\n type: (enumTypes ?? {}) as Record<string, PostgresEnumTypeInput>,\n },\n };\n if (input.id === UNBOUND_NAMESPACE_ID) {\n return new PostgresUnboundSchema(schemaInput);\n }\n return new PostgresSchema(schemaInput);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAqCA,IAAa,iBAAb,cAAoC,cAAc;;;;;;;;CAQhD,OAAO;CAGP;CACA;CAKA,YAAY,OAA4B;EACtC,MAAM;EACN,KAAK,KAAK,MAAM;EAChB,KAAK,UAAU,OAAO,OAAO;GAC3B,OAAO,OAAO,OACZ,OAAO,YACL,OAAO,QAAQ,MAAM,QAAQ,KAAK,CAAC,CAAC,KAAK,CAAC,GAAG,OAAO,CAClD,GACA,aAAa,eAAe,IAAI,IAAI,aAAa,CAAsB,CACzE,CAAC,CACH,CACF;GACA,MAAM,OAAO,OACX,OAAO,YACL,OAAO,QAAQ,MAAM,QAAQ,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,OAAO,CACjD,GACA,aAAa,mBAAmB,IAAI,IAAI,iBAAiB,CAA0B,CACrF,CAAC,CACH,CACF;EACF,CAAC;EACD,OAAO,eAAe,MAAM,QAAQ;GAClC,OAAO;GACP,UAAU;GACV,YAAY;GACZ,cAAc;EAChB,CAAC;EACD,WAAW,IAAI;CACjB;;;;;;CAOA,YAAoB;EAClB,OAAO,IAAI,KAAK,GAAG;CACrB;;;;;;;CAQA,aAAa,WAA2B;EACtC,OAAO,IAAI,KAAK,GAAG,KAAK,UAAU;CACpC;;;;;;;CAQA,gBAAgB,MAAsB;EACpC,OAAO,IAAI,cAAc,KAAK,aAAa,IAAI,CAAC,EAAE;CACpD;;;;;;;;;CAUA,sBAA8B;EAC5B,OAAO,IAAI,cAAc,KAAK,EAAE,EAAE;CACpC;;;;;;;;;;;;CAaA,cAAc,UAA8B;EAC1C,OAAO,KAAK;CACd;AACF;;;;;;;;;;;;;;;;;;;;AAqBA,IAAa,wBAAb,MAAa,8BAA8B,eAAe;CACxD,OAAgB,WAAkC,IAAI,sBAAsB;CAE5E,YAAY,OAA6B;EACvC,MAAM,SAAS;GAAE,IAAI;GAAsB,SAAS;IAAE,OAAO,CAAC;IAAG,MAAM,CAAC;GAAE;EAAE,CAAC;CAC/E;CAEA,YAA6B;EAC3B,OAAO;CACT;CAEA,aAAsB,WAA2B;EAC/C,OAAO,IAAI,UAAU;CACvB;CAEA,sBAAuC;EACrC,OAAO;CACT;AACF;AAEA,eAAe,UAAU,sBAAsB;;;;;;;;;;AAW/C,SAAgB,iBAAiB,IAAmC;CAClE,OAAQ,IAA8C,SAAS;AACjE;;;;;;;;;;;;AAaA,SAAgB,wBACd,OACA,WACgB;CAChB,MAAM,cAAmC;EACvC,IAAI,MAAM;EACV,SAAS;GACP,OAAO,MAAM,QAAQ;GACrB,MAAO,aAAa,CAAC;EACvB;CACF;CACA,IAAI,MAAM,OAAO,sBACf,OAAO,IAAI,sBAAsB,WAAW;CAE9C,OAAO,IAAI,eAAe,WAAW;AACvC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"render-ops-BpjstrKQ.mjs","names":[],"sources":["../src/core/migrations/render-ops.ts"],"sourcesContent":["import type { SqlMigrationPlanOperation } from '@prisma-next/family-sql/control';\nimport type { Lowerer } from '@prisma-next/family-sql/control-adapter';\nimport type { OpFactoryCall } from '@prisma-next/framework-components/control';\nimport { blindCast } from '@prisma-next/utils/casts';\nimport type { PostgresPlanTargetDetails } from './planner-target-details';\n\ntype Op = SqlMigrationPlanOperation<PostgresPlanTargetDetails>;\n\n/**\n * Asserts an op materialised by an `OpFactoryCall` targets postgres. The\n * extension surface lets any contributor emit calls, so this is the\n * integration boundary where a stray non-postgres op would otherwise\n * silently flow through to postgres-shaped renderers — exactly the\n * place to fail loudly with op metadata (`id` + `target.id`).\n */\nfunction assertPostgresOp(\n op: ReturnType<OpFactoryCall['toOp']>,\n callFactoryName: string,\n): asserts op is Op {\n const targetId = (op as Partial<Op>).target?.id;\n if (targetId !== 'postgres') {\n throw new Error(\n `renderOps: expected postgres op but got target.id=\"${String(targetId)}\" for op.id=\"${op.id}\" (factoryName=\"${callFactoryName}\"). An OpFactoryCall produced an op for a different target on the postgres planner path; check the call's target binding.`,\n );\n }\n}\n\nexport function renderOps(calls: readonly OpFactoryCall[], lowerer?: Lowerer): Op[] {\n return calls.map((c) => {\n const op = blindCast<\n { toOp(lowerer?: Lowerer): ReturnType<OpFactoryCall['toOp']> },\n 'PG OpFactoryCall.toOp accepts an optional Lowerer; the framework interface omits it because not all targets need a lowerer — the PG target overrides with this extended signature'\n >(c).toOp(lowerer);\n assertPostgresOp(op, c.factoryName);\n return op;\n });\n}\n"],"mappings":";;;;;;;;;AAeA,SAAS,iBACP,IACA,iBACkB;CAClB,MAAM,WAAY,GAAmB,QAAQ;CAC7C,IAAI,aAAa,YACf,MAAM,IAAI,MACR,sDAAsD,OAAO,QAAQ,EAAE,eAAe,GAAG,GAAG,kBAAkB,gBAAgB,0HAChI;AAEJ;AAEA,SAAgB,UAAU,OAAiC,SAAyB;CAClF,OAAO,MAAM,KAAK,MAAM;EACtB,MAAM,KAAK,UAGT,CAAC,CAAC,CAAC,KAAK,OAAO;EACjB,iBAAiB,IAAI,EAAE,WAAW;EAClC,OAAO;CACT,CAAC;AACH"}
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import { t as PostgresPlanTargetDetails } from "./planner-target-details-CIY6tLeo.mjs";
|
|
2
|
-
import { SqlMigrationPlanOperation } from "@prisma-next/family-sql/control";
|
|
3
|
-
import { ReferentialAction } from "@prisma-next/sql-contract/types";
|
|
4
|
-
|
|
5
|
-
//#region src/core/migrations/operations/shared.d.ts
|
|
6
|
-
type Op = SqlMigrationPlanOperation<PostgresPlanTargetDetails>;
|
|
7
|
-
/**
|
|
8
|
-
* Literal-args shape for a column definition consumed by `addColumn` and
|
|
9
|
-
* similar operations. Fully materialized: codec expansion and default
|
|
10
|
-
* rendering have already happened in the wrapper.
|
|
11
|
-
*
|
|
12
|
-
* - `typeSql` is the column's DDL type string (e.g. `"integer"`, `"SERIAL"`,
|
|
13
|
-
* `"varchar(100)"`), already produced by `buildColumnTypeSql` in the
|
|
14
|
-
* call-factory wrapper.
|
|
15
|
-
* - `defaultSql` is the full `DEFAULT …` clause (e.g. `"DEFAULT 42"`) or an
|
|
16
|
-
* empty string when the column has no default, matching
|
|
17
|
-
* `buildColumnDefaultSql`'s output.
|
|
18
|
-
*/
|
|
19
|
-
interface ColumnSpec {
|
|
20
|
-
readonly name: string;
|
|
21
|
-
readonly typeSql: string;
|
|
22
|
-
readonly defaultSql: string;
|
|
23
|
-
readonly nullable: boolean;
|
|
24
|
-
}
|
|
25
|
-
/**
|
|
26
|
-
* Literal-args shape for a foreign key definition. `references.schema`
|
|
27
|
-
* carries the target table's namespace (schema) coordinate so the rendered
|
|
28
|
-
* DDL qualifies the REFERENCES clause correctly for cross-schema FKs.
|
|
29
|
-
*/
|
|
30
|
-
interface ForeignKeySpec {
|
|
31
|
-
readonly name: string;
|
|
32
|
-
readonly columns: readonly string[];
|
|
33
|
-
readonly references: {
|
|
34
|
-
readonly schema: string;
|
|
35
|
-
readonly table: string;
|
|
36
|
-
readonly columns: readonly string[];
|
|
37
|
-
};
|
|
38
|
-
readonly onDelete?: ReferentialAction;
|
|
39
|
-
readonly onUpdate?: ReferentialAction;
|
|
40
|
-
}
|
|
41
|
-
//#endregion
|
|
42
|
-
export { ForeignKeySpec as n, Op as r, ColumnSpec as t };
|
|
43
|
-
//# sourceMappingURL=shared-DarONYBZ.d.mts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"shared-DarONYBZ.d.mts","names":[],"sources":["../src/core/migrations/operations/shared.ts"],"mappings":";;;;;KAMY,EAAA,GAAK,yBAAyB,CAAC,yBAAA;;AAA3C;;;;AAAoE;AAcpE;;;;;;UAAiB,UAAA;EAAA,SACN,IAAA;EAAA,SACA,OAAA;EAAA,SACA,UAAA;EAAA,SACA,QAAA;AAAA;;;;;;UAQM,cAAA;EAAA,SACN,IAAA;EAAA,SACA,OAAA;EAAA,SACA,UAAA;IAAA,SACE,MAAA;IAAA,SACA,KAAA;IAAA,SACA,OAAA;EAAA;EAAA,SAEF,QAAA,GAAW,iBAAA;EAAA,SACX,QAAA,GAAW,iBAAiB;AAAA"}
|
|
@@ -1,213 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Pure planning helpers for Postgres enum types: the diff/rebuild logic
|
|
3
|
-
* that the verifier and planner use to walk `PostgresEnumType` instances
|
|
4
|
-
* natively. Op builders live in `./operations/enums.ts`.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { arraysEqual } from '@prisma-next/family-sql/schema-verify';
|
|
8
|
-
import { UNBOUND_NAMESPACE_ID } from '@prisma-next/framework-components/ir';
|
|
9
|
-
import type { PostgresEnumStorageEntry, SqlStorage } from '@prisma-next/sql-contract/types';
|
|
10
|
-
import type { SqlSchemaIR } from '@prisma-next/sql-schema-ir/types';
|
|
11
|
-
import { PG_ENUM_CODEC_ID } from '../codec-ids';
|
|
12
|
-
import type { PostgresEnumType } from '../postgres-enum-type';
|
|
13
|
-
import { isPostgresSchema } from '../postgres-schema';
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Codec-typed enum entry shape stored under
|
|
17
|
-
* `schema.annotations.pg.storageTypes[(schemaName, nativeType)]`.
|
|
18
|
-
*/
|
|
19
|
-
interface PgStorageTypeEntry {
|
|
20
|
-
readonly codecId?: string;
|
|
21
|
-
readonly typeParams?: { readonly values?: unknown };
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/** Postgres-specific subtree on family `SqlSchemaIR.annotations`. */
|
|
25
|
-
export interface PostgresSchemaIrAnnotations {
|
|
26
|
-
readonly schema?: string;
|
|
27
|
-
readonly storageTypes?: Readonly<Record<string, PgStorageTypeEntry>>;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
function readOptionalString(value: unknown): string | undefined {
|
|
31
|
-
return typeof value === 'string' ? value : undefined;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
function readPgStorageTypeEntry(value: unknown): PgStorageTypeEntry | undefined {
|
|
35
|
-
if (value === null || typeof value !== 'object' || Array.isArray(value)) {
|
|
36
|
-
return undefined;
|
|
37
|
-
}
|
|
38
|
-
const codecId = Reflect.get(value, 'codecId');
|
|
39
|
-
const typeParamsRaw = Reflect.get(value, 'typeParams');
|
|
40
|
-
const typeParams =
|
|
41
|
-
typeParamsRaw !== undefined &&
|
|
42
|
-
typeParamsRaw !== null &&
|
|
43
|
-
typeof typeParamsRaw === 'object' &&
|
|
44
|
-
!Array.isArray(typeParamsRaw)
|
|
45
|
-
? { values: Reflect.get(typeParamsRaw, 'values') }
|
|
46
|
-
: undefined;
|
|
47
|
-
return {
|
|
48
|
-
...(typeof codecId === 'string' ? { codecId } : {}),
|
|
49
|
-
...(typeParams !== undefined ? { typeParams } : {}),
|
|
50
|
-
};
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
function readPgStorageTypesMap(
|
|
54
|
-
value: unknown,
|
|
55
|
-
): Readonly<Record<string, PgStorageTypeEntry>> | undefined {
|
|
56
|
-
if (value === null || typeof value !== 'object' || Array.isArray(value)) {
|
|
57
|
-
return undefined;
|
|
58
|
-
}
|
|
59
|
-
const entries: Record<string, PgStorageTypeEntry> = {};
|
|
60
|
-
for (const [key, entryValue] of Object.entries(value)) {
|
|
61
|
-
const entry = readPgStorageTypeEntry(entryValue);
|
|
62
|
-
if (entry !== undefined) {
|
|
63
|
-
entries[key] = entry;
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
return Object.keys(entries).length > 0 ? entries : undefined;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* Reads the Postgres annotation envelope (`schema.annotations.pg`) from
|
|
71
|
-
* family Schema IR. `SqlAnnotations` is an open target-pack extensibility
|
|
72
|
-
* map (`Record<string, unknown>`); this accessor narrows the `pg` slot at
|
|
73
|
-
* runtime so Postgres code can read introspection fields without casts.
|
|
74
|
-
*/
|
|
75
|
-
export function readPostgresSchemaIrAnnotations(schema: SqlSchemaIR): PostgresSchemaIrAnnotations {
|
|
76
|
-
const raw = schema.annotations?.['pg'];
|
|
77
|
-
if (raw === undefined || raw === null || typeof raw !== 'object' || Array.isArray(raw)) {
|
|
78
|
-
return {};
|
|
79
|
-
}
|
|
80
|
-
const schemaField = readOptionalString(Reflect.get(raw, 'schema'));
|
|
81
|
-
const storageTypes = readPgStorageTypesMap(Reflect.get(raw, 'storageTypes'));
|
|
82
|
-
return {
|
|
83
|
-
...(schemaField !== undefined ? { schema: schemaField } : {}),
|
|
84
|
-
...(storageTypes !== undefined ? { storageTypes } : {}),
|
|
85
|
-
};
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
/**
|
|
89
|
-
* Separator for `(schemaName, nativeType)` keys in introspected
|
|
90
|
-
* `schema.annotations.pg.storageTypes`. NUL cannot appear in Postgres
|
|
91
|
-
* identifiers, so the pair is unambiguous.
|
|
92
|
-
*/
|
|
93
|
-
export const ENUM_STORAGE_KEY_SEP = '\u0000';
|
|
94
|
-
|
|
95
|
-
/** Builds the schema-qualified storageTypes map key for a live Postgres enum. */
|
|
96
|
-
export function enumStorageCompoundKey(schemaName: string, nativeType: string): string {
|
|
97
|
-
return `${schemaName}${ENUM_STORAGE_KEY_SEP}${nativeType}`;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* Resolves the live-schema name a namespace's enums are introspected under,
|
|
102
|
-
* for keying `readExistingEnumValues` lookups. The unbound namespace's
|
|
103
|
-
* `ddlSchemaName` is a planner-emit sentinel (`__unbound__`) that never names a
|
|
104
|
-
* real schema, so for the unbound coordinate we read the *introspected* schema
|
|
105
|
-
* recorded on `annotations.pg.schema` (the live `current_schema()` the adapter
|
|
106
|
-
* walked) — that is the schema the enum's `storageTypes` entry is keyed under.
|
|
107
|
-
* Named namespaces resolve to their own DDL schema, which matches the
|
|
108
|
-
* per-schema introspection key directly.
|
|
109
|
-
*/
|
|
110
|
-
export function resolveDdlSchemaForNamespaceStorage(
|
|
111
|
-
storage: SqlStorage,
|
|
112
|
-
namespaceId: string,
|
|
113
|
-
schemaIr?: SqlSchemaIR,
|
|
114
|
-
): string {
|
|
115
|
-
if (namespaceId === UNBOUND_NAMESPACE_ID) {
|
|
116
|
-
return (schemaIr ? readPostgresSchemaIrAnnotations(schemaIr).schema : undefined) ?? 'public';
|
|
117
|
-
}
|
|
118
|
-
const namespace = storage.namespaces[namespaceId];
|
|
119
|
-
if (namespace && isPostgresSchema(namespace)) {
|
|
120
|
-
return namespace.ddlSchemaName(storage);
|
|
121
|
-
}
|
|
122
|
-
return namespaceId;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
/** Contract-scoped bridge for the family verifier's enum value resolver. */
|
|
126
|
-
export function createResolveExistingEnumValues(
|
|
127
|
-
storage: SqlStorage,
|
|
128
|
-
): (
|
|
129
|
-
schema: SqlSchemaIR,
|
|
130
|
-
enumType: PostgresEnumStorageEntry,
|
|
131
|
-
namespaceId: string,
|
|
132
|
-
) => readonly string[] | null {
|
|
133
|
-
return (schema, enumType, namespaceId) =>
|
|
134
|
-
readExistingEnumValues(
|
|
135
|
-
schema,
|
|
136
|
-
resolveDdlSchemaForNamespaceStorage(storage, namespaceId, schema),
|
|
137
|
-
enumType.nativeType,
|
|
138
|
-
);
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
/**
|
|
142
|
-
* Categorisation of how an existing enum type's values relate to the
|
|
143
|
-
* desired set in the contract.
|
|
144
|
-
*/
|
|
145
|
-
export type EnumDiff =
|
|
146
|
-
| { readonly kind: 'unchanged' }
|
|
147
|
-
| { readonly kind: 'add_values'; readonly values: readonly string[] }
|
|
148
|
-
| { readonly kind: 'rebuild'; readonly removedValues: readonly string[] };
|
|
149
|
-
|
|
150
|
-
/**
|
|
151
|
-
* Reads existing enum values for `(schemaName, nativeType)` from the
|
|
152
|
-
* Postgres-introspected `schema.annotations.pg.storageTypes` map.
|
|
153
|
-
*
|
|
154
|
-
* Schema IR's `storageTypes` slots are always codec-typed
|
|
155
|
-
* (`{codecId: PG_ENUM_CODEC_ID, typeParams.values}`): the introspector
|
|
156
|
-
* writes that shape, and the Contract→Schema IR projector resolves
|
|
157
|
-
* `PostgresEnumType` instances down to the same codec-typed triple before
|
|
158
|
-
* they ever land in Schema IR. There is no second on-disk shape to
|
|
159
|
-
* accept here.
|
|
160
|
-
*
|
|
161
|
-
* Returns `null` when no enum entry exists for the given native type.
|
|
162
|
-
*/
|
|
163
|
-
export function readExistingEnumValues(
|
|
164
|
-
schema: SqlSchemaIR,
|
|
165
|
-
schemaName: string,
|
|
166
|
-
nativeType: string,
|
|
167
|
-
): readonly string[] | null {
|
|
168
|
-
const storageTypes = readPostgresSchemaIrAnnotations(schema).storageTypes;
|
|
169
|
-
const existing = storageTypes?.[enumStorageCompoundKey(schemaName, nativeType)];
|
|
170
|
-
if (!existing || existing.codecId !== PG_ENUM_CODEC_ID) {
|
|
171
|
-
return null;
|
|
172
|
-
}
|
|
173
|
-
const enumValues = existing.typeParams?.values;
|
|
174
|
-
if (!Array.isArray(enumValues) || !enumValues.every((v) => typeof v === 'string')) {
|
|
175
|
-
return null;
|
|
176
|
-
}
|
|
177
|
-
return enumValues;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
/**
|
|
181
|
-
* Determines what changes are needed to transform existing enum values to
|
|
182
|
-
* desired values.
|
|
183
|
-
*
|
|
184
|
-
* Postgres enums can only have values added (not removed or reordered)
|
|
185
|
-
* without a full type rebuild involving temp type creation and column
|
|
186
|
-
* migration; `'rebuild'` covers the value-removal and reorder cases.
|
|
187
|
-
*/
|
|
188
|
-
export function determineEnumDiff(
|
|
189
|
-
existing: readonly string[],
|
|
190
|
-
desired: readonly string[],
|
|
191
|
-
): EnumDiff {
|
|
192
|
-
if (arraysEqual(existing, desired)) {
|
|
193
|
-
return { kind: 'unchanged' };
|
|
194
|
-
}
|
|
195
|
-
const existingSet = new Set(existing);
|
|
196
|
-
const desiredSet = new Set(desired);
|
|
197
|
-
const missingValues = desired.filter((value) => !existingSet.has(value));
|
|
198
|
-
const removedValues = existing.filter((value) => !desiredSet.has(value));
|
|
199
|
-
const orderMismatch =
|
|
200
|
-
missingValues.length === 0 && removedValues.length === 0 && !arraysEqual(existing, desired);
|
|
201
|
-
if (removedValues.length > 0 || orderMismatch) {
|
|
202
|
-
return { kind: 'rebuild', removedValues };
|
|
203
|
-
}
|
|
204
|
-
return { kind: 'add_values', values: missingValues };
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
/**
|
|
208
|
-
* Convenience accessor — returns the enum's desired values from a
|
|
209
|
-
* `PostgresEnumType` IR instance.
|
|
210
|
-
*/
|
|
211
|
-
export function getDesiredEnumValues(typeInstance: PostgresEnumType): readonly string[] {
|
|
212
|
-
return typeInstance.values;
|
|
213
|
-
}
|
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
import { escapeLiteral, qualifyName, quoteIdentifier } from '../../sql-utils';
|
|
2
|
-
import { type Op, step, targetDetails } from './shared';
|
|
3
|
-
|
|
4
|
-
function enumTypeExistsCheck(schemaName: string, nativeType: string, exists = true): string {
|
|
5
|
-
const clause = exists ? 'EXISTS' : 'NOT EXISTS';
|
|
6
|
-
return `SELECT ${clause} (
|
|
7
|
-
SELECT 1
|
|
8
|
-
FROM pg_type t
|
|
9
|
-
JOIN pg_namespace n ON t.typnamespace = n.oid
|
|
10
|
-
WHERE n.nspname = '${escapeLiteral(schemaName)}'
|
|
11
|
-
AND t.typname = '${escapeLiteral(nativeType)}'
|
|
12
|
-
)`;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export function createEnumType(
|
|
16
|
-
schemaName: string,
|
|
17
|
-
typeName: string,
|
|
18
|
-
values: readonly string[],
|
|
19
|
-
nativeType: string = typeName,
|
|
20
|
-
): Op {
|
|
21
|
-
const qualifiedType = qualifyName(schemaName, nativeType);
|
|
22
|
-
const literalValues = values.map((v) => `'${escapeLiteral(v)}'`).join(', ');
|
|
23
|
-
return {
|
|
24
|
-
id: `type.${typeName}`,
|
|
25
|
-
label: `Create enum type "${typeName}"`,
|
|
26
|
-
operationClass: 'additive',
|
|
27
|
-
target: targetDetails('type', typeName, schemaName),
|
|
28
|
-
precheck: [
|
|
29
|
-
step(
|
|
30
|
-
`ensure type "${nativeType}" does not exist`,
|
|
31
|
-
enumTypeExistsCheck(schemaName, nativeType, false),
|
|
32
|
-
),
|
|
33
|
-
],
|
|
34
|
-
execute: [
|
|
35
|
-
step(
|
|
36
|
-
`create enum type "${typeName}"`,
|
|
37
|
-
`CREATE TYPE ${qualifiedType} AS ENUM (${literalValues})`,
|
|
38
|
-
),
|
|
39
|
-
],
|
|
40
|
-
postcheck: [
|
|
41
|
-
step(`verify type "${nativeType}" exists`, enumTypeExistsCheck(schemaName, nativeType)),
|
|
42
|
-
],
|
|
43
|
-
};
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* `typeName` is the contract-facing type name (used for id/label).
|
|
48
|
-
* `nativeType` is the Postgres type name to mutate (may differ for external types).
|
|
49
|
-
*/
|
|
50
|
-
export function addEnumValues(
|
|
51
|
-
schemaName: string,
|
|
52
|
-
typeName: string,
|
|
53
|
-
nativeType: string,
|
|
54
|
-
values: readonly string[],
|
|
55
|
-
): Op {
|
|
56
|
-
const qualifiedType = qualifyName(schemaName, nativeType);
|
|
57
|
-
return {
|
|
58
|
-
id: `type.${typeName}.addValues`,
|
|
59
|
-
label: `Add values to enum type "${typeName}": ${values.join(', ')}`,
|
|
60
|
-
operationClass: 'additive',
|
|
61
|
-
target: targetDetails('type', typeName, schemaName),
|
|
62
|
-
precheck: [
|
|
63
|
-
step(`ensure type "${nativeType}" exists`, enumTypeExistsCheck(schemaName, nativeType)),
|
|
64
|
-
],
|
|
65
|
-
execute: values.map((value) =>
|
|
66
|
-
step(
|
|
67
|
-
`add value '${value}' to enum "${nativeType}"`,
|
|
68
|
-
`ALTER TYPE ${qualifiedType} ADD VALUE '${escapeLiteral(value)}'`,
|
|
69
|
-
),
|
|
70
|
-
),
|
|
71
|
-
postcheck: [
|
|
72
|
-
step(`verify type "${nativeType}" exists`, enumTypeExistsCheck(schemaName, nativeType)),
|
|
73
|
-
],
|
|
74
|
-
};
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
export function dropEnumType(schemaName: string, typeName: string): Op {
|
|
78
|
-
const qualified = qualifyName(schemaName, typeName);
|
|
79
|
-
return {
|
|
80
|
-
id: `type.${typeName}.drop`,
|
|
81
|
-
label: `Drop enum type "${typeName}"`,
|
|
82
|
-
operationClass: 'destructive',
|
|
83
|
-
target: targetDetails('type', typeName, schemaName),
|
|
84
|
-
precheck: [step(`ensure type "${typeName}" exists`, enumTypeExistsCheck(schemaName, typeName))],
|
|
85
|
-
execute: [step(`drop enum type "${typeName}"`, `DROP TYPE ${qualified}`)],
|
|
86
|
-
postcheck: [
|
|
87
|
-
step(`verify type "${typeName}" removed`, enumTypeExistsCheck(schemaName, typeName, false)),
|
|
88
|
-
],
|
|
89
|
-
};
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
export function renameType(schemaName: string, fromName: string, toName: string): Op {
|
|
93
|
-
const qualifiedFrom = qualifyName(schemaName, fromName);
|
|
94
|
-
return {
|
|
95
|
-
id: `type.${fromName}.rename`,
|
|
96
|
-
label: `Rename type "${fromName}" to "${toName}"`,
|
|
97
|
-
operationClass: 'destructive',
|
|
98
|
-
target: targetDetails('type', fromName, schemaName),
|
|
99
|
-
precheck: [
|
|
100
|
-
step(`ensure type "${fromName}" exists`, enumTypeExistsCheck(schemaName, fromName)),
|
|
101
|
-
step(
|
|
102
|
-
`ensure type "${toName}" does not already exist`,
|
|
103
|
-
enumTypeExistsCheck(schemaName, toName, false),
|
|
104
|
-
),
|
|
105
|
-
],
|
|
106
|
-
execute: [
|
|
107
|
-
step(
|
|
108
|
-
`rename type "${fromName}" to "${toName}"`,
|
|
109
|
-
`ALTER TYPE ${qualifiedFrom} RENAME TO ${quoteIdentifier(toName)}`,
|
|
110
|
-
),
|
|
111
|
-
],
|
|
112
|
-
postcheck: [step(`verify type "${toName}" exists`, enumTypeExistsCheck(schemaName, toName))],
|
|
113
|
-
};
|
|
114
|
-
}
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
import type { ControlPolicy } from '@prisma-next/contract/types';
|
|
2
|
-
import { freezeNode } from '@prisma-next/framework-components/ir';
|
|
3
|
-
import { SqlNode } from '@prisma-next/sql-contract/types';
|
|
4
|
-
|
|
5
|
-
export interface PostgresEnumTypeInput<
|
|
6
|
-
TName extends string = string,
|
|
7
|
-
TValues extends readonly string[] = readonly string[],
|
|
8
|
-
> {
|
|
9
|
-
/**
|
|
10
|
-
* Contract-level enum name (e.g. `'Role'`). Used as the key in
|
|
11
|
-
* `SqlStorage.types` and as the contract-facing identifier in
|
|
12
|
-
* planner / verifier diagnostics.
|
|
13
|
-
*/
|
|
14
|
-
readonly name: TName;
|
|
15
|
-
/**
|
|
16
|
-
* Postgres-side native type name created by `CREATE TYPE … AS ENUM`.
|
|
17
|
-
* Defaults to `name` when not overridden via PSL `@map(...)` or the
|
|
18
|
-
* TS authoring surface.
|
|
19
|
-
*/
|
|
20
|
-
readonly nativeType?: string;
|
|
21
|
-
readonly values: TValues;
|
|
22
|
-
readonly control?: ControlPolicy;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
/** Codec id used by Postgres enum-typed columns (text wire format). */
|
|
26
|
-
const PG_ENUM_CODEC_ID = 'pg/enum@1';
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Postgres IR class for the `CREATE TYPE … AS ENUM` concept.
|
|
30
|
-
*
|
|
31
|
-
* Per Decision 18, enum is a target-only concept (Postgres alone today;
|
|
32
|
-
* SQLite emulates via CHECK constraints). There is no family-layer
|
|
33
|
-
* enum abstract — the abstract-earns-existence rule keeps the IR class
|
|
34
|
-
* hierarchy minimal: this class extends `SqlNode` directly and is the
|
|
35
|
-
* single concrete representation of the polymorphic `'postgres-enum'`
|
|
36
|
-
* slot variant.
|
|
37
|
-
*
|
|
38
|
-
* Carries Postgres-specific resolution (`nativeType` defaults to
|
|
39
|
-
* `name`; `values` is frozen at construction time). Constructor calls
|
|
40
|
-
* `freezeNode(this)` per Decision 8 — the instance is fully immutable,
|
|
41
|
-
* JSON-clean, and dispatchable on its enumerable `kind: 'postgres-enum'`
|
|
42
|
-
* literal.
|
|
43
|
-
*
|
|
44
|
-
* The family-layer slot dispatch (verifier, planner, lowering, etc.)
|
|
45
|
-
* narrows polymorphic `StorageType` entries via the `kind` literal
|
|
46
|
-
* (e.g. `isPostgresEnumStorageEntry`) — SQL-domain code must not import
|
|
47
|
-
* `target-postgres` directly (cross-domain layering rule). The
|
|
48
|
-
* structural interface lives at the family layer for that purpose;
|
|
49
|
-
* this class is the runtime concrete that satisfies it.
|
|
50
|
-
*/
|
|
51
|
-
export class PostgresEnumType<
|
|
52
|
-
TName extends string = string,
|
|
53
|
-
TValues extends readonly string[] = readonly string[],
|
|
54
|
-
> extends SqlNode {
|
|
55
|
-
override readonly kind = 'postgres-enum' as const;
|
|
56
|
-
readonly name: TName;
|
|
57
|
-
readonly nativeType: string;
|
|
58
|
-
readonly values: TValues;
|
|
59
|
-
/**
|
|
60
|
-
* Enumerable own property so the persisted JSON envelope carries
|
|
61
|
-
* `codecId: 'pg/enum@1'` alongside `kind: 'postgres-enum'`. The
|
|
62
|
-
* runtime path (`codecRefForStorageColumn`, `assertColumnCodecIntegrity`)
|
|
63
|
-
* receives JSON-shaped contracts (e.g. inside a user-written
|
|
64
|
-
* `migration.ts` that loads `endContract` from `end-contract.json`)
|
|
65
|
-
* and reads `codecId` directly from the envelope rather than
|
|
66
|
-
* dispatching through the prototype-only `codecBinding` accessor.
|
|
67
|
-
*/
|
|
68
|
-
readonly codecId: typeof PG_ENUM_CODEC_ID = PG_ENUM_CODEC_ID;
|
|
69
|
-
declare readonly control?: ControlPolicy;
|
|
70
|
-
|
|
71
|
-
constructor(input: PostgresEnumTypeInput<TName, TValues>) {
|
|
72
|
-
super();
|
|
73
|
-
this.name = input.name;
|
|
74
|
-
this.nativeType = input.nativeType ?? input.name;
|
|
75
|
-
// `Object.freeze` returns `Readonly<string[]>`, widening past the
|
|
76
|
-
// `TValues` literal tuple. Cast preserves the caller-supplied
|
|
77
|
-
// tuple shape so inferred contract types retain literal narrowing.
|
|
78
|
-
this.values = Object.freeze([...input.values] as unknown as TValues);
|
|
79
|
-
if (input.control !== undefined) this.control = input.control;
|
|
80
|
-
freezeNode(this);
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
get codecBinding(): {
|
|
84
|
-
readonly codecId: typeof PG_ENUM_CODEC_ID;
|
|
85
|
-
readonly typeParams: { readonly values: TValues };
|
|
86
|
-
} {
|
|
87
|
-
return { codecId: PG_ENUM_CODEC_ID, typeParams: { values: this.values } };
|
|
88
|
-
}
|
|
89
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
export {
|
|
2
|
-
createResolveExistingEnumValues,
|
|
3
|
-
determineEnumDiff,
|
|
4
|
-
type EnumDiff,
|
|
5
|
-
enumStorageCompoundKey,
|
|
6
|
-
getDesiredEnumValues,
|
|
7
|
-
type PostgresSchemaIrAnnotations,
|
|
8
|
-
readExistingEnumValues,
|
|
9
|
-
readPostgresSchemaIrAnnotations,
|
|
10
|
-
resolveDdlSchemaForNamespaceStorage,
|
|
11
|
-
} from '../core/migrations/enum-planning';
|