@prisma-next/target-postgres 0.15.0 → 0.16.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 (188) hide show
  1. package/dist/{authoring-BtsOWgI3.mjs → authoring-34L18kA1.mjs} +18 -8
  2. package/dist/authoring-34L18kA1.mjs.map +1 -0
  3. package/dist/canonicalize-D1F4vUnP.d.mts.map +1 -1
  4. package/dist/{codec-ids-CI144z7g.d.mts → codec-ids-BswpvvND.d.mts} +3 -3
  5. package/dist/codec-ids-BswpvvND.d.mts.map +1 -0
  6. package/dist/{codec-ids-B10ZZHzw.mjs → codec-ids-D3G8K0YM.mjs} +3 -2
  7. package/dist/codec-ids-D3G8K0YM.mjs.map +1 -0
  8. package/dist/codec-ids.d.mts +2 -2
  9. package/dist/codec-ids.mjs +2 -2
  10. package/dist/{codec-types-CTfT4U4O.d.mts → codec-types-CQ07nOz-.d.mts} +4 -5
  11. package/dist/codec-types-CQ07nOz-.d.mts.map +1 -0
  12. package/dist/codec-types.d.mts +1 -1
  13. package/dist/{codecs-D7W9O0Xx.d.mts → codecs-G4DTY0F_.d.mts} +35 -7
  14. package/dist/codecs-G4DTY0F_.d.mts.map +1 -0
  15. package/dist/{codecs-DRbb26Or.mjs → codecs-TCsGgW-Y.mjs} +77 -5
  16. package/dist/codecs-TCsGgW-Y.mjs.map +1 -0
  17. package/dist/codecs.d.mts +2 -3
  18. package/dist/codecs.d.mts.map +1 -1
  19. package/dist/codecs.mjs +2 -2
  20. package/dist/contract-free.d.mts +2 -3
  21. package/dist/contract-free.d.mts.map +1 -1
  22. package/dist/contract-free.mjs +3 -3
  23. package/dist/{control-policy-DtbkLLGv.mjs → control-policy-CZKdMztu.mjs} +44 -75
  24. package/dist/control-policy-CZKdMztu.mjs.map +1 -0
  25. package/dist/control.d.mts +0 -1
  26. package/dist/control.d.mts.map +1 -1
  27. package/dist/control.mjs +75 -25
  28. package/dist/control.mjs.map +1 -1
  29. package/dist/data-transform-BOWpliq8.mjs.map +1 -1
  30. package/dist/{data-transform-DPzwBMhW.d.mts → data-transform-CGvE8yGx.d.mts} +1 -2
  31. package/dist/data-transform-CGvE8yGx.d.mts.map +1 -0
  32. package/dist/data-transform.d.mts +1 -1
  33. package/dist/{ddl-GTTOvjx_.mjs → ddl-DHXKzQ99.mjs} +3 -3
  34. package/dist/{ddl-GTTOvjx_.mjs.map → ddl-DHXKzQ99.mjs.map} +1 -1
  35. package/dist/ddl.d.mts +1 -1
  36. package/dist/default-normalizer-B9ZUiyUE.mjs +264 -0
  37. package/dist/default-normalizer-B9ZUiyUE.mjs.map +1 -0
  38. package/dist/default-normalizer.d.mts +14 -2
  39. package/dist/default-normalizer.d.mts.map +1 -1
  40. package/dist/default-normalizer.mjs +2 -248
  41. package/dist/{descriptor-meta-CFQKLXl_.mjs → descriptor-meta-qubYaxQA.mjs} +9 -4
  42. package/dist/descriptor-meta-qubYaxQA.mjs.map +1 -0
  43. package/dist/{diff-database-schema-GncqMuSI.mjs → diff-database-schema-C-hnJ5mr.mjs} +92 -26
  44. package/dist/diff-database-schema-C-hnJ5mr.mjs.map +1 -0
  45. package/dist/diff-database-schema.d.mts +4 -13
  46. package/dist/diff-database-schema.d.mts.map +1 -1
  47. package/dist/diff-database-schema.mjs +1 -1
  48. package/dist/{errors-DO-w0EUS.mjs → errors-ByDS0xJL.mjs} +6 -6
  49. package/dist/errors-ByDS0xJL.mjs.map +1 -0
  50. package/dist/errors.d.mts +4 -4
  51. package/dist/errors.d.mts.map +1 -1
  52. package/dist/errors.mjs +1 -1
  53. package/dist/issue-planner.d.mts +1 -2
  54. package/dist/issue-planner.d.mts.map +1 -1
  55. package/dist/issue-planner.mjs +1 -1
  56. package/dist/migration.d.mts +3 -4
  57. package/dist/migration.d.mts.map +1 -1
  58. package/dist/migration.mjs +2 -2
  59. package/dist/native-type-normalizer.d.mts.map +1 -1
  60. package/dist/{nodes-Dv5eCSq9.d.mts → nodes-CQzM2hR0.d.mts} +1 -2
  61. package/dist/nodes-CQzM2hR0.d.mts.map +1 -0
  62. package/dist/{op-factory-call-Bn9zDx4_.d.mts → op-factory-call-DT7kdjVP.d.mts} +10 -7
  63. package/dist/op-factory-call-DT7kdjVP.d.mts.map +1 -0
  64. package/dist/{op-factory-call-C38NzvQD.mjs → op-factory-call-DuRj7WXX.mjs} +37 -16
  65. package/dist/{op-factory-call-C38NzvQD.mjs.map → op-factory-call-DuRj7WXX.mjs.map} +1 -1
  66. package/dist/op-factory-call.d.mts +2 -2
  67. package/dist/op-factory-call.mjs +2 -2
  68. package/dist/pack.d.mts +122 -6
  69. package/dist/pack.d.mts.map +1 -1
  70. package/dist/pack.mjs +1 -1
  71. package/dist/{planner-kql24i_F.mjs → planner-DPGxFcXo.mjs} +13 -13
  72. package/dist/planner-DPGxFcXo.mjs.map +1 -0
  73. package/dist/planner-ddl-builders.d.mts +1 -2
  74. package/dist/planner-ddl-builders.d.mts.map +1 -1
  75. package/dist/planner-identity-values.d.mts +0 -1
  76. package/dist/planner-identity-values.d.mts.map +1 -1
  77. package/dist/{planner-produced-postgres-migration-BEY1T0Xm.d.mts → planner-produced-postgres-migration-C-dwGdb2.d.mts} +2 -3
  78. package/dist/planner-produced-postgres-migration-C-dwGdb2.d.mts.map +1 -0
  79. package/dist/{planner-produced-postgres-migration-D7y-PEHK.mjs → planner-produced-postgres-migration-CFDpqWWE.mjs} +2 -2
  80. package/dist/planner-produced-postgres-migration-CFDpqWWE.mjs.map +1 -0
  81. package/dist/planner-produced-postgres-migration.d.mts +1 -1
  82. package/dist/planner-produced-postgres-migration.mjs +1 -1
  83. package/dist/planner-schema-lookup.d.mts +0 -1
  84. package/dist/planner-schema-lookup.d.mts.map +1 -1
  85. package/dist/{planner-sql-checks-zqNfs2XZ.mjs → planner-sql-checks-BuB877wH.mjs} +2 -2
  86. package/dist/{planner-sql-checks-zqNfs2XZ.mjs.map → planner-sql-checks-BuB877wH.mjs.map} +1 -1
  87. package/dist/planner-sql-checks.d.mts +0 -1
  88. package/dist/planner-sql-checks.d.mts.map +1 -1
  89. package/dist/planner-sql-checks.mjs +1 -1
  90. package/dist/planner-target-details-HkP4RrRO.d.mts.map +1 -1
  91. package/dist/planner.d.mts +3 -4
  92. package/dist/planner.d.mts.map +1 -1
  93. package/dist/planner.mjs +2 -2
  94. package/dist/{postgres-contract-view-C9j5cqP0.d.mts → postgres-contract-view-CeU7FJjW.d.mts} +4 -3
  95. package/dist/postgres-contract-view-CeU7FJjW.d.mts.map +1 -0
  96. package/dist/{postgres-contract-view-DM8sN1Ot.mjs → postgres-contract-view-DebHMqGR.mjs} +4 -4
  97. package/dist/{postgres-contract-view-DM8sN1Ot.mjs.map → postgres-contract-view-DebHMqGR.mjs.map} +1 -1
  98. package/dist/{postgres-database-schema-node-CJv5bfbs.d.mts → postgres-database-schema-node-DMXsIwAb.d.mts} +12 -4
  99. package/dist/postgres-database-schema-node-DMXsIwAb.d.mts.map +1 -0
  100. package/dist/{postgres-migration-arMSWU9b.mjs → postgres-migration-C_OPFhIF.mjs} +22 -6
  101. package/dist/postgres-migration-C_OPFhIF.mjs.map +1 -0
  102. package/dist/{postgres-migration-DbckK1su.d.mts → postgres-migration-DLIvzHjX.d.mts} +31 -7
  103. package/dist/postgres-migration-DLIvzHjX.d.mts.map +1 -0
  104. package/dist/{postgres-rls-policy--CSddvMR.d.mts → postgres-rls-policy-CYXdqG9B.d.mts} +1 -2
  105. package/dist/postgres-rls-policy-CYXdqG9B.d.mts.map +1 -0
  106. package/dist/{postgres-role-schema-node-Cm-j0ZGM.mjs → postgres-role-schema-node-bg32e7I-.mjs} +3 -2
  107. package/dist/postgres-role-schema-node-bg32e7I-.mjs.map +1 -0
  108. package/dist/{postgres-schema-Cm4DtiGA.mjs → postgres-schema-CewLYHB7.mjs} +2 -2
  109. package/dist/{postgres-schema-Cm4DtiGA.mjs.map → postgres-schema-CewLYHB7.mjs.map} +1 -1
  110. package/dist/{postgres-schema-DKq6s1P3.d.mts → postgres-schema-FdKRwe7X.d.mts} +3 -4
  111. package/dist/postgres-schema-FdKRwe7X.d.mts.map +1 -0
  112. package/dist/render-ops.d.mts +0 -1
  113. package/dist/render-ops.d.mts.map +1 -1
  114. package/dist/render-typescript.d.mts +0 -1
  115. package/dist/render-typescript.d.mts.map +1 -1
  116. package/dist/{resolve-ddl-schema-XyBaaenM.mjs → resolve-ddl-schema-D0wi_P9Q.mjs} +2 -2
  117. package/dist/{resolve-ddl-schema-XyBaaenM.mjs.map → resolve-ddl-schema-D0wi_P9Q.mjs.map} +1 -1
  118. package/dist/rls-canonicalize.d.mts +0 -1
  119. package/dist/rls-canonicalize.d.mts.map +1 -1
  120. package/dist/runtime.d.mts +1 -2
  121. package/dist/runtime.d.mts.map +1 -1
  122. package/dist/runtime.mjs +1 -1
  123. package/dist/schema-ir-annotations.d.mts +0 -1
  124. package/dist/schema-ir-annotations.d.mts.map +1 -1
  125. package/dist/schema-ir-annotations.mjs +1 -1
  126. package/dist/schema-node-kinds-DxvWh2Ic.d.mts +29 -0
  127. package/dist/schema-node-kinds-DxvWh2Ic.d.mts.map +1 -0
  128. package/dist/sql-utils.d.mts.map +1 -1
  129. package/dist/{table-source-BvFo7gVs.d.mts → table-source-D5c2fxAQ.d.mts} +1 -2
  130. package/dist/table-source-D5c2fxAQ.d.mts.map +1 -0
  131. package/dist/{types-BDKkx8MA.d.mts → types-D2MLzLBD.d.mts} +1 -2
  132. package/dist/types-D2MLzLBD.d.mts.map +1 -0
  133. package/dist/types.d.mts +6 -5
  134. package/dist/types.mjs +4 -4
  135. package/package.json +21 -21
  136. package/src/core/authoring.ts +18 -5
  137. package/src/core/codec-helpers.ts +53 -1
  138. package/src/core/codec-ids.ts +1 -0
  139. package/src/core/codecs.ts +56 -3
  140. package/src/core/default-normalizer.ts +22 -0
  141. package/src/core/descriptor-meta.ts +2 -0
  142. package/src/core/errors.ts +5 -5
  143. package/src/core/index-types.ts +15 -0
  144. package/src/core/migrations/contract-to-postgres-database-schema-node.ts +99 -19
  145. package/src/core/migrations/control-policy.ts +4 -3
  146. package/src/core/migrations/diff-database-schema.ts +6 -3
  147. package/src/core/migrations/issue-planner.ts +41 -80
  148. package/src/core/migrations/op-factory-call.ts +40 -16
  149. package/src/core/migrations/operations/data-transform.ts +1 -1
  150. package/src/core/migrations/planner-produced-postgres-migration.ts +1 -1
  151. package/src/core/migrations/planner-strategies.ts +6 -6
  152. package/src/core/migrations/planner.ts +5 -4
  153. package/src/core/migrations/postgres-migration.ts +62 -2
  154. package/src/core/migrations/runner.ts +12 -11
  155. package/src/core/migrations/verify-postgres-namespaces.ts +0 -1
  156. package/src/core/psl-infer/infer-psl-contract.ts +130 -12
  157. package/src/core/schema-ir/postgres-policy-schema-node.ts +12 -2
  158. package/src/exports/codecs.ts +2 -0
  159. package/src/exports/control.ts +2 -0
  160. package/src/exports/default-normalizer.ts +1 -1
  161. package/src/exports/op-factory-call.ts +5 -0
  162. package/src/exports/types.ts +1 -0
  163. package/dist/authoring-BtsOWgI3.mjs.map +0 -1
  164. package/dist/codec-ids-B10ZZHzw.mjs.map +0 -1
  165. package/dist/codec-ids-CI144z7g.d.mts.map +0 -1
  166. package/dist/codec-types-CTfT4U4O.d.mts.map +0 -1
  167. package/dist/codecs-D7W9O0Xx.d.mts.map +0 -1
  168. package/dist/codecs-DRbb26Or.mjs.map +0 -1
  169. package/dist/control-policy-DtbkLLGv.mjs.map +0 -1
  170. package/dist/data-transform-DPzwBMhW.d.mts.map +0 -1
  171. package/dist/default-normalizer.mjs.map +0 -1
  172. package/dist/descriptor-meta-CFQKLXl_.mjs.map +0 -1
  173. package/dist/diff-database-schema-GncqMuSI.mjs.map +0 -1
  174. package/dist/errors-DO-w0EUS.mjs.map +0 -1
  175. package/dist/nodes-Dv5eCSq9.d.mts.map +0 -1
  176. package/dist/op-factory-call-Bn9zDx4_.d.mts.map +0 -1
  177. package/dist/planner-kql24i_F.mjs.map +0 -1
  178. package/dist/planner-produced-postgres-migration-BEY1T0Xm.d.mts.map +0 -1
  179. package/dist/planner-produced-postgres-migration-D7y-PEHK.mjs.map +0 -1
  180. package/dist/postgres-contract-view-C9j5cqP0.d.mts.map +0 -1
  181. package/dist/postgres-database-schema-node-CJv5bfbs.d.mts.map +0 -1
  182. package/dist/postgres-migration-DbckK1su.d.mts.map +0 -1
  183. package/dist/postgres-migration-arMSWU9b.mjs.map +0 -1
  184. package/dist/postgres-rls-policy--CSddvMR.d.mts.map +0 -1
  185. package/dist/postgres-role-schema-node-Cm-j0ZGM.mjs.map +0 -1
  186. package/dist/postgres-schema-DKq6s1P3.d.mts.map +0 -1
  187. package/dist/table-source-BvFo7gVs.d.mts.map +0 -1
  188. package/dist/types-BDKkx8MA.d.mts.map +0 -1
