@prisma-next/target-postgres 0.14.0-dev.9 → 0.14.0-dev.90

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 (266) hide show
  1. package/dist/authoring-BtsOWgI3.mjs +674 -0
  2. package/dist/authoring-BtsOWgI3.mjs.map +1 -0
  3. package/dist/canonicalize-D1F4vUnP.d.mts +48 -0
  4. package/dist/canonicalize-D1F4vUnP.d.mts.map +1 -0
  5. package/dist/{codec-ids-BvytN2P8.mjs → codec-ids-B10ZZHzw.mjs} +4 -2
  6. package/dist/codec-ids-B10ZZHzw.mjs.map +1 -0
  7. package/dist/{codec-ids-CnXu9Qy3.d.mts → codec-ids-CI144z7g.d.mts} +4 -2
  8. package/dist/codec-ids-CI144z7g.d.mts.map +1 -0
  9. package/dist/codec-ids.d.mts +2 -2
  10. package/dist/codec-ids.mjs +2 -2
  11. package/dist/{codec-types-DHCkwPKE.d.mts → codec-types-CTfT4U4O.d.mts} +4 -2
  12. package/dist/codec-types-CTfT4U4O.d.mts.map +1 -0
  13. package/dist/codec-types.d.mts +1 -1
  14. package/dist/{codecs--0A5_4Bq.d.mts → codecs-D7W9O0Xx.d.mts} +134 -4
  15. package/dist/codecs-D7W9O0Xx.d.mts.map +1 -0
  16. package/dist/codecs-DRbb26Or.mjs +955 -0
  17. package/dist/codecs-DRbb26Or.mjs.map +1 -0
  18. package/dist/codecs.d.mts +2 -2
  19. package/dist/codecs.mjs +3 -757
  20. package/dist/codecs.mjs.map +1 -1
  21. package/dist/contract-free.d.mts +33 -3
  22. package/dist/contract-free.d.mts.map +1 -1
  23. package/dist/contract-free.mjs +23 -7
  24. package/dist/contract-free.mjs.map +1 -1
  25. package/dist/control-policy-DtbkLLGv.mjs +1285 -0
  26. package/dist/control-policy-DtbkLLGv.mjs.map +1 -0
  27. package/dist/control.d.mts +2 -2
  28. package/dist/control.d.mts.map +1 -1
  29. package/dist/control.mjs +880 -36
  30. package/dist/control.mjs.map +1 -1
  31. package/dist/data-transform-BOWpliq8.mjs.map +1 -1
  32. package/dist/{data-transform-DDgWdB5o.d.mts → data-transform-DPzwBMhW.d.mts} +3 -3
  33. package/dist/{data-transform-DDgWdB5o.d.mts.map → data-transform-DPzwBMhW.d.mts.map} +1 -1
  34. package/dist/data-transform.d.mts +1 -1
  35. package/dist/{ddl-QDyOSeLc.mjs → ddl-GTTOvjx_.mjs} +128 -6
  36. package/dist/ddl-GTTOvjx_.mjs.map +1 -0
  37. package/dist/ddl.d.mts +3 -2
  38. package/dist/ddl.mjs +2 -2
  39. package/dist/default-normalizer.d.mts +1 -1
  40. package/dist/default-normalizer.d.mts.map +1 -1
  41. package/dist/default-normalizer.mjs +247 -1
  42. package/dist/default-normalizer.mjs.map +1 -0
  43. package/dist/descriptor-meta-CFQKLXl_.mjs +23 -0
  44. package/dist/descriptor-meta-CFQKLXl_.mjs.map +1 -0
  45. package/dist/descriptor-meta-runtime-UwYdV8fD.mjs +12 -0
  46. package/dist/descriptor-meta-runtime-UwYdV8fD.mjs.map +1 -0
  47. package/dist/diff-database-schema-GncqMuSI.mjs +305 -0
  48. package/dist/diff-database-schema-GncqMuSI.mjs.map +1 -0
  49. package/dist/diff-database-schema.d.mts +46 -0
  50. package/dist/diff-database-schema.d.mts.map +1 -0
  51. package/dist/diff-database-schema.mjs +2 -0
  52. package/dist/errors-DO-w0EUS.mjs +35 -0
  53. package/dist/errors-DO-w0EUS.mjs.map +1 -0
  54. package/dist/errors.d.mts +11 -9
  55. package/dist/errors.d.mts.map +1 -1
  56. package/dist/errors.mjs +1 -1
  57. package/dist/issue-planner.d.mts +35 -11
  58. package/dist/issue-planner.d.mts.map +1 -1
  59. package/dist/issue-planner.mjs +2 -2
  60. package/dist/migration.d.mts +5 -5
  61. package/dist/migration.d.mts.map +1 -1
  62. package/dist/migration.mjs +4 -4
  63. package/dist/namespace-ids-xtp_ZY86.mjs +7 -0
  64. package/dist/namespace-ids-xtp_ZY86.mjs.map +1 -0
  65. package/dist/native-type-normalizer.mjs +37 -1
  66. package/dist/native-type-normalizer.mjs.map +1 -0
  67. package/dist/nodes-DJC5B8Id.mjs +192 -0
  68. package/dist/nodes-DJC5B8Id.mjs.map +1 -0
  69. package/dist/nodes-Dv5eCSq9.d.mts +170 -0
  70. package/dist/nodes-Dv5eCSq9.d.mts.map +1 -0
  71. package/dist/{op-factory-call-DmQEc3XV.d.mts → op-factory-call-Bn9zDx4_.d.mts} +114 -15
  72. package/dist/op-factory-call-Bn9zDx4_.d.mts.map +1 -0
  73. package/dist/{op-factory-call-D_p5vxwt.mjs → op-factory-call-C38NzvQD.mjs} +469 -32
  74. package/dist/op-factory-call-C38NzvQD.mjs.map +1 -0
  75. package/dist/op-factory-call.d.mts +2 -2
  76. package/dist/op-factory-call.mjs +2 -2
  77. package/dist/pack.d.mts +321 -3
  78. package/dist/pack.d.mts.map +1 -1
  79. package/dist/pack.mjs +1 -1
  80. package/dist/{planner-ddl-builders-B2wOwLqI.mjs → planner-ddl-builders-BKlmGDJl.mjs} +17 -28
  81. package/dist/planner-ddl-builders-BKlmGDJl.mjs.map +1 -0
  82. package/dist/planner-ddl-builders.d.mts +4 -6
  83. package/dist/planner-ddl-builders.d.mts.map +1 -1
  84. package/dist/planner-ddl-builders.mjs +2 -2
  85. package/dist/planner-identity-values-CJPha2Sz.mjs.map +1 -1
  86. package/dist/planner-identity-values.d.mts +8 -2
  87. package/dist/planner-identity-values.d.mts.map +1 -1
  88. package/dist/planner-identity-values.mjs +2 -2
  89. package/dist/planner-kql24i_F.mjs +390 -0
  90. package/dist/planner-kql24i_F.mjs.map +1 -0
  91. package/dist/{planner-produced-postgres-migration-QqHa2C2l.d.mts → planner-produced-postgres-migration-BEY1T0Xm.d.mts} +4 -4
  92. package/dist/{planner-produced-postgres-migration-QqHa2C2l.d.mts.map → planner-produced-postgres-migration-BEY1T0Xm.d.mts.map} +1 -1
  93. package/dist/{planner-produced-postgres-migration-Cji5vxUf.mjs → planner-produced-postgres-migration-D7y-PEHK.mjs} +3 -3
  94. package/dist/{planner-produced-postgres-migration-Cji5vxUf.mjs.map → planner-produced-postgres-migration-D7y-PEHK.mjs.map} +1 -1
  95. package/dist/planner-produced-postgres-migration.d.mts +1 -1
  96. package/dist/planner-produced-postgres-migration.mjs +1 -1
  97. package/dist/{planner-sql-checks-jqUUGyQR.mjs → planner-sql-checks-zqNfs2XZ.mjs} +5 -5
  98. package/dist/{planner-sql-checks-jqUUGyQR.mjs.map → planner-sql-checks-zqNfs2XZ.mjs.map} +1 -1
  99. package/dist/planner-sql-checks.d.mts +2 -2
  100. package/dist/planner-sql-checks.d.mts.map +1 -1
  101. package/dist/planner-sql-checks.mjs +1 -1
  102. package/dist/{planner-target-details-CIY6tLeo.d.mts → planner-target-details-HkP4RrRO.d.mts} +2 -2
  103. package/dist/planner-target-details-HkP4RrRO.d.mts.map +1 -0
  104. package/dist/planner-target-details.d.mts +1 -1
  105. package/dist/planner.d.mts +72 -17
  106. package/dist/planner.d.mts.map +1 -1
  107. package/dist/planner.mjs +3 -2
  108. package/dist/postgres-contract-view-C9j5cqP0.d.mts +34 -0
  109. package/dist/postgres-contract-view-C9j5cqP0.d.mts.map +1 -0
  110. package/dist/{postgres-contract-serializer-k3TAcPMY.mjs → postgres-contract-view-DM8sN1Ot.mjs} +45 -41
  111. package/dist/postgres-contract-view-DM8sN1Ot.mjs.map +1 -0
  112. package/dist/postgres-database-schema-node-CJv5bfbs.d.mts +262 -0
  113. package/dist/postgres-database-schema-node-CJv5bfbs.d.mts.map +1 -0
  114. package/dist/{postgres-migration-Y4YBJqkS.d.mts → postgres-migration-DbckK1su.d.mts} +58 -9
  115. package/dist/postgres-migration-DbckK1su.d.mts.map +1 -0
  116. package/dist/{postgres-migration-B5jKrXv3.mjs → postgres-migration-arMSWU9b.mjs} +78 -45
  117. package/dist/postgres-migration-arMSWU9b.mjs.map +1 -0
  118. package/dist/postgres-native-enum-BwVNf0Ku.mjs +45 -0
  119. package/dist/postgres-native-enum-BwVNf0Ku.mjs.map +1 -0
  120. package/dist/postgres-rls-policy--CSddvMR.d.mts +52 -0
  121. package/dist/postgres-rls-policy--CSddvMR.d.mts.map +1 -0
  122. package/dist/postgres-role-schema-node-Cm-j0ZGM.mjs +190 -0
  123. package/dist/postgres-role-schema-node-Cm-j0ZGM.mjs.map +1 -0
  124. package/dist/{postgres-schema-COGZ1ark.mjs → postgres-schema-Cm4DtiGA.mjs} +200 -11
  125. package/dist/postgres-schema-Cm4DtiGA.mjs.map +1 -0
  126. package/dist/postgres-schema-DKq6s1P3.d.mts +269 -0
  127. package/dist/postgres-schema-DKq6s1P3.d.mts.map +1 -0
  128. package/dist/postgres-table-schema-node-D6LvInCe.mjs +216 -0
  129. package/dist/postgres-table-schema-node-D6LvInCe.mjs.map +1 -0
  130. package/dist/render-ops.d.mts +1 -1
  131. package/dist/{render-typescript-KMgosran.mjs → render-typescript-7yqILcwr.mjs} +45 -16
  132. package/dist/render-typescript-7yqILcwr.mjs.map +1 -0
  133. package/dist/render-typescript.mjs +1 -1
  134. package/dist/resolve-ddl-schema-XyBaaenM.mjs +22 -0
  135. package/dist/resolve-ddl-schema-XyBaaenM.mjs.map +1 -0
  136. package/dist/rls-canonicalize.d.mts +27 -0
  137. package/dist/rls-canonicalize.d.mts.map +1 -0
  138. package/dist/rls-canonicalize.mjs +2 -0
  139. package/dist/runtime.d.mts +6 -8
  140. package/dist/runtime.d.mts.map +1 -1
  141. package/dist/runtime.mjs +3 -3
  142. package/dist/runtime.mjs.map +1 -1
  143. package/dist/schema-ir-annotations.d.mts +15 -0
  144. package/dist/schema-ir-annotations.d.mts.map +1 -0
  145. package/dist/schema-ir-annotations.mjs +2 -0
  146. package/dist/{sql-utils-DcfMz4MQ.mjs → sql-utils-SU4FDvIV.mjs} +12 -3
  147. package/dist/{sql-utils-DcfMz4MQ.mjs.map → sql-utils-SU4FDvIV.mjs.map} +1 -1
  148. package/dist/sql-utils.d.mts +8 -1
  149. package/dist/sql-utils.d.mts.map +1 -1
  150. package/dist/sql-utils.mjs +2 -2
  151. package/dist/types.d.mts +4 -140
  152. package/dist/types.mjs +5 -2
  153. package/dist/wire-name-DbQ9-2RC.mjs +104 -0
  154. package/dist/wire-name-DbQ9-2RC.mjs.map +1 -0
  155. package/package.json +26 -20
  156. package/src/contract-free/checks.ts +153 -0
  157. package/src/contract-free/control-bootstrap.ts +20 -3
  158. package/src/contract-free/ddl.ts +98 -1
  159. package/src/core/authoring.ts +726 -2
  160. package/src/core/codec-helpers.ts +33 -7
  161. package/src/core/codec-ids.ts +2 -0
  162. package/src/core/codec-type-map.ts +4 -0
  163. package/src/core/codecs.ts +236 -12
  164. package/src/core/ddl/nodes.ts +185 -2
  165. package/src/core/default-normalizer.ts +122 -2
  166. package/src/core/descriptor-meta.ts +12 -1
  167. package/src/core/entity-kinds.ts +41 -0
  168. package/src/core/errors.ts +14 -12
  169. package/src/core/migrations/bound-schema.ts +10 -0
  170. package/src/core/migrations/column-ddl-rendering.ts +117 -0
  171. package/src/core/migrations/contract-to-postgres-database-schema-node.ts +189 -0
  172. package/src/core/migrations/control-policy.ts +217 -65
  173. package/src/core/migrations/diff-database-schema.ts +252 -0
  174. package/src/core/migrations/issue-planner.ts +817 -656
  175. package/src/core/migrations/op-factory-call.ts +383 -23
  176. package/src/core/migrations/operations/columns.ts +24 -12
  177. package/src/core/migrations/operations/constraints.ts +1 -1
  178. package/src/core/migrations/operations/data-transform.ts +6 -0
  179. package/src/core/migrations/operations/dependencies.ts +2 -1
  180. package/src/core/migrations/operations/native-enum-types.ts +62 -0
  181. package/src/core/migrations/operations/rls.ts +187 -0
  182. package/src/core/migrations/operations/shared.ts +0 -30
  183. package/src/core/migrations/planner-ddl-builders.ts +31 -59
  184. package/src/core/migrations/planner-identity-values.ts +1 -1
  185. package/src/core/migrations/planner-recipes.ts +31 -13
  186. package/src/core/migrations/planner-sql-checks.ts +1 -1
  187. package/src/core/migrations/planner-strategies.ts +248 -216
  188. package/src/core/migrations/planner-target-details.ts +3 -1
  189. package/src/core/migrations/planner.ts +357 -67
  190. package/src/core/migrations/postgres-migration.ts +118 -86
  191. package/src/core/migrations/render-typescript.ts +42 -15
  192. package/src/core/migrations/resolve-ddl-schema.ts +26 -0
  193. package/src/core/migrations/runner.ts +11 -16
  194. package/src/core/migrations/verify-postgres-namespaces.ts +46 -31
  195. package/src/core/namespace-ids.ts +3 -0
  196. package/src/core/postgres-contract-serializer.ts +46 -71
  197. package/src/core/postgres-contract-view.ts +48 -0
  198. package/src/core/postgres-native-enum.ts +61 -0
  199. package/src/core/postgres-rls-enablement.ts +34 -0
  200. package/src/core/postgres-rls-policy.ts +64 -0
  201. package/src/core/postgres-role.ts +59 -0
  202. package/src/core/postgres-schema-verifier.ts +10 -7
  203. package/src/core/postgres-schema.ts +85 -15
  204. package/src/core/postgres-validators.ts +34 -0
  205. package/src/core/psl-infer/infer-psl-contract.ts +1290 -0
  206. package/src/core/psl-infer/postgres-default-mapping.ts +16 -0
  207. package/src/core/psl-infer/postgres-type-map.ts +129 -0
  208. package/src/core/rls/canonicalize.ts +65 -0
  209. package/src/core/rls/wire-name.ts +33 -0
  210. package/src/core/schema-ir/node-storage-coordinate.ts +26 -0
  211. package/src/core/schema-ir/postgres-database-schema-node.ts +61 -0
  212. package/src/core/schema-ir/postgres-namespace-schema-node.ts +70 -0
  213. package/src/core/schema-ir/postgres-native-enum-schema-node.ts +83 -0
  214. package/src/core/schema-ir/postgres-policy-schema-node.ts +90 -0
  215. package/src/core/schema-ir/postgres-role-schema-node.ts +65 -0
  216. package/src/core/schema-ir/postgres-table-schema-node.ts +140 -0
  217. package/src/core/schema-ir/schema-node-kinds.ts +122 -0
  218. package/src/core/sql-utils.ts +15 -2
  219. package/src/exports/codecs.ts +5 -0
  220. package/src/exports/contract-free.ts +11 -1
  221. package/src/exports/control.ts +27 -33
  222. package/src/exports/ddl.ts +8 -0
  223. package/src/exports/diff-database-schema.ts +7 -0
  224. package/src/exports/issue-planner.ts +1 -1
  225. package/src/exports/migration.ts +1 -0
  226. package/src/exports/op-factory-call.ts +4 -0
  227. package/src/exports/planner-ddl-builders.ts +0 -2
  228. package/src/exports/planner-identity-values.ts +4 -1
  229. package/src/exports/planner.ts +1 -0
  230. package/src/exports/rls-canonicalize.ts +12 -0
  231. package/src/exports/runtime.ts +1 -0
  232. package/src/exports/schema-ir-annotations.ts +1 -0
  233. package/src/exports/sql-utils.ts +1 -0
  234. package/src/exports/types.ts +37 -0
  235. package/dist/codec-ids-BvytN2P8.mjs.map +0 -1
  236. package/dist/codec-ids-CnXu9Qy3.d.mts.map +0 -1
  237. package/dist/codec-types-DHCkwPKE.d.mts.map +0 -1
  238. package/dist/codecs--0A5_4Bq.d.mts.map +0 -1
  239. package/dist/ddl-QDyOSeLc.mjs.map +0 -1
  240. package/dist/default-normalizer-DyyCHQWs.mjs +0 -131
  241. package/dist/default-normalizer-DyyCHQWs.mjs.map +0 -1
  242. package/dist/descriptor-meta-CpGygXpI.mjs +0 -140
  243. package/dist/descriptor-meta-CpGygXpI.mjs.map +0 -1
  244. package/dist/errors-CUk87ByX.mjs +0 -33
  245. package/dist/errors-CUk87ByX.mjs.map +0 -1
  246. package/dist/issue-planner-DL6g3CmE.mjs +0 -824
  247. package/dist/issue-planner-DL6g3CmE.mjs.map +0 -1
  248. package/dist/native-type-normalizer-Bc9XJzWC.mjs +0 -38
  249. package/dist/native-type-normalizer-Bc9XJzWC.mjs.map +0 -1
  250. package/dist/nodes-Bbhs2rwj.mjs +0 -76
  251. package/dist/nodes-Bbhs2rwj.mjs.map +0 -1
  252. package/dist/nodes-pLeLgdis.d.mts +0 -67
  253. package/dist/nodes-pLeLgdis.d.mts.map +0 -1
  254. package/dist/op-factory-call-D_p5vxwt.mjs.map +0 -1
  255. package/dist/op-factory-call-DmQEc3XV.d.mts.map +0 -1
  256. package/dist/planner-Bs_baQax.mjs +0 -324
  257. package/dist/planner-Bs_baQax.mjs.map +0 -1
  258. package/dist/planner-ddl-builders-B2wOwLqI.mjs.map +0 -1
  259. package/dist/planner-target-details-CIY6tLeo.d.mts.map +0 -1
  260. package/dist/postgres-contract-serializer-k3TAcPMY.mjs.map +0 -1
  261. package/dist/postgres-migration-B5jKrXv3.mjs.map +0 -1
  262. package/dist/postgres-migration-Y4YBJqkS.d.mts.map +0 -1
  263. package/dist/postgres-schema-COGZ1ark.mjs.map +0 -1
  264. package/dist/render-typescript-KMgosran.mjs.map +0 -1
  265. package/dist/types.d.mts.map +0 -1
  266. package/src/core/postgres-enum-type-schema.ts +0 -17
