@prisma-next/target-postgres 0.13.0-dev.3 → 0.13.0-dev.31
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 +17 -2
- package/dist/contract-free.d.mts.map +1 -1
- package/dist/contract-free.mjs +3 -3
- 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-77SyXgFt.mjs → ddl-DY2R_Yqz.mjs} +18 -3
- package/dist/ddl-DY2R_Yqz.mjs.map +1 -0
- package/dist/ddl.d.mts +2 -2
- package/dist/ddl.mjs +2 -2
- package/dist/{descriptor-meta-DKmj-IMN.mjs → descriptor-meta-BKma_hQ5.mjs} +2 -2
- package/dist/{descriptor-meta-DKmj-IMN.mjs.map → descriptor-meta-BKma_hQ5.mjs.map} +1 -1
- package/dist/descriptor-meta-runtime-e5f2tscJ.mjs +131 -0
- package/dist/descriptor-meta-runtime-e5f2tscJ.mjs.map +1 -0
- package/dist/{issue-planner-Br0pt1Ea.mjs → issue-planner-DsjB7xDj.mjs} +48 -252
- package/dist/issue-planner-DsjB7xDj.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 +4 -15
- 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-DMA86_2D.d.mts → op-factory-call-CdtMyrlU.d.mts} +12 -56
- package/dist/op-factory-call-CdtMyrlU.d.mts.map +1 -0
- package/dist/{op-factory-call-D2aAUhmS.mjs → op-factory-call-CjR846f7.mjs} +70 -198
- package/dist/op-factory-call-CjR846f7.mjs.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-_FOL4I21.mjs} +25 -45
- package/dist/planner-_FOL4I21.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-BmCpyWLJ.mjs} +6 -4
- package/dist/planner-produced-postgres-migration-BmCpyWLJ.mjs.map +1 -0
- package/dist/{planner-produced-postgres-migration-B4EDvLdz.d.mts → planner-produced-postgres-migration-wLhnJMMA.d.mts} +5 -6
- package/dist/planner-produced-postgres-migration-wLhnJMMA.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-DAdhnI2c.mjs → planner-sql-checks-CJJtPfDH.mjs} +3 -3
- package/dist/planner-sql-checks-CJJtPfDH.mjs.map +1 -0
- package/dist/planner-sql-checks.d.mts +2 -2
- package/dist/planner-sql-checks.d.mts.map +1 -1
- package/dist/planner-sql-checks.mjs +1 -1
- 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-CyAe8ZFv.mjs} +27 -37
- package/dist/postgres-contract-serializer-CyAe8ZFv.mjs.map +1 -0
- package/dist/{postgres-migration-DZ_gLUOW.d.mts → postgres-migration-DLXL0GBf.d.mts} +10 -5
- package/dist/postgres-migration-DLXL0GBf.d.mts.map +1 -0
- package/dist/{postgres-migration-COore9Mz.mjs → postgres-migration-dG-J0aI8.mjs} +7 -3
- package/dist/postgres-migration-dG-J0aI8.mjs.map +1 -0
- package/dist/{postgres-schema-BuxCxbvB.mjs → postgres-schema-CTKYiTHu.mjs} +30 -13
- package/dist/postgres-schema-CTKYiTHu.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.map +1 -1
- package/dist/runtime.mjs +2 -2
- package/dist/{shared-DarONYBZ.d.mts → shared-jcsbXxiW.d.mts} +2 -20
- package/dist/shared-jcsbXxiW.d.mts.map +1 -0
- package/dist/types.d.mts +8 -13
- package/dist/types.d.mts.map +1 -1
- package/dist/types.mjs +2 -3
- package/package.json +17 -18
- 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 +89 -142
- package/src/core/migrations/operations/data-transform.ts +15 -18
- 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 +2 -6
- package/src/core/migrations/planner-sql-checks.ts +2 -6
- package/src/core/migrations/planner-strategies.ts +51 -376
- 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 +19 -4
- package/src/core/migrations/render-ops.ts +26 -13
- package/src/core/migrations/runner.ts +26 -20
- package/src/core/postgres-contract-serializer.ts +32 -54
- package/src/core/postgres-enum-type-schema.ts +17 -0
- package/src/core/postgres-schema.ts +56 -34
- package/src/exports/codecs.ts +2 -2
- package/src/exports/contract-free.ts +1 -1
- package/src/exports/control.ts +0 -22
- package/src/exports/ddl.ts +4 -0
- package/src/exports/migration.ts +0 -7
- package/src/exports/op-factory-call.ts +0 -4
- 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.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.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.map +0 -1
- 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.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,19 +1,19 @@
|
|
|
1
|
-
import { t as PostgresEnumType } from "./postgres-enum-type-DPKqCBem.mjs";
|
|
2
1
|
import { i as quoteIdentifier } from "./sql-utils-DcfMz4MQ.mjs";
|
|
3
|
-
import { r as isPostgresSchema } from "./postgres-schema-
|
|
4
|
-
import {
|
|
5
|
-
import { a as columnNullabilityCheck, c as qualifyTableName, i as columnHasNoDefaultCheck, r as columnExistsCheck, t as buildExpectedFormatType, u as tableIsEmptyCheck } from "./planner-sql-checks-
|
|
6
|
-
import {
|
|
7
|
-
import { n as buildColumnDefaultSql, r as buildColumnTypeSql, t as buildAddColumnSql } from "./planner-ddl-builders-
|
|
8
|
-
import { n as resolveIdentityValue } from "./planner-identity-values-
|
|
2
|
+
import { r as isPostgresSchema } from "./postgres-schema-CTKYiTHu.mjs";
|
|
3
|
+
import { t as resolveColumnTypeMetadata } from "./planner-type-resolution-Bt2f_q-F.mjs";
|
|
4
|
+
import { a as columnNullabilityCheck, c as qualifyTableName, i as columnHasNoDefaultCheck, r as columnExistsCheck, t as buildExpectedFormatType, u as tableIsEmptyCheck } from "./planner-sql-checks-CJJtPfDH.mjs";
|
|
5
|
+
import { S as postgresDefaultToDdlColumnDefault, _ as DropNotNullCall, a as AddUniqueCall, b as SetDefaultCall, c as CreateIndexCall, d as DataTransformCall, f as DropCheckConstraintCall, g as DropIndexCall, h as DropDefaultCall, i as AddPrimaryKeyCall, l as CreateSchemaCall, m as DropConstraintCall, n as AddColumnCall, o as AlterColumnTypeCall, p as DropColumnCall, r as AddForeignKeyCall, t as AddCheckConstraintCall, u as CreateTableCall, v as DropTableCall, x as SetNotNullCall, y as RawSqlCall } from "./op-factory-call-CjR846f7.mjs";
|
|
6
|
+
import { n as buildColumnDefaultSql, r as buildColumnTypeSql, t as buildAddColumnSql } from "./planner-ddl-builders-B2wOwLqI.mjs";
|
|
7
|
+
import { n as resolveIdentityValue } from "./planner-identity-values-CJPha2Sz.mjs";
|
|
9
8
|
import { i as hasUniqueConstraint, n as hasForeignKey, t as buildSchemaLookupMap } from "./planner-schema-lookup-CiVaAQP-.mjs";
|
|
9
|
+
import { blindCast } from "@prisma-next/utils/casts";
|
|
10
10
|
import { resolveValueSetValues } from "@prisma-next/family-sql/control";
|
|
11
11
|
import { ifDefined } from "@prisma-next/utils/defined";
|
|
12
|
-
import { UNBOUND_NAMESPACE_ID } from "@prisma-next/framework-components/ir";
|
|
13
|
-
import { StorageTable, isPostgresEnumStorageEntry } from "@prisma-next/sql-contract/types";
|
|
14
12
|
import { arraysEqual } from "@prisma-next/family-sql/schema-verify";
|
|
15
|
-
import {
|
|
13
|
+
import { UNBOUND_NAMESPACE_ID } from "@prisma-next/framework-components/ir";
|
|
14
|
+
import { StorageTable } from "@prisma-next/sql-contract/types";
|
|
16
15
|
import * as contractFree from "@prisma-next/sql-relational-core/contract-free";
|
|
16
|
+
import { col } from "@prisma-next/sql-relational-core/contract-free";
|
|
17
17
|
import { notOk, ok } from "@prisma-next/utils/result";
|
|
18
18
|
//#region src/core/migrations/planner-target-details.ts
|
|
19
19
|
function buildTargetDetails(objectType, name, schema, table) {
|
|
@@ -90,7 +90,6 @@ function buildAddNotNullColumnWithTemporaryDefaultOperation(options) {
|
|
|
90
90
|
}
|
|
91
91
|
//#endregion
|
|
92
92
|
//#region src/core/migrations/planner-strategies.ts
|
|
93
|
-
const REBUILD_SUFFIX = "__prisma_next_new";
|
|
94
93
|
/**
|
|
95
94
|
* Look up a storage table by its explicit namespace coordinate. Returns
|
|
96
95
|
* `undefined` when the namespace has no table by that name (or no such
|
|
@@ -102,7 +101,9 @@ const REBUILD_SUFFIX = "__prisma_next_new";
|
|
|
102
101
|
* contracts where two namespaces can carry the same table name).
|
|
103
102
|
*/
|
|
104
103
|
function tableAt(storage, namespaceId, tableName) {
|
|
105
|
-
|
|
104
|
+
const ns = storage.namespaces[namespaceId];
|
|
105
|
+
if (ns === void 0) return void 0;
|
|
106
|
+
return ns.entries.table?.[tableName];
|
|
106
107
|
}
|
|
107
108
|
/**
|
|
108
109
|
* Default namespace coordinate for an issue that does not carry one
|
|
@@ -131,57 +132,24 @@ function resolveDdlSchemaForNamespace(ctx, namespaceId) {
|
|
|
131
132
|
if (isPostgresSchema(namespace)) return namespace.ddlSchemaName(ctx.toContract.storage);
|
|
132
133
|
return namespaceId;
|
|
133
134
|
}
|
|
134
|
-
/** Default Postgres enum landing namespace — where contract-level (`types:`)
|
|
135
|
-
* enums are placed by the authoring builder when no explicit namespace is
|
|
136
|
-
* given. Mirrors `POSTGRES_ENUM_NAMESPACE_ID` in the contract-ts builder. */
|
|
137
|
-
const DEFAULT_ENUM_NAMESPACE_ID = "public";
|
|
138
|
-
function namespaceHasEnum(storage, namespaceId, typeName) {
|
|
139
|
-
const ns = storage.namespaces[namespaceId];
|
|
140
|
-
if (!isPostgresSchema(ns)) return false;
|
|
141
|
-
return ns.entries.type[typeName] !== void 0;
|
|
142
|
-
}
|
|
143
|
-
/**
|
|
144
|
-
* Resolves which namespace's enum a column's bare `typeRef` binds to.
|
|
145
|
-
*
|
|
146
|
-
* Columns carry a bare (non-namespace-qualified) `typeRef`; the enum it names
|
|
147
|
-
* may live in a different namespace than the column's own (the authoring
|
|
148
|
-
* builder places contract-level `types:` enums in the default `public`
|
|
149
|
-
* namespace while a model's table may sit in the unbound namespace). The
|
|
150
|
-
* binding rule: an enum declared in the column's *own* namespace shadows
|
|
151
|
-
* everything; otherwise the column references the ambient enum — the sole
|
|
152
|
-
* namespace that defines `typeName`, preferring the default `public`
|
|
153
|
-
* namespace when several do. Returns `undefined` when no namespace defines it.
|
|
154
|
-
*/
|
|
155
|
-
function resolveColumnEnumNamespace(storage, columnNamespaceId, typeName) {
|
|
156
|
-
if (namespaceHasEnum(storage, columnNamespaceId, typeName)) return columnNamespaceId;
|
|
157
|
-
const owners = Object.keys(storage.namespaces).filter((nsId) => namespaceHasEnum(storage, nsId, typeName));
|
|
158
|
-
if (owners.length === 1) return owners[0];
|
|
159
|
-
if (owners.includes(DEFAULT_ENUM_NAMESPACE_ID)) return DEFAULT_ENUM_NAMESPACE_ID;
|
|
160
|
-
return owners[0];
|
|
161
|
-
}
|
|
162
|
-
/**
|
|
163
|
-
* Finds a type entry by explicit namespace coordinate. Namespace types (e.g.
|
|
164
|
-
* Postgres enums) live under `storage.namespaces[nsId].entries.type`. Returns the
|
|
165
|
-
* entry from the named namespace only — never scans other namespaces, so two
|
|
166
|
-
* namespaces that hold an enum with the same name resolve independently.
|
|
167
|
-
*/
|
|
168
|
-
function locateNamespaceType(storage, namespaceId, typeName) {
|
|
169
|
-
const raw = storage.namespaces[namespaceId]?.entries["type"]?.[typeName];
|
|
170
|
-
if (raw === void 0) return void 0;
|
|
171
|
-
return blindCast(raw);
|
|
172
|
-
}
|
|
173
135
|
function buildColumnSpec(namespaceId, table, column, ctx, overrides) {
|
|
174
|
-
const
|
|
175
|
-
if (!
|
|
136
|
+
const storageCol = tableAt(ctx.toContract.storage, namespaceId, table)?.columns[column];
|
|
137
|
+
if (!storageCol) throw new Error(`Column "${table}"."${column}" not found in destination contract`);
|
|
176
138
|
const mutableHooks = ctx.codecHooks;
|
|
177
139
|
const mutableTypes = ctx.storageTypes;
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
140
|
+
const typeSql = buildColumnTypeSql(storageCol, mutableHooks, mutableTypes);
|
|
141
|
+
const ddlDefault = postgresDefaultToDdlColumnDefault(storageCol.default);
|
|
142
|
+
const resolved = resolveColumnTypeMetadata(storageCol, mutableTypes);
|
|
143
|
+
const typeParams = resolved.typeParams === void 0 ? void 0 : blindCast(resolved.typeParams);
|
|
144
|
+
const codecRef = resolved.codecId ? {
|
|
145
|
+
codecId: resolved.codecId,
|
|
146
|
+
...ifDefined("typeParams", typeParams)
|
|
147
|
+
} : void 0;
|
|
148
|
+
return col(column, typeSql, {
|
|
149
|
+
...!(overrides?.nullable ?? storageCol.nullable) ? { notNull: true } : {},
|
|
150
|
+
...ifDefined("default", ddlDefault),
|
|
151
|
+
...ifDefined("codecRef", codecRef)
|
|
152
|
+
});
|
|
185
153
|
}
|
|
186
154
|
function buildAlterTypeOptions(namespaceId, table, column, ctx, using) {
|
|
187
155
|
const col = tableAt(ctx.toContract.storage, namespaceId, table)?.columns[column];
|
|
@@ -277,154 +245,13 @@ const nullableTighteningCallStrategy = (issues, ctx) => {
|
|
|
277
245
|
recipe: true
|
|
278
246
|
};
|
|
279
247
|
};
|
|
280
|
-
function enumRebuildCallRecipe(namespaceId, typeName, ctx) {
|
|
281
|
-
const toType = locateNamespaceType(ctx.toContract.storage, namespaceId, typeName);
|
|
282
|
-
if (!toType) return [];
|
|
283
|
-
const isEnum = isPostgresEnumStorageEntry(toType);
|
|
284
|
-
const nativeType = toType.nativeType;
|
|
285
|
-
const desiredValues = isEnum ? toType.values : toType.typeParams["values"] ?? [];
|
|
286
|
-
const tempName = `${nativeType}${REBUILD_SUFFIX}`;
|
|
287
|
-
const ddlSchema = resolveDdlSchemaForNamespaceStorage(ctx.toContract.storage, namespaceId, ctx.schema);
|
|
288
|
-
const columnRefs = [];
|
|
289
|
-
for (const [nsId, ns] of Object.entries(ctx.toContract.storage.namespaces)) for (const [tableName, tableNode] of Object.entries(ns.entries.table)) {
|
|
290
|
-
const table = tableNode;
|
|
291
|
-
for (const [columnName, column] of Object.entries(table.columns)) if (column.typeRef === typeName && resolveColumnEnumNamespace(ctx.toContract.storage, nsId, typeName) === namespaceId) columnRefs.push({
|
|
292
|
-
namespaceId: nsId,
|
|
293
|
-
table: tableName,
|
|
294
|
-
column: columnName
|
|
295
|
-
});
|
|
296
|
-
}
|
|
297
|
-
return [
|
|
298
|
-
new CreateEnumTypeCall(ddlSchema, tempName, desiredValues),
|
|
299
|
-
...columnRefs.map((ref) => {
|
|
300
|
-
const using = `${ref.column}::text::${tempName}`;
|
|
301
|
-
return new AlterColumnTypeCall(resolveDdlSchemaForNamespace(ctx, ref.namespaceId), ref.table, ref.column, {
|
|
302
|
-
qualifiedTargetType: tempName,
|
|
303
|
-
formatTypeExpected: tempName,
|
|
304
|
-
rawTargetTypeForLabel: tempName,
|
|
305
|
-
using
|
|
306
|
-
});
|
|
307
|
-
}),
|
|
308
|
-
new DropEnumTypeCall(ddlSchema, nativeType),
|
|
309
|
-
new RenameTypeCall(ddlSchema, tempName, nativeType)
|
|
310
|
-
];
|
|
311
|
-
}
|
|
312
|
-
/**
|
|
313
|
-
* Single planner strategy for `PostgresEnumType` instances. Walks
|
|
314
|
-
* `toContract.storage.types` directly (no codec-hook dispatch) and
|
|
315
|
-
* resolves existing values via `readExistingEnumValues`, the same
|
|
316
|
-
* Postgres bridging adapter the verifier uses.
|
|
317
|
-
*
|
|
318
|
-
* Per-enum dispatch:
|
|
319
|
-
*
|
|
320
|
-
* - No existing type → `CreateEnumTypeCall` with the contract's desired
|
|
321
|
-
* values.
|
|
322
|
-
* - Diff is `unchanged` → no calls emitted (consumes the matching
|
|
323
|
-
* `enum_values_changed` issue if present).
|
|
324
|
-
* - Diff is `add_values` → `AddEnumValuesCall` with the new labels.
|
|
325
|
-
* - Diff is `rebuild` → the create-temp / migrate-columns /
|
|
326
|
-
* drop-original / rename rebuild recipe. When
|
|
327
|
-
* `policy.allowedOperationClasses` includes `'data'` and the rebuild
|
|
328
|
-
* removes labels (`removedValues.length > 0`), prepend a
|
|
329
|
-
* `DataTransformCall` placeholder so the user can author the value
|
|
330
|
-
* remap before the destructive recipe runs. Without `'data'` in the
|
|
331
|
-
* policy (`db update` / `db init`), the rebuild's PG `USING ::text`
|
|
332
|
-
* cast surfaces any value-removal data loss as a runtime error rather
|
|
333
|
-
* than silent loss.
|
|
334
|
-
*
|
|
335
|
-
* Returns `recipe: true` only when a rebuild recipe was emitted (its
|
|
336
|
-
* `createEnumType(temp) → alterColumnType → dropEnumType(orig) →
|
|
337
|
-
* renameType` sequence mixes `dep`-class and `alter`-class calls that
|
|
338
|
-
* would mis-order if the planner hoisted them into its DDL sequencing
|
|
339
|
-
* buckets). For the create-only and add-values paths the strategy
|
|
340
|
-
* returns `recipe: false` so the planner hoists `CreateEnumTypeCall`
|
|
341
|
-
* into the `dep` bucket — i.e. `CREATE TYPE` runs before any
|
|
342
|
-
* `CreateTableCall` that references the new enum.
|
|
343
|
-
*/
|
|
344
|
-
/**
|
|
345
|
-
* Separator character for compound enum map keys (`namespaceId\u0000typeName`).
|
|
346
|
-
* NUL (`\u0000`) is invalid in both Postgres identifiers and TypeScript symbol
|
|
347
|
-
* names so it cannot appear in either component — unambiguous separator.
|
|
348
|
-
*/
|
|
349
|
-
const COMPOUND_KEY_SEP = "\0";
|
|
350
|
-
/** Builds the compound map key for a namespace-qualified enum entry. */
|
|
351
|
-
function enumCompoundKey(namespaceId, typeName) {
|
|
352
|
-
return `${namespaceId}${COMPOUND_KEY_SEP}${typeName}`;
|
|
353
|
-
}
|
|
354
|
-
const nativeEnumPlanCallStrategy = (issues, ctx) => {
|
|
355
|
-
const enumTypes = collectPostgresEnumTypes(ctx.toContract.storage);
|
|
356
|
-
if (enumTypes.size === 0) return { kind: "no_match" };
|
|
357
|
-
const dataAllowed = ctx.policy.allowedOperationClasses.includes("data");
|
|
358
|
-
const calls = [];
|
|
359
|
-
const handledKeys = /* @__PURE__ */ new Set();
|
|
360
|
-
const introducedKeys = /* @__PURE__ */ new Set();
|
|
361
|
-
const rebuiltKeys = /* @__PURE__ */ new Set();
|
|
362
|
-
let emittedRebuildRecipe = false;
|
|
363
|
-
for (const [key, enumType] of enumTypes) {
|
|
364
|
-
const sepIdx = key.indexOf(COMPOUND_KEY_SEP);
|
|
365
|
-
const enumNamespaceId = key.slice(0, sepIdx);
|
|
366
|
-
const typeName = key.slice(sepIdx + 1);
|
|
367
|
-
const desired = enumType.values;
|
|
368
|
-
const ddlSchema = resolveDdlSchemaForNamespaceStorage(ctx.toContract.storage, enumNamespaceId, ctx.schema);
|
|
369
|
-
const existing = readExistingEnumValues(ctx.schema, ddlSchema, enumType.nativeType);
|
|
370
|
-
if (!existing) {
|
|
371
|
-
calls.push(new CreateEnumTypeCall(ddlSchema, typeName, desired, enumType.nativeType));
|
|
372
|
-
handledKeys.add(key);
|
|
373
|
-
introducedKeys.add(key);
|
|
374
|
-
continue;
|
|
375
|
-
}
|
|
376
|
-
const diff = determineEnumDiff(existing, desired);
|
|
377
|
-
if (diff.kind === "unchanged") {
|
|
378
|
-
handledKeys.add(key);
|
|
379
|
-
continue;
|
|
380
|
-
}
|
|
381
|
-
if (diff.kind === "add_values") {
|
|
382
|
-
calls.push(new AddEnumValuesCall(ddlSchema, typeName, enumType.nativeType, diff.values));
|
|
383
|
-
handledKeys.add(key);
|
|
384
|
-
continue;
|
|
385
|
-
}
|
|
386
|
-
if (dataAllowed && diff.removedValues.length > 0) calls.push(new DataTransformCall(`migrate-${typeName}-values`, `migrate-${typeName}-values:check`, `migrate-${typeName}-values:run`));
|
|
387
|
-
calls.push(...enumRebuildCallRecipe(enumNamespaceId, typeName, ctx));
|
|
388
|
-
emittedRebuildRecipe = true;
|
|
389
|
-
handledKeys.add(key);
|
|
390
|
-
rebuiltKeys.add(key);
|
|
391
|
-
}
|
|
392
|
-
if (introducedKeys.size > 0 && rebuiltKeys.size > 0) {
|
|
393
|
-
const introducedDisplay = [...introducedKeys].sort().map((k) => k.replace(COMPOUND_KEY_SEP, ".")).join(", ");
|
|
394
|
-
const rebuiltDisplay = [...rebuiltKeys].sort().map((k) => k.replace(COMPOUND_KEY_SEP, ".")).join(", ");
|
|
395
|
-
throw new Error(`nativeEnumPlanCallStrategy: cannot emit both a brand-new enum and a rebuild on a different enum in the same plan; the single recipe flag cannot route them to different buckets. Introduced: [${introducedDisplay}]; rebuilt: [${rebuiltDisplay}]. Split the strategy or grow the \`match\` return type before this case lands.`);
|
|
396
|
-
}
|
|
397
|
-
const remaining = issues.filter((issue) => !((issue.kind === "type_missing" || issue.kind === "enum_values_changed") && issue.typeName && handledKeys.has(enumCompoundKey(resolveNamespaceIdForIssue(issue), issue.typeName))));
|
|
398
|
-
if (calls.length === 0 && remaining.length === issues.length) return { kind: "no_match" };
|
|
399
|
-
return {
|
|
400
|
-
kind: "match",
|
|
401
|
-
issues: remaining,
|
|
402
|
-
calls,
|
|
403
|
-
recipe: emittedRebuildRecipe
|
|
404
|
-
};
|
|
405
|
-
};
|
|
406
|
-
/**
|
|
407
|
-
* Collects every `PostgresEnumType` instance across all declared namespaces,
|
|
408
|
-
* returning a compound-keyed map (`${namespaceId}\u0000${typeName}`). Two
|
|
409
|
-
* namespaces that declare an enum with the same name produce two distinct
|
|
410
|
-
* entries — no name collision, no last-write-wins.
|
|
411
|
-
*
|
|
412
|
-
* Entries within each namespace are sorted by name for deterministic ordering.
|
|
413
|
-
*/
|
|
414
|
-
function collectPostgresEnumTypes(storage) {
|
|
415
|
-
const result = /* @__PURE__ */ new Map();
|
|
416
|
-
for (const [nsId, ns] of Object.entries(storage.namespaces)) {
|
|
417
|
-
if (!isPostgresSchema(ns)) continue;
|
|
418
|
-
for (const [name, instance] of Object.entries(ns.entries.type).sort(([a], [b]) => a.localeCompare(b))) if (instance instanceof PostgresEnumType) result.set(enumCompoundKey(nsId, name), instance);
|
|
419
|
-
}
|
|
420
|
-
return result;
|
|
421
|
-
}
|
|
422
248
|
/**
|
|
423
249
|
* Collects every check constraint from a table in the contract storage.
|
|
424
250
|
* Returns an empty array when the table has no checks or the table is absent.
|
|
425
251
|
*/
|
|
426
252
|
function collectContractChecks(storage, namespaceId, tableName) {
|
|
427
|
-
const
|
|
253
|
+
const ns = storage.namespaces[namespaceId];
|
|
254
|
+
const tableRaw = ns !== void 0 ? ns.entries.table?.[tableName] : void 0;
|
|
428
255
|
if (!(tableRaw instanceof StorageTable)) return [];
|
|
429
256
|
const checks = tableRaw.checks;
|
|
430
257
|
if (!checks || checks.length === 0) return [];
|
|
@@ -456,13 +283,11 @@ function checkValueSetsEqual(a, b) {
|
|
|
456
283
|
* be altered in place).
|
|
457
284
|
*
|
|
458
285
|
* Consumes `check_missing`, `check_removed`, and `check_mismatch` issues.
|
|
459
|
-
* Does not touch the native enum path (`nativeEnumPlanCallStrategy` is
|
|
460
|
-
* unchanged).
|
|
461
286
|
*/
|
|
462
287
|
const checkConstraintPlanCallStrategy = (issues, ctx) => {
|
|
463
288
|
const calls = [];
|
|
464
289
|
const handledIssueKeys = /* @__PURE__ */ new Set();
|
|
465
|
-
for (const [namespaceId, ns] of Object.entries(ctx.toContract.storage.namespaces)) for (const tableName of Object.keys(ns.entries.table)) {
|
|
290
|
+
for (const [namespaceId, ns] of Object.entries(ctx.toContract.storage.namespaces)) for (const tableName of Object.keys(ns.entries.table ?? {})) {
|
|
466
291
|
const contractChecks = collectContractChecks(ctx.toContract.storage, namespaceId, tableName);
|
|
467
292
|
if (contractChecks.length === 0) continue;
|
|
468
293
|
const liveChecks = ctx.schema.tables[tableName]?.checks ?? [];
|
|
@@ -497,10 +322,9 @@ const checkConstraintPlanCallStrategy = (issues, ctx) => {
|
|
|
497
322
|
};
|
|
498
323
|
};
|
|
499
324
|
/**
|
|
500
|
-
* Dispatches
|
|
325
|
+
* Dispatches codec-typed storage types through their codec's
|
|
501
326
|
* `planTypeOperations` hook (the authoritative source for codec-driven DDL
|
|
502
|
-
* such as custom type creation).
|
|
503
|
-
* `nativeEnumPlanCallStrategy` and no longer relies on codec hooks.
|
|
327
|
+
* such as custom type creation).
|
|
504
328
|
*/
|
|
505
329
|
const storageTypePlanCallStrategy = (issues, ctx) => {
|
|
506
330
|
const storageTypes = ctx.toContract.storage.types ?? {};
|
|
@@ -508,7 +332,6 @@ const storageTypePlanCallStrategy = (issues, ctx) => {
|
|
|
508
332
|
const calls = [];
|
|
509
333
|
const handledTypeNames = /* @__PURE__ */ new Set();
|
|
510
334
|
for (const [typeName, typeInstance] of Object.entries(storageTypes).sort(([a], [b]) => a.localeCompare(b))) {
|
|
511
|
-
if (isPostgresEnumStorageEntry(typeInstance)) continue;
|
|
512
335
|
const codecInstance = typeInstance;
|
|
513
336
|
const hook = ctx.codecHooks.get(codecInstance.codecId);
|
|
514
337
|
if (!hook?.planTypeOperations) continue;
|
|
@@ -662,8 +485,7 @@ function canUseSharedTemporaryDefaultStrategy(options) {
|
|
|
662
485
|
*
|
|
663
486
|
* - When `'data'` is allowed (`migration plan`), the data-safe strategies
|
|
664
487
|
* (`notNullBackfillCallStrategy`, `typeChangeCallStrategy`,
|
|
665
|
-
* `nullableTighteningCallStrategy`)
|
|
666
|
-
* (`nativeEnumPlanCallStrategy`) consume their matching issues and emit
|
|
488
|
+
* `nullableTighteningCallStrategy`) consume their matching issues and emit
|
|
667
489
|
* `DataTransformCall` placeholders or recipe ops.
|
|
668
490
|
*
|
|
669
491
|
* - When `'data'` is not allowed (`db update` / `db init`), the
|
|
@@ -671,37 +493,20 @@ function canUseSharedTemporaryDefaultStrategy(options) {
|
|
|
671
493
|
* the issue for the downstream walk-schema strategies
|
|
672
494
|
* (`storageTypePlanCallStrategy`, `notNullAddColumnCallStrategy`) or the
|
|
673
495
|
* `mapIssueToCall` default to handle with direct DDL.
|
|
674
|
-
* `nativeEnumPlanCallStrategy` runs in both modes; under `db update` /
|
|
675
|
-
* `db init` it emits the rebuild recipe without the data-transform
|
|
676
|
-
* placeholder so value-removal data loss surfaces as a runtime cast
|
|
677
|
-
* error rather than silent loss.
|
|
678
496
|
*
|
|
679
|
-
*
|
|
680
|
-
* `
|
|
681
|
-
* rebuild recipe (`recipe: true`, contiguous slot) or hoist the call
|
|
682
|
-
* into the `dep` bucket (`recipe: false`, so a brand-new
|
|
683
|
-
* `CreateEnumTypeCall` runs before any `CreateTableCall` referencing
|
|
684
|
-
* it). Codec-typed entries continue through `storageTypePlanCallStrategy`.
|
|
497
|
+
* Codec-typed storage type entries are dispatched through
|
|
498
|
+
* `storageTypePlanCallStrategy`.
|
|
685
499
|
*/
|
|
686
500
|
const postgresPlannerStrategies = [
|
|
687
501
|
notNullBackfillCallStrategy,
|
|
688
502
|
typeChangeCallStrategy,
|
|
689
503
|
nullableTighteningCallStrategy,
|
|
690
|
-
nativeEnumPlanCallStrategy,
|
|
691
504
|
checkConstraintPlanCallStrategy,
|
|
692
505
|
storageTypePlanCallStrategy,
|
|
693
506
|
notNullAddColumnCallStrategy
|
|
694
507
|
];
|
|
695
508
|
//#endregion
|
|
696
509
|
//#region src/core/migrations/issue-planner.ts
|
|
697
|
-
/**
|
|
698
|
-
* Finds a type entry by explicit namespace coordinate. Reads the named
|
|
699
|
-
* namespace's `enum` slot directly — never scans other namespaces.
|
|
700
|
-
*/
|
|
701
|
-
function locateNamespaceTypeInStorage(storage, namespaceId, typeName) {
|
|
702
|
-
const ns = storage.namespaces[namespaceId];
|
|
703
|
-
return isPostgresSchema(ns) ? ns.entries.type[typeName] : void 0;
|
|
704
|
-
}
|
|
705
510
|
const ISSUE_KIND_ORDER = {
|
|
706
511
|
missing_schema: 1,
|
|
707
512
|
type_missing: 2,
|
|
@@ -743,20 +548,18 @@ function isMissing(issue) {
|
|
|
743
548
|
if (issue.kind === "enum_values_changed") return false;
|
|
744
549
|
return issue.actual === void 0;
|
|
745
550
|
}
|
|
746
|
-
function toColumnSpec(name, column, codecHooks, storageTypes) {
|
|
747
|
-
return {
|
|
748
|
-
name,
|
|
749
|
-
typeSql: buildColumnTypeSql(column, codecHooks, storageTypes),
|
|
750
|
-
defaultSql: buildColumnDefaultSql(column.default, column),
|
|
751
|
-
nullable: column.nullable
|
|
752
|
-
};
|
|
753
|
-
}
|
|
754
551
|
function toDdlColumn(name, column, codecHooks, storageTypes) {
|
|
755
552
|
const typeSql = buildColumnTypeSql(column, codecHooks, storageTypes);
|
|
756
553
|
const ddlDefault = postgresDefaultToDdlColumnDefault(column.default);
|
|
554
|
+
const resolved = resolveColumnTypeMetadata(column, storageTypes);
|
|
555
|
+
const codecRef = resolved.codecId ? {
|
|
556
|
+
codecId: resolved.codecId,
|
|
557
|
+
...resolved.typeParams !== void 0 ? { typeParams: blindCast(resolved.typeParams) } : {}
|
|
558
|
+
} : void 0;
|
|
757
559
|
return contractFree.col(name, typeSql, {
|
|
758
560
|
...!column.nullable ? { notNull: true } : {},
|
|
759
|
-
...
|
|
561
|
+
...ifDefined("default", ddlDefault),
|
|
562
|
+
...ifDefined("codecRef", codecRef)
|
|
760
563
|
});
|
|
761
564
|
}
|
|
762
565
|
function mapIssueToCall(issue, ctx) {
|
|
@@ -821,7 +624,7 @@ function mapIssueToCall(issue, ctx) {
|
|
|
821
624
|
const namespaceId = resolveNamespaceIdForIssue(issue);
|
|
822
625
|
const column = tableAt(ctx.toContract.storage, namespaceId, issue.table)?.columns[issue.column];
|
|
823
626
|
if (!column) return notOk(issueConflict("unsupportedOperation", `Column "${issue.table}"."${issue.column}" not in destination contract`));
|
|
824
|
-
return ok([new AddColumnCall(tableSchema(issue), issue.table,
|
|
627
|
+
return ok([new AddColumnCall(tableSchema(issue), issue.table, toDdlColumn(issue.column, column, codecHooks, storageTypes))]);
|
|
825
628
|
}
|
|
826
629
|
case "default_missing":
|
|
827
630
|
if (!issue.table || !issue.column) return notOk(issueConflict("unsupportedOperation", "Default missing issue has no table/column name"));
|
|
@@ -960,12 +763,9 @@ function mapIssueToCall(issue, ctx) {
|
|
|
960
763
|
return notOk(issueConflict("foreignKeyConflict", `Foreign key on "${issue.table}" differs (expected: ${issue.expected}, actual: ${issue.actual})`, { table: issue.table }));
|
|
961
764
|
case "type_missing": {
|
|
962
765
|
if (!issue.typeName) return notOk(issueConflict("unsupportedOperation", "Type missing issue has no typeName"));
|
|
963
|
-
const
|
|
964
|
-
const typeInstance = ctx.toContract.storage.types?.[issue.typeName] ?? locateNamespaceTypeInStorage(ctx.toContract.storage, namespaceId, issue.typeName);
|
|
766
|
+
const typeInstance = ctx.toContract.storage.types?.[issue.typeName];
|
|
965
767
|
if (!typeInstance) return notOk(issueConflict("unsupportedOperation", `Type "${issue.typeName}" reported missing but not found in destination contract`));
|
|
966
|
-
|
|
967
|
-
const codecInstance = typeInstance;
|
|
968
|
-
return notOk(issueConflict("unsupportedOperation", `Type "${issue.typeName}" uses codec "${codecInstance.codecId}" — only enum types are supported`));
|
|
768
|
+
return notOk(issueConflict("unsupportedOperation", `Type "${issue.typeName}" uses codec "${typeInstance.codecId}" — only value-set types are supported`));
|
|
969
769
|
}
|
|
970
770
|
case "type_values_mismatch": return notOk(issueConflict("unsupportedOperation", `Type "${issue.typeName ?? "unknown"}" values differ — type alteration not yet supported`));
|
|
971
771
|
default: return notOk(issueConflict("unsupportedOperation", `Unhandled issue kind: ${issue.kind}`));
|
|
@@ -980,11 +780,7 @@ function mapIssueToCall(issue, ctx) {
|
|
|
980
780
|
function classifyCall(call) {
|
|
981
781
|
switch (call.factoryName) {
|
|
982
782
|
case "createExtension":
|
|
983
|
-
case "createSchema":
|
|
984
|
-
case "createEnumType":
|
|
985
|
-
case "addEnumValues":
|
|
986
|
-
case "dropEnumType":
|
|
987
|
-
case "renameType": return "dep";
|
|
783
|
+
case "createSchema": return "dep";
|
|
988
784
|
case "dropTable":
|
|
989
785
|
case "dropColumn":
|
|
990
786
|
case "dropConstraint":
|
|
@@ -1135,4 +931,4 @@ function planIssues(options) {
|
|
|
1135
931
|
//#endregion
|
|
1136
932
|
export { postgresPlannerStrategies as n, planIssues as t };
|
|
1137
933
|
|
|
1138
|
-
//# sourceMappingURL=issue-planner-
|
|
934
|
+
//# sourceMappingURL=issue-planner-DsjB7xDj.mjs.map
|