@@ -1,7 +1,14 @@
1
1
  import type { ContractToSchemaIROptions } from '@prisma-next/family-sql/control';
2
2
  import { contractNamespaceToSchemaIR } from '@prisma-next/family-sql/control';
3
+ import type { SchemaNodeRef } from '@prisma-next/framework-components/control';
3
4
  import { UNBOUND_NAMESPACE_ID } from '@prisma-next/framework-components/ir';
4
- import { SqlForeignKeyIR } from '@prisma-next/sql-schema-ir/types';
5
+ import {
6
+ PrimaryKey,
7
+ RelationalSchemaNodeKind,
8
+ SqlForeignKeyIR,
9
+ SqlIndexIR,
10
+ SqlUniqueIR,
11
+ } from '@prisma-next/sql-schema-ir/types';
5
12
  import { ifDefined } from '@prisma-next/utils/defined';
6
13
  import type { PostgresRlsPolicy } from '../postgres-rls-policy';
7
14
  import type { PostgresContract } from '../postgres-schema';
@@ -12,8 +19,43 @@ import { PostgresNativeEnumSchemaNode } from '../schema-ir/postgres-native-enum-
12
19
  import { PostgresPolicySchemaNode } from '../schema-ir/postgres-policy-schema-node';
13
20
  import { PostgresRoleSchemaNode } from '../schema-ir/postgres-role-schema-node';
