@prisma-next/target-postgres 0.12.0 → 0.13.0-dev.10

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 (211) hide show
  1. package/dist/{codec-ids-D9fJ4HP5.d.mts → codec-ids-B1vOchLE.d.mts} +3 -2
  2. package/dist/codec-ids-B1vOchLE.d.mts.map +1 -0
  3. package/dist/{codec-ids-C5qzBqus.mjs → codec-ids-CTikp1if.mjs} +3 -2
  4. package/dist/codec-ids-CTikp1if.mjs.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-CRlHq7Cz.d.mts → codec-types-CnFiNML4.d.mts} +8 -9
  8. package/dist/codec-types-CnFiNML4.d.mts.map +1 -0
  9. package/dist/codec-types.d.mts +2 -2
  10. package/dist/{codecs-Dud5KDNk.d.mts → codecs-CBpEv4s5.d.mts} +33 -35
  11. package/dist/codecs-CBpEv4s5.d.mts.map +1 -0
  12. package/dist/codecs.d.mts +1 -1
  13. package/dist/codecs.mjs +37 -2
  14. package/dist/codecs.mjs.map +1 -1
  15. package/dist/contract-free.d.mts +80 -0
  16. package/dist/contract-free.d.mts.map +1 -0
  17. package/dist/contract-free.mjs +117 -0
  18. package/dist/contract-free.mjs.map +1 -0
  19. package/dist/control.d.mts +1 -1
  20. package/dist/control.d.mts.map +1 -1
  21. package/dist/control.mjs +67 -41
  22. package/dist/control.mjs.map +1 -1
  23. package/dist/{data-transform-CdtGUWp2.mjs → data-transform-D25tLeYU.mjs} +1 -1
  24. package/dist/{data-transform-CdtGUWp2.mjs.map → data-transform-D25tLeYU.mjs.map} +1 -1
  25. package/dist/{data-transform-bmOKkygi.d.mts → data-transform-DGOqcLrf.d.mts} +2 -2
  26. package/dist/{data-transform-bmOKkygi.d.mts.map → data-transform-DGOqcLrf.d.mts.map} +1 -1
  27. package/dist/data-transform.d.mts +1 -1
  28. package/dist/data-transform.mjs +1 -1
  29. package/dist/ddl-77SyXgFt.mjs +30 -0
  30. package/dist/ddl-77SyXgFt.mjs.map +1 -0
  31. package/dist/ddl.d.mts +2 -0
  32. package/dist/ddl.mjs +2 -0
  33. package/dist/{default-normalizer-CRscvhS5.mjs → default-normalizer-DyyCHQWs.mjs} +1 -1
  34. package/dist/{default-normalizer-CRscvhS5.mjs.map → default-normalizer-DyyCHQWs.mjs.map} +1 -1
  35. package/dist/default-normalizer.mjs +1 -1
  36. package/dist/descriptor-meta-DKmj-IMN.mjs +14 -0
  37. package/dist/descriptor-meta-DKmj-IMN.mjs.map +1 -0
  38. package/dist/{descriptor-meta-DLA2xV6B.mjs → descriptor-meta-runtime-My8_s4cs.mjs} +82 -78
  39. package/dist/descriptor-meta-runtime-My8_s4cs.mjs.map +1 -0
  40. package/dist/{enum-planning-Dz0Ye3Lb.mjs → enum-planning-DTMrPLkN.mjs} +0 -0
  41. package/dist/enum-planning-DTMrPLkN.mjs.map +1 -0
  42. package/dist/enum-planning.d.mts +14 -8
  43. package/dist/enum-planning.d.mts.map +1 -1
  44. package/dist/enum-planning.mjs +2 -2
  45. package/dist/{errors--zafB5_n.mjs → errors-CUk87ByX.mjs} +1 -1
  46. package/dist/{errors--zafB5_n.mjs.map → errors-CUk87ByX.mjs.map} +1 -1
  47. package/dist/errors.d.mts.map +1 -1
  48. package/dist/errors.mjs +1 -1
  49. package/dist/{issue-planner-ByQhUzS4.mjs → issue-planner-B0A7RFN2.mjs} +130 -28
  50. package/dist/issue-planner-B0A7RFN2.mjs.map +1 -0
  51. package/dist/issue-planner.d.mts +1 -1
  52. package/dist/issue-planner.d.mts.map +1 -1
  53. package/dist/issue-planner.mjs +1 -1
  54. package/dist/migration.d.mts +7 -8
  55. package/dist/migration.d.mts.map +1 -1
  56. package/dist/migration.mjs +5 -4
  57. package/dist/migration.mjs.map +1 -1
  58. package/dist/{native-type-normalizer-ClNPq__-.mjs → native-type-normalizer-Bc9XJzWC.mjs} +1 -1
  59. package/dist/{native-type-normalizer-ClNPq__-.mjs.map → native-type-normalizer-Bc9XJzWC.mjs.map} +1 -1
  60. package/dist/native-type-normalizer.mjs +1 -1
  61. package/dist/nodes-779hmCfL.d.mts +40 -0
  62. package/dist/nodes-779hmCfL.d.mts.map +1 -0
  63. package/dist/nodes-DZk2JZG3.mjs +47 -0
  64. package/dist/nodes-DZk2JZG3.mjs.map +1 -0
  65. package/dist/op-factory-call-Clp7Zr1z.mjs +1307 -0
  66. package/dist/op-factory-call-Clp7Zr1z.mjs.map +1 -0
  67. package/dist/{op-factory-call-Drccm_JD.d.mts → op-factory-call-DMA86_2D.d.mts} +39 -14
  68. package/dist/op-factory-call-DMA86_2D.d.mts.map +1 -0
  69. package/dist/op-factory-call.d.mts +2 -2
  70. package/dist/op-factory-call.mjs +2 -2
  71. package/dist/pack.d.mts +13 -12
  72. package/dist/pack.d.mts.map +1 -1
  73. package/dist/pack.mjs +1 -1
  74. package/dist/planner-DID7RZCQ.mjs +344 -0
  75. package/dist/planner-DID7RZCQ.mjs.map +1 -0
  76. package/dist/{planner-ddl-builders-BxRCSn_b.mjs → planner-ddl-builders-Cw2n2llW.mjs} +7 -30
  77. package/dist/planner-ddl-builders-Cw2n2llW.mjs.map +1 -0
  78. package/dist/planner-ddl-builders.d.mts +6 -7
  79. package/dist/planner-ddl-builders.d.mts.map +1 -1
  80. package/dist/planner-ddl-builders.mjs +2 -2
  81. package/dist/{planner-identity-values-ojX-6cPV.mjs → planner-identity-values-BIpa5p2I.mjs} +1 -1
  82. package/dist/{planner-identity-values-ojX-6cPV.mjs.map → planner-identity-values-BIpa5p2I.mjs.map} +1 -1
  83. package/dist/planner-identity-values.mjs +1 -1
  84. package/dist/{planner-produced-postgres-migration-p-VKkCia.d.mts → planner-produced-postgres-migration-B4EDvLdz.d.mts} +5 -4
  85. package/dist/planner-produced-postgres-migration-B4EDvLdz.d.mts.map +1 -0
  86. package/dist/{planner-produced-postgres-migration-N1yqYg20.mjs → planner-produced-postgres-migration-B8gZBPOR.mjs} +8 -6
  87. package/dist/planner-produced-postgres-migration-B8gZBPOR.mjs.map +1 -0
  88. package/dist/planner-produced-postgres-migration.d.mts +1 -1
  89. package/dist/planner-produced-postgres-migration.mjs +1 -1
  90. package/dist/{planner-schema-lookup-BGyukuzG.mjs → planner-schema-lookup-CiVaAQP-.mjs} +1 -1
  91. package/dist/{planner-schema-lookup-BGyukuzG.mjs.map → planner-schema-lookup-CiVaAQP-.mjs.map} +1 -1
  92. package/dist/planner-schema-lookup.mjs +1 -1
  93. package/dist/{planner-sql-checks-D3H-xOO1.mjs → planner-sql-checks-DRD5E8A1.mjs} +41 -30
  94. package/dist/planner-sql-checks-DRD5E8A1.mjs.map +1 -0
  95. package/dist/planner-sql-checks.d.mts.map +1 -1
  96. package/dist/planner-sql-checks.mjs +1 -1
  97. package/dist/{planner-target-details-CIj61DUj.d.mts → planner-target-details-CIY6tLeo.d.mts} +2 -2
  98. package/dist/planner-target-details-CIY6tLeo.d.mts.map +1 -0
  99. package/dist/planner-target-details.d.mts +2 -2
  100. package/dist/planner-type-resolution-836DExFN.mjs +20 -0
  101. package/dist/planner-type-resolution-836DExFN.mjs.map +1 -0
  102. package/dist/planner.d.mts +7 -3
  103. package/dist/planner.d.mts.map +1 -1
  104. package/dist/planner.mjs +1 -1
  105. package/dist/{postgres-contract-serializer-YJvjKrmo.mjs → postgres-contract-serializer-DCg7YaP3.mjs} +40 -24
  106. package/dist/postgres-contract-serializer-DCg7YaP3.mjs.map +1 -0
  107. package/dist/{postgres-enum-type-CNhPTDhy.d.mts → postgres-enum-type-BVn63a89.d.mts} +4 -1
  108. package/dist/postgres-enum-type-BVn63a89.d.mts.map +1 -0
  109. package/dist/{postgres-enum-type-DS-KLVRH.mjs → postgres-enum-type-DPKqCBem.mjs} +2 -1
  110. package/dist/postgres-enum-type-DPKqCBem.mjs.map +1 -0
  111. package/dist/{postgres-migration-uADmx0dW.mjs → postgres-migration-BCQEjFHK.mjs} +23 -3
  112. package/dist/postgres-migration-BCQEjFHK.mjs.map +1 -0
  113. package/dist/{postgres-migration-Fd4fQkBw.d.mts → postgres-migration-DZ_gLUOW.d.mts} +25 -3
  114. package/dist/postgres-migration-DZ_gLUOW.d.mts.map +1 -0
  115. package/dist/{postgres-schema-Bm7vjlOv.mjs → postgres-schema-BVTA2QH7.mjs} +41 -15
  116. package/dist/postgres-schema-BVTA2QH7.mjs.map +1 -0
  117. package/dist/{render-ops-BC2PtCkj.mjs → render-ops-BpjstrKQ.mjs} +4 -3
  118. package/dist/{render-ops-BC2PtCkj.mjs.map → render-ops-BpjstrKQ.mjs.map} +1 -1
  119. package/dist/render-ops.d.mts +3 -2
  120. package/dist/render-ops.d.mts.map +1 -1
  121. package/dist/render-ops.mjs +1 -1
  122. package/dist/{render-typescript-CPk7hhWH.mjs → render-typescript-KMgosran.mjs} +5 -2
  123. package/dist/render-typescript-KMgosran.mjs.map +1 -0
  124. package/dist/render-typescript.mjs +1 -1
  125. package/dist/runtime.d.mts.map +1 -1
  126. package/dist/runtime.mjs +3 -3
  127. package/dist/runtime.mjs.map +1 -1
  128. package/dist/{shared-ByhSooBS.d.mts → shared-DarONYBZ.d.mts} +5 -5
  129. package/dist/{shared-ByhSooBS.d.mts.map → shared-DarONYBZ.d.mts.map} +1 -1
  130. package/dist/{sql-utils-B_ruBD-M.mjs → sql-utils-DcfMz4MQ.mjs} +1 -1
  131. package/dist/{sql-utils-B_ruBD-M.mjs.map → sql-utils-DcfMz4MQ.mjs.map} +1 -1
  132. package/dist/sql-utils.mjs +1 -1
  133. package/dist/{types-D-XIpzHA.d.mts → types-BDKkx8MA.d.mts} +1 -1
  134. package/dist/types-BDKkx8MA.d.mts.map +1 -0
  135. package/dist/types.d.mts +18 -11
  136. package/dist/types.d.mts.map +1 -1
  137. package/dist/types.mjs +2 -2
  138. package/package.json +21 -20
  139. package/src/contract-free/columns.ts +49 -0
  140. package/src/contract-free/control-bootstrap.ts +55 -0
  141. package/src/contract-free/ddl.ts +37 -0
  142. package/src/core/ast/table-source.ts +23 -0
  143. package/src/core/authoring.ts +1 -1
  144. package/src/core/codec-ids.ts +1 -0
  145. package/src/core/codecs.ts +44 -0
  146. package/src/core/ddl/nodes.ts +72 -0
  147. package/src/core/descriptor-meta-runtime.ts +28 -0
  148. package/src/core/descriptor-meta.ts +3 -6
  149. package/src/core/migrations/control-policy.ts +234 -0
  150. package/src/core/migrations/enum-planning.ts +33 -29
  151. package/src/core/migrations/issue-planner.ts +81 -13
  152. package/src/core/migrations/op-factory-call.ts +289 -46
  153. package/src/core/migrations/operations/constraints.ts +79 -10
  154. package/src/core/migrations/operations/dependencies.ts +0 -17
  155. package/src/core/migrations/operations/shared.ts +3 -3
  156. package/src/core/migrations/operations/tables.ts +1 -39
  157. package/src/core/migrations/planner-ddl-builders.ts +7 -48
  158. package/src/core/migrations/planner-produced-postgres-migration.ts +11 -6
  159. package/src/core/migrations/planner-sql-checks.ts +9 -9
  160. package/src/core/migrations/planner-strategies.ts +149 -11
  161. package/src/core/migrations/planner-target-details.ts +2 -1
  162. package/src/core/migrations/planner.ts +66 -8
  163. package/src/core/migrations/postgres-migration.ts +41 -0
  164. package/src/core/migrations/render-ops.ts +7 -2
  165. package/src/core/migrations/render-typescript.ts +5 -1
  166. package/src/core/migrations/runner.ts +78 -50
  167. package/src/core/postgres-contract-serializer.ts +66 -46
  168. package/src/core/postgres-enum-type.ts +4 -0
  169. package/src/core/postgres-schema.ts +56 -19
  170. package/src/exports/contract-free.ts +7 -0
  171. package/src/exports/control.ts +15 -24
  172. package/src/exports/ddl.ts +7 -0
  173. package/src/exports/enum-planning.ts +0 -1
  174. package/src/exports/migration.ts +11 -2
  175. package/src/exports/op-factory-call.ts +2 -0
  176. package/src/exports/planner-ddl-builders.ts +0 -1
  177. package/src/exports/runtime.ts +2 -2
  178. package/dist/codec-ids-C5qzBqus.mjs.map +0 -1
  179. package/dist/codec-ids-D9fJ4HP5.d.mts.map +0 -1
  180. package/dist/codec-types-CRlHq7Cz.d.mts.map +0 -1
  181. package/dist/codecs-Dud5KDNk.d.mts.map +0 -1
  182. package/dist/descriptor-meta-DLA2xV6B.mjs.map +0 -1
  183. package/dist/enum-planning-Dz0Ye3Lb.mjs.map +0 -1
  184. package/dist/issue-planner-ByQhUzS4.mjs.map +0 -1
  185. package/dist/op-factory-call-B0WNg30h.mjs +0 -625
  186. package/dist/op-factory-call-B0WNg30h.mjs.map +0 -1
  187. package/dist/op-factory-call-Drccm_JD.d.mts.map +0 -1
  188. package/dist/planner-ClF0y0YR.mjs +0 -177
  189. package/dist/planner-ClF0y0YR.mjs.map +0 -1
  190. package/dist/planner-ddl-builders-BxRCSn_b.mjs.map +0 -1
  191. package/dist/planner-produced-postgres-migration-N1yqYg20.mjs.map +0 -1
  192. package/dist/planner-produced-postgres-migration-p-VKkCia.d.mts.map +0 -1
  193. package/dist/planner-sql-checks-D3H-xOO1.mjs.map +0 -1
  194. package/dist/planner-target-details-CIj61DUj.d.mts.map +0 -1
  195. package/dist/postgres-contract-serializer-YJvjKrmo.mjs.map +0 -1
  196. package/dist/postgres-enum-type-CNhPTDhy.d.mts.map +0 -1
  197. package/dist/postgres-enum-type-DS-KLVRH.mjs.map +0 -1
  198. package/dist/postgres-migration-Fd4fQkBw.d.mts.map +0 -1
  199. package/dist/postgres-migration-uADmx0dW.mjs.map +0 -1
  200. package/dist/postgres-schema-Bm7vjlOv.mjs.map +0 -1
  201. package/dist/render-typescript-CPk7hhWH.mjs.map +0 -1
  202. package/dist/statement-builders-vImtdfmM.mjs +0 -131
  203. package/dist/statement-builders-vImtdfmM.mjs.map +0 -1
  204. package/dist/statement-builders.d.mts +0 -51
  205. package/dist/statement-builders.d.mts.map +0 -1
  206. package/dist/statement-builders.mjs +0 -2
  207. package/dist/tables-Dcb2q9zV.mjs +0 -516
  208. package/dist/tables-Dcb2q9zV.mjs.map +0 -1
  209. package/dist/types-D-XIpzHA.d.mts.map +0 -1
  210. package/src/core/migrations/statement-builders.ts +0 -183
  211. package/src/exports/statement-builders.ts +0 -8