@@ -1,9 +1,13 @@
1
1
  import type { Contract } from '@prisma-next/contract/types';
2
- import type { SchemaIssue } from '@prisma-next/framework-components/control';
2
+ import type { SchemaDiffIssue } from '@prisma-next/framework-components/control';
3
3
  import { UNBOUND_NAMESPACE_ID } from '@prisma-next/framework-components/ir';
4
4
  import type { SqlStorage } from '@prisma-next/sql-contract/types';
5
- import type { SqlSchemaIR } from '@prisma-next/sql-schema-ir/types';
5
+ import type { SqlSchemaIRNode } from '@prisma-next/sql-schema-ir/types';
6
+ import { DEFAULT_NAMESPACE_ID } from '../namespace-ids';
6
7
  import { isPostgresSchema } from '../postgres-schema';
8
+ import { PostgresDatabaseSchemaNode } from '../schema-ir/postgres-database-schema-node';
9
+ import { PostgresNamespaceSchemaNode } from '../schema-ir/postgres-namespace-schema-node';
10
+ import type { SqlSchemaDiffNode } from '../schema-ir/schema-node-kinds';
7
11
 
8
12
  /**
9
13
  * Resolves the live-database schema name for a given namespace
@@ -23,32 +27,36 @@ function resolveDdlSchemaName(storage: SqlStorage, namespaceId: string): string
23
27
  }
24
28
 
25
29
  /**
26
- * Reads the introspected list of schema names from the Postgres-flavoured
27
- * annotations slot on the schema IR. Defaults to the always-present
28
- * `public` schema when introspection did not populate the slot a fresh
29
- * Postgres database always carries `public` (unless an operator dropped
30
- * it manually), so any verifier path that runs without an enriched
31
- * introspection still suppresses the redundant `CREATE SCHEMA "public"`.
30
+ * Reads the introspected list of schema names from the database-root schema
31
+ * node. `existingSchemas` is database-level, so it lives on the
32
+ * `PostgresDatabaseSchemaNode` root not on the per-schema namespace nodes.
33
+ *
34
+ * Defaults to the always-present `public` schema when the node is not the
35
+ * database root a fresh Postgres database always carries `public` (unless an
36
+ * operator dropped it manually), so any verifier path that runs without an
37
+ * enriched introspection still suppresses the redundant `CREATE SCHEMA
38
+ * "public"`.
32
39
  *
33
40
  * Production introspection (`PostgresControlAdapter.introspect`) is the
34
- * authoritative source: it queries `pg_namespace` and writes every
35
- * non-system schema into `annotations.pg.existingSchemas`. Tests that
36
- * want to assert against a richer initial state pass the slot
37
- * explicitly via the schema IR.
41
+ * authoritative source: it queries `pg_namespace` and sets `existingSchemas`
42
+ * on the returned root. Tests that want to assert against a richer initial
43
+ * state construct a `PostgresDatabaseSchemaNode` explicitly.
38
44
  */
