@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.
Files changed (190) hide show
  1. package/dist/{codec-ids-CTikp1if.mjs → codec-ids-BvytN2P8.mjs} +3 -3
  2. package/dist/codec-ids-BvytN2P8.mjs.map +1 -0
  3. package/dist/{codec-ids-B1vOchLE.d.mts → codec-ids-CnXu9Qy3.d.mts} +3 -3
  4. package/dist/codec-ids-CnXu9Qy3.d.mts.map +1 -0
  5. package/dist/codec-ids.d.mts +2 -2
  6. package/dist/codec-ids.mjs +2 -2
  7. package/dist/{codec-types-CnFiNML4.d.mts → codec-types-DHCkwPKE.d.mts} +3 -3
  8. package/dist/{codec-types-CnFiNML4.d.mts.map → codec-types-DHCkwPKE.d.mts.map} +1 -1
  9. package/dist/codec-types.d.mts +1 -1
  10. package/dist/{codecs-CBpEv4s5.d.mts → codecs--0A5_4Bq.d.mts} +26 -23
  11. package/dist/codecs--0A5_4Bq.d.mts.map +1 -0
  12. package/dist/codecs.d.mts +2 -2
  13. package/dist/codecs.mjs +28 -35
  14. package/dist/codecs.mjs.map +1 -1
  15. package/dist/contract-free.d.mts +163 -15
  16. package/dist/contract-free.d.mts.map +1 -1
  17. package/dist/contract-free.mjs +4 -17
  18. package/dist/contract-free.mjs.map +1 -1
  19. package/dist/control.d.mts.map +1 -1
  20. package/dist/control.mjs +21 -27
  21. package/dist/control.mjs.map +1 -1
  22. package/dist/{data-transform-D25tLeYU.mjs → data-transform-BOWpliq8.mjs} +9 -17
  23. package/dist/data-transform-BOWpliq8.mjs.map +1 -0
  24. package/dist/{data-transform-DGOqcLrf.d.mts → data-transform-DDgWdB5o.d.mts} +2 -2
  25. package/dist/data-transform-DDgWdB5o.d.mts.map +1 -0
  26. package/dist/data-transform.d.mts +1 -1
  27. package/dist/data-transform.mjs +1 -1
  28. package/dist/ddl-QDyOSeLc.mjs +251 -0
  29. package/dist/ddl-QDyOSeLc.mjs.map +1 -0
  30. package/dist/ddl.d.mts +2 -2
  31. package/dist/ddl.mjs +2 -2
  32. package/dist/descriptor-meta-CpGygXpI.mjs +140 -0
  33. package/dist/descriptor-meta-CpGygXpI.mjs.map +1 -0
  34. package/dist/{issue-planner-Br0pt1Ea.mjs → issue-planner-DL6g3CmE.mjs} +52 -366
  35. package/dist/issue-planner-DL6g3CmE.mjs.map +1 -0
  36. package/dist/issue-planner.d.mts +8 -11
  37. package/dist/issue-planner.d.mts.map +1 -1
  38. package/dist/issue-planner.mjs +1 -1
  39. package/dist/migration.d.mts +5 -92
  40. package/dist/migration.d.mts.map +1 -1
  41. package/dist/migration.mjs +4 -4
  42. package/dist/{nodes-DZk2JZG3.mjs → nodes-Bbhs2rwj.mjs} +31 -2
  43. package/dist/nodes-Bbhs2rwj.mjs.map +1 -0
  44. package/dist/{nodes-779hmCfL.d.mts → nodes-pLeLgdis.d.mts} +30 -3
  45. package/dist/nodes-pLeLgdis.d.mts.map +1 -0
  46. package/dist/{op-factory-call-D2aAUhmS.mjs → op-factory-call-D_p5vxwt.mjs} +601 -418
  47. package/dist/op-factory-call-D_p5vxwt.mjs.map +1 -0
  48. package/dist/{op-factory-call-DMA86_2D.d.mts → op-factory-call-DmQEc3XV.d.mts} +119 -72
  49. package/dist/op-factory-call-DmQEc3XV.d.mts.map +1 -0
  50. package/dist/op-factory-call.d.mts +2 -2
  51. package/dist/op-factory-call.mjs +2 -2
  52. package/dist/pack.d.mts +36 -15
  53. package/dist/pack.d.mts.map +1 -1
  54. package/dist/pack.mjs +1 -1
  55. package/dist/{planner-CAYPJObw.mjs → planner-Bs_baQax.mjs} +25 -45
  56. package/dist/planner-Bs_baQax.mjs.map +1 -0
  57. package/dist/{planner-ddl-builders-Cw2n2llW.mjs → planner-ddl-builders-B2wOwLqI.mjs} +2 -2
  58. package/dist/planner-ddl-builders-B2wOwLqI.mjs.map +1 -0
  59. package/dist/planner-ddl-builders.d.mts +4 -4
  60. package/dist/planner-ddl-builders.d.mts.map +1 -1
  61. package/dist/planner-ddl-builders.mjs +1 -1
  62. package/dist/{planner-identity-values-BIpa5p2I.mjs → planner-identity-values-CJPha2Sz.mjs} +3 -9
  63. package/dist/planner-identity-values-CJPha2Sz.mjs.map +1 -0
  64. package/dist/planner-identity-values.d.mts +1 -1
  65. package/dist/planner-identity-values.d.mts.map +1 -1
  66. package/dist/planner-identity-values.mjs +1 -1
  67. package/dist/{planner-produced-postgres-migration-NSEhWL0L.mjs → planner-produced-postgres-migration-Cji5vxUf.mjs} +6 -4
  68. package/dist/planner-produced-postgres-migration-Cji5vxUf.mjs.map +1 -0
  69. package/dist/{planner-produced-postgres-migration-B4EDvLdz.d.mts → planner-produced-postgres-migration-QqHa2C2l.d.mts} +5 -6
  70. package/dist/planner-produced-postgres-migration-QqHa2C2l.d.mts.map +1 -0
  71. package/dist/planner-produced-postgres-migration.d.mts +1 -1
  72. package/dist/planner-produced-postgres-migration.mjs +1 -1
  73. package/dist/planner-sql-checks-jqUUGyQR.mjs +152 -0
  74. package/dist/planner-sql-checks-jqUUGyQR.mjs.map +1 -0
  75. package/dist/planner-sql-checks.d.mts +3 -49
  76. package/dist/planner-sql-checks.d.mts.map +1 -1
  77. package/dist/planner-sql-checks.mjs +2 -2
  78. package/dist/{planner-type-resolution-836DExFN.mjs → planner-type-resolution-Bt2f_q-F.mjs} +1 -6
  79. package/dist/planner-type-resolution-Bt2f_q-F.mjs.map +1 -0
  80. package/dist/planner.d.mts +4 -4
  81. package/dist/planner.d.mts.map +1 -1
  82. package/dist/planner.mjs +1 -1
  83. package/dist/{postgres-contract-serializer-DYTyXjPf.mjs → postgres-contract-serializer-k3TAcPMY.mjs} +30 -37
  84. package/dist/postgres-contract-serializer-k3TAcPMY.mjs.map +1 -0
  85. package/dist/postgres-migration-B5jKrXv3.mjs +145 -0
  86. package/dist/postgres-migration-B5jKrXv3.mjs.map +1 -0
  87. package/dist/postgres-migration-Y4YBJqkS.d.mts +181 -0
  88. package/dist/postgres-migration-Y4YBJqkS.d.mts.map +1 -0
  89. package/dist/{postgres-schema-BuxCxbvB.mjs → postgres-schema-COGZ1ark.mjs} +82 -23
  90. package/dist/postgres-schema-COGZ1ark.mjs.map +1 -0
  91. package/dist/{render-ops-BpjstrKQ.mjs → render-ops-BREh1kHe.mjs} +10 -5
  92. package/dist/render-ops-BREh1kHe.mjs.map +1 -0
  93. package/dist/render-ops.d.mts +2 -2
  94. package/dist/render-ops.d.mts.map +1 -1
  95. package/dist/render-ops.mjs +1 -1
  96. package/dist/runtime.d.mts +1 -0
  97. package/dist/runtime.d.mts.map +1 -1
  98. package/dist/runtime.mjs +2 -2
  99. package/dist/table-source-BvFo7gVs.d.mts +15 -0
  100. package/dist/table-source-BvFo7gVs.d.mts.map +1 -0
  101. package/dist/types.d.mts +34 -19
  102. package/dist/types.d.mts.map +1 -1
  103. package/dist/types.mjs +2 -3
  104. package/package.json +17 -18
  105. package/src/contract-free/checks.ts +363 -0
  106. package/src/contract-free/ddl.ts +28 -1
  107. package/src/core/authoring.ts +43 -44
  108. package/src/core/codec-helpers.ts +0 -17
  109. package/src/core/codec-ids.ts +1 -1
  110. package/src/core/codec-type-map.ts +2 -2
  111. package/src/core/codecs.ts +43 -48
  112. package/src/core/ddl/nodes.ts +59 -1
  113. package/src/core/migrations/control-policy.ts +17 -47
  114. package/src/core/migrations/issue-planner.ts +34 -70
  115. package/src/core/migrations/op-factory-call.ts +486 -215
  116. package/src/core/migrations/operations/columns.ts +175 -140
  117. package/src/core/migrations/operations/constraints.ts +79 -108
  118. package/src/core/migrations/operations/data-transform.ts +15 -18
  119. package/src/core/migrations/operations/dependencies.ts +16 -14
  120. package/src/core/migrations/operations/indexes.ts +31 -28
  121. package/src/core/migrations/operations/shared.ts +2 -2
  122. package/src/core/migrations/operations/tables.ts +13 -14
  123. package/src/core/migrations/planner-ddl-builders.ts +3 -4
  124. package/src/core/migrations/planner-identity-values.ts +4 -28
  125. package/src/core/migrations/planner-produced-postgres-migration.ts +15 -7
  126. package/src/core/migrations/planner-recipes.ts +44 -39
  127. package/src/core/migrations/planner-sql-checks.ts +3 -178
  128. package/src/core/migrations/planner-strategies.ts +76 -449
  129. package/src/core/migrations/planner-type-resolution.ts +2 -20
  130. package/src/core/migrations/planner.ts +6 -6
  131. package/src/core/migrations/postgres-migration.ts +287 -7
  132. package/src/core/migrations/render-ops.ts +26 -13
  133. package/src/core/migrations/runner.ts +26 -20
  134. package/src/core/postgres-contract-serializer.ts +37 -54
  135. package/src/core/postgres-enum-type-schema.ts +17 -0
  136. package/src/core/postgres-schema.ts +86 -46
  137. package/src/exports/codecs.ts +2 -2
  138. package/src/exports/contract-free.ts +22 -1
  139. package/src/exports/control.ts +0 -22
  140. package/src/exports/ddl.ts +4 -0
  141. package/src/exports/migration.ts +1 -29
  142. package/src/exports/op-factory-call.ts +0 -4
  143. package/src/exports/planner-sql-checks.ts +0 -7
  144. package/src/exports/types.ts +0 -1
  145. package/dist/codec-ids-B1vOchLE.d.mts.map +0 -1
  146. package/dist/codec-ids-CTikp1if.mjs.map +0 -1
  147. package/dist/codecs-CBpEv4s5.d.mts.map +0 -1
  148. package/dist/data-transform-D25tLeYU.mjs.map +0 -1
  149. package/dist/data-transform-DGOqcLrf.d.mts.map +0 -1
  150. package/dist/ddl-77SyXgFt.mjs +0 -30
  151. package/dist/ddl-77SyXgFt.mjs.map +0 -1
  152. package/dist/descriptor-meta-DKmj-IMN.mjs +0 -14
  153. package/dist/descriptor-meta-DKmj-IMN.mjs.map +0 -1
  154. package/dist/descriptor-meta-runtime-My8_s4cs.mjs +0 -130
  155. package/dist/descriptor-meta-runtime-My8_s4cs.mjs.map +0 -1
  156. package/dist/enum-planning-BCyvlFHk.mjs +0 -0
  157. package/dist/enum-planning-BCyvlFHk.mjs.map +0 -1
  158. package/dist/enum-planning.d.mts +0 -86
  159. package/dist/enum-planning.d.mts.map +0 -1
  160. package/dist/enum-planning.mjs +0 -2
  161. package/dist/issue-planner-Br0pt1Ea.mjs.map +0 -1
  162. package/dist/nodes-779hmCfL.d.mts.map +0 -1
  163. package/dist/nodes-DZk2JZG3.mjs.map +0 -1
  164. package/dist/op-factory-call-D2aAUhmS.mjs.map +0 -1
  165. package/dist/op-factory-call-DMA86_2D.d.mts.map +0 -1
  166. package/dist/planner-CAYPJObw.mjs.map +0 -1
  167. package/dist/planner-ddl-builders-Cw2n2llW.mjs.map +0 -1
  168. package/dist/planner-identity-values-BIpa5p2I.mjs.map +0 -1
  169. package/dist/planner-produced-postgres-migration-B4EDvLdz.d.mts.map +0 -1
  170. package/dist/planner-produced-postgres-migration-NSEhWL0L.mjs.map +0 -1
  171. package/dist/planner-sql-checks-DAdhnI2c.mjs +0 -272
  172. package/dist/planner-sql-checks-DAdhnI2c.mjs.map +0 -1
  173. package/dist/planner-type-resolution-836DExFN.mjs.map +0 -1
  174. package/dist/postgres-contract-serializer-DYTyXjPf.mjs.map +0 -1
  175. package/dist/postgres-enum-type-BVn63a89.d.mts +0 -72
  176. package/dist/postgres-enum-type-BVn63a89.d.mts.map +0 -1
  177. package/dist/postgres-enum-type-DPKqCBem.mjs +0 -62
  178. package/dist/postgres-enum-type-DPKqCBem.mjs.map +0 -1
  179. package/dist/postgres-migration-COore9Mz.mjs +0 -71
  180. package/dist/postgres-migration-COore9Mz.mjs.map +0 -1
  181. package/dist/postgres-migration-DZ_gLUOW.d.mts +0 -72
  182. package/dist/postgres-migration-DZ_gLUOW.d.mts.map +0 -1
  183. package/dist/postgres-schema-BuxCxbvB.mjs.map +0 -1
  184. package/dist/render-ops-BpjstrKQ.mjs.map +0 -1
  185. package/dist/shared-DarONYBZ.d.mts +0 -43
  186. package/dist/shared-DarONYBZ.d.mts.map +0 -1
  187. package/src/core/migrations/enum-planning.ts +0 -213
  188. package/src/core/migrations/operations/enums.ts +0 -114
  189. package/src/core/postgres-enum-type.ts +0 -89
  190. package/src/exports/enum-planning.ts +0 -11