@@ -0,0 +1,344 @@
1
+ import { r as isPostgresSchema } from "./postgres-schema-BVTA2QH7.mjs";
2
+ import { t as createResolveExistingEnumValues } from "./enum-planning-DTMrPLkN.mjs";
3
+ import { t as parsePostgresDefault } from "./default-normalizer-DyyCHQWs.mjs";
4
+ import { t as normalizeSchemaNativeType } from "./native-type-normalizer-Bc9XJzWC.mjs";
5
+ import { n as postgresPlannerStrategies, t as planIssues } from "./issue-planner-B0A7RFN2.mjs";
6
+ import { t as TypeScriptRenderablePostgresMigration } from "./planner-produced-postgres-migration-B8gZBPOR.mjs";
7
+ import { extractCodecControlHooks, partitionCallsByControlPolicy, partitionIssuesByControlPolicy, planFieldEventOperations, plannerFailure } from "@prisma-next/family-sql/control";
8
+ import { ifDefined } from "@prisma-next/utils/defined";
9
+ import { UNBOUND_NAMESPACE_ID } from "@prisma-next/framework-components/ir";
10
+ import { isPostgresEnumStorageEntry, storageTableAt } from "@prisma-next/sql-contract/types";
11
+ import { verifySqlSchema } from "@prisma-next/family-sql/schema-verify";
12
+ import { blindCast } from "@prisma-next/utils/casts";
13
+ //#region src/core/migrations/control-policy.ts
14
+ /**
15
+ * Factory calls that create a whole, previously-absent top-level storage
16
+ * object. Used to decide whether `tolerated` permits a call (it only allows
17
+ * creating absent objects, never modifying existing ones).
18
+ *
19
+ * Deliberately an explicit, closed set rather than a `factoryName`
20
+ * create/alter/drop classification: it answers exactly one yes/no question
21
+ * and is fail-closed. Any call not listed here — including future or
22
+ * extension-contributed factories — is treated as NOT object-creation, so it
23
+ * is suppressed under `tolerated` rather than permissively emitted.
24
+ */
25
+ const OBJECT_CREATION_FACTORIES = new Set([
26
+ "createTable",
27
+ "createEnumType",
28
+ "createSchema"
29
+ ]);
30
+ function createsNewTopLevelObject(call) {
31
+ return OBJECT_CREATION_FACTORIES.has(call.factoryName);
32
+ }
33
+ function ddlSchemaNameForNamespace(contract, namespaceId) {
34
+ const namespace = contract.storage.namespaces[namespaceId];
35
+ return isPostgresSchema(namespace) ? namespace.ddlSchemaName(contract.storage) : namespaceId;
36
+ }
37
+ function resolveNamespaceIdForTable(contract, tableName, ddlSchemaName) {
38
+ for (const namespaceId of Object.keys(contract.storage.namespaces)) {
39
+ if (!storageTableAt(contract.storage, namespaceId, tableName)) continue;
40
+ if (ddlSchemaName === void 0 || ddlSchemaNameForNamespace(contract, namespaceId) === ddlSchemaName) return namespaceId;
41
+ }
42
+ return UNBOUND_NAMESPACE_ID;
43
+ }
44
+ function resolveNamespaceIdForDdlSchema(contract, ddlSchemaName) {
45
+ for (const namespaceId of Object.keys(contract.storage.namespaces)) {
46
+ const ns = contract.storage.namespaces[namespaceId];
47
+ if (isPostgresSchema(ns) && ns.ddlSchemaName(contract.storage) === ddlSchemaName) return namespaceId;
48
+ if (namespaceId === ddlSchemaName) return namespaceId;
49
+ }
50
+ return UNBOUND_NAMESPACE_ID;
51
+ }
52
+ function postgresCallFields(call) {
53
+ return {
54
+ ...ifDefined("schemaName", "schemaName" in call ? call.schemaName : void 0),
55
+ ...ifDefined("tableName", "tableName" in call ? call.tableName : void 0),
56
+ ...ifDefined("columnName", "columnName" in call ? call.columnName : void 0),
57
+ ...ifDefined("typeName", "typeName" in call ? call.typeName : void 0)
58
+ };
59
+ }
60
+ function formatPostgresControlPolicySubjectLabel(factoryName, subject, contract) {
61
+ if (subject?.table) return `${factoryName}(${ddlSchemaNameForNamespace(contract, subject.namespaceId)}.${subject.table})`;
62
+ if (subject?.typeName) return `${factoryName}(${ddlSchemaNameForNamespace(contract, subject.namespaceId)}.${subject.typeName})`;
63
+ return factoryName;
64
+ }
65
+ function resolvePostgresCallControlPolicySubject(call, contract) {
66
+ const callFields = postgresCallFields(call);
67
+ const createsNewObject = createsNewTopLevelObject(call);
68
+ if (call.factoryName === "createSchema" && callFields.schemaName) return {
69
+ namespaceId: resolveNamespaceIdForDdlSchema(contract, callFields.schemaName),
70
+ createsNewObject
71
+ };
72
+ if (callFields.typeName && call.factoryName !== "addColumn") {
73
+ const namespaceId = callFields.schemaName ? resolveNamespaceIdForDdlSchema(contract, callFields.schemaName) : UNBOUND_NAMESPACE_ID;
74
+ const ns = contract.storage.namespaces[namespaceId];
75
+ const rawEnum = isPostgresSchema(ns) ? ns.entries.type[callFields.typeName] : void 0;
76
+ return {
77
+ namespaceId,
78
+ ...ifDefined("explicitNodeControlPolicy", isPostgresEnumStorageEntry(rawEnum) ? rawEnum.control : void 0),
79
+ typeName: callFields.typeName,
80
+ createsNewObject
81
+ };
82
+ }
83
+ if (callFields.tableName) {
84
+ const namespaceId = resolveNamespaceIdForTable(contract, callFields.tableName, callFields.schemaName);
85
+ const tableControlPolicy = storageTableAt(contract.storage, namespaceId, callFields.tableName)?.control;
86
+ return {
87
+ namespaceId,
88
+ ...ifDefined("explicitNodeControlPolicy", tableControlPolicy),
89
+ table: callFields.tableName,
90
+ ...ifDefined("column", callFields.columnName),
91
+ createsNewObject
92
+ };
93
+ }
94
+ if (callFields.schemaName) return {
95
+ namespaceId: resolveNamespaceIdForDdlSchema(contract, callFields.schemaName),
96
+ createsNewObject
97
+ };
98
+ }
99
+ /**
100
+ * Issue kinds that describe the absence of a whole, top-level Postgres
101
+ * object — the same kinds `createsNewTopLevelObject` recognises for calls.
102
+ * Used by {@link resolvePostgresIssueCreationFactoryName} to decide whether
103
+ * a `tolerated` subject permits the issue to flow into the planner
104
+ * (create-if-absent) and to seed the suppressed-subject warning's
105
+ * `factoryName` when the planner is skipped.
106
+ */
107
+ const POSTGRES_ISSUE_CREATION_FACTORY = Object.freeze({
108
+ missing_schema: "createSchema",
109
+ missing_table: "createTable",
110
+ type_missing: "createEnumType"
111
+ });
112
+ function resolvePostgresIssueCreationFactoryName(issue) {
113
+ return POSTGRES_ISSUE_CREATION_FACTORY[issue.kind];
114
+ }
115
+ /**
116
+ * Resolve the control-policy subject coordinate for a single
117
+ * {@link SchemaIssue}. Mirrors the resolution `resolvePostgresCallControlPolicySubject`
118
+ * performs for a generated DDL call, but works *off the issue* — so the
119
+ * planner can partition issues by effective policy before the diff engine
120
+ * runs. `createsNewObject` is derived from the issue's kind: schema/table/
121
+ * type-missing issues describe a brand-new top-level object; everything else
122
+ * touches an existing object.
123
+ *
124
+ * An `extra_table` issue carries no contract namespace coordinate (the table
125
+ * isn't in any contract namespace), so the subject's `namespaceId` falls
126
+ * back to {@link UNBOUND_NAMESPACE_ID}; the call-side resolver does the same
127
+ * for the `DropTableCall` it produces.
128
+ */
129
+ function resolvePostgresIssueControlPolicySubject(issue, contract) {
130
+ const createsNewObject = POSTGRES_ISSUE_CREATION_FACTORY[issue.kind] !== void 0;
131
+ if (issue.kind === "missing_schema" && issue.namespaceId) return {
132
+ namespaceId: issue.namespaceId,
133
+ createsNewObject
134
+ };
135
+ if ("typeName" in issue && issue.typeName) {
136
+ const namespaceId = "namespaceId" in issue && issue.namespaceId ? issue.namespaceId : UNBOUND_NAMESPACE_ID;
137
+ const ns = contract.storage.namespaces[namespaceId];
138
+ const rawEnum = isPostgresSchema(ns) ? ns.entries.type[issue.typeName] : void 0;
139
+ return {
140
+ namespaceId,
141
+ ...ifDefined("explicitNodeControlPolicy", isPostgresEnumStorageEntry(rawEnum) ? rawEnum.control : void 0),
142
+ typeName: issue.typeName,
143
+ createsNewObject
144
+ };
145
+ }
146
+ if ("table" in issue && issue.table) {
147
+ const namespaceId = "namespaceId" in issue && issue.namespaceId ? issue.namespaceId : resolveNamespaceIdForTable(contract, issue.table, void 0);
148
+ return {
149
+ namespaceId,
150
+ ...ifDefined("explicitNodeControlPolicy", storageTableAt(contract.storage, namespaceId, issue.table)?.control),
151
+ table: issue.table,
152
+ ...ifDefined("column", "column" in issue ? issue.column : void 0),
153
+ createsNewObject
154
+ };
155
+ }
156
+ }
157
+ //#endregion
158
+ //#region src/core/migrations/verify-postgres-namespaces.ts
159
+ /**
160
+ * Resolves the live-database schema name for a given namespace
161
+ * coordinate. Mirrors `resolveDdlSchemaForNamespace` in
162
+ * `planner-strategies.ts` so the verifier's projection and the
163
+ * planner's projection always agree — Postgres-aware namespaces (the
164
+ * production path) dispatch to `ddlSchemaName(storage)`, and bare
165
+ * object payloads (used by some tests) fall back to the coordinate
166
+ * itself.
167
+ */
168
+ function resolveDdlSchemaName(storage, namespaceId) {
169
+ const namespace = storage.namespaces[namespaceId];
170
+ if (isPostgresSchema(namespace)) return namespace.ddlSchemaName(storage);
171
+ return namespaceId;
172
+ }
173
+ /**
174
+ * Reads the introspected list of schema names from the Postgres-flavoured
175
+ * annotations slot on the schema IR. Defaults to the always-present
176
+ * `public` schema when introspection did not populate the slot — a fresh
177
+ * Postgres database always carries `public` (unless an operator dropped
178
+ * it manually), so any verifier path that runs without an enriched
179
+ * introspection still suppresses the redundant `CREATE SCHEMA "public"`.
180
+ *
181
+ * Production introspection (`PostgresControlAdapter.introspect`) is the
182
+ * authoritative source: it queries `pg_namespace` and writes every
183
+ * non-system schema into `annotations.pg.existingSchemas`. Tests that
184
+ * want to assert against a richer initial state pass the slot
185
+ * explicitly via the schema IR.
186
+ */
187
+ function existingSchemasFromSchema(schema) {
188
+ const slot = schema.annotations?.pg?.existingSchemas;
189
+ if (Array.isArray(slot)) return slot.filter((s) => typeof s === "string");
190
+ return ["public"];
191
+ }
192
+ /**
193
+ * Emits a `missing_schema` issue for every contract-declared Postgres
194
+ * namespace whose live container does not yet exist.
195
+ *
196
+ * A namespace's live container is the schema returned by its
197
+ * polymorphic `ddlSchemaName(storage)` method — named schemas resolve
198
+ * to their own id; the unbound singleton returns `UNBOUND_NAMESPACE_ID`
199
+ * and is skipped explicitly (late-bound namespaces have no fixed DDL
200
+ * schema). Issues are emitted only when the resolved name is a real,
201
+ * creatable schema (not the unbound sentinel) and is missing from the
202
+ * introspected list. `public` is suppressed implicitly because the
203
+ * introspection (or its sensible default) always carries it.
204
+ *
205
+ * Each emitted issue stamps `namespaceId` with the contract namespace
206
+ * coordinate so the downstream `mapIssueToCall` re-resolves the DDL
207
+ * schema name through the same polymorphic path — keeping the
208
+ * coordinate, not the resolved name, as the issue's stable identity.
209
+ */
210
+ function verifyPostgresNamespacePresence(input) {
211
+ const { contract, schema } = input;
212
+ const existing = new Set(existingSchemasFromSchema(schema));
213
+ const issues = [];
214
+ const namespaceIds = Object.keys(contract.storage.namespaces).sort();
215
+ for (const namespaceId of namespaceIds) {
216
+ if (namespaceId === UNBOUND_NAMESPACE_ID) continue;
217
+ const ddlName = resolveDdlSchemaName(contract.storage, namespaceId);
218
+ if (ddlName === UNBOUND_NAMESPACE_ID) continue;
219
+ if (existing.has(ddlName)) continue;
220
+ issues.push({
221
+ kind: "missing_schema",
222
+ namespaceId,
223
+ message: `Schema "${ddlName}" is missing from database`
224
+ });
225
+ }
226
+ return issues;
227
+ }
228
+ //#endregion
229
+ //#region src/core/migrations/planner.ts
230
+ function createPostgresMigrationPlanner(lowerer) {
231
+ return new PostgresMigrationPlanner(lowerer);
232
+ }
233
+ /**
234
+ * Postgres migration planner — a thin wrapper over `planIssues`.
235
+ *
236
+ * `plan()` verifies the live schema against the target contract (producing
237
+ * `SchemaIssue[]`) and delegates to `planIssues` with the unified
238
+ * `postgresPlannerStrategies` list: enum-change, NOT-NULL backfill,
239
+ * type-change, nullable-tightening, codec-hook storage types,
240
+ * component-declared dependency installs, and shared-temp-default /
241
+ * empty-table-guarded NOT-NULL add-column. The same strategy list runs for
242
+ * `migration plan`, `db update`, and `db init`; behavior diverges purely on
243
+ * `policy.allowedOperationClasses` (the data-safe strategies short-circuit
244
+ * when `'data'` is excluded). The issue planner applies operation-class
245
+ * policy gates and emits a single `PostgresOpFactoryCall[]` that drives both
246
+ * the runtime-ops view (via `renderOps`) and the `renderTypeScript()`
247
+ * authoring surface.
248
+ */
249
+ var PostgresMigrationPlanner = class {
250
+ #lowerer;
251
+ constructor(lowerer) {
252
+ this.#lowerer = lowerer;
253
+ }
254
+ plan(options) {
255
+ return this.planSql(options);
256
+ }
257
+ emptyMigration(context, spaceId) {
258
+ return new TypeScriptRenderablePostgresMigration([], {
259
+ from: context.fromHash,
260
+ to: context.toHash
261
+ }, spaceId, this.#lowerer);
262
+ }
263
+ planSql(options) {
264
+ const schemaName = options.schemaName ?? Object.keys(options.contract.storage.namespaces).find((id) => id !== UNBOUND_NAMESPACE_ID) ?? UNBOUND_NAMESPACE_ID;
265
+ const policyResult = this.ensureAdditivePolicy(options.policy);
266
+ if (policyResult) return policyResult;
267
+ const schemaIssues = this.collectSchemaIssues(options);
268
+ const codecHooks = extractCodecControlHooks(options.frameworkComponents);
269
+ const storageTypes = options.contract.storage.types ?? {};
270
+ const issuePartition = partitionIssuesByControlPolicy({
271
+ issues: schemaIssues,
272
+ contract: options.contract,
273
+ resolveControlPolicySubject: (issue) => resolvePostgresIssueControlPolicySubject(issue, options.contract),
274
+ resolveCreationFactoryName: resolvePostgresIssueCreationFactoryName,
275
+ formatSubjectLabel: (factoryName, subject) => formatPostgresControlPolicySubjectLabel(factoryName, subject, options.contract)
276
+ });
277
+ const result = planIssues({
278
+ issues: issuePartition.plannable,
279
+ toContract: options.contract,
280
+ fromContract: options.fromContract,
281
+ schemaName,
282
+ codecHooks,
283
+ storageTypes,
284
+ schema: options.schema,
285
+ policy: options.policy,
286
+ frameworkComponents: options.frameworkComponents,
287
+ strategies: postgresPlannerStrategies
288
+ });
289
+ if (!result.ok) return plannerFailure(result.failure);
290
+ const fieldEventPartition = partitionCallsByControlPolicy({
291
+ calls: blindCast(planFieldEventOperations({
292
+ priorContract: options.fromContract,
293
+ newContract: options.contract,
294
+ codecHooks
295
+ })),
296
+ contract: options.contract,
297
+ resolveControlPolicySubject: (call) => resolvePostgresCallControlPolicySubject(call, options.contract),
298
+ resolveFactoryName: (call) => call.factoryName,
299
+ formatSubjectLabel: (factoryName, subject) => formatPostgresControlPolicySubjectLabel(factoryName, subject, options.contract)
300
+ });
301
+ const calls = [...result.value.calls, ...fieldEventPartition.kept];
302
+ const warnings = [...issuePartition.warnings, ...fieldEventPartition.warnings];
303
+ return Object.freeze({
304
+ kind: "success",
305
+ plan: new TypeScriptRenderablePostgresMigration(calls, {
306
+ from: options.fromContract?.storage.storageHash ?? null,
307
+ to: options.contract.storage.storageHash
308
+ }, options.spaceId, this.#lowerer),
309
+ ...warnings.length > 0 ? { warnings: Object.freeze(warnings) } : {}
310
+ });
311
+ }
312
+ ensureAdditivePolicy(policy) {
313
+ if (!policy.allowedOperationClasses.includes("additive")) return plannerFailure([{
314
+ kind: "unsupportedOperation",
315
+ summary: "Migration planner requires additive operations be allowed",
316
+ why: "The planner requires the \"additive\" operation class to be allowed in the policy."
317
+ }]);
318
+ return null;
319
+ }
320
+ collectSchemaIssues(options) {
321
+ const allowed = options.policy.allowedOperationClasses;
322
+ const strict = allowed.includes("widening") || allowed.includes("destructive");
323
+ const verifyResult = verifySqlSchema({
324
+ contract: options.contract,
325
+ schema: options.schema,
326
+ strict,
327
+ typeMetadataRegistry: /* @__PURE__ */ new Map(),
328
+ frameworkComponents: options.frameworkComponents,
329
+ normalizeDefault: parsePostgresDefault,
330
+ normalizeNativeType: normalizeSchemaNativeType,
331
+ resolveExistingEnumValues: createResolveExistingEnumValues(options.contract.storage)
332
+ });
333
+ const namespaceIssues = verifyPostgresNamespacePresence({
334
+ contract: options.contract,
335
+ schema: options.schema
336
+ });
337
+ if (namespaceIssues.length === 0) return verifyResult.schema.issues;
338
+ return [...namespaceIssues, ...verifyResult.schema.issues];
339
+ }
340
+ };
341
+ //#endregion
342
+ export { createPostgresMigrationPlanner as t };
343
+
344
+ //# sourceMappingURL=planner-DID7RZCQ.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"planner-DID7RZCQ.mjs","names":["#lowerer"],"sources":["../src/core/migrations/control-policy.ts","../src/core/migrations/verify-postgres-namespaces.ts","../src/core/migrations/planner.ts"],"sourcesContent":["import type { Contract } from '@prisma-next/contract/types';\nimport type { ControlPolicySubject } from '@prisma-next/family-sql/control';\nimport type { SchemaIssue } from '@prisma-next/framework-components/control';\nimport { UNBOUND_NAMESPACE_ID } from '@prisma-next/framework-components/ir';\nimport {\n isPostgresEnumStorageEntry,\n type SqlStorage,\n storageTableAt,\n} from '@prisma-next/sql-contract/types';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { isPostgresSchema } from '../postgres-schema';\nimport type { PostgresOpFactoryCall } from './op-factory-call';\n\n/**\n * Factory calls that create a whole, previously-absent top-level storage\n * object. Used to decide whether `tolerated` permits a call (it only allows\n * creating absent objects, never modifying existing ones).\n *\n * Deliberately an explicit, closed set rather than a `factoryName`\n * create/alter/drop classification: it answers exactly one yes/no question\n * and is fail-closed. Any call not listed here — including future or\n * extension-contributed factories — is treated as NOT object-creation, so it\n * is suppressed under `tolerated` rather than permissively emitted.\n */\nconst OBJECT_CREATION_FACTORIES: ReadonlySet<string> = new Set<string>([\n 'createTable',\n 'createEnumType',\n 'createSchema',\n]);\n\nfunction createsNewTopLevelObject(call: PostgresOpFactoryCall): boolean {\n return OBJECT_CREATION_FACTORIES.has(call.factoryName);\n}\n\nfunction ddlSchemaNameForNamespace(contract: Contract<SqlStorage>, namespaceId: string): string {\n const namespace = contract.storage.namespaces[namespaceId];\n return isPostgresSchema(namespace) ? namespace.ddlSchemaName(contract.storage) : namespaceId;\n}\n\nfunction resolveNamespaceIdForTable(\n contract: Contract<SqlStorage>,\n tableName: string,\n ddlSchemaName: string | undefined,\n): string {\n for (const namespaceId of Object.keys(contract.storage.namespaces)) {\n const table = storageTableAt(contract.storage, namespaceId, tableName);\n if (!table) continue;\n if (\n ddlSchemaName === undefined ||\n ddlSchemaNameForNamespace(contract, namespaceId) === ddlSchemaName\n ) {\n return namespaceId;\n }\n }\n return UNBOUND_NAMESPACE_ID;\n}\n\nfunction resolveNamespaceIdForDdlSchema(\n contract: Contract<SqlStorage>,\n ddlSchemaName: string,\n): string {\n for (const namespaceId of Object.keys(contract.storage.namespaces)) {\n const ns = contract.storage.namespaces[namespaceId];\n if (isPostgresSchema(ns) && ns.ddlSchemaName(contract.storage) === ddlSchemaName) {\n return namespaceId;\n }\n if (namespaceId === ddlSchemaName) {\n return namespaceId;\n }\n }\n return UNBOUND_NAMESPACE_ID;\n}\n\ninterface PostgresCallFields {\n readonly schemaName?: string;\n readonly tableName?: string;\n readonly columnName?: string;\n readonly typeName?: string;\n}\n\nfunction postgresCallFields(call: PostgresOpFactoryCall): PostgresCallFields {\n return {\n ...ifDefined('schemaName', 'schemaName' in call ? call.schemaName : undefined),\n ...ifDefined('tableName', 'tableName' in call ? call.tableName : undefined),\n ...ifDefined('columnName', 'columnName' in call ? call.columnName : undefined),\n ...ifDefined('typeName', 'typeName' in call ? call.typeName : undefined),\n };\n}\n\nexport function formatPostgresControlPolicySubjectLabel(\n factoryName: string,\n subject: ControlPolicySubject | undefined,\n contract: Contract<SqlStorage>,\n): string {\n if (subject?.table) {\n const ddlSchema = ddlSchemaNameForNamespace(contract, subject.namespaceId);\n return `${factoryName}(${ddlSchema}.${subject.table})`;\n }\n if (subject?.typeName) {\n const ddlSchema = ddlSchemaNameForNamespace(contract, subject.namespaceId);\n return `${factoryName}(${ddlSchema}.${subject.typeName})`;\n }\n return factoryName;\n}\n\nexport function resolvePostgresCallControlPolicySubject(\n call: PostgresOpFactoryCall,\n contract: Contract<SqlStorage>,\n): ControlPolicySubject | undefined {\n const callFields = postgresCallFields(call);\n const createsNewObject = createsNewTopLevelObject(call);\n\n if (call.factoryName === 'createSchema' && callFields.schemaName) {\n return {\n namespaceId: resolveNamespaceIdForDdlSchema(contract, callFields.schemaName),\n createsNewObject,\n };\n }\n\n if (callFields.typeName && call.factoryName !== 'addColumn') {\n const namespaceId = callFields.schemaName\n ? resolveNamespaceIdForDdlSchema(contract, callFields.schemaName)\n : UNBOUND_NAMESPACE_ID;\n const ns = contract.storage.namespaces[namespaceId];\n const rawEnum = isPostgresSchema(ns) ? ns.entries.type[callFields.typeName] : undefined;\n const controlPolicy = isPostgresEnumStorageEntry(rawEnum) ? rawEnum.control : undefined;\n return {\n namespaceId,\n ...ifDefined('explicitNodeControlPolicy', controlPolicy),\n typeName: callFields.typeName,\n createsNewObject,\n };\n }\n\n if (callFields.tableName) {\n const namespaceId = resolveNamespaceIdForTable(\n contract,\n callFields.tableName,\n callFields.schemaName,\n );\n const table = storageTableAt(contract.storage, namespaceId, callFields.tableName);\n const tableControlPolicy = table?.control;\n return {\n namespaceId,\n ...ifDefined('explicitNodeControlPolicy', tableControlPolicy),\n table: callFields.tableName,\n ...ifDefined('column', callFields.columnName),\n createsNewObject,\n };\n }\n\n if (callFields.schemaName) {\n return {\n namespaceId: resolveNamespaceIdForDdlSchema(contract, callFields.schemaName),\n createsNewObject,\n };\n }\n\n return undefined;\n}\n\n/**\n * Issue kinds that describe the absence of a whole, top-level Postgres\n * object — the same kinds `createsNewTopLevelObject` recognises for calls.\n * Used by {@link resolvePostgresIssueCreationFactoryName} to decide whether\n * a `tolerated` subject permits the issue to flow into the planner\n * (create-if-absent) and to seed the suppressed-subject warning's\n * `factoryName` when the planner is skipped.\n */\nconst POSTGRES_ISSUE_CREATION_FACTORY: Readonly<Record<string, string>> = Object.freeze({\n missing_schema: 'createSchema',\n missing_table: 'createTable',\n type_missing: 'createEnumType',\n});\n\nexport function resolvePostgresIssueCreationFactoryName(issue: SchemaIssue): string | undefined {\n return POSTGRES_ISSUE_CREATION_FACTORY[issue.kind];\n}\n\n/**\n * Resolve the control-policy subject coordinate for a single\n * {@link SchemaIssue}. Mirrors the resolution `resolvePostgresCallControlPolicySubject`\n * performs for a generated DDL call, but works *off the issue* — so the\n * planner can partition issues by effective policy before the diff engine\n * runs. `createsNewObject` is derived from the issue's kind: schema/table/\n * type-missing issues describe a brand-new top-level object; everything else\n * touches an existing object.\n *\n * An `extra_table` issue carries no contract namespace coordinate (the table\n * isn't in any contract namespace), so the subject's `namespaceId` falls\n * back to {@link UNBOUND_NAMESPACE_ID}; the call-side resolver does the same\n * for the `DropTableCall` it produces.\n */\nexport function resolvePostgresIssueControlPolicySubject(\n issue: SchemaIssue,\n contract: Contract<SqlStorage>,\n): ControlPolicySubject | undefined {\n const createsNewObject = POSTGRES_ISSUE_CREATION_FACTORY[issue.kind] !== undefined;\n\n if (issue.kind === 'missing_schema' && issue.namespaceId) {\n return { namespaceId: issue.namespaceId, createsNewObject };\n }\n\n if ('typeName' in issue && issue.typeName) {\n const namespaceId =\n 'namespaceId' in issue && issue.namespaceId ? issue.namespaceId : UNBOUND_NAMESPACE_ID;\n const ns = contract.storage.namespaces[namespaceId];\n const rawEnum = isPostgresSchema(ns) ? ns.entries.type[issue.typeName] : undefined;\n const controlPolicy = isPostgresEnumStorageEntry(rawEnum) ? rawEnum.control : undefined;\n return {\n namespaceId,\n ...ifDefined('explicitNodeControlPolicy', controlPolicy),\n typeName: issue.typeName,\n createsNewObject,\n };\n }\n\n if ('table' in issue && issue.table) {\n const namespaceId =\n 'namespaceId' in issue && issue.namespaceId\n ? issue.namespaceId\n : resolveNamespaceIdForTable(contract, issue.table, undefined);\n const table = storageTableAt(contract.storage, namespaceId, issue.table);\n return {\n namespaceId,\n ...ifDefined('explicitNodeControlPolicy', table?.control),\n table: issue.table,\n ...ifDefined('column', 'column' in issue ? issue.column : undefined),\n createsNewObject,\n };\n }\n\n return undefined;\n}\n","import type { Contract } from '@prisma-next/contract/types';\nimport type { SchemaIssue } from '@prisma-next/framework-components/control';\nimport { UNBOUND_NAMESPACE_ID } from '@prisma-next/framework-components/ir';\nimport type { SqlStorage } from '@prisma-next/sql-contract/types';\nimport type { SqlSchemaIR } from '@prisma-next/sql-schema-ir/types';\nimport { isPostgresSchema } from '../postgres-schema';\n\n/**\n * Resolves the live-database schema name for a given namespace\n * coordinate. Mirrors `resolveDdlSchemaForNamespace` in\n * `planner-strategies.ts` so the verifier's projection and the\n * planner's projection always agree — Postgres-aware namespaces (the\n * production path) dispatch to `ddlSchemaName(storage)`, and bare\n * object payloads (used by some tests) fall back to the coordinate\n * itself.\n */\nfunction resolveDdlSchemaName(storage: SqlStorage, namespaceId: string): string {\n const namespace = storage.namespaces[namespaceId];\n if (isPostgresSchema(namespace)) {\n return namespace.ddlSchemaName(storage);\n }\n return namespaceId;\n}\n\n/**\n * Reads the introspected list of schema names from the Postgres-flavoured\n * annotations slot on the schema IR. Defaults to the always-present\n * `public` schema when introspection did not populate the slot — a fresh\n * Postgres database always carries `public` (unless an operator dropped\n * it manually), so any verifier path that runs without an enriched\n * introspection still suppresses the redundant `CREATE SCHEMA \"public\"`.\n *\n * Production introspection (`PostgresControlAdapter.introspect`) is the\n * authoritative source: it queries `pg_namespace` and writes every\n * non-system schema into `annotations.pg.existingSchemas`. Tests that\n * want to assert against a richer initial state pass the slot\n * explicitly via the schema IR.\n */\nfunction existingSchemasFromSchema(schema: SqlSchemaIR): readonly string[] {\n const annotations = (schema as { annotations?: { pg?: { existingSchemas?: unknown } } })\n .annotations;\n const slot = annotations?.pg?.existingSchemas;\n if (Array.isArray(slot)) {\n return slot.filter((s): s is string => typeof s === 'string');\n }\n return ['public'];\n}\n\n/**\n * Emits a `missing_schema` issue for every contract-declared Postgres\n * namespace whose live container does not yet exist.\n *\n * A namespace's live container is the schema returned by its\n * polymorphic `ddlSchemaName(storage)` method — named schemas resolve\n * to their own id; the unbound singleton returns `UNBOUND_NAMESPACE_ID`\n * and is skipped explicitly (late-bound namespaces have no fixed DDL\n * schema). Issues are emitted only when the resolved name is a real,\n * creatable schema (not the unbound sentinel) and is missing from the\n * introspected list. `public` is suppressed implicitly because the\n * introspection (or its sensible default) always carries it.\n *\n * Each emitted issue stamps `namespaceId` with the contract namespace\n * coordinate so the downstream `mapIssueToCall` re-resolves the DDL\n * schema name through the same polymorphic path — keeping the\n * coordinate, not the resolved name, as the issue's stable identity.\n */\nexport function verifyPostgresNamespacePresence(input: {\n readonly contract: Contract<SqlStorage>;\n readonly schema: SqlSchemaIR;\n}): readonly SchemaIssue[] {\n const { contract, schema } = input;\n const existing = new Set(existingSchemasFromSchema(schema));\n const issues: SchemaIssue[] = [];\n const namespaceIds = Object.keys(contract.storage.namespaces).sort();\n for (const namespaceId of namespaceIds) {\n if (namespaceId === UNBOUND_NAMESPACE_ID) continue;\n const ddlName = resolveDdlSchemaName(contract.storage, namespaceId);\n if (ddlName === UNBOUND_NAMESPACE_ID) continue;\n if (existing.has(ddlName)) continue;\n issues.push({\n kind: 'missing_schema',\n namespaceId,\n message: `Schema \"${ddlName}\" is missing from database`,\n });\n }\n return issues;\n}\n","import type { Contract } from '@prisma-next/contract/types';\nimport type {\n MigrationOperationPolicy,\n SqlMigrationPlannerPlanOptions,\n SqlPlannerConflict,\n SqlPlannerFailureResult,\n} from '@prisma-next/family-sql/control';\nimport {\n extractCodecControlHooks,\n partitionCallsByControlPolicy,\n partitionIssuesByControlPolicy,\n planFieldEventOperations,\n plannerFailure,\n} from '@prisma-next/family-sql/control';\nimport type { Lowerer } from '@prisma-next/family-sql/control-adapter';\nimport { verifySqlSchema } from '@prisma-next/family-sql/schema-verify';\nimport type { TargetBoundComponentDescriptor } from '@prisma-next/framework-components/components';\nimport type {\n MigrationPlanner,\n MigrationPlanWithAuthoringSurface,\n MigrationScaffoldContext,\n SchemaIssue,\n} from '@prisma-next/framework-components/control';\nimport { UNBOUND_NAMESPACE_ID } from '@prisma-next/framework-components/ir';\nimport { blindCast } from '@prisma-next/utils/casts';\nimport { parsePostgresDefault } from '../default-normalizer';\nimport { normalizeSchemaNativeType } from '../native-type-normalizer';\nimport {\n formatPostgresControlPolicySubjectLabel,\n resolvePostgresCallControlPolicySubject,\n resolvePostgresIssueControlPolicySubject,\n resolvePostgresIssueCreationFactoryName,\n} from './control-policy';\nimport { createResolveExistingEnumValues } from './enum-planning';\nimport { planIssues } from './issue-planner';\nimport type { PostgresOpFactoryCall } from './op-factory-call';\nimport { TypeScriptRenderablePostgresMigration } from './planner-produced-postgres-migration';\nimport { postgresPlannerStrategies } from './planner-strategies';\nimport { verifyPostgresNamespacePresence } from './verify-postgres-namespaces';\n\ntype PlannerFrameworkComponents = SqlMigrationPlannerPlanOptions extends {\n readonly frameworkComponents: infer T;\n}\n ? T\n : ReadonlyArray<unknown>;\n\ntype PlannerOptionsWithComponents = SqlMigrationPlannerPlanOptions & {\n readonly frameworkComponents: PlannerFrameworkComponents;\n};\n\ntype VerifySqlSchemaOptionsWithComponents = Parameters<typeof verifySqlSchema>[0] & {\n readonly frameworkComponents: PlannerFrameworkComponents;\n};\n\nexport function createPostgresMigrationPlanner(lowerer: Lowerer): PostgresMigrationPlanner {\n return new PostgresMigrationPlanner(lowerer);\n}\n\n/**\n * Result of `PostgresMigrationPlanner.plan()`. A discriminated union whose\n * success variant carries a `TypeScriptRenderablePostgresMigration` — a\n * migration object that both the CLI (via `renderTypeScript()`) and the\n * SQL-typed callers (via `operations`, `describe()`, etc.) consume\n * uniformly.\n */\nexport type PostgresPlanResult =\n | {\n readonly kind: 'success';\n readonly plan: TypeScriptRenderablePostgresMigration;\n readonly warnings?: readonly SqlPlannerConflict[];\n }\n | SqlPlannerFailureResult;\n\n/**\n * Postgres migration planner — a thin wrapper over `planIssues`.\n *\n * `plan()` verifies the live schema against the target contract (producing\n * `SchemaIssue[]`) and delegates to `planIssues` with the unified\n * `postgresPlannerStrategies` list: enum-change, NOT-NULL backfill,\n * type-change, nullable-tightening, codec-hook storage types,\n * component-declared dependency installs, and shared-temp-default /\n * empty-table-guarded NOT-NULL add-column. The same strategy list runs for\n * `migration plan`, `db update`, and `db init`; behavior diverges purely on\n * `policy.allowedOperationClasses` (the data-safe strategies short-circuit\n * when `'data'` is excluded). The issue planner applies operation-class\n * policy gates and emits a single `PostgresOpFactoryCall[]` that drives both\n * the runtime-ops view (via `renderOps`) and the `renderTypeScript()`\n * authoring surface.\n */\nexport class PostgresMigrationPlanner implements MigrationPlanner<'sql', 'postgres'> {\n readonly #lowerer: Lowerer | undefined;\n\n constructor(lowerer?: Lowerer) {\n this.#lowerer = lowerer;\n }\n\n plan(options: {\n readonly contract: unknown;\n readonly schema: unknown;\n readonly policy: MigrationOperationPolicy;\n /**\n * The \"from\" contract (state the planner assumes the database starts\n * at), or `null` for reconciliation flows. Only `migration plan` ever\n * supplies a non-null value; `db update` / `db init` reconcile against\n * the live schema and pass `null`. When present alongside the\n * `'data'` operation class, strategies that need from/to column-shape\n * comparisons (unsafe type change, nullability tightening) activate.\n *\n * Typed as the framework `Contract | null` to satisfy the\n * `MigrationPlanner` interface contract; `planSql` narrows to the SQL\n * shape via `SqlMigrationPlannerPlanOptions`. Used to populate\n * `describe().from` on the produced plan as\n * `fromContract?.storage.storageHash ?? null`.\n */\n readonly fromContract: Contract | null;\n readonly schemaName?: string;\n readonly frameworkComponents: ReadonlyArray<TargetBoundComponentDescriptor<'sql', string>>;\n /**\n * Contract space this plan applies to. Stamped onto the produced\n * {@link TypeScriptRenderablePostgresMigration.spaceId} so the runner keys\n * the marker row by the right space.\n */\n readonly spaceId: string;\n }): PostgresPlanResult {\n return this.planSql(options as SqlMigrationPlannerPlanOptions);\n }\n\n emptyMigration(\n context: MigrationScaffoldContext,\n spaceId: string,\n ): MigrationPlanWithAuthoringSurface {\n return new TypeScriptRenderablePostgresMigration(\n [],\n {\n from: context.fromHash,\n to: context.toHash,\n },\n spaceId,\n this.#lowerer,\n );\n }\n\n private planSql(options: SqlMigrationPlannerPlanOptions): PostgresPlanResult {\n const schemaName =\n options.schemaName ??\n Object.keys(options.contract.storage.namespaces).find((id) => id !== UNBOUND_NAMESPACE_ID) ??\n UNBOUND_NAMESPACE_ID;\n const policyResult = this.ensureAdditivePolicy(options.policy);\n if (policyResult) {\n return policyResult;\n }\n\n const schemaIssues = this.collectSchemaIssues(options);\n const codecHooks = extractCodecControlHooks(options.frameworkComponents);\n const storageTypes = options.contract.storage.types ?? {};\n\n // Input-side control-policy partition. `external` / `observed` subjects\n // — and non-creation issues for `tolerated` subjects — are dropped from\n // the planner's input entirely; the planner never observes them, never\n // diffs them, never generates DDL for them. Suppression warnings are\n // built directly from the suppressed partition (one per subject), so the\n // user-visible message survives even when the planner would have failed\n // to model the subject's live shape.\n const issuePartition = partitionIssuesByControlPolicy({\n issues: schemaIssues,\n contract: options.contract,\n resolveControlPolicySubject: (issue) =>\n resolvePostgresIssueControlPolicySubject(issue, options.contract),\n resolveCreationFactoryName: resolvePostgresIssueCreationFactoryName,\n formatSubjectLabel: (factoryName, subject) =>\n formatPostgresControlPolicySubjectLabel(factoryName, subject, options.contract),\n });\n\n const result = planIssues({\n issues: issuePartition.plannable,\n toContract: options.contract,\n // `fromContract` is only supplied by `migration plan`. It is `null` for\n // `db update` / `db init`, which means data-safety strategies needing\n // from/to comparisons (unsafe type change, nullable tightening) are\n // inapplicable there — reconciliation falls through to\n // `mapIssueToCall`'s direct destructive handlers.\n fromContract: options.fromContract,\n schemaName,\n codecHooks,\n storageTypes,\n schema: options.schema,\n policy: options.policy,\n frameworkComponents: options.frameworkComponents,\n strategies: postgresPlannerStrategies,\n });\n\n if (!result.ok) {\n return plannerFailure(result.failure);\n }\n\n // Inline `onFieldEvent`-emitted ops after structural DDL. The fixed\n // ordering is `structural → added → dropped → altered`, with\n // within-group sorting by `(tableName, fieldName)` so re-emits are\n // byte-stable. The hook fires only at the application emitter —\n // extension-space planning never reaches this helper.\n const fieldEventOps = planFieldEventOperations({\n priorContract: options.fromContract,\n newContract: options.contract,\n codecHooks,\n });\n // Codec hook ops are target-agnostic `OpFactoryCall`; Postgres planning\n // lifts them at this integration boundary (see field-event-planner JSDoc).\n const fieldEventPostgresCalls = blindCast<\n readonly PostgresOpFactoryCall[],\n 'Codec hook ops conform to PostgresOpFactoryCall at the app emitter boundary'\n >(fieldEventOps);\n const fieldEventPartition = partitionCallsByControlPolicy({\n calls: fieldEventPostgresCalls,\n contract: options.contract,\n resolveControlPolicySubject: (call) =>\n resolvePostgresCallControlPolicySubject(call, options.contract),\n resolveFactoryName: (call) => call.factoryName,\n formatSubjectLabel: (factoryName, subject) =>\n formatPostgresControlPolicySubjectLabel(factoryName, subject, options.contract),\n });\n const calls = [...result.value.calls, ...fieldEventPartition.kept];\n const warnings: SqlPlannerConflict[] = [\n ...issuePartition.warnings,\n ...fieldEventPartition.warnings,\n ];\n\n return Object.freeze({\n kind: 'success' as const,\n plan: new TypeScriptRenderablePostgresMigration(\n calls,\n {\n from: options.fromContract?.storage.storageHash ?? null,\n to: options.contract.storage.storageHash,\n },\n options.spaceId,\n this.#lowerer,\n ),\n ...(warnings.length > 0 ? { warnings: Object.freeze(warnings) } : {}),\n });\n }\n\n private ensureAdditivePolicy(policy: MigrationOperationPolicy) {\n if (!policy.allowedOperationClasses.includes('additive')) {\n return plannerFailure([\n {\n kind: 'unsupportedOperation',\n summary: 'Migration planner requires additive operations be allowed',\n why: 'The planner requires the \"additive\" operation class to be allowed in the policy.',\n },\n ]);\n }\n return null;\n }\n\n private collectSchemaIssues(options: PlannerOptionsWithComponents): readonly SchemaIssue[] {\n // `db init` uses additive-only policy and intentionally ignores extra\n // schema objects. Any reconciliation-capable policy (widening or\n // destructive) must inspect extras to reconcile strict equality.\n const allowed = options.policy.allowedOperationClasses;\n const strict = allowed.includes('widening') || allowed.includes('destructive');\n const verifyOptions: VerifySqlSchemaOptionsWithComponents = {\n contract: options.contract,\n schema: options.schema,\n strict,\n typeMetadataRegistry: new Map(),\n frameworkComponents: options.frameworkComponents,\n normalizeDefault: parsePostgresDefault,\n normalizeNativeType: normalizeSchemaNativeType,\n resolveExistingEnumValues: createResolveExistingEnumValues(options.contract.storage),\n };\n const verifyResult = verifySqlSchema(verifyOptions);\n // Schema presence is a Postgres-specific concern (no equivalent in\n // SQLite / Mongo), so the issue emission lives in the target layer\n // rather than in the family verifier. Stitch it in here so a single\n // `SchemaIssue[]` flows through `planIssues` and the planner emits\n // CREATE SCHEMA in the dep bucket before any CreateTableCall.\n const namespaceIssues = verifyPostgresNamespacePresence({\n contract: options.contract,\n schema: options.schema,\n });\n if (namespaceIssues.length === 0) {\n return verifyResult.schema.issues;\n }\n return [...namespaceIssues, ...verifyResult.schema.issues];\n }\n}\n"],"mappings":"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"}
@@ -1,5 +1,6 @@
1
- import { i as quoteIdentifier, n as escapeLiteral } from "./sql-utils-B_ruBD-M.mjs";
2
- import { c as qualifyTableName, f as resolveColumnTypeMetadata } from "./planner-sql-checks-D3H-xOO1.mjs";
1
+ import { i as quoteIdentifier, n as escapeLiteral } from "./sql-utils-DcfMz4MQ.mjs";
2
+ import { t as resolveColumnTypeMetadata } from "./planner-type-resolution-836DExFN.mjs";
3
+ import { ifDefined } from "@prisma-next/utils/defined";
3
4
  //#region src/core/migrations/planner-ddl-builders.ts
4
5
  function buildCreateTableSql(qualifiedTableName, table, codecHooks, storageTypes = {}) {
5
6
  const columnDefinitions = Object.entries(table.columns).map(([columnName, column]) => {
@@ -55,7 +56,7 @@ function buildColumnTypeSql(column, codecHooks, storageTypes = {}, allowPseudoTy
55
56
  return resolved.nativeType;
56
57
  }
57
58
  function expandParameterizedTypeSql(column, codecHooks) {
58
- if (!column.typeParams) return null;
59
+ if (!column.typeParams || Object.keys(column.typeParams).length === 0) return null;
59
60
  if (!column.codecId) throw new Error(`Column declares typeParams for nativeType "${column.nativeType}" but has no codecId. Ensure the column is associated with a codec.`);
60
61
  const hooks = codecHooks.get(column.codecId);
61
62
  if (!hooks?.expandNativeType) {
@@ -65,7 +66,7 @@ function expandParameterizedTypeSql(column, codecHooks) {
65
66
  const expanded = hooks.expandNativeType({
66
67
  nativeType: column.nativeType,
67
68
  codecId: column.codecId,
68
- typeParams: column.typeParams
69
+ ...ifDefined("typeParams", column.typeParams)
69
70
  });
70
71
  return expanded !== column.nativeType ? expanded : null;
71
72
  }
@@ -101,31 +102,7 @@ function buildAddColumnSql(qualifiedTableName, columnName, column, codecHooks, t
101
102
  column.nullable ? "" : "NOT NULL"
102
103
  ].filter(Boolean).join(" ");
103
104
  }
104
- const REFERENTIAL_ACTION_SQL = {
105
- noAction: "NO ACTION",
106
- restrict: "RESTRICT",
107
- cascade: "CASCADE",
108
- setNull: "SET NULL",
109
- setDefault: "SET DEFAULT"
110
- };
111
- function buildForeignKeySql(schemaName, tableName, fkName, foreignKey) {
112
- let sql = `ALTER TABLE ${qualifyTableName(schemaName, tableName)}
113
- ADD CONSTRAINT ${quoteIdentifier(fkName)}
114
- FOREIGN KEY (${foreignKey.source.columns.map(quoteIdentifier).join(", ")})
115
- REFERENCES ${qualifyTableName(schemaName, foreignKey.target.tableName)} (${foreignKey.target.columns.map(quoteIdentifier).join(", ")})`;
116
- if (foreignKey.onDelete !== void 0) {
117
- const action = REFERENTIAL_ACTION_SQL[foreignKey.onDelete];
118
- if (!action) throw new Error(`Unknown referential action for onDelete: ${String(foreignKey.onDelete)}`);
119
- sql += `\nON DELETE ${action}`;
120
- }
121
- if (foreignKey.onUpdate !== void 0) {
122
- const action = REFERENTIAL_ACTION_SQL[foreignKey.onUpdate];
123
- if (!action) throw new Error(`Unknown referential action for onUpdate: ${String(foreignKey.onUpdate)}`);
124
- sql += `\nON UPDATE ${action}`;
125
- }
126
- return sql;
127
- }
128
105
  //#endregion
129
- export { buildForeignKeySql as a, buildCreateTableSql as i, buildColumnDefaultSql as n, renderDefaultLiteral as o, buildColumnTypeSql as r, buildAddColumnSql as t };
106
+ export { renderDefaultLiteral as a, buildCreateTableSql as i, buildColumnDefaultSql as n, buildColumnTypeSql as r, buildAddColumnSql as t };
130
107
 
131
- //# sourceMappingURL=planner-ddl-builders-BxRCSn_b.mjs.map
108
+ //# sourceMappingURL=planner-ddl-builders-Cw2n2llW.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"planner-ddl-builders-Cw2n2llW.mjs","names":[],"sources":["../src/core/migrations/planner-ddl-builders.ts"],"sourcesContent":["import type { CodecControlHooks } from '@prisma-next/family-sql/control';\nimport type {\n PostgresEnumStorageEntry,\n StorageColumn,\n StorageTable,\n StorageTypeInstance,\n} from '@prisma-next/sql-contract/types';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { escapeLiteral, quoteIdentifier } from '../sql-utils';\nimport type { PostgresColumnDefault } from '../types';\nimport { resolveColumnTypeMetadata } from './planner-type-resolution';\n\nexport function buildCreateTableSql(\n qualifiedTableName: string,\n table: StorageTable,\n codecHooks: ReadonlyMap<string, CodecControlHooks>,\n storageTypes: Record<string, StorageTypeInstance | PostgresEnumStorageEntry> = {},\n): string {\n const columnDefinitions = Object.entries(table.columns).map(\n ([columnName, column]: [string, StorageColumn]) => {\n const parts = [\n quoteIdentifier(columnName),\n buildColumnTypeSql(column, codecHooks, storageTypes),\n buildColumnDefaultSql(column.default, column),\n column.nullable ? '' : 'NOT NULL',\n ].filter(Boolean);\n return parts.join(' ');\n },\n );\n\n const constraintDefinitions: string[] = [];\n if (table.primaryKey) {\n constraintDefinitions.push(\n `PRIMARY KEY (${table.primaryKey.columns.map(quoteIdentifier).join(', ')})`,\n );\n }\n\n const allDefinitions = [...columnDefinitions, ...constraintDefinitions];\n return `CREATE TABLE ${qualifiedTableName} (\\n ${allDefinitions.join(',\\n ')}\\n)`;\n}\n\n/**\n * Pattern for safe PostgreSQL type names.\n * Allows letters, digits, underscores, spaces (for \"double precision\", \"character varying\"),\n * and trailing [] for array types.\n */\nconst SAFE_NATIVE_TYPE_PATTERN = /^[a-zA-Z][a-zA-Z0-9_ ]*(\\[\\])?$/;\n\nfunction assertSafeNativeType(nativeType: string): void {\n if (!SAFE_NATIVE_TYPE_PATTERN.test(nativeType)) {\n throw new Error(\n `Unsafe native type name in contract: \"${nativeType}\". ` +\n 'Native type names must match /^[a-zA-Z][a-zA-Z0-9_ ]*(\\\\[\\\\])?$/',\n );\n }\n}\n\n/**\n * Sanity check against accidental SQL injection from malformed contract files.\n * Rejects semicolons, SQL comment tokens, and dollar-quoting.\n * Not a comprehensive security boundary — the contract is developer-authored.\n */\nfunction assertSafeDefaultExpression(expression: string): void {\n if (expression.includes(';') || /--|\\/\\*|\\$\\$|\\bSELECT\\b/i.test(expression)) {\n throw new Error(\n `Unsafe default expression in contract: \"${expression}\". ` +\n 'Default expressions must not contain semicolons, SQL comment tokens, dollar-quoting, or subqueries.',\n );\n }\n}\n\n/**\n * Renders the SQL type for a column in DDL context.\n *\n * @param allowPseudoTypes - When true (default), autoincrement integer columns\n * produce SERIAL/BIGSERIAL/SMALLSERIAL pseudo-types. Set to false for contexts\n * like ALTER COLUMN TYPE where pseudo-types are invalid.\n */\nexport function buildColumnTypeSql(\n column: StorageColumn,\n codecHooks: ReadonlyMap<string, CodecControlHooks>,\n storageTypes: Record<string, StorageTypeInstance | PostgresEnumStorageEntry> = {},\n allowPseudoTypes = true,\n): string {\n const resolved = resolveColumnTypeMetadata(column, storageTypes);\n\n if (allowPseudoTypes) {\n const columnDefault = column.default;\n if (columnDefault?.kind === 'function' && columnDefault.expression === 'autoincrement()') {\n if (resolved.nativeType === 'int4' || resolved.nativeType === 'integer') {\n return 'SERIAL';\n }\n if (resolved.nativeType === 'int8' || resolved.nativeType === 'bigint') {\n return 'BIGSERIAL';\n }\n if (resolved.nativeType === 'int2' || resolved.nativeType === 'smallint') {\n return 'SMALLSERIAL';\n }\n }\n }\n\n const expanded = expandParameterizedTypeSql(resolved, codecHooks);\n if (expanded !== null) {\n return expanded;\n }\n\n if (column.typeRef) {\n return quoteIdentifier(resolved.nativeType);\n }\n\n assertSafeNativeType(resolved.nativeType);\n return resolved.nativeType;\n}\n\nfunction expandParameterizedTypeSql(\n column: Pick<StorageColumn, 'nativeType' | 'codecId' | 'typeParams'>,\n codecHooks: ReadonlyMap<string, CodecControlHooks>,\n): string | null {\n if (!column.typeParams || Object.keys(column.typeParams).length === 0) {\n return null;\n }\n\n if (!column.codecId) {\n throw new Error(\n `Column declares typeParams for nativeType \"${column.nativeType}\" but has no codecId. ` +\n 'Ensure the column is associated with a codec.',\n );\n }\n\n const hooks = codecHooks.get(column.codecId);\n if (!hooks?.expandNativeType) {\n if (hooks?.planTypeOperations) {\n return null;\n }\n throw new Error(\n `Column declares typeParams for nativeType \"${column.nativeType}\" ` +\n `but no expandNativeType hook is registered for codecId \"${column.codecId}\". ` +\n 'Ensure the extension providing this codec is included in extensionPacks.',\n );\n }\n\n const expanded = hooks.expandNativeType({\n nativeType: column.nativeType,\n codecId: column.codecId,\n ...ifDefined('typeParams', column.typeParams),\n });\n\n return expanded !== column.nativeType ? expanded : null;\n}\n\n/** Autoincrement columns use SERIAL types, so this returns empty for them. */\nexport function buildColumnDefaultSql(\n columnDefault: PostgresColumnDefault | undefined,\n column?: StorageColumn,\n): string {\n if (!columnDefault) {\n return '';\n }\n\n switch (columnDefault.kind) {\n case 'literal':\n return `DEFAULT ${renderDefaultLiteral(columnDefault.value, column)}`;\n case 'function': {\n if (columnDefault.expression === 'autoincrement()') {\n return '';\n }\n assertSafeDefaultExpression(columnDefault.expression);\n return `DEFAULT (${columnDefault.expression})`;\n }\n case 'sequence':\n return `DEFAULT nextval('${escapeLiteral(quoteIdentifier(columnDefault.name))}'::regclass)`;\n }\n}\n\nexport function renderDefaultLiteral(value: unknown, column?: StorageColumn): string {\n const isJsonColumn = column?.nativeType === 'json' || column?.nativeType === 'jsonb';\n\n if (value instanceof Date) {\n return `'${escapeLiteral(value.toISOString())}'`;\n }\n if (typeof value === 'string') {\n return `'${escapeLiteral(value)}'`;\n }\n if (typeof value === 'number' || typeof value === 'boolean') {\n return String(value);\n }\n if (value === null) {\n return 'NULL';\n }\n const json = JSON.stringify(value);\n if (isJsonColumn) {\n return `'${escapeLiteral(json)}'::${column.nativeType}`;\n }\n return `'${escapeLiteral(json)}'`;\n}\n\nexport function buildAddColumnSql(\n qualifiedTableName: string,\n columnName: string,\n column: StorageColumn,\n codecHooks: ReadonlyMap<string, CodecControlHooks>,\n temporaryDefault?: string | null,\n storageTypes: Record<string, StorageTypeInstance | PostgresEnumStorageEntry> = {},\n): string {\n const typeSql = buildColumnTypeSql(column, codecHooks, storageTypes);\n const defaultSql =\n buildColumnDefaultSql(column.default, column) ||\n (temporaryDefault ? `DEFAULT ${temporaryDefault}` : '');\n const parts = [\n `ALTER TABLE ${qualifiedTableName}`,\n `ADD COLUMN ${quoteIdentifier(columnName)} ${typeSql}`,\n defaultSql,\n column.nullable ? '' : 'NOT NULL',\n ].filter(Boolean);\n return parts.join(' ');\n}\n"],"mappings":"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"}
@@ -1,9 +1,9 @@
1
- import { t as PostgresColumnDefault } from "./types-D-XIpzHA.mjs";
1
+ import { t as PostgresColumnDefault } from "./types-BDKkx8MA.mjs";
2
2
  import { CodecControlHooks } from "@prisma-next/family-sql/control";
3
- import { ForeignKey, PostgresEnumStorageEntry, StorageColumn, StorageTable, StorageTypeInstance } from "@prisma-next/sql-contract/types";
3
+ import { PostgresEnumStorageEntry, StorageColumn, StorageTable, StorageTypeInstance } from "@prisma-next/sql-contract/types";
4
4
 
5
5
  //#region src/core/migrations/planner-ddl-builders.d.ts
6
- declare function buildCreateTableSql(qualifiedTableName: string, table: StorageTable, codecHooks: Map<string, CodecControlHooks>, storageTypes?: Record<string, StorageTypeInstance | PostgresEnumStorageEntry>): string;
6
+ declare function buildCreateTableSql(qualifiedTableName: string, table: StorageTable, codecHooks: ReadonlyMap<string, CodecControlHooks>, storageTypes?: Record<string, StorageTypeInstance | PostgresEnumStorageEntry>): string;
7
7
  /**
8
8
  * Renders the SQL type for a column in DDL context.
9
9
  *
@@ -11,12 +11,11 @@ declare function buildCreateTableSql(qualifiedTableName: string, table: StorageT
11
11
  * produce SERIAL/BIGSERIAL/SMALLSERIAL pseudo-types. Set to false for contexts
12
12
  * like ALTER COLUMN TYPE where pseudo-types are invalid.
13
13
  */
14
- declare function buildColumnTypeSql(column: StorageColumn, codecHooks: Map<string, CodecControlHooks>, storageTypes?: Record<string, StorageTypeInstance | PostgresEnumStorageEntry>, allowPseudoTypes?: boolean): string;
14
+ declare function buildColumnTypeSql(column: StorageColumn, codecHooks: ReadonlyMap<string, CodecControlHooks>, storageTypes?: Record<string, StorageTypeInstance | PostgresEnumStorageEntry>, allowPseudoTypes?: boolean): string;
15
15
  /** Autoincrement columns use SERIAL types, so this returns empty for them. */
16
16
  declare function buildColumnDefaultSql(columnDefault: PostgresColumnDefault | undefined, column?: StorageColumn): string;
17
17
  declare function renderDefaultLiteral(value: unknown, column?: StorageColumn): string;
18
- declare function buildAddColumnSql(qualifiedTableName: string, columnName: string, column: StorageColumn, codecHooks: Map<string, CodecControlHooks>, temporaryDefault?: string | null, storageTypes?: Record<string, StorageTypeInstance | PostgresEnumStorageEntry>): string;
19
- declare function buildForeignKeySql(schemaName: string, tableName: string, fkName: string, foreignKey: ForeignKey): string;
18
+ declare function buildAddColumnSql(qualifiedTableName: string, columnName: string, column: StorageColumn, codecHooks: ReadonlyMap<string, CodecControlHooks>, temporaryDefault?: string | null, storageTypes?: Record<string, StorageTypeInstance | PostgresEnumStorageEntry>): string;
20
19
  //#endregion
21
- export { buildAddColumnSql, buildColumnDefaultSql, buildColumnTypeSql, buildCreateTableSql, buildForeignKeySql, renderDefaultLiteral };
20
+ export { buildAddColumnSql, buildColumnDefaultSql, buildColumnTypeSql, buildCreateTableSql, renderDefaultLiteral };
22
21
  //# sourceMappingURL=planner-ddl-builders.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"planner-ddl-builders.d.mts","names":[],"sources":["../src/core/migrations/planner-ddl-builders.ts"],"mappings":";;;;;iBAcgB,mBAAA,CACd,kBAAA,UACA,KAAA,EAAO,YAAA,EACP,UAAA,EAAY,GAAA,SAAY,iBAAA,GACxB,YAAA,GAAc,MAAA,SAAe,mBAAA,GAAsB,wBAAA;;AAJrD;;;;;;iBAkEgB,kBAAA,CACd,MAAA,EAAQ,aAAA,EACR,UAAA,EAAY,GAAA,SAAY,iBAAA,GACxB,YAAA,GAAc,MAAA,SAAe,mBAAA,GAAsB,wBAAA,GACnD,gBAAA;;iBAqEc,qBAAA,CACd,aAAA,EAAe,qBAAA,cACf,MAAA,GAAS,aAAa;AAAA,iBAqBR,oBAAA,CAAqB,KAAA,WAAgB,MAAA,GAAS,aAAa;AAAA,iBAsB3D,iBAAA,CACd,kBAAA,UACA,UAAA,UACA,MAAA,EAAQ,aAAA,EACR,UAAA,EAAY,GAAA,SAAY,iBAAA,GACxB,gBAAA,kBACA,YAAA,GAAc,MAAA,SAAe,mBAAA,GAAsB,wBAAA;AAAA,iBAuBrC,kBAAA,CACd,UAAA,UACA,SAAA,UACA,MAAA,UACA,UAAA,EAAY,UAAU"}
1
+ {"version":3,"file":"planner-ddl-builders.d.mts","names":[],"sources":["../src/core/migrations/planner-ddl-builders.ts"],"mappings":";;;;;iBAYgB,mBAAA,CACd,kBAAA,UACA,KAAA,EAAO,YAAA,EACP,UAAA,EAAY,WAAA,SAAoB,iBAAA,GAChC,YAAA,GAAc,MAAA,SAAe,mBAAA,GAAsB,wBAAA;;AAJrD;;;;;;iBAkEgB,kBAAA,CACd,MAAA,EAAQ,aAAA,EACR,UAAA,EAAY,WAAA,SAAoB,iBAAA,GAChC,YAAA,GAAc,MAAA,SAAe,mBAAA,GAAsB,wBAAA,GACnD,gBAAA;;iBAqEc,qBAAA,CACd,aAAA,EAAe,qBAAA,cACf,MAAA,GAAS,aAAa;AAAA,iBAqBR,oBAAA,CAAqB,KAAA,WAAgB,MAAA,GAAS,aAAa;AAAA,iBAsB3D,iBAAA,CACd,kBAAA,UACA,UAAA,UACA,MAAA,EAAQ,aAAA,EACR,UAAA,EAAY,WAAA,SAAoB,iBAAA,GAChC,gBAAA,kBACA,YAAA,GAAc,MAAA,SAAe,mBAAA,GAAsB,wBAAA"}
@@ -1,2 +1,2 @@
1
- import { a as buildForeignKeySql, i as buildCreateTableSql, n as buildColumnDefaultSql, o as renderDefaultLiteral, r as buildColumnTypeSql, t as buildAddColumnSql } from "./planner-ddl-builders-BxRCSn_b.mjs";
2
- export { buildAddColumnSql, buildColumnDefaultSql, buildColumnTypeSql, buildCreateTableSql, buildForeignKeySql, renderDefaultLiteral };
1
+ import { a as renderDefaultLiteral, i as buildCreateTableSql, n as buildColumnDefaultSql, r as buildColumnTypeSql, t as buildAddColumnSql } from "./planner-ddl-builders-Cw2n2llW.mjs";
2
+ export { buildAddColumnSql, buildColumnDefaultSql, buildColumnTypeSql, buildCreateTableSql, renderDefaultLiteral };
@@ -93,4 +93,4 @@ function buildBitIdentityValue(typeParams) {
93
93
  //#endregion
94
94
  export { resolveIdentityValue as n, buildBuiltinIdentityValue as t };
95
95
 
96
- //# sourceMappingURL=planner-identity-values-ojX-6cPV.mjs.map
96
+ //# sourceMappingURL=planner-identity-values-BIpa5p2I.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"planner-identity-values-ojX-6cPV.mjs","names":[],"sources":["../src/core/migrations/planner-identity-values.ts"],"sourcesContent":["import type { CodecControlHooks } from '@prisma-next/family-sql/control';\nimport {\n isPostgresEnumStorageEntry,\n type PostgresEnumStorageEntry,\n type StorageColumn,\n type StorageTypeInstance,\n} from '@prisma-next/sql-contract/types';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport type { PostgresEnumType } from '../postgres-enum-type';\n\n/**\n * Resolves the identity value (monoid neutral element) as a SQL literal for a column's type.\n * Checks codec hooks first (extensions can provide type-specific identity values),\n * then falls back to the built-in map.\n */\nexport function resolveIdentityValue(\n column: StorageColumn,\n codecHooks: Map<string, CodecControlHooks>,\n storageTypes: Record<string, StorageTypeInstance | PostgresEnumStorageEntry> = {},\n): string | null {\n const referencedType = column.typeRef ? storageTypes[column.typeRef] : undefined;\n const referencedIsEnum =\n referencedType !== undefined && isPostgresEnumStorageEntry(referencedType);\n const referencedBinding = referencedIsEnum\n ? ((referencedType as PostgresEnumType).codecBinding ?? {\n codecId: (referencedType as PostgresEnumStorageEntry).codecId,\n typeParams: { values: (referencedType as PostgresEnumStorageEntry).values },\n })\n : undefined;\n const codecId =\n referencedBinding?.codecId ??\n (referencedType && !referencedIsEnum\n ? (referencedType as StorageTypeInstance).codecId\n : undefined) ??\n column.codecId;\n const nativeType = referencedType?.nativeType ?? column.nativeType;\n const typeParams =\n (referencedBinding?.typeParams as Record<string, unknown> | undefined) ??\n (referencedType && !referencedIsEnum\n ? (referencedType as StorageTypeInstance).typeParams\n : undefined) ??\n column.typeParams;\n\n if (codecId) {\n const hookDefault = codecHooks.get(codecId)?.resolveIdentityValue?.({\n nativeType,\n codecId,\n ...ifDefined('typeParams', typeParams),\n });\n if (hookDefault !== undefined) {\n return hookDefault;\n }\n }\n\n return buildBuiltinIdentityValue(nativeType, typeParams);\n}\n\n/**\n * Returns the built-in identity value (monoid neutral element) as a SQL literal for the given\n * PostgreSQL native type — e.g. 0 for integers, '' for text, false for booleans.\n *\n * This is the planner's fallback when no codec hook provides a type-specific identity value.\n *\n * Returns null for unrecognized types (for example enums and extension-owned types without a\n * hook), which causes the planner to fall back to the empty-table precheck.\n *\n * @internal Exported for testing only.\n */\nexport function buildBuiltinIdentityValue(\n nativeType: string,\n typeParams?: Record<string, unknown>,\n): string | null {\n const normalizedNativeType = normalizeIdentityValueNativeType(nativeType);\n\n if (normalizedNativeType.endsWith('[]')) {\n return \"'{}'\";\n }\n\n switch (normalizedNativeType) {\n case 'text':\n case 'character':\n case 'bpchar':\n case 'character varying':\n case 'varchar':\n return \"''\";\n\n case 'int2':\n case 'int4':\n case 'int8':\n case 'integer':\n case 'bigint':\n case 'smallint':\n case 'float4':\n case 'float8':\n case 'real':\n case 'double precision':\n case 'numeric':\n case 'decimal':\n return '0';\n\n case 'bool':\n case 'boolean':\n return 'false';\n\n case 'uuid':\n return \"'00000000-0000-0000-0000-000000000000'\";\n\n case 'json':\n return \"'{}'::json\";\n case 'jsonb':\n return \"'{}'::jsonb\";\n\n case 'date':\n case 'timestamp':\n case 'timestamptz':\n case 'timestamp with time zone':\n case 'timestamp without time zone':\n return \"'epoch'\";\n\n case 'time':\n case 'time without time zone':\n return \"'00:00:00'\";\n case 'timetz':\n case 'time with time zone':\n return \"'00:00:00+00'\";\n\n case 'interval':\n return \"'0'\";\n\n case 'bytea':\n return \"''::bytea\";\n case 'tsvector':\n return \"''::tsvector\";\n\n case 'bit':\n return buildBitIdentityValue(typeParams);\n case 'bit varying':\n case 'varbit':\n return \"B''\";\n\n default:\n return null;\n }\n}\n\nfunction normalizeIdentityValueNativeType(nativeType: string): string {\n return nativeType.trim().toLowerCase().replace(/\\s+/g, ' ');\n}\n\nfunction buildBitIdentityValue(typeParams?: Record<string, unknown>): string | null {\n const length = typeParams?.['length'];\n if (length === undefined) {\n return \"B'0'\";\n }\n if (typeof length !== 'number' || !Number.isInteger(length) || length <= 0) {\n return null;\n }\n return `B'${'0'.repeat(length)}'`;\n}\n"],"mappings":";;;;;;;;AAeA,SAAgB,qBACd,QACA,YACA,eAA+E,CAAC,GACjE;CACf,MAAM,iBAAiB,OAAO,UAAU,aAAa,OAAO,WAAW,KAAA;CACvE,MAAM,mBACJ,mBAAmB,KAAA,KAAa,2BAA2B,cAAc;CAC3E,MAAM,oBAAoB,mBACpB,eAAoC,gBAAgB;EACpD,SAAU,eAA4C;EACtD,YAAY,EAAE,QAAS,eAA4C,OAAO;CAC5E,IACA,KAAA;CACJ,MAAM,UACJ,mBAAmB,YAClB,kBAAkB,CAAC,mBACf,eAAuC,UACxC,KAAA,MACJ,OAAO;CACT,MAAM,aAAa,gBAAgB,cAAc,OAAO;CACxD,MAAM,aACH,mBAAmB,eACnB,kBAAkB,CAAC,mBACf,eAAuC,aACxC,KAAA,MACJ,OAAO;CAET,IAAI,SAAS;EACX,MAAM,cAAc,WAAW,IAAI,OAAO,GAAG,uBAAuB;GAClE;GACA;GACA,GAAG,UAAU,cAAc,UAAU;EACvC,CAAC;EACD,IAAI,gBAAgB,KAAA,GAClB,OAAO;CAEX;CAEA,OAAO,0BAA0B,YAAY,UAAU;AACzD;;;;;;;;;;;;AAaA,SAAgB,0BACd,YACA,YACe;CACf,MAAM,uBAAuB,iCAAiC,UAAU;CAExE,IAAI,qBAAqB,SAAS,IAAI,GACpC,OAAO;CAGT,QAAQ,sBAAR;EACE,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK,WACH,OAAO;EAET,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK,WACH,OAAO;EAET,KAAK;EACL,KAAK,WACH,OAAO;EAET,KAAK,QACH,OAAO;EAET,KAAK,QACH,OAAO;EACT,KAAK,SACH,OAAO;EAET,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK,+BACH,OAAO;EAET,KAAK;EACL,KAAK,0BACH,OAAO;EACT,KAAK;EACL,KAAK,uBACH,OAAO;EAET,KAAK,YACH,OAAO;EAET,KAAK,SACH,OAAO;EACT,KAAK,YACH,OAAO;EAET,KAAK,OACH,OAAO,sBAAsB,UAAU;EACzC,KAAK;EACL,KAAK,UACH,OAAO;EAET,SACE,OAAO;CACX;AACF;AAEA,SAAS,iCAAiC,YAA4B;CACpE,OAAO,WAAW,KAAK,EAAE,YAAY,EAAE,QAAQ,QAAQ,GAAG;AAC5D;AAEA,SAAS,sBAAsB,YAAqD;CAClF,MAAM,SAAS,aAAa;CAC5B,IAAI,WAAW,KAAA,GACb,OAAO;CAET,IAAI,OAAO,WAAW,YAAY,CAAC,OAAO,UAAU,MAAM,KAAK,UAAU,GACvE,OAAO;CAET,OAAO,KAAK,IAAI,OAAO,MAAM,EAAE;AACjC"}
1
+ {"version":3,"file":"planner-identity-values-BIpa5p2I.mjs","names":[],"sources":["../src/core/migrations/planner-identity-values.ts"],"sourcesContent":["import type { CodecControlHooks } from '@prisma-next/family-sql/control';\nimport {\n isPostgresEnumStorageEntry,\n type PostgresEnumStorageEntry,\n type StorageColumn,\n type StorageTypeInstance,\n} from '@prisma-next/sql-contract/types';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport type { PostgresEnumType } from '../postgres-enum-type';\n\n/**\n * Resolves the identity value (monoid neutral element) as a SQL literal for a column's type.\n * Checks codec hooks first (extensions can provide type-specific identity values),\n * then falls back to the built-in map.\n */\nexport function resolveIdentityValue(\n column: StorageColumn,\n codecHooks: Map<string, CodecControlHooks>,\n storageTypes: Record<string, StorageTypeInstance | PostgresEnumStorageEntry> = {},\n): string | null {\n const referencedType = column.typeRef ? storageTypes[column.typeRef] : undefined;\n const referencedIsEnum =\n referencedType !== undefined && isPostgresEnumStorageEntry(referencedType);\n const referencedBinding = referencedIsEnum\n ? ((referencedType as PostgresEnumType).codecBinding ?? {\n codecId: (referencedType as PostgresEnumStorageEntry).codecId,\n typeParams: { values: (referencedType as PostgresEnumStorageEntry).values },\n })\n : undefined;\n const codecId =\n referencedBinding?.codecId ??\n (referencedType && !referencedIsEnum\n ? (referencedType as StorageTypeInstance).codecId\n : undefined) ??\n column.codecId;\n const nativeType = referencedType?.nativeType ?? column.nativeType;\n const typeParams =\n (referencedBinding?.typeParams as Record<string, unknown> | undefined) ??\n (referencedType && !referencedIsEnum\n ? (referencedType as StorageTypeInstance).typeParams\n : undefined) ??\n column.typeParams;\n\n if (codecId) {\n const hookDefault = codecHooks.get(codecId)?.resolveIdentityValue?.({\n nativeType,\n codecId,\n ...ifDefined('typeParams', typeParams),\n });\n if (hookDefault !== undefined) {\n return hookDefault;\n }\n }\n\n return buildBuiltinIdentityValue(nativeType, typeParams);\n}\n\n/**\n * Returns the built-in identity value (monoid neutral element) as a SQL literal for the given\n * PostgreSQL native type — e.g. 0 for integers, '' for text, false for booleans.\n *\n * This is the planner's fallback when no codec hook provides a type-specific identity value.\n *\n * Returns null for unrecognized types (for example enums and extension-owned types without a\n * hook), which causes the planner to fall back to the empty-table precheck.\n *\n * @internal Exported for testing only.\n */\nexport function buildBuiltinIdentityValue(\n nativeType: string,\n typeParams?: Record<string, unknown>,\n): string | null {\n const normalizedNativeType = normalizeIdentityValueNativeType(nativeType);\n\n if (normalizedNativeType.endsWith('[]')) {\n return \"'{}'\";\n }\n\n switch (normalizedNativeType) {\n case 'text':\n case 'character':\n case 'bpchar':\n case 'character varying':\n case 'varchar':\n return \"''\";\n\n case 'int2':\n case 'int4':\n case 'int8':\n case 'integer':\n case 'bigint':\n case 'smallint':\n case 'float4':\n case 'float8':\n case 'real':\n case 'double precision':\n case 'numeric':\n case 'decimal':\n return '0';\n\n case 'bool':\n case 'boolean':\n return 'false';\n\n case 'uuid':\n return \"'00000000-0000-0000-0000-000000000000'\";\n\n case 'json':\n return \"'{}'::json\";\n case 'jsonb':\n return \"'{}'::jsonb\";\n\n case 'date':\n case 'timestamp':\n case 'timestamptz':\n case 'timestamp with time zone':\n case 'timestamp without time zone':\n return \"'epoch'\";\n\n case 'time':\n case 'time without time zone':\n return \"'00:00:00'\";\n case 'timetz':\n case 'time with time zone':\n return \"'00:00:00+00'\";\n\n case 'interval':\n return \"'0'\";\n\n case 'bytea':\n return \"''::bytea\";\n case 'tsvector':\n return \"''::tsvector\";\n\n case 'bit':\n return buildBitIdentityValue(typeParams);\n case 'bit varying':\n case 'varbit':\n return \"B''\";\n\n default:\n return null;\n }\n}\n\nfunction normalizeIdentityValueNativeType(nativeType: string): string {\n return nativeType.trim().toLowerCase().replace(/\\s+/g, ' ');\n}\n\nfunction buildBitIdentityValue(typeParams?: Record<string, unknown>): string | null {\n const length = typeParams?.['length'];\n if (length === undefined) {\n return \"B'0'\";\n }\n if (typeof length !== 'number' || !Number.isInteger(length) || length <= 0) {\n return null;\n }\n return `B'${'0'.repeat(length)}'`;\n}\n"],"mappings":";;;;;;;;AAeA,SAAgB,qBACd,QACA,YACA,eAA+E,CAAC,GACjE;CACf,MAAM,iBAAiB,OAAO,UAAU,aAAa,OAAO,WAAW,KAAA;CACvE,MAAM,mBACJ,mBAAmB,KAAA,KAAa,2BAA2B,cAAc;CAC3E,MAAM,oBAAoB,mBACpB,eAAoC,gBAAgB;EACpD,SAAU,eAA4C;EACtD,YAAY,EAAE,QAAS,eAA4C,OAAO;CAC5E,IACA,KAAA;CACJ,MAAM,UACJ,mBAAmB,YAClB,kBAAkB,CAAC,mBACf,eAAuC,UACxC,KAAA,MACJ,OAAO;CACT,MAAM,aAAa,gBAAgB,cAAc,OAAO;CACxD,MAAM,aACH,mBAAmB,eACnB,kBAAkB,CAAC,mBACf,eAAuC,aACxC,KAAA,MACJ,OAAO;CAET,IAAI,SAAS;EACX,MAAM,cAAc,WAAW,IAAI,OAAO,CAAC,EAAE,uBAAuB;GAClE;GACA;GACA,GAAG,UAAU,cAAc,UAAU;EACvC,CAAC;EACD,IAAI,gBAAgB,KAAA,GAClB,OAAO;CAEX;CAEA,OAAO,0BAA0B,YAAY,UAAU;AACzD;;;;;;;;;;;;AAaA,SAAgB,0BACd,YACA,YACe;CACf,MAAM,uBAAuB,iCAAiC,UAAU;CAExE,IAAI,qBAAqB,SAAS,IAAI,GACpC,OAAO;CAGT,QAAQ,sBAAR;EACE,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK,WACH,OAAO;EAET,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK,WACH,OAAO;EAET,KAAK;EACL,KAAK,WACH,OAAO;EAET,KAAK,QACH,OAAO;EAET,KAAK,QACH,OAAO;EACT,KAAK,SACH,OAAO;EAET,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK,+BACH,OAAO;EAET,KAAK;EACL,KAAK,0BACH,OAAO;EACT,KAAK;EACL,KAAK,uBACH,OAAO;EAET,KAAK,YACH,OAAO;EAET,KAAK,SACH,OAAO;EACT,KAAK,YACH,OAAO;EAET,KAAK,OACH,OAAO,sBAAsB,UAAU;EACzC,KAAK;EACL,KAAK,UACH,OAAO;EAET,SACE,OAAO;CACX;AACF;AAEA,SAAS,iCAAiC,YAA4B;CACpE,OAAO,WAAW,KAAK,CAAC,CAAC,YAAY,CAAC,CAAC,QAAQ,QAAQ,GAAG;AAC5D;AAEA,SAAS,sBAAsB,YAAqD;CAClF,MAAM,SAAS,aAAa;CAC5B,IAAI,WAAW,KAAA,GACb,OAAO;CAET,IAAI,OAAO,WAAW,YAAY,CAAC,OAAO,UAAU,MAAM,KAAK,UAAU,GACvE,OAAO;CAET,OAAO,KAAK,IAAI,OAAO,MAAM,EAAE;AACjC"}
@@ -1,2 +1,2 @@
1
- import { t as buildBuiltinIdentityValue } from "./planner-identity-values-ojX-6cPV.mjs";
1
+ import { t as buildBuiltinIdentityValue } from "./planner-identity-values-BIpa5p2I.mjs";
2
2
  export { buildBuiltinIdentityValue };
@@ -1,14 +1,15 @@
1
- import { t as PostgresPlanTargetDetails } from "./planner-target-details-CIj61DUj.mjs";
2
- import { t as PostgresMigration } from "./postgres-migration-Fd4fQkBw.mjs";
1
+ import { t as PostgresPlanTargetDetails } from "./planner-target-details-CIY6tLeo.mjs";
2
+ import { t as PostgresMigration } from "./postgres-migration-DZ_gLUOW.mjs";
3
3
  import { SqlMigrationPlanOperation } from "@prisma-next/family-sql/control";
4
4
  import { MigrationPlanWithAuthoringSurface, OpFactoryCall } from "@prisma-next/framework-components/control";
5
+ import { Lowerer } from "@prisma-next/family-sql/control-adapter";
5
6
  import { MigrationMeta } from "@prisma-next/migration-tools/migration";
6
7
 
7
8
  //#region src/core/migrations/planner-produced-postgres-migration.d.ts
8
9
  type Op = SqlMigrationPlanOperation<PostgresPlanTargetDetails>;
9
10
  declare class TypeScriptRenderablePostgresMigration extends PostgresMigration implements MigrationPlanWithAuthoringSurface {
10
11
  #private;
11
- constructor(calls: readonly OpFactoryCall[], meta: MigrationMeta, spaceId: string);
12
+ constructor(calls: readonly OpFactoryCall[], meta: MigrationMeta, spaceId: string, lowerer?: Lowerer);
12
13
  get operations(): readonly Op[];
13
14
  describe(): MigrationMeta;
14
15
  /**
@@ -21,4 +22,4 @@ declare class TypeScriptRenderablePostgresMigration extends PostgresMigration im
21
22
  }
22
23
  //#endregion
23
24
  export { TypeScriptRenderablePostgresMigration as t };
24
- //# sourceMappingURL=planner-produced-postgres-migration-p-VKkCia.d.mts.map
25
+ //# sourceMappingURL=planner-produced-postgres-migration-B4EDvLdz.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"planner-produced-postgres-migration-B4EDvLdz.d.mts","names":[],"sources":["../src/core/migrations/planner-produced-postgres-migration.ts"],"mappings":";;;;;;;;KAqCK,EAAA,GAAK,yBAAyB,CAAC,yBAAA;AAAA,cAEvB,qCAAA,SACH,iBAAA,YACG,iCAAA;EAAA;cAQT,KAAA,WAAgB,aAAA,IAChB,IAAA,EAAM,aAAA,EACN,OAAA,UACA,OAAA,GAAU,OAAA;EAAA,IASC,UAAA,aAAuB,EAAA;EAI3B,QAAA,IAAY,aAAA;EAJR;;;;;EAAA,IAaT,OAAA;EAIJ,gBAAA;AAAA"}