39
- function existingSchemasFromSchema(schema: SqlSchemaIR): readonly string[] {
40
- const annotations = (schema as { annotations?: { pg?: { existingSchemas?: unknown } } })
41
- .annotations;
42
- const slot = annotations?.pg?.existingSchemas;
43
- if (Array.isArray(slot)) {
44
- return slot.filter((s): s is string => typeof s === 'string');
45
+ function existingSchemasFromSchema(schema: SqlSchemaIRNode): readonly string[] {
46
+ if (PostgresDatabaseSchemaNode.is(schema)) {
47
+ return schema.existingSchemas;
45
48
  }
46
- return ['public'];
49
+ return [DEFAULT_NAMESPACE_ID];
47
50
  }
48
51
 
49
52
  /**
50
- * Emits a `missing_schema` issue for every contract-declared Postgres
51
- * namespace whose live container does not yet exist.
53
+ * Emits a `postgres-namespace` `not-found` diff issue for every
54
+ * contract-declared Postgres namespace whose live container does not yet
55
+ * exist. The planner prepends these (node-typed, synthesized) to the
56
+ * relational diff issues so a multi-schema plan emits `CREATE SCHEMA`
57
+ * before the tables that need it — a planner-only concern (verify already
58
+ * rejects via the `not-found` table issues a missing schema already
59
+ * produces), so this is not part of the shared diff.
52
60
  *
53
61
  * A namespace's live container is the schema returned by its
54
62
  * polymorphic `ddlSchemaName(storage)` method — named schemas resolve
@@ -59,28 +67,35 @@ function existingSchemasFromSchema(schema: SqlSchemaIR): readonly string[] {
59
67
  * introspected list. `public` is suppressed implicitly because the
60
68
  * introspection (or its sensible default) always carries it.
61
69
  *
62
- * Each emitted issue stamps `namespaceId` with the contract namespace
63
- * coordinate so the downstream `mapIssueToCall` re-resolves the DDL
64
- * schema name through the same polymorphic path keeping the
65
- * coordinate, not the resolved name, as the issue's stable identity.
70
+ * Each emitted issue's path is `['database', ddlName]` an ancestor of
71
+ * every table path under that schema, so it must never be run through
72
+ * `coalesceSubtreeIssues` alongside the table diff (it would swallow the
73
+ * table-level `not-found` issues that drive `CREATE TABLE`); the planner
74
+ * adds these AFTER coalescing the relational issues, and they are not
75
+ * subject to sibling-space ownership scoping (mirrors the retired
76
+ * coordinate walk, which prepended namespace issues after that filter).
66
77
  */
67
78
  export function verifyPostgresNamespacePresence(input: {
68
79
  readonly contract: Contract<SqlStorage>;
69
- readonly schema: SqlSchemaIR;
70
- }): readonly SchemaIssue[] {
80
+ readonly schema: SqlSchemaIRNode;
81
+ }): readonly SchemaDiffIssue<SqlSchemaDiffNode>[] {
71
82
  const { contract, schema } = input;
72
83
  const existing = new Set(existingSchemasFromSchema(schema));
73
- const issues: SchemaIssue[] = [];
84
+ const issues: SchemaDiffIssue<SqlSchemaDiffNode>[] = [];
74
85
  const namespaceIds = Object.keys(contract.storage.namespaces).sort();
75
86
  for (const namespaceId of namespaceIds) {
76
87
  if (namespaceId === UNBOUND_NAMESPACE_ID) continue;
77
88
  const ddlName = resolveDdlSchemaName(contract.storage, namespaceId);
78
89
  if (ddlName === UNBOUND_NAMESPACE_ID) continue;
79
90
  if (existing.has(ddlName)) continue;
91
+ const namespace = new PostgresNamespaceSchemaNode({
92
+ schemaName: ddlName,
93
+ tables: {},
94
+ });
80
95
  issues.push({
81
- kind: 'missing_schema',
82
- namespaceId,
83
- message: `Schema "${ddlName}" is missing from database`,
96
+ path: ['database', ddlName],
97
+ reason: 'not-found',
98
+ expected: namespace,
84
99
  });
85
100
  }
86
101
  return issues;
@@ -0,0 +1,3 @@
1
+ // Leaf module: authoring.ts and descriptor-meta.ts both need this and import each other.
2
+ /** Postgres's default schema; `postgresTargetDescriptorMeta.defaultNamespaceId` is this value. */
3
+ export const DEFAULT_NAMESPACE_ID = 'public' as const;
@@ -10,20 +10,27 @@ import {
10
10
  isAuthoringEntityTypeDescriptor,
11
11
  } from '@prisma-next/framework-components/authoring';
12
12
  import {
13
+ type AnyEntityKindDescriptor,
13
14
  type Namespace,
14
- NamespaceBase,
15
15
  UNBOUND_NAMESPACE_ID,
16
16
  } from '@prisma-next/framework-components/ir';
17
- import type { SqlNamespaceTablesInput, SqlStorage } from '@prisma-next/sql-contract/types';
17
+ import type { SqlNamespaceInput, SqlStorage } from '@prisma-next/sql-contract/types';
18
18
  import { blindCast } from '@prisma-next/utils/casts';
19
19
  import type { JsonObject } from '@prisma-next/utils/json';
20
20
  import { postgresAuthoringEntityTypes } from './authoring';
21
- import { postgresTargetDescriptorMeta } from './descriptor-meta';
22
- import { isPostgresSchema, PostgresSchema } from './postgres-schema';
21
+ import { PG_INT_CODEC_ID, PG_TEXT_CODEC_ID } from './codec-ids';
22
+ import {
23
+ nativeEnumEntityKind,
24
+ policyEntityKind,
25
+ rlsEnablementEntityKind,
26
+ roleEntityKind,
27
+ } from './entity-kinds';
28
+ import { PostgresSchema } from './postgres-schema';
23
29
 
24
30
  const POSTGRES_AUTHORING_CTX: AuthoringEntityContext = {
25
31
  family: 'sql',
26
32
  target: 'postgres',
33
+ enumInferenceCodecs: { text: PG_TEXT_CODEC_ID, int: PG_INT_CODEC_ID },
27
34
  };
28
35
 
29
36
  function isAuthoringEntityTypeFactoryOutput(
@@ -32,7 +39,8 @@ function isAuthoringEntityTypeFactoryOutput(
32
39
  return (
33
40
  typeof output === 'object' &&
34
41
  output !== null &&
35
- typeof (output as AuthoringEntityTypeFactoryOutput).factory === 'function'
42
+ 'factory' in output &&
43
+ typeof output.factory === 'function'
36
44
  );
37
45
  }
38
46
 
@@ -65,34 +73,35 @@ function collectStorageTypesHydrators(
65
73
  }
66
74
 
67
75
  export class PostgresContractSerializer extends SqlContractSerializerBase<Contract<SqlStorage>> {
68
- constructor() {
76
+ constructor(extraPackEntityKinds: readonly AnyEntityKindDescriptor[] = []) {
69
77
  const storageTypesHydrators = collectStorageTypesHydrators(postgresAuthoringEntityTypes);
70
- super(storageTypesHydrators);
71
- }
72
-
73
- protected override get defaultNamespaceId(): string {
74
- return postgresTargetDescriptorMeta.defaultNamespaceId;
78
+ super(storageTypesHydrators, [
79
+ policyEntityKind,
80
+ roleEntityKind,
81
+ rlsEnablementEntityKind,
82
+ nativeEnumEntityKind,
83
+ ...extraPackEntityKinds,
84
+ ]);
75
85
  }
76
86
 
77
87
  protected override hydrateSqlNamespaceEntry(
78
88
  nsId: string,
79
- raw: Namespace | Record<string, unknown>,
80
- ): Namespace | SqlNamespaceTablesInput {
81
- if (raw instanceof NamespaceBase) {
82
- return raw;
83
- }
89
+ raw: Record<string, unknown>,
90
+ ): Namespace | SqlNamespaceInput {
84
91
  const hydrated = blindCast<
85
- SqlNamespaceTablesInput,
86
- 'super.hydrateSqlNamespaceEntry returns SqlNamespaceTablesInput when raw is not a NamespaceBase'
92
+ SqlNamespaceInput,
93
+ 'raw is always plain JSON, so super.hydrateSqlNamespaceEntry returns SqlNamespaceInput'
87
94
  >(super.hydrateSqlNamespaceEntry(nsId, raw));
88
95
  const { id, entries } = hydrated;
89
96
 
90
- const valueSetSlot = entries['valueSet'];
91
- const hasValueSets = valueSetSlot !== undefined && Object.keys(valueSetSlot).length > 0;
92
- const emptyTables = Object.keys(entries['table'] ?? {}).length === 0;
93
- if (id === UNBOUND_NAMESPACE_ID && emptyTables && !hasValueSets) {
97
+ const allSlotsEmpty = Object.values(entries).every(
98
+ (slot) => slot === undefined || Object.keys(slot).length === 0,
99
+ );
100
+ if (id === UNBOUND_NAMESPACE_ID && allSlotsEmpty) {
94
101
  return PostgresSchema.unbound;
95
102
  }
103
+ const valueSetSlot = entries['valueSet'];
104
+ const hasValueSets = valueSetSlot !== undefined && Object.keys(valueSetSlot).length > 0;
96
105
  return new PostgresSchema({
97
106
  id,
98
107
  entries: {
@@ -106,24 +115,16 @@ export class PostgresContractSerializer extends SqlContractSerializerBase<Contra
106
115
  override serializeContract(contract: Contract<SqlStorage>): JsonObject {
107
116
  const { storage, ...rest } = contract;
108
117
  const namespacesJson: Record<string, JsonObject> = {};
118
+ // Each namespace serializes to its id, its schema-kind tag, and the
119
+ // base's generic entries walk — every enumerable kind on
120
+ // `PostgresSchema.entries`, including `native_enum`.
109
121
  for (const [nsId, ns] of Object.entries(storage.namespaces)) {
110
- if (isPostgresSchema(ns)) {
111
- namespacesJson[nsId] = this.serializePostgresNamespace(ns, ns.id === UNBOUND_NAMESPACE_ID);
112
- } else {
113
- const isUnboundSlot = nsId === UNBOUND_NAMESPACE_ID;
114
- namespacesJson[nsId] = {
115
- id: nsId,
116
- kind: isUnboundSlot ? 'postgres-unbound-schema' : 'postgres-schema',
117
- entries: {
118
- table: Object.fromEntries(
119
- Object.entries(ns.entries.table ?? {}).map(([tableName, table]) => [
120
- tableName,
121
- this.serializeJsonValue(table) as JsonObject,
122
- ]),
123
- ),
124
- },
125
- };
126
- }
122
+ const isUnboundSlot = ns.id === UNBOUND_NAMESPACE_ID;
123
+ namespacesJson[nsId] = {
124
+ id: ns.id,
125
+ kind: isUnboundSlot ? 'postgres-unbound-schema' : 'postgres-schema',
126
+ entries: this.serializeNamespaceEntries(ns.entries),
127
+ };
127
128
  }
128
129
  const storageOut: Record<string, unknown> = {
129
130
  storageHash: String(storage.storageHash),
@@ -132,42 +133,16 @@ export class PostgresContractSerializer extends SqlContractSerializerBase<Contra
132
133
  if (storage.types !== undefined) {
133
134
  const typesOut: Record<string, JsonObject> = {};
134
135
  for (const [name, entry] of Object.entries(storage.types)) {
135
- typesOut[name] = this.serializeJsonValue(entry) as JsonObject;
136
+ typesOut[name] = this.serializeJsonObject(entry);
136
137
  }
137
138
  storageOut['types'] = typesOut;
138
139
  }
139
- return {
140
+ return blindCast<
141
+ JsonObject,
142
+ 'contract minus storage plus a JSON-shaped storageOut is a JsonObject'
143
+ >({
140
144
  ...rest,
141
145
  storage: storageOut,
142
- } as unknown as JsonObject;
143
- }
144
-
145
- private serializePostgresNamespace(ns: PostgresSchema, isUnboundSlot: boolean): JsonObject {
146
- const tablesOut: Record<string, JsonObject> = {};
147
- for (const [tableName, table] of Object.entries(ns.table)) {
148
- tablesOut[tableName] = this.serializeJsonValue(table) as JsonObject;
149
- }
150
- const valueSetEntries = ns.valueSet;
151
- const valueSetOut: Record<string, JsonObject> = {};
152
- if (valueSetEntries !== undefined) {
153
- for (const [valueSetName, valueSet] of Object.entries(valueSetEntries)) {
154
- valueSetOut[valueSetName] = blindCast<
155
- JsonObject,
156
- 'serializeJsonValue round-trips the value-set node through JSON, yielding a JsonObject'
157
- >(this.serializeJsonValue(valueSet));
158
- }
159
- }
160
- return {
161
- id: ns.id,
162
- kind: isUnboundSlot ? 'postgres-unbound-schema' : 'postgres-schema',
163
- entries: {
164
- table: tablesOut,
165
- ...(Object.keys(valueSetOut).length > 0 ? { valueSet: valueSetOut } : {}),
166
- },
167
- };
168
- }
169
-
170
- private serializeJsonValue(value: unknown): unknown {
171
- return JSON.parse(JSON.stringify(value)) as unknown;
146
+ });
172
147
  }
173
148
  }
@@ -0,0 +1,48 @@
1
+ import type { Contract } from '@prisma-next/contract/types';
2
+ import {
3
+ buildSqlSchemaQualifiedView,
4
+ type SqlSchemaQualifiedView,
5
+ } from '@prisma-next/sql-contract/contract-view';
6
+ import type { SqlStorage } from '@prisma-next/sql-contract/types';
7
+ import { PostgresContractSerializer } from './postgres-contract-serializer';
8
+
9
+ /**
10
+ * A schema-qualified Postgres contract view: the deserialized contract
11
+ * intersected with a single `namespace` member holding every schema by id. It is
12
+ * substitutable for `Contract` (carries `storage`, `domain`, …) and reaches each
13
+ * schema's entities through `view.namespace.<schema>`:
14
+ *
15
+ * ```ts
16
+ * const view = PostgresContractView.fromJson<Contract>(contractJson);
17
+ * view.namespace.public.table.users // typed table leaf in the public schema
18
+ * view.namespace.auth.table.users // the auth schema's own users table
19
+ * view.namespace.public.entries.policy.X // pack-contributed kind (RLS / #771 path)
20
+ * view.namespace.__unbound__.table.X // default schema, keyed by its raw id
21
+ * view.storage // the full contract is still present
22
+ * ```
23
+ *
24
+ * This mirrors the runtime `db.enums.<ns>` keying exactly (the default schema
25
+ * keeps its literal `__unbound__` id). Schema names are NOT promoted to the
26
+ * contract root, so there is no collision with contract envelope fields — a
27
+ * schema named `storage` is `view.namespace.storage`, while `view.storage`
28
+ * stays the contract's `storage`.
29
+ */
30
+ export type PostgresContractView<TContract extends Contract<SqlStorage> = Contract<SqlStorage>> =
31
+ SqlSchemaQualifiedView<TContract>;
32
+
33
+ export const PostgresContractView = {
34
+ /** Wrap an already-deserialized Postgres contract in a schema-qualified view. */
35
+ from<TContract extends Contract<SqlStorage>>(
36
+ contract: TContract,
37
+ ): PostgresContractView<TContract> {
38
+ return buildSqlSchemaQualifiedView(contract);
39
+ },
40
+
41
+ /** Deserialize a Postgres contract JSON envelope and wrap it in a view. */
42
+ fromJson<TContract extends Contract<SqlStorage> = Contract<SqlStorage>>(
43
+ json: unknown,
44
+ ): PostgresContractView<TContract> {
45
+ const contract = new PostgresContractSerializer().deserializeContract<TContract>(json);
46
+ return buildSqlSchemaQualifiedView(contract);
47
+ },
48
+ };
@@ -0,0 +1,61 @@
1
+ import type { ControlPolicy } from '@prisma-next/contract/types';
2
+ import { freezeNode } from '@prisma-next/framework-components/ir';
3
+ import { SqlNode } from '@prisma-next/sql-contract/types';
4
+ import { blindCast } from '@prisma-next/utils/casts';
5
+
6
+ export interface PostgresNativeEnumInput<Members extends readonly string[] = readonly string[]> {
7
+ /** The Postgres type name (`CREATE TYPE <typeName> AS ENUM (…)`). */
8
+ readonly typeName: string;
9
+ /** Member values in declaration order — this is the Postgres enum sort order. */
10
+ readonly members: Members;
11
+ readonly control?: ControlPolicy;
12
+ }
13
+
14
+ function freezeMembers<Members extends readonly string[]>(members: Members): Members {
15
+ return blindCast<
16
+ Members,
17
+ 'Object.freeze clones+freezes the tuple for immutability; the clone widens to readonly string[], but it holds exactly the values of members (already typed Members)'
18
+ >(Object.freeze([...members]));
19
+ }
20
+
21
+ /**
22
+ * Postgres contract-IR class for a native enum type (`CREATE TYPE … AS ENUM (…)`).
23
+ *
24
+ * This is an authored, serialized Contract-IR entity — it is registered as an entity
25
+ * kind, extends `SqlNode`, and is stored in `contract.json`. It is NOT a DiffableNode;
26
+ * the schema-diff tree will use `PostgresNativeEnumSchemaNode` when the managed phase
27
+ * builds it.
28
+ *
29
+ * A member is a value, not a name→value pair — matching `CREATE TYPE … AS ENUM
30
+ * ('a', 'b')`, which has no separate member name.
31
+ *
32
+ * Target-only concept — no SQL-family abstract. Extends `SqlNode` directly,
33
+ * frozen at construction via `freezeNode(this)`. The `kind: 'postgres-enum'`
34
+ * discriminant is enumerable so it survives JSON. Lives at
35
+ * `storage.namespaces[ns].entries.native_enum[HandleName]`; the entries key
36
+ * (`native_enum`) is the entity-kind descriptor's `kind`, decoupled from this
37
+ * node's own `kind` literal — the same shape as `table`/`StorageTable` and
38
+ * `valueSet`/`StorageValueSet`.
39
+ */
40
+ export class PostgresNativeEnum<
41
+ Members extends readonly string[] = readonly string[],
42
+ > extends SqlNode {
43
+ static is(node: unknown): node is PostgresNativeEnum {
44
+ return (
45
+ typeof node === 'object' && node !== null && 'kind' in node && node.kind === 'postgres-enum'
46
+ );
47
+ }
48
+
49
+ override readonly kind = 'postgres-enum' as const;
50
+ readonly typeName: string;
51
+ readonly members: Members;
52
+ declare readonly control?: ControlPolicy;
53
+
54
+ constructor(input: PostgresNativeEnumInput<Members>) {
55
+ super();
56
+ this.typeName = input.typeName;
57
+ this.members = freezeMembers(input.members);
58
+ if (input.control !== undefined) this.control = input.control;
59
+ freezeNode(this);
60
+ }
61
+ }
@@ -0,0 +1,34 @@
1
+ import { freezeNode } from '@prisma-next/framework-components/ir';
2
+ import { SqlNode } from '@prisma-next/sql-contract/types';
3
+
4
+ export interface PostgresRlsEnablementInput {
5
+ /** Name of the table this marker declares RLS-controlled. */
6
+ readonly tableName: string;
7
+ /** Namespace coordinate (schema name). Markers are schema-scoped like policies. */
8
+ readonly namespaceId: string;
9
+ }
10
+
11
+ /**
12
+ * Postgres contract-IR marker for `@@rls` on a model: the table named here is
13
+ * RLS-controlled (`ENABLE ROW LEVEL SECURITY` is driven by this marker, never
14
+ * by the policy set).
15
+ *
16
+ * This is an authored, serialized Contract-IR entity — it is registered as an
17
+ * entity kind, extends `SqlNode`, and is stored in `contract.json` under
18
+ * `entries.rls[tableName]`. Target-only concept — no SQL-family abstract.
19
+ * Frozen at construction via `freezeNode(this)`. The `kind: 'rls'`
20
+ * discriminant is enumerable so it survives JSON serialization; the literal
21
+ * matches the entries key (one-string rule).
22
+ */
23
+ export class PostgresRlsEnablement extends SqlNode {
24
+ override readonly kind = 'rls' as const;
25
+ readonly tableName: string;
26
+ readonly namespaceId: string;
27
+
28
+ constructor(input: PostgresRlsEnablementInput) {
29
+ super();
30
+ this.tableName = input.tableName;
31
+ this.namespaceId = input.namespaceId;
32
+ freezeNode(this);
33
+ }
34
+ }
@@ -0,0 +1,64 @@
1
+ import { freezeNode } from '@prisma-next/framework-components/ir';
2
+ import { SqlNode } from '@prisma-next/sql-contract/types';
3
+
4
+ export type RlsPolicyOperation = 'select' | 'insert' | 'update' | 'delete' | 'all';
5
+
6
+ export interface PostgresRlsPolicyInput {
7
+ /** Full wire name: `<prefix>_<8hex>`. Stored as-is; hashing is not this class's job. */
8
+ readonly name: string;
9
+ /** User-supplied prefix (the part before the `_<8hex>` suffix). */
10
+ readonly prefix: string;
11
+ /** Name of the table this policy attaches to, by name within the same schema. */
12
+ readonly tableName: string;
13
+ /** Namespace coordinate (schema name). Policies are schema-scoped. */
14
+ readonly namespaceId: string;
15
+ readonly operation: RlsPolicyOperation;
16
+ /** Sorted role names rendered in `TO <roles>`. Plain strings in this slice. */
17
+ readonly roles: readonly string[];
18
+ /** USING predicate SQL string, if present. */
19
+ readonly using?: string;
20
+ /** WITH CHECK predicate SQL string, if present. */
21
+ readonly withCheck?: string;
22
+ /** `true` = `AS PERMISSIVE`, `false` = `AS RESTRICTIVE`. */
23
+ readonly permissive: boolean;
24
+ }
25
+
26
+ /**
27
+ * Postgres contract-IR class for a row-level security policy (`CREATE POLICY … ON …`).
28
+ *
29
+ * This is an authored, serialized Contract-IR entity — it is registered as an entity
30
+ * kind, extends `SqlNode`, and is stored in `contract.json`. It is NOT a DiffableNode;
31
+ * the schema-diff tree uses `PostgresPolicySchemaNode` for that role.
32
+ *
33
+ * Target-only concept — no SQL-family abstract. Extends `SqlNode` directly.
34
+ * Frozen at construction via `freezeNode(this)`. The `kind: 'policy'`
35
+ * discriminant is enumerable (overrides SqlNode's non-enumerable `'sql'`) so it
36
+ * survives JSON serialization and enables dispatch. The literal matches the
37
+ * entries key (one-string rule: node.kind === entries key === entity kind).
38
+ */
39
+ export class PostgresRlsPolicy extends SqlNode {
40
+ override readonly kind = 'policy' as const;
41
+ readonly name: string;
42
+ readonly prefix: string;
43
+ readonly tableName: string;
44
+ readonly namespaceId: string;
45
+ readonly operation: RlsPolicyOperation;
46
+ readonly roles: readonly string[];
47
+ declare readonly using?: string;
48
+ declare readonly withCheck?: string;
49
+ readonly permissive: boolean;
50
+
51
+ constructor(input: PostgresRlsPolicyInput) {
52
+ super();
53
+ this.name = input.name;
54
+ this.prefix = input.prefix;
55
+ this.tableName = input.tableName;
56
+ this.namespaceId = input.namespaceId;
57
+ this.operation = input.operation;
58
+ this.roles = Object.freeze([...input.roles]);
59
+ if (input.using !== undefined) this.using = input.using;
60
+ if (input.withCheck !== undefined) this.withCheck = input.withCheck;
61
+ this.permissive = input.permissive;
62
+ freezeNode(this);
63
+ }
64
+ }
@@ -0,0 +1,59 @@
1
+ import { freezeNode } from '@prisma-next/framework-components/ir';
2
+ import { SqlNode } from '@prisma-next/sql-contract/types';
3
+
4
+ /**
5
+ * Roles are referenced by the contract but never owned — the framework
6
+ * issues no `CREATE`/`DROP ROLE`, so a role's effective governance is always
7
+ * `external`: a missing declared role fails verify, an extra live role is
8
+ * tolerated, and the planner emits zero role DDL. `external` is the only
9
+ * value a role's control can ever carry.
10
+ */
11
+ export const ROLE_DEFAULT_CONTROL_POLICY = 'external';
12
+
13
+ export interface PostgresRoleInput {
14
+ readonly name: string;
15
+ /**
16
+ * Namespace coordinate. Roles are cluster-scoped; pass `UNBOUND_NAMESPACE_ID`
17
+ * from `@prisma-next/framework-components/ir`.
18
+ */
19
+ readonly namespaceId: string;
20
+ /**
21
+ * Defaults to {@link ROLE_DEFAULT_CONTROL_POLICY} when omitted. Roles are
22
+ * referenced but never owned, so `'external'` is the only allowed value.
23
+ */
24
+ readonly control?: 'external';
25
+ }
26
+
27
+ /**
28
+ * Postgres contract-IR class for a database role (`CREATE ROLE …`).
29
+ *
30
+ * This is an authored, serialized Contract-IR entity — it is registered as an entity
31
+ * kind, extends `SqlNode`, and is stored in `contract.json`. It is NOT a DiffableNode;
32
+ * the schema-diff tree uses `PostgresRoleSchemaNode` for that role.
33
+ *
34
+ * Roles are cluster-scoped, so their namespace coordinate is always
35
+ * `UNBOUND_NAMESPACE_ID`. Target-only concept — no SQL-family abstract.
36
+ * Extends `SqlNode` directly, frozen at construction via `freezeNode(this)`.
37
+ * The `kind: 'role'` discriminant is enumerable so it survives JSON.
38
+ * Matches the entries key (one-string rule).
39
+ *
40
+ * `control` always carries a value (never omitted): it defaults to
41
+ * {@link ROLE_DEFAULT_CONTROL_POLICY} in the constructor, so both a
42
+ * freshly-authored role and one hydrated from an older `contract.json`
43
+ * lacking the field resolve the same way — the control-policy resolver
44
+ * reads it directly off the entity instead of special-casing role issues.
45
+ */
46
+ export class PostgresRole extends SqlNode {
47
+ override readonly kind = 'role' as const;
48
+ readonly name: string;
49
+ readonly namespaceId: string;
50
+ readonly control: 'external';
51
+
52
+ constructor(input: PostgresRoleInput) {
53
+ super();
54
+ this.name = input.name;
55
+ this.namespaceId = input.namespaceId;
56
+ this.control = input.control ?? ROLE_DEFAULT_CONTROL_POLICY;
57
+ freezeNode(this);
58
+ }
59
+ }
@@ -1,16 +1,19 @@
1
1
  import type { Contract } from '@prisma-next/contract/types';
2
2
  import { SqlSchemaVerifierBase } from '@prisma-next/family-sql/ir';
3
- import type { SchemaIssue, SchemaVerifyOptions } from '@prisma-next/framework-components/control';
3
+ import type {
4
+ SchemaDiffIssue,
5
+ SchemaVerifyOptions,
6
+ } from '@prisma-next/framework-components/control';
4
7
  import type { SqlStorage } from '@prisma-next/sql-contract/types';
5
8
  import type { SqlSchemaIR } from '@prisma-next/sql-schema-ir/types';
6
9
 
7
10
  /**
8
11
  * Postgres target `SchemaVerifier` concretion. Plugs into the
9
12
  * SQL-shared verification surface; production verification today still
10
- * routes through the legacy `verifySqlSchema` entry point, which
11
- * carries options (codec hooks, normalizers, framework components)
12
- * that the framework-level `SchemaVerifyOptions` shape does not yet
13
- * surface.
13
+ * routes through the family verify verdict (`verifySqlSchemaByDiff` over
14
+ * `diffPostgresSchema`), which carries options (codec hooks,
15
+ * normalizers, framework components) that the framework-level
16
+ * `SchemaVerifyOptions` shape does not yet surface.
14
17
  *
15
18
  * The hooks return the empty list pending the call-site migration that
16
19
  * routes the existing verifier behaviour through the SPI — at that
@@ -25,13 +28,13 @@ export class PostgresSchemaVerifier extends SqlSchemaVerifierBase<
25
28
  > {
26
29
  protected verifyCommonSqlSchema(
27
30
  _options: SchemaVerifyOptions<Contract<SqlStorage>, SqlSchemaIR>,
28
- ): readonly SchemaIssue[] {
31
+ ): readonly SchemaDiffIssue[] {
29
32
  return [];
30
33
  }
31
34
 
32
35
  protected verifyTargetExtensions(
33
36
  _options: SchemaVerifyOptions<Contract<SqlStorage>, SqlSchemaIR>,
34
- ): readonly SchemaIssue[] {
37
+ ): readonly SchemaDiffIssue[] {
35
38
  return [];
36
39
  }
37
40
  }