@@ -1,96 +1,20 @@
1
- import { t as PostgresEnumType } from "./postgres-enum-type-DPKqCBem.mjs";
2
- import { i as quoteIdentifier } from "./sql-utils-DcfMz4MQ.mjs";
3
- import { r as isPostgresSchema } from "./postgres-schema-BuxCxbvB.mjs";
4
- import { a as readExistingEnumValues, n as determineEnumDiff, s as resolveDdlSchemaForNamespaceStorage } from "./enum-planning-BCyvlFHk.mjs";
5
- import { a as columnNullabilityCheck, c as qualifyTableName, i as columnHasNoDefaultCheck, r as columnExistsCheck, t as buildExpectedFormatType, u as tableIsEmptyCheck } from "./planner-sql-checks-DAdhnI2c.mjs";
6
- import { C as RenameTypeCall, E as postgresDefaultToDdlColumnDefault, S as RawSqlCall, T as SetNotNullCall, _ as DropDefaultCall, a as AddPrimaryKeyCall, b as DropNotNullCall, c as CreateEnumTypeCall, d as CreateSchemaCall, f as CreateTableCall, g as DropConstraintCall, h as DropColumnCall, i as AddForeignKeyCall, m as DropCheckConstraintCall, n as AddColumnCall, o as AddUniqueCall, p as DataTransformCall, r as AddEnumValuesCall, s as AlterColumnTypeCall, t as AddCheckConstraintCall, u as CreateIndexCall, v as DropEnumTypeCall, w as SetDefaultCall, x as DropTableCall, y as DropIndexCall } from "./op-factory-call-D2aAUhmS.mjs";
7
- import { n as buildColumnDefaultSql, r as buildColumnTypeSql, t as buildAddColumnSql } from "./planner-ddl-builders-Cw2n2llW.mjs";
8
- import { n as resolveIdentityValue } from "./planner-identity-values-BIpa5p2I.mjs";
1
+ import { r as isPostgresSchema } from "./postgres-schema-COGZ1ark.mjs";
2
+ import { t as resolveColumnTypeMetadata } from "./planner-type-resolution-Bt2f_q-F.mjs";
3
+ import { n as qualifyTableName, t as buildExpectedFormatType } from "./planner-sql-checks-jqUUGyQR.mjs";
4
+ import { C as SetNotNullCall, S as SetDefaultCall, T as buildTargetDetails, _ as DropDefaultCall, a as AddNotNullColumnWithTempDefaultCall, b as DropTableCall, c as AlterColumnTypeCall, d as CreateSchemaCall, f as CreateTableCall, g as DropConstraintCall, h as DropColumnCall, i as AddNotNullColumnDirectCall, m as DropCheckConstraintCall, n as AddColumnCall, o as AddPrimaryKeyCall, p as DataTransformCall, r as AddForeignKeyCall, s as AddUniqueCall, t as AddCheckConstraintCall, u as CreateIndexCall, v as DropIndexCall, w as postgresDefaultToDdlColumnDefault, x as RawSqlCall, y as DropNotNullCall } from "./op-factory-call-D_p5vxwt.mjs";
5
+ import { n as buildColumnDefaultSql, r as buildColumnTypeSql, t as buildAddColumnSql } from "./planner-ddl-builders-B2wOwLqI.mjs";
6
+ import { n as resolveIdentityValue } from "./planner-identity-values-CJPha2Sz.mjs";
9
7
  import { i as hasUniqueConstraint, n as hasForeignKey, t as buildSchemaLookupMap } from "./planner-schema-lookup-CiVaAQP-.mjs";