14
21
  import { PostgresTableSchemaNode } from '../schema-ir/postgres-table-schema-node';
22
+ import { PostgresSchemaNodeKind } from '../schema-ir/schema-node-kinds';
15
23
  import { resolveDdlSchemaForNamespaceStorage } from './resolve-ddl-schema';
16
24
 
25
+ /** The database root's fixed sentinel id (`PostgresDatabaseSchemaNode#id`). */
26
+ function databaseStep(): { readonly nodeKind: string; readonly id: string } {
27
+ return { nodeKind: PostgresSchemaNodeKind.database, id: 'database' };
28
+ }
29
+
30
+ function tableDependsOn(namespaceId: string, tableName: string): SchemaNodeRef {
31
+ return [
32
+ databaseStep(),
33
+ { nodeKind: PostgresSchemaNodeKind.namespace, id: namespaceId },
34
+ { nodeKind: PostgresSchemaNodeKind.table, id: tableName },
35
+ ];
36
+ }
37
+
38
+ function roleDependsOn(role: string): SchemaNodeRef {
39
+ return [databaseStep(), { nodeKind: PostgresSchemaNodeKind.role, id: role }];
40
+ }
41
+
42
+ /**
43
+ * The chains from a table-child object (foreign key, index, unique, primary
44
+ * key) to each of the own columns it is built on, in the Postgres tree.
45
+ * Dropping a covered column auto-drops the object, so the object's drop must
46
+ * precede the column's; the graph derives that direction from these edges.
47
+ */
48
+ function columnDependsOn(
49
+ namespaceId: string,
50
+ tableName: string,
51
+ columns: readonly string[],
52
+ ): readonly SchemaNodeRef[] {
53
+ return columns.map((column) => [
54
+ ...tableDependsOn(namespaceId, tableName),
55
+ { nodeKind: RelationalSchemaNodeKind.column, id: `column:${column}` },
56
+ ]);
57
+ }
58
+
17
59
  function toPolicyNode(policy: PostgresRlsPolicy, namespaceId: string): PostgresPolicySchemaNode {
18
60
  return new PostgresPolicySchemaNode({
19
61
  name: policy.name,
@@ -25,6 +67,7 @@ function toPolicyNode(policy: PostgresRlsPolicy, namespaceId: string): PostgresP
25
67
  ...ifDefined('using', policy.using),
26
68
  ...ifDefined('withCheck', policy.withCheck),
27
69
  permissive: policy.permissive,
70
+ dependsOn: [tableDependsOn(namespaceId, policy.tableName), ...policy.roles.map(roleDependsOn)],
28
71
  });
29
72
  }
30
73
 