8
+ import { blindCast } from "@prisma-next/utils/casts";
10
9
  import { resolveValueSetValues } from "@prisma-next/family-sql/control";
11
10
  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
11
  import { arraysEqual } from "@prisma-next/family-sql/schema-verify";
15
- import { blindCast } from "@prisma-next/utils/casts";
12
+ import { UNBOUND_NAMESPACE_ID } from "@prisma-next/framework-components/ir";
16
13
  import * as contractFree from "@prisma-next/sql-relational-core/contract-free";
14
+ import { col } from "@prisma-next/sql-relational-core/contract-free";
17
15
  import { notOk, ok } from "@prisma-next/utils/result";
18
- //#region src/core/migrations/planner-target-details.ts
19
- function buildTargetDetails(objectType, name, schema, table) {
20
- return {
21
- schema,
22
- objectType,
23
- name,
24
- ...ifDefined("table", table)
25
- };
26
- }
27
- //#endregion
28
- //#region src/core/migrations/planner-recipes.ts
29
- function buildAddColumnOperationIdentity(schema, tableName, columnName) {
30
- return {
31
- id: `column.${tableName}.${columnName}`,
32
- label: `Add column ${columnName} to ${tableName}`,
33
- summary: `Adds column ${columnName} to table ${tableName}`,
34
- target: {
35
- id: "postgres",
36
- details: buildTargetDetails("table", tableName, schema)
37
- }
38
- };
39
- }
40
- function buildAddNotNullColumnWithTemporaryDefaultOperation(options) {
41
- const { schema, tableName, columnName, column, codecHooks, storageTypes, temporaryDefault } = options;
42
- const qualified = qualifyTableName(schema, tableName);
43
- return {
44
- ...buildAddColumnOperationIdentity(schema, tableName, columnName),
45
- operationClass: "additive",
46
- precheck: [{
47
- description: `ensure column "${columnName}" is missing`,
48
- sql: columnExistsCheck({
49
- schema,
50
- table: tableName,
51
- column: columnName,
52
- exists: false
53
- })
54
- }],
55
- execute: [{
56
- description: `add column "${columnName}"`,
57
- sql: buildAddColumnSql(qualified, columnName, column, codecHooks, temporaryDefault, storageTypes)
58
- }, {
59
- description: `drop temporary default from column "${columnName}"`,
60
- sql: `ALTER TABLE ${qualified} ALTER COLUMN ${quoteIdentifier(columnName)} DROP DEFAULT`
61
- }],
62
- postcheck: [
63
- {
64
- description: `verify column "${columnName}" exists`,
65
- sql: columnExistsCheck({
66
- schema,
67
- table: tableName,
68
- column: columnName
69
- })
70
- },
71
- {
72
- description: `verify column "${columnName}" is NOT NULL`,
73
- sql: columnNullabilityCheck({
74
- schema,
75
- table: tableName,
76
- column: columnName,
77
- nullable: false
78
- })
79
- },
80
- {
81
- description: `verify column "${columnName}" has no default after temporary default removal`,
82
- sql: columnHasNoDefaultCheck({
83
- schema,
84
- table: tableName,
85
- column: columnName
86
- })
87
- }
88
- ]
89
- };
90
- }
91
- //#endregion
16
+ import { StorageTable } from "@prisma-next/sql-contract/types";
92
17
  //#region src/core/migrations/planner-strategies.ts
93
- const REBUILD_SUFFIX = "__prisma_next_new";
94
18
  /**
95
19
  * Look up a storage table by its explicit namespace coordinate. Returns
96
20
  * `undefined` when the namespace has no table by that name (or no such
@@ -102,7 +26,9 @@ const REBUILD_SUFFIX = "__prisma_next_new";
102
26
  * contracts where two namespaces can carry the same table name).
103
27
  */
104
28
  function tableAt(storage, namespaceId, tableName) {
105
- return storage.namespaces[namespaceId]?.entries.table[tableName];
29
+ const ns = storage.namespaces[namespaceId];
30
+ if (ns === void 0) return void 0;
31
+ return ns.entries.table?.[tableName];
106
32
  }
107
33
  /**
108
34
  * Default namespace coordinate for an issue that does not carry one
@@ -131,57 +57,24 @@ function resolveDdlSchemaForNamespace(ctx, namespaceId) {
131
57
  if (isPostgresSchema(namespace)) return namespace.ddlSchemaName(ctx.toContract.storage);
132
58
  return namespaceId;
133
59
  }
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
60
  function buildColumnSpec(namespaceId, table, column, ctx, overrides) {
174
- const col = tableAt(ctx.toContract.storage, namespaceId, table)?.columns[column];
175
- if (!col) throw new Error(`Column "${table}"."${column}" not found in destination contract`);
61
+ const storageCol = tableAt(ctx.toContract.storage, namespaceId, table)?.columns[column];
62
+ if (!storageCol) throw new Error(`Column "${table}"."${column}" not found in destination contract`);
176
63
  const mutableHooks = ctx.codecHooks;
177
64
  const mutableTypes = ctx.storageTypes;
178
- return {
179
- name: column,
180
- typeSql: buildColumnTypeSql(col, mutableHooks, mutableTypes),
181
- defaultSql: buildColumnDefaultSql(col.default, col),
182
- columnDefault: col.default,
183
- nullable: overrides?.nullable ?? col.nullable
184
- };
65
+ const typeSql = buildColumnTypeSql(storageCol, mutableHooks, mutableTypes);
66
+ const ddlDefault = postgresDefaultToDdlColumnDefault(storageCol.default);
67
+ const resolved = resolveColumnTypeMetadata(storageCol, mutableTypes);
68
+ const typeParams = resolved.typeParams === void 0 ? void 0 : blindCast(resolved.typeParams);
69
+ const codecRef = resolved.codecId ? {
70
+ codecId: resolved.codecId,
71
+ ...ifDefined("typeParams", typeParams)
72
+ } : void 0;
73
+ return col(column, typeSql, {
74
+ ...!(overrides?.nullable ?? storageCol.nullable) ? { notNull: true } : {},
75
+ ...ifDefined("default", ddlDefault),
76
+ ...ifDefined("codecRef", codecRef)
77
+ });
185
78
  }
186
79
  function buildAlterTypeOptions(namespaceId, table, column, ctx, using) {
187
80
  const col = tableAt(ctx.toContract.storage, namespaceId, table)?.columns[column];
@@ -277,154 +170,13 @@ const nullableTighteningCallStrategy = (issues, ctx) => {
277
170
  recipe: true
278
171
  };
279
172
  };
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
173
  /**
423
174
  * Collects every check constraint from a table in the contract storage.
424
175
  * Returns an empty array when the table has no checks or the table is absent.
425
176
  */