@@ -115,30 +158,67 @@ export function contractToPostgresDatabaseSchemaNode(
115
158
  // clauses, and resolves the real live DDL schema — introspected FKs
116
159
  // already carry the live schema, so this is what lets an expected FK
117
160
  // pair (by diff-node id) with its introspected counterpart.
118
- const foreignKeys = sqlTable.foreignKeys.map(
119
- (fk) =>
120
- new SqlForeignKeyIR({
121
- columns: fk.columns,
122
- referencedTable: fk.referencedTable,
123
- referencedColumns: fk.referencedColumns,
124
- referencedSchema: fk.referencedSchema ?? UNBOUND_NAMESPACE_ID,
125
- ...ifDefined('name', fk.name),
126
- ...ifDefined('onDelete', fk.onDelete),
127
- ...ifDefined('onUpdate', fk.onUpdate),
128
- ...ifDefined('annotations', fk.annotations),
129
- resolvedReferencedNamespace: resolveDdlSchemaForNamespaceStorage(
130
- contract.storage,
131
- fk.referencedSchema ?? UNBOUND_NAMESPACE_ID,
132
- ),
161
+ const foreignKeys = sqlTable.foreignKeys.map((fk) => {
162
+ const resolvedReferencedNamespace = resolveDdlSchemaForNamespaceStorage(
163
+ contract.storage,
164
+ fk.referencedSchema ?? UNBOUND_NAMESPACE_ID,
165
+ );
166
+ return new SqlForeignKeyIR({
167
+ columns: fk.columns,
168
+ referencedTable: fk.referencedTable,
169
+ referencedColumns: fk.referencedColumns,
170
+ referencedSchema: fk.referencedSchema ?? UNBOUND_NAMESPACE_ID,
171
+ ...ifDefined('name', fk.name),
172
+ ...ifDefined('onDelete', fk.onDelete),
173
+ ...ifDefined('onUpdate', fk.onUpdate),
174
+ ...ifDefined('annotations', fk.annotations),
175
+ resolvedReferencedNamespace,
176
+ dependsOn: [
177
+ tableDependsOn(resolvedReferencedNamespace, fk.referencedTable),
178
+ ...columnDependsOn(ddlSchema, tableName, fk.columns),
179
+ ],
180
+ });
181
+ });
182
+ // The family stamped these children's own-column `dependsOn` with the
183
+ // flat (single-schema) chain; the Postgres tree nests them under a
184
+ // namespace, so re-stamp with the multi-schema chain that matches this
185
+ // tree's paths. Every other field is carried through unchanged.
186
+ const uniques = sqlTable.uniques.map(
187
+ (u) =>
188
+ new SqlUniqueIR({
189
+ columns: u.columns,
190
+ ...ifDefined('name', u.name),
191
+ ...ifDefined('annotations', u.annotations),
192
+ dependsOn: columnDependsOn(ddlSchema, tableName, u.columns),
193
+ }),
194
+ );
195
+ const indexes = sqlTable.indexes.map(
196
+ (i) =>
197
+ new SqlIndexIR({
198
+ columns: i.columns,
199
+ unique: i.unique,
200
+ ...ifDefined('name', i.name),
201
+ ...ifDefined('type', i.type),
202
+ ...ifDefined('options', i.options),
203
+ ...ifDefined('annotations', i.annotations),
204
+ dependsOn: columnDependsOn(ddlSchema, tableName, i.columns),
133
205
  }),
134
206
  );
207
+ const primaryKey =
208
+ sqlTable.primaryKey !== undefined
209
+ ? new PrimaryKey({
210
+ columns: sqlTable.primaryKey.columns,
211
+ ...ifDefined('name', sqlTable.primaryKey.name),
212
+ dependsOn: columnDependsOn(ddlSchema, tableName, sqlTable.primaryKey.columns),
213
+ })
214
+ : undefined;
135
215
  tables[tableName] = new PostgresTableSchemaNode({
136
216
  name: sqlTable.name,
137
217
  columns: sqlTable.columns,
138
218
  foreignKeys,
139
- uniques: sqlTable.uniques,
140
- indexes: sqlTable.indexes,
141
- ...ifDefined('primaryKey', sqlTable.primaryKey),
219
+ uniques,
220
+ indexes,
221
+ ...ifDefined('primaryKey', primaryKey),
142
222
  ...ifDefined('annotations', sqlTable.annotations),
143
223
  ...ifDefined('checks', sqlTable.checks),
144
224
  policies: policiesByTable.get(tableName) ?? [],
@@ -5,6 +5,7 @@ import type {
5
5
  SuppressionRecord,
6
6
  } from '@prisma-next/family-sql/control';
7
7
  import type { SchemaDiffIssue } from '@prisma-next/framework-components/control';
8
+ import { issueOutcome } from '@prisma-next/framework-components/control';
8
9
  import { entityAt, UNBOUND_NAMESPACE_ID } from '@prisma-next/framework-components/ir';
9
10
  import type { SqlStorage, StorageTable } from '@prisma-next/sql-contract/types';
10
11
  import { blindCast } from '@prisma-next/utils/casts';
@@ -252,7 +253,7 @@ const POSTGRES_NODE_CREATION_FACTORY: Readonly<Record<string, string>> = Object.
252
253
  * it is not admitted as creation-class here.
253
254
  */
254
255
  function isEnablementCreationIssue(issue: SchemaDiffIssue<SqlSchemaDiffNode>): boolean {
255
- if (issue.reason !== 'not-equal') return false;
256
+ if (issueOutcome(issue) !== 'not-equal') return false;
256
257
  const { expected, actual } = issue;
257
258
  return (
258
259
  expected !== undefined &&
@@ -270,7 +271,7 @@ export function resolvePostgresNodeIssueCreationFactoryName(
270
271
  if (isEnablementCreationIssue(issue)) {
271
272
  return 'enableRowLevelSecurity';
272
273
  }
273
- if (issue.reason !== 'not-found') return undefined;
274
+ if (issueOutcome(issue) !== 'not-found') return undefined;
274
275
  const node = issue.expected ?? issue.actual;
275
276
  if (node === undefined) return undefined;
276
277
  return POSTGRES_NODE_CREATION_FACTORY[node.nodeKind];
@@ -298,7 +299,7 @@ export function resolvePostgresNodeIssueControlPolicySubject(
298
299
  >(node);
299
300
  return {
300
301
  namespaceId: resolveNamespaceIdForDdlSchema(contract, namespaceNode.schemaName),
301
- createsNewObject: issue.reason === 'not-found',
302
+ createsNewObject: issueOutcome(issue) === 'not-found',
302
303
  };
303
304
  }
304
305
 
@@ -4,12 +4,13 @@ import { buildNativeTypeExpander } from '@prisma-next/family-sql/control';
4
4
  import { classifyDiffSubjectGranularity } from '@prisma-next/family-sql/diff';
5
5
  import type { TargetBoundComponentDescriptor } from '@prisma-next/framework-components/components';
6
6
  import type { DiffableNode, SchemaDiffIssue } from '@prisma-next/framework-components/control';
7
- import { diffSchemas } from '@prisma-next/framework-components/control';
7
+ import { diffSchemas, issueOutcome } from '@prisma-next/framework-components/control';
8
8
  import { UNBOUND_NAMESPACE_ID } from '@prisma-next/framework-components/ir';
9
9
  import type { SqlStorage } from '@prisma-next/sql-contract/types';
10
10
  import type { SqlSchemaIRNode } from '@prisma-next/sql-schema-ir/types';
11
11
  import { blindCast } from '@prisma-next/utils/casts';
12
12
  import { ifDefined } from '@prisma-next/utils/defined';
13
+ import { postgresResolveDefault } from '../default-normalizer';
13
14
  import type { PostgresContract } from '../postgres-schema';
14
15
  import { PostgresDatabaseSchemaNode } from '../schema-ir/postgres-database-schema-node';
15
16
  import { PostgresNamespaceSchemaNode } from '../schema-ir/postgres-namespace-schema-node';
@@ -135,12 +136,13 @@ export function diffPostgresSchema(input: {
135
136
  const fullExpected = contractToPostgresDatabaseSchemaNode(postgresContract, {
136
137
  annotationNamespace: 'pg',
137
138
  ...ifDefined('expandNativeType', expandNativeType),
139
+ resolveDefault: postgresResolveDefault,
138
140
  });
139
141
  const expected = pruneTableLessNamespaces(fullExpected);
140
142
  const relationalOwned = ownedSchemaNames(expected);
141
143
  const structuralOwned = ownedSchemaNames(fullExpected);
142
144
  const issues = diffSchemas(expected, actual).filter((issue) => {
143
- if (issue.reason !== 'not-expected') return true;
145
+ if (issueOutcome(issue) !== 'not-expected') return true;
144
146
  if (isClusterScopedIssue(issue)) return true;
145
147
  const granularity = classifyDiffSubjectGranularity(issue, postgresDiffSubjectGranularity);
146
148
  const namespaceSegment = issue.path[1];
@@ -230,6 +232,7 @@ export function buildPostgresPlanDiff(input: {
230
232
  const projectionOptions = {
231
233
  annotationNamespace: 'pg',
232
234
  ...ifDefined('expandNativeType', expandNativeType),
235
+ resolveDefault: postgresResolveDefault,
233
236
  };
234
237
  const fullExpected = contractToPostgresDatabaseSchemaNode(postgresContract, projectionOptions);
235
238
  const expected = pruneTableLessNamespaces(fullExpected);
@@ -240,7 +243,7 @@ export function buildPostgresPlanDiff(input: {
240
243
  readonly SchemaDiffIssue<SqlSchemaDiffNode>[],
241
244
  'both trees are PostgresDatabaseSchemaNodes, so every diff-issue node is a SqlSchemaDiffNode'
242
245
  >(diffSchemas(expected, paddedActual)).filter((issue) => {
243
- if (issue.reason !== 'not-expected') return true;
246
+ if (issueOutcome(issue) !== 'not-expected') return true;
244
247
  if (isClusterScopedIssue(issue)) return true;
245
248
  const granularity = classifyDiffSubjectGranularity(issue, postgresDiffSubjectGranularity);
246
249
  const namespaceSegment = issue.path[1];
@@ -25,6 +25,7 @@ import type {
25
25
  } from '@prisma-next/family-sql/control';
26
26
  import type { TargetBoundComponentDescriptor } from '@prisma-next/framework-components/components';
27
27
  import type { DiffableNode, SchemaDiffIssue } from '@prisma-next/framework-components/control';
28
+ import { issueOutcome, orderIssuesByDependencies } from '@prisma-next/framework-components/control';
28
29
  import { UNBOUND_NAMESPACE_ID } from '@prisma-next/framework-components/ir';
29
30
  import type { SqlStorage, StorageTypeInstance } from '@prisma-next/sql-contract/types';
30
31
  import type { DdlTableConstraint } from '@prisma-next/sql-relational-core/ast';
@@ -136,6 +137,7 @@ export interface IssuePlannerValue {
136
137
  type CallCategory =
137
138
  | 'dep'
138
139
  | 'drop'
140
+ | 'dropType'
139
141
  | 'table'
140
142
  | 'rlsEnable'
141
143
  | 'rlsPolicy'
@@ -151,6 +153,13 @@ type CallCategory =
151
153
  * legacy walk-schema planner's emission order so `db init` and `db update`
152
154
  * produce byte-identical plans for the shared shape (deps → drops → tables
153
155
  * → columns → alters → PKs → uniques → indexes → FKs).
156
+ *
157
+ * `dropType` (DROP TYPE for a managed native enum) is its own bucket, ordered
158
+ * after the general drop bucket: a type can only be dropped once every table
159
+ * whose column uses it is gone. A column→enum edge would make this precise,
160
+ * but `coalesceSubtreeIssues` removes the column issue under a whole-table
161
+ * drop, so the edge never reaches the graph; the coarse bucket stands in until
162
+ * that edge lands (the coordinate work is a later slice).
154
163
  */
155
164
  function classifyCall(call: PostgresOpFactoryCall): CallCategory {
156
165
  switch (call.factoryName) {
@@ -159,8 +168,9 @@ function classifyCall(call: PostgresOpFactoryCall): CallCategory {
159
168
  case 'createNativeEnumType':
160
169
  case 'addNativeEnumValue':
161
170
  return 'dep';
162
- case 'dropTable':
163
171
  case 'dropNativeEnumType':
172
+ return 'dropType';
173
+ case 'dropTable':
164
174
  case 'dropColumn':
165
175
  case 'dropConstraint':
166
176
  case 'dropCheckConstraint':
@@ -369,57 +379,6 @@ export function columnTypeChanged(expected: SqlColumnIR, actual: SqlColumnIR): b
369
379
  );
370
380
  }
371
381
 
372
- // ----------------------------------------------------------------------------
373
- // Node-keyed issue ordering (re-keys ISSUE_KIND_ORDER on nodeKind + reason)
374
- // ----------------------------------------------------------------------------
375
-
376
- /**
377
- * Re-keys the legacy `ISSUE_KIND_ORDER` on `(nodeKind, reason)`, numbers
378
- * preserved so the dependency intent stays legible. Final emission order is
379
- * fixed downstream by `classifyCall` bucketing (dep → drop → table → column →
380
- * recipe → alter → primaryKey → unique → index → foreignKey), so this only
381
- * breaks ties within a bucket.
382
- */
383
- export function nodeIssueOrder(issue: SchemaDiffIssue): number {
384
- const node = issueNode(issue);
385
- if (node === undefined) return 99;
386
- switch (node.nodeKind) {
387
- case PostgresSchemaNodeKind.namespace:
388
- return 1;
389
- case PostgresSchemaNodeKind.nativeEnum:
390
- // Creates order right after namespace creates within the 'dep' bucket
391
- // (CREATE SCHEMA before CREATE TYPE); drops order after table drops
392
- // within the 'drop' bucket (DROP TYPE only after its dependents left).
393
- return issue.reason === 'not-expected' ? 17 : 2;
394
- case RelationalSchemaNodeKind.foreignKey:
395
- return issue.reason === 'not-expected' ? 10 : 60;
396
- case RelationalSchemaNodeKind.unique:
397
- return issue.reason === 'not-expected' ? 11 : 51;
398
- case RelationalSchemaNodeKind.primaryKey:
399
- return issue.reason === 'not-expected' ? 12 : 50;
400
- case RelationalSchemaNodeKind.index:
401
- return issue.reason === 'not-expected' ? 13 : 52;
402
- case RelationalSchemaNodeKind.columnDefault:
403
- if (issue.reason === 'not-expected') return 14;
404
- return issue.reason === 'not-found' ? 42 : 43;
405
- case RelationalSchemaNodeKind.column:
406
- if (issue.reason === 'not-expected') return 15;
407
- return issue.reason === 'not-found' ? 30 : 40;
408
- case PostgresSchemaNodeKind.table:
409
- return issue.reason === 'not-expected' ? 16 : 20;
410
- case RelationalSchemaNodeKind.check:
411
- if (issue.reason === 'not-found') return 53;
412
- return issue.reason === 'not-expected' ? 55 : 54;
413
- default:
414
- return 99;
415
- }
416
- }
417
-
418
- /** Deterministic tiebreak within an order bucket: the diff path already encodes schema → table → child. */
419
- export function nodeIssueKey(issue: SchemaDiffIssue): string {
420
- return issue.path.join(' ');
421
- }
422
-
423
382
  // ----------------------------------------------------------------------------
424
383
  // Subtree coalescing (the planner's responsibility per the differ's contract)
425
384
  // ----------------------------------------------------------------------------
@@ -437,7 +396,7 @@ export function coalesceSubtreeIssues<TNode extends DiffableNode = DiffableNode>
437
396
  issues: readonly SchemaDiffIssue<TNode>[],
438
397
  ): readonly SchemaDiffIssue<TNode>[] {
439
398
  const collapsingPaths = issues
440
- .filter((issue) => issue.reason === 'not-found' || issue.reason === 'not-expected')
399
+ .filter((issue) => issueOutcome(issue) !== 'not-equal')
441
400
  .map((issue) => issue.path);
442
401
  if (collapsingPaths.length === 0) return issues;
443
402
  return issues.filter(
@@ -601,14 +560,14 @@ function mapNativeEnumNodeIssue(
601
560
  );
602
561
  }
603
562
  const schemaName = emissionSchemaName(ctx, ddlSchemaName);
604
- if (issue.reason === 'not-found') {
563
+ if (issueOutcome(issue) === 'not-found') {
605
564
  const expected = blindCast<
606
565
  PostgresNativeEnumSchemaNode,
607
566
  'a not-found native-enum issue always carries the expected PostgresNativeEnumSchemaNode'
608
567
  >(issue.expected);
609
568
  return ok([new CreateNativeEnumTypeCall(schemaName, expected.typeName, expected.members)]);
610
569
  }
611
- if (issue.reason === 'not-expected') {
570
+ if (issueOutcome(issue) === 'not-expected') {
612
571
  const actual = blindCast<
613
572
  PostgresNativeEnumSchemaNode,
614
573
  'a not-expected native-enum issue always carries the actual PostgresNativeEnumSchemaNode'
@@ -654,14 +613,14 @@ function mapTableNodeIssue(
654
613
  ddlSchemaName: string,
655
614
  codecHooks: ReadonlyMap<string, CodecControlHooks>,
656
615
  ): Result<readonly PostgresOpFactoryCall[], SqlPlannerConflict> {
657
- if (issue.reason === 'not-found') {
616
+ if (issueOutcome(issue) === 'not-found') {
658
617
  const table = blindCast<
659
618
  PostgresTableSchemaNode,
660
619
  'a not-found table issue always carries the expected PostgresTableSchemaNode'
661
620
  >(issue.expected);
662
621
  return ok(buildCreateTableCallsFromNode(schemaName, ddlSchemaName, table, codecHooks));
663
622
  }
664
- if (issue.reason === 'not-expected') {
623
+ if (issueOutcome(issue) === 'not-expected') {
665
624
  const table = blindCast<
666
625
  PostgresTableSchemaNode,
667
626
  'a not-expected table issue always carries the actual PostgresTableSchemaNode'
@@ -703,7 +662,7 @@ function mapColumnNodeIssue(
703
662
  tableName: string,
704
663
  codecHooks: ReadonlyMap<string, CodecControlHooks>,
705
664
  ): Result<readonly PostgresOpFactoryCall[], SqlPlannerConflict> {
706
- if (issue.reason === 'not-found') {
665
+ if (issueOutcome(issue) === 'not-found') {
707
666
  const column = blindCast<
708
667
  SqlColumnIR,
709
668
  'a not-found column issue always carries the expected column node'
@@ -712,7 +671,7 @@ function mapColumnNodeIssue(
712
671
  new AddColumnCall(schemaName, tableName, renderColumnDdl(column.name, column, codecHooks)),
713
672
  ]);
714
673
  }
715
- if (issue.reason === 'not-expected') {
674
+ if (issueOutcome(issue) === 'not-expected') {
716
675
  const column = blindCast<
717
676
  SqlColumnIR,
718
677
  'a not-expected column issue always carries the actual column node'
@@ -755,7 +714,7 @@ function mapColumnDefaultNodeIssue(
755
714
  tableName: string,
756
715
  columnName: string,
757
716
  ): Result<readonly PostgresOpFactoryCall[], SqlPlannerConflict> {
758
- if (issue.reason === 'not-expected') {
717
+ if (issueOutcome(issue) === 'not-expected') {
759
718
  return ok([new DropDefaultCall(schemaName, tableName, columnName)]);
760
719
  }
761
720
  // not-found (SET DEFAULT, additive) or not-equal (SET DEFAULT, widening).
@@ -772,7 +731,7 @@ function mapColumnDefaultNodeIssue(
772
731
  tableName,
773
732
  columnName,
774
733
  defaultSql,
775
- issue.reason === 'not-equal' ? 'widening' : 'additive',
734
+ issueOutcome(issue) === 'not-equal' ? 'widening' : 'additive',
776
735
  ),
777
736
  ]);
778
737
  }
@@ -782,7 +741,7 @@ function mapPrimaryKeyNodeIssue(
782
741
  schemaName: string,
783
742
  tableName: string,
784
743
  ): Result<readonly PostgresOpFactoryCall[], SqlPlannerConflict> {
785
- if (issue.reason === 'not-found') {
744
+ if (issueOutcome(issue) === 'not-found') {
786
745
  const pk = blindCast<
787
746
  { readonly columns: readonly string[]; readonly name?: string },
788
747
  'a not-found primary-key issue always carries the expected PrimaryKey node'
@@ -790,7 +749,7 @@ function mapPrimaryKeyNodeIssue(
790
749
  const constraintName = pk.name ?? `${tableName}_pkey`;
791
750
  return ok([new AddPrimaryKeyCall(schemaName, tableName, constraintName, [...pk.columns])]);
792
751
  }
793
- if (issue.reason === 'not-expected') {
752
+ if (issueOutcome(issue) === 'not-expected') {
794
753
  const pk = blindCast<
795
754
  { readonly name?: string },
796
755
  'a not-expected primary-key issue always carries the actual PrimaryKey node'
@@ -807,14 +766,14 @@ function mapForeignKeyNodeIssue(
807
766
  schemaName: string,
808
767
  tableName: string,
809
768
  ): Result<readonly PostgresOpFactoryCall[], SqlPlannerConflict> {
810
- if (issue.reason === 'not-found') {
769
+ if (issueOutcome(issue) === 'not-found') {
811
770
  const fk = blindCast<
812
771
  SqlForeignKeyIR,
813
772
  'a not-found foreign-key issue always carries the expected foreign-key node'
814
773
  >(issue.expected);
815
774
  return ok([new AddForeignKeyCall(schemaName, tableName, fkSpecFromNode(fk, tableName))]);
816
775
  }
817
- if (issue.reason === 'not-expected') {
776
+ if (issueOutcome(issue) === 'not-expected') {
818
777
  const fk = blindCast<
819
778
  SqlForeignKeyIR,
820
779
  'a not-expected foreign-key issue always carries the actual foreign-key node'
@@ -830,7 +789,7 @@ function mapUniqueNodeIssue(
830
789
  schemaName: string,
831
790
  tableName: string,
832
791
  ): Result<readonly PostgresOpFactoryCall[], SqlPlannerConflict> {
833
- if (issue.reason === 'not-found') {
792
+ if (issueOutcome(issue) === 'not-found') {
834
793
  const unique = blindCast<
835
794
  SqlUniqueIR,
836
795
  'a not-found unique issue always carries the expected unique node'
@@ -838,7 +797,7 @@ function mapUniqueNodeIssue(
838
797
  const name = unique.name ?? `${tableName}_${unique.columns.join('_')}_key`;
839
798
  return ok([new AddUniqueCall(schemaName, tableName, name, [...unique.columns])]);
840
799
  }
841
- if (issue.reason === 'not-expected') {
800
+ if (issueOutcome(issue) === 'not-expected') {
842
801
  const unique = blindCast<
843
802
  SqlUniqueIR,
844
803
  'a not-expected unique issue always carries the actual unique node'
@@ -854,7 +813,7 @@ function mapIndexNodeIssue(
854
813
  schemaName: string,
855
814
  tableName: string,
856
815
  ): Result<readonly PostgresOpFactoryCall[], SqlPlannerConflict> {
857
- if (issue.reason === 'not-found') {
816
+ if (issueOutcome(issue) === 'not-found') {
858
817
  const index = blindCast<
859
818
  SqlIndexIR,
860
819
  'a not-found index issue always carries the expected index node'
@@ -865,7 +824,7 @@ function mapIndexNodeIssue(
865
824
  if (index.options !== undefined) extras.options = index.options;
866
825
  return ok([new CreateIndexCall(schemaName, tableName, indexName, [...index.columns], extras)]);
867
826
  }
868
- if (issue.reason === 'not-expected') {
827
+ if (issueOutcome(issue) === 'not-expected') {
869
828
  const index = blindCast<
870
829
  SqlIndexIR,
871
830
  'a not-expected index issue always carries the actual index node'
@@ -885,7 +844,7 @@ function mapCheckNodeIssue(
885
844
  // the default mapper handles directly; check_missing / check_mismatch are
886
845
  // consumed by `checkConstraintPlanCallStrategy` (drop+recreate), so reaching
887
846
  // here for them means the strategy did not run — a conflict.
888
- if (issue.reason === 'not-expected') {
847
+ if (issueOutcome(issue) === 'not-expected') {
889
848
  const check = blindCast<
890
849
  { readonly name: string },
891
850
  'a not-expected check issue always carries the actual check node'
@@ -902,8 +861,8 @@ function mapCheckNodeIssue(
902
861
 
903
862
  /**
904
863
  * Maps one node-typed diff issue to its migration call(s), dispatching on the
905
- * node's `nodeKind` + `issue.reason`, reading nodes and resolving column DDL
906
- * from `codecRef` via `column-ddl-rendering.ts`.
864
+ * node's `nodeKind` and the issue's presence-derived `issueOutcome`, reading
865
+ * nodes and resolving column DDL from `codecRef` via `column-ddl-rendering.ts`.
907
866
  */
908
867
  export function mapNodeIssueToCall(
909
868
  issue: SchemaDiffIssue,
@@ -919,7 +878,7 @@ export function mapNodeIssueToCall(
919
878
  );
920
879
  }
921
880
  if (node.nodeKind === PostgresSchemaNodeKind.namespace) {
922
- if (issue.reason !== 'not-found') {
881
+ if (issueOutcome(issue) !== 'not-found') {
923
882
  return notOk(
924
883
  nodeConflict('unsupportedOperation', `Unexpected namespace drift: ${issue.path.join('/')}`),
925
884
  );
@@ -1052,13 +1011,12 @@ export function planIssues(
1052
1011
  }
1053
1012
  }
1054
1013
 
1055
- const sorted = [...remaining].sort((a, b) => {
1056
- const kindDelta = nodeIssueOrder(a) - nodeIssueOrder(b);
1057
- if (kindDelta !== 0) return kindDelta;
1058
- const keyA = nodeIssueKey(a);
1059
- const keyB = nodeIssueKey(b);
1060
- return keyA < keyB ? -1 : keyA > keyB ? 1 : 0;
1061
- });
1014
+ // Dependency-graph order: a topological sort over the issues' `dependsOn`
1015
+ // cross-links and containment edges (the ordering law drives edge direction
1016
+ // by presence), path-tiebroken for determinism. `classifyCall` bucketing
1017
+ // downstream fixes the coarse cross-entity DDL sequence; this settles the
1018
+ // order within each bucket (notably the teardown order among drops).
1019
+ const sorted = orderIssuesByDependencies(remaining);
1062
1020
 
1063
1021
  const defaultCalls: PostgresOpFactoryCall[] = [];
1064
1022
  const conflicts: SqlPlannerConflict[] = [];
@@ -1106,6 +1064,9 @@ export function planIssues(
1106
1064
  const calls: PostgresOpFactoryCall[] = [
1107
1065
  ...byCategory('dep'),
1108
1066
  ...byCategory('drop'),
1067
+ // DROP TYPE after every table drop — a managed enum type can only go once
1068
+ // no live column still uses it.
1069
+ ...byCategory('dropType'),
1109
1070
  ...byCategory('table'),
1110
1071
  ...byCategory('column'),
1111
1072
  ...gatedRecipe,
@@ -9,7 +9,7 @@
9
9
  * - `toOp()` — converts the IR node to a runtime
10
10
  * `SqlMigrationPlanOperation` by delegating to the matching pure factory
11
11
  * under `operations/`. `DataTransformCall.toOp()` always throws
12
- * `PN-MIG-2001` because a planner-generated data transform is an
12
+ * `MIGRATION.UNFILLED_PLACEHOLDER` because a planner-generated data transform is an
13
13
  * unfilled authoring stub by construction.
14
14
  * - `renderTypeScript()` / `importRequirements()` — inherited from
15
15
  * `TsExpression`. Used by `renderCallsToTypeScript` to emit the call as
@@ -45,7 +45,7 @@ import {
45
45
  tableExistsAst,
46
46
  } from '../../contract-free/checks';
47
47
  import * as contractFreeDdl from '../../contract-free/ddl';
48
- import type { PostgresRlsPolicy } from '../postgres-rls-policy';
48
+ import type { PostgresRlsPolicy, PostgresRlsPolicyInput } from '../postgres-rls-policy';
49
49
  import {
50
50
  escapeLiteral,
51
51
  quoteIdentifier,
@@ -740,10 +740,6 @@ export class AddNotNullColumnDirectCall extends PostgresOpFactoryCallNode {
740
740
  renderTypeScript(): string {
741
741
  return `rawSql(${jsonToTsSource({ id: `column.${this.tableName}.${this.columnName}`, label: this.label, operationClass: 'additive' })})`;
742
742
  }
743
-
744
- override importRequirements(): readonly ImportRequirement[] {
745
- return [];
746
- }
747
743
  }
748
744
 
749
745
  /**
@@ -810,10 +806,6 @@ export class AddNotNullColumnWithTempDefaultCall extends PostgresOpFactoryCallNo
810
806
  renderTypeScript(): string {
811
807
  return `rawSql(${jsonToTsSource({ id: `column.${this.tableName}.${this.columnName}`, label: this.label, operationClass: 'additive' })})`;
812
808
  }
813
-
814
- override importRequirements(): readonly ImportRequirement[] {
815
- return [];
816
- }
817
809
  }
818
810
 
819
811
  // ============================================================================
@@ -1515,7 +1507,7 @@ export class AddNativeEnumValueCall extends PostgresOpFactoryCallNode {
1515
1507
  * A planner-generated data-transform stub. `checkSlot` and `runSlot` name
1516
1508
  * the unfilled authoring slots that the rendered `migration.ts` will expose
1517
1509
  * to the user via `placeholder("…")` calls. `toOp()` always throws
1518
- * `PN-MIG-2001`: the planner cannot lower a stubbed transform to a runtime
1510
+ * `MIGRATION.UNFILLED_PLACEHOLDER`: the planner cannot lower a stubbed transform to a runtime
1519
1511
  * op — the user must fill the rendered `migration.ts` and re-emit.
1520
1512
  */
1521
1513
  export class DataTransformCall extends PostgresOpFactoryCallNode {
@@ -1592,7 +1584,23 @@ export class CreatePostgresRlsPolicyCall extends PostgresOpFactoryCallNode {
1592
1584
  }
1593
1585
 
1594
1586
  renderTypeScript(): string {
1595
- return `createRlsPolicy(${jsonToTsSource(this.schemaName)}, ${jsonToTsSource(this.tableName)}, ${jsonToTsSource(this.policy)})`;
1587
+ const p = this.policy;
1588
+ const input: PostgresRlsPolicyInput = {
1589
+ name: p.name,
1590
+ prefix: p.prefix,
1591
+ tableName: p.tableName,
1592
+ namespaceId: p.namespaceId,
1593
+ operation: p.operation,
1594
+ roles: p.roles,
1595
+ ...ifDefined('using', p.using),
1596
+ ...ifDefined('withCheck', p.withCheck),
1597
+ permissive: p.permissive,
1598
+ };
1599
+ return `this.createRlsPolicy({ schema: ${jsonToTsSource(this.schemaName)}, table: ${jsonToTsSource(this.tableName)}, policy: ${jsonToTsSource(input)} })`;
1600
+ }
1601
+
1602
+ override importRequirements(): readonly ImportRequirement[] {
1603
+ return [];
1596
1604
  }
1597
1605
  }
1598
1606
 
@@ -1623,7 +1631,11 @@ export class DropPostgresRlsPolicyCall extends PostgresOpFactoryCallNode {
1623
1631
  }
1624
1632
 
1625
1633
  renderTypeScript(): string {
1626
- return `dropRlsPolicy(${jsonToTsSource(this.schemaName)}, ${jsonToTsSource(this.tableName)}, ${jsonToTsSource(this.policyName)})`;
1634
+ return `this.dropRlsPolicy({ schema: ${jsonToTsSource(this.schemaName)}, table: ${jsonToTsSource(this.tableName)}, policy: ${jsonToTsSource(this.policyName)} })`;
1635
+ }
1636
+
1637
+ override importRequirements(): readonly ImportRequirement[] {
1638
+ return [];
1627
1639
  }
1628
1640
  }
1629
1641
 
@@ -1652,7 +1664,11 @@ export class EnableRowLevelSecurityCall extends PostgresOpFactoryCallNode {
1652
1664
  }
1653
1665
 
1654
1666
  renderTypeScript(): string {
1655
- return `enableRowLevelSecurity(${jsonToTsSource(this.schemaName)}, ${jsonToTsSource(this.tableName)})`;
1667
+ return `this.enableRowLevelSecurity({ schema: ${jsonToTsSource(this.schemaName)}, table: ${jsonToTsSource(this.tableName)} })`;
1668
+ }
1669
+
1670
+ override importRequirements(): readonly ImportRequirement[] {
1671
+ return [];
1656
1672
  }
1657
1673
  }
1658
1674
 
@@ -1681,7 +1697,11 @@ export class DisableRowLevelSecurityCall extends PostgresOpFactoryCallNode {
1681
1697
  }
1682
1698
 
1683
1699
  renderTypeScript(): string {
1684
- return `disableRowLevelSecurity(${jsonToTsSource(this.schemaName)}, ${jsonToTsSource(this.tableName)})`;
1700
+ return `this.disableRowLevelSecurity({ schema: ${jsonToTsSource(this.schemaName)}, table: ${jsonToTsSource(this.tableName)} })`;
1701
+ }
1702
+
1703
+ override importRequirements(): readonly ImportRequirement[] {
1704
+ return [];
1685
1705
  }
1686
1706
  }
1687
1707
 
@@ -1724,7 +1744,11 @@ export class RenamePostgresRlsPolicyCall extends PostgresOpFactoryCallNode {
1724
1744
  }
1725
1745
 
1726
1746
  renderTypeScript(): string {
1727
- return `renameRlsPolicy(${jsonToTsSource(this.schemaName)}, ${jsonToTsSource(this.tableName)}, ${jsonToTsSource(this.oldPolicyName)}, ${jsonToTsSource(this.newPolicyName)})`;
1747
+ return `this.renameRlsPolicy({ schema: ${jsonToTsSource(this.schemaName)}, table: ${jsonToTsSource(this.tableName)}, from: ${jsonToTsSource(this.oldPolicyName)}, to: ${jsonToTsSource(this.newPolicyName)} })`;
1748
+ }
1749
+
1750
+ override importRequirements(): readonly ImportRequirement[] {
1751
+ return [];
1728
1752
  }
1729
1753
  }
1730
1754
 
@@ -21,7 +21,7 @@
21
21
  *
22
22
  * The factory accepts lazy closures (`() => SqlQueryPlan | Buildable`),
23
23
  * invokes each one, asserts that its `meta.storageHash` matches the
24
- * `contract` it was handed (→ `PN-MIG-2005` on mismatch), and lowers the
24
+ * `contract` it was handed (→ `MIGRATION.DATA_TRANSFORM_CONTRACT_MISMATCH` on mismatch), and lowers the
25
25
  * plan via the supplied control adapter to a serialized `{sql, params}`
26
26
  * payload.
27
27
  *