426
177
  function collectContractChecks(storage, namespaceId, tableName) {
427
- const tableRaw = storage.namespaces[namespaceId]?.entries.table[tableName];
178
+ const ns = storage.namespaces[namespaceId];
179
+ const tableRaw = ns !== void 0 ? ns.entries.table?.[tableName] : void 0;
428
180
  if (!(tableRaw instanceof StorageTable)) return [];
429
181
  const checks = tableRaw.checks;
430
182
  if (!checks || checks.length === 0) return [];
@@ -456,13 +208,11 @@ function checkValueSetsEqual(a, b) {
456
208
  * be altered in place).
457
209
  *
458
210
  * Consumes `check_missing`, `check_removed`, and `check_mismatch` issues.
459
- * Does not touch the native enum path (`nativeEnumPlanCallStrategy` is
460
- * unchanged).
461
211
  */
462
212
  const checkConstraintPlanCallStrategy = (issues, ctx) => {
463
213
  const calls = [];
464
214
  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)) {
215
+ for (const [namespaceId, ns] of Object.entries(ctx.toContract.storage.namespaces)) for (const tableName of Object.keys(ns.entries.table ?? {})) {
466
216
  const contractChecks = collectContractChecks(ctx.toContract.storage, namespaceId, tableName);
467
217
  if (contractChecks.length === 0) continue;
468
218
  const liveChecks = ctx.schema.tables[tableName]?.checks ?? [];
@@ -497,10 +247,9 @@ const checkConstraintPlanCallStrategy = (issues, ctx) => {
497
247
  };
498
248
  };
499
249
  /**
500
- * Dispatches non-enum codec-typed storage types through their codec's
250
+ * Dispatches codec-typed storage types through their codec's
501
251
  * `planTypeOperations` hook (the authoritative source for codec-driven DDL
502
- * such as custom type creation). Enum dispatch lives in
503
- * `nativeEnumPlanCallStrategy` and no longer relies on codec hooks.
252
+ * such as custom type creation).
504
253
  */
505
254
  const storageTypePlanCallStrategy = (issues, ctx) => {
506
255
  const storageTypes = ctx.toContract.storage.types ?? {};
@@ -508,7 +257,6 @@ const storageTypePlanCallStrategy = (issues, ctx) => {
508
257
  const calls = [];
509
258
  const handledTypeNames = /* @__PURE__ */ new Set();
510
259
  for (const [typeName, typeInstance] of Object.entries(storageTypes).sort(([a], [b]) => a.localeCompare(b))) {
511
- if (isPostgresEnumStorageEntry(typeInstance)) continue;
512
260
  const codecInstance = typeInstance;
513
261
  const hook = ctx.codecHooks.get(codecInstance.codecId);
514
262
  if (!hook?.planTypeOperations) continue;
@@ -584,54 +332,19 @@ const notNullAddColumnCallStrategy = (issues, ctx) => {
584
332
  matched.push(issue);
585
333
  const schemaForTable = resolveDdlSchemaForNamespace(ctx, namespaceId);
586
334
  if (canUseSharedTempDefault && temporaryDefault !== null) {
587
- calls.push(new RawSqlCall(buildAddNotNullColumnWithTemporaryDefaultOperation({
588
- schema: schemaForTable,
335
+ calls.push(new AddNotNullColumnWithTempDefaultCall({
336
+ schemaName: schemaForTable,
589
337
  tableName: issue.table,
590
338
  columnName: issue.column,
591
339
  column,
592
340
  codecHooks: mutableCodecHooks,
593
341
  storageTypes: mutableStorageTypes,
594
342
  temporaryDefault
595
- })));
343
+ }));
596
344
  continue;
597
345
  }
598
346
  const qualified = qualifyTableName(schemaForTable, issue.table);
599
- calls.push(new RawSqlCall({
600
- ...buildAddColumnOperationIdentity(schemaForTable, issue.table, issue.column),
601
- operationClass: "additive",
602
- precheck: [{
603
- description: `ensure column "${issue.column}" is missing`,
604
- sql: columnExistsCheck({
605
- schema: schemaForTable,
606
- table: issue.table,
607
- column: issue.column,
608
- exists: false
609
- })
610
- }, {
611
- description: `ensure table "${issue.table}" is empty before adding NOT NULL column without default`,
612
- sql: tableIsEmptyCheck(qualified)
613
- }],
614
- execute: [{
615
- description: `add column "${issue.column}"`,
616
- sql: buildAddColumnSql(qualified, issue.column, column, mutableCodecHooks, void 0, mutableStorageTypes)
617
- }],
618
- postcheck: [{
619
- description: `verify column "${issue.column}" exists`,
620
- sql: columnExistsCheck({
621
- schema: schemaForTable,
622
- table: issue.table,
623
- column: issue.column
624
- })
625
- }, {
626
- description: `verify column "${issue.column}" is NOT NULL`,
627
- sql: columnNullabilityCheck({
628
- schema: schemaForTable,
629
- table: issue.table,
630
- column: issue.column,
631
- nullable: false
632
- })
633
- }]
634
- }));
347
+ calls.push(new AddNotNullColumnDirectCall(schemaForTable, issue.table, issue.column, buildAddColumnSql(qualified, issue.column, column, mutableCodecHooks, void 0, mutableStorageTypes)));
635
348
  }
636
349
  if (matched.length === 0) return { kind: "no_match" };
637
350
  return {
@@ -662,8 +375,7 @@ function canUseSharedTemporaryDefaultStrategy(options) {
662
375
  *
663
376
  * - When `'data'` is allowed (`migration plan`), the data-safe strategies
664
377
  * (`notNullBackfillCallStrategy`, `typeChangeCallStrategy`,
665
- * `nullableTighteningCallStrategy`) and the enum walk
666
- * (`nativeEnumPlanCallStrategy`) consume their matching issues and emit
378
+ * `nullableTighteningCallStrategy`) consume their matching issues and emit
667
379
  * `DataTransformCall` placeholders or recipe ops.
668
380
  *
669
381
  * - When `'data'` is not allowed (`db update` / `db init`), the
@@ -671,37 +383,20 @@ function canUseSharedTemporaryDefaultStrategy(options) {
671
383
  * the issue for the downstream walk-schema strategies
672
384
  * (`storageTypePlanCallStrategy`, `notNullAddColumnCallStrategy`) or the
673
385
  * `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
386
  *
679
- * Enum dispatch is unified into a single strategy: the
680
- * `nativeEnumPlanCallStrategy` decides per-emission whether to emit a
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`.
387
+ * Codec-typed storage type entries are dispatched through
388
+ * `storageTypePlanCallStrategy`.
685
389
  */
686
390
  const postgresPlannerStrategies = [
687
391
  notNullBackfillCallStrategy,
688
392
  typeChangeCallStrategy,
689
393
  nullableTighteningCallStrategy,
690
- nativeEnumPlanCallStrategy,
691
394
  checkConstraintPlanCallStrategy,
692
395
  storageTypePlanCallStrategy,
693
396
  notNullAddColumnCallStrategy
694
397
  ];
695
398
  //#endregion
696
399
  //#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
400
  const ISSUE_KIND_ORDER = {
706
401
  missing_schema: 1,
707
402
  type_missing: 2,
@@ -743,20 +438,18 @@ function isMissing(issue) {
743
438
  if (issue.kind === "enum_values_changed") return false;
744
439
  return issue.actual === void 0;
745
440
  }
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
441
  function toDdlColumn(name, column, codecHooks, storageTypes) {
755
442
  const typeSql = buildColumnTypeSql(column, codecHooks, storageTypes);
756
443
  const ddlDefault = postgresDefaultToDdlColumnDefault(column.default);
444
+ const resolved = resolveColumnTypeMetadata(column, storageTypes);
445
+ const codecRef = resolved.codecId ? {
446
+ codecId: resolved.codecId,
447
+ ...resolved.typeParams !== void 0 ? { typeParams: blindCast(resolved.typeParams) } : {}
448
+ } : void 0;
757
449
  return contractFree.col(name, typeSql, {
758
450
  ...!column.nullable ? { notNull: true } : {},
759
- ...ddlDefault ? { default: ddlDefault } : {}
451
+ ...ifDefined("default", ddlDefault),
452
+ ...ifDefined("codecRef", codecRef)
760
453
  });
761
454
  }
762
455
  function mapIssueToCall(issue, ctx) {
@@ -821,7 +514,7 @@ function mapIssueToCall(issue, ctx) {
821
514
  const namespaceId = resolveNamespaceIdForIssue(issue);
822
515
  const column = tableAt(ctx.toContract.storage, namespaceId, issue.table)?.columns[issue.column];
823
516
  if (!column) return notOk(issueConflict("unsupportedOperation", `Column "${issue.table}"."${issue.column}" not in destination contract`));
824
- return ok([new AddColumnCall(tableSchema(issue), issue.table, toColumnSpec(issue.column, column, codecHooks, storageTypes))]);
517
+ return ok([new AddColumnCall(tableSchema(issue), issue.table, toDdlColumn(issue.column, column, codecHooks, storageTypes))]);
825
518
  }
826
519
  case "default_missing":
827
520
  if (!issue.table || !issue.column) return notOk(issueConflict("unsupportedOperation", "Default missing issue has no table/column name"));
@@ -960,12 +653,9 @@ function mapIssueToCall(issue, ctx) {
960
653
  return notOk(issueConflict("foreignKeyConflict", `Foreign key on "${issue.table}" differs (expected: ${issue.expected}, actual: ${issue.actual})`, { table: issue.table }));
961
654
  case "type_missing": {
962
655
  if (!issue.typeName) return notOk(issueConflict("unsupportedOperation", "Type missing issue has no typeName"));
963
- const namespaceId = resolveNamespaceIdForIssue(issue);
964
- const typeInstance = ctx.toContract.storage.types?.[issue.typeName] ?? locateNamespaceTypeInStorage(ctx.toContract.storage, namespaceId, issue.typeName);
656
+ const typeInstance = ctx.toContract.storage.types?.[issue.typeName];
965
657
  if (!typeInstance) return notOk(issueConflict("unsupportedOperation", `Type "${issue.typeName}" reported missing but not found in destination contract`));
966
- if (typeInstance instanceof PostgresEnumType) return ok([new CreateEnumTypeCall(resolveDdlSchemaForNamespace(ctx, namespaceId), issue.typeName, typeInstance.values, typeInstance.nativeType)]);
967
- const codecInstance = typeInstance;
968
- return notOk(issueConflict("unsupportedOperation", `Type "${issue.typeName}" uses codec "${codecInstance.codecId}" — only enum types are supported`));
658
+ return notOk(issueConflict("unsupportedOperation", `Type "${issue.typeName}" uses codec "${typeInstance.codecId}" — only value-set types are supported`));
969
659
  }
970
660
  case "type_values_mismatch": return notOk(issueConflict("unsupportedOperation", `Type "${issue.typeName ?? "unknown"}" values differ — type alteration not yet supported`));
971
661
  default: return notOk(issueConflict("unsupportedOperation", `Unhandled issue kind: ${issue.kind}`));
@@ -980,11 +670,7 @@ function mapIssueToCall(issue, ctx) {
980
670
  function classifyCall(call) {
981
671
  switch (call.factoryName) {
982
672
  case "createExtension":
983
- case "createSchema":
984
- case "createEnumType":
985
- case "addEnumValues":
986
- case "dropEnumType":
987
- case "renameType": return "dep";
673
+ case "createSchema": return "dep";
988
674
  case "dropTable":
989
675
  case "dropColumn":
990
676
  case "dropConstraint":
@@ -1135,4 +821,4 @@ function planIssues(options) {
1135
821
  //#endregion
1136
822
  export { postgresPlannerStrategies as n, planIssues as t };
1137
823
 
1138
- //# sourceMappingURL=issue-planner-Br0pt1Ea.mjs.map
824
+ //# sourceMappingURL=issue-planner-DL6g3CmE.mjs.map