@prisma-next/target-postgres 0.14.0-dev.8 → 0.14.0-dev.80

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-Bi9aa8zG.mjs +574 -0
  2. package/dist/authoring-Bi9aa8zG.mjs.map +1 -0
  3. package/dist/canonicalize-CAbXtVtB.d.mts +37 -0
  4. package/dist/canonicalize-CAbXtVtB.d.mts.map +1 -0
  5. package/dist/{codec-ids-CnXu9Qy3.d.mts → codec-ids-BzrFF-I4.d.mts} +3 -2
  6. package/dist/codec-ids-BzrFF-I4.d.mts.map +1 -0
  7. package/dist/{codec-ids-BvytN2P8.mjs → codec-ids-C_-Hj6bL.mjs} +3 -2
  8. package/dist/codec-ids-C_-Hj6bL.mjs.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-BiIWziRO.d.mts} +3 -2
  12. package/dist/codec-types-BiIWziRO.d.mts.map +1 -0
  13. package/dist/codec-types.d.mts +1 -1
  14. package/dist/codecs-BemGS69L.mjs +927 -0
  15. package/dist/codecs-BemGS69L.mjs.map +1 -0
  16. package/dist/{codecs--0A5_4Bq.d.mts → codecs-Cm-nS4mQ.d.mts} +111 -4
  17. package/dist/codecs-Cm-nS4mQ.d.mts.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-5LE2kwfb.mjs +1285 -0
  26. package/dist/control-policy-5LE2kwfb.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 +866 -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-BQzITB_e.mjs} +128 -6
  36. package/dist/ddl-BQzITB_e.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-DzL6vXAz.mjs +22 -0
  44. package/dist/descriptor-meta-DzL6vXAz.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-DULhiCNM.mjs +305 -0
  48. package/dist/diff-database-schema-DULhiCNM.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-Bc2N3tMy.d.mts +170 -0
  68. package/dist/nodes-Bc2N3tMy.d.mts.map +1 -0
  69. package/dist/nodes-DJC5B8Id.mjs +192 -0
  70. package/dist/nodes-DJC5B8Id.mjs.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-D6yu-PlS.mjs} +469 -32
  74. package/dist/op-factory-call-D6yu-PlS.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 +300 -3
  78. package/dist/pack.d.mts.map +1 -1
  79. package/dist/pack.mjs +1 -1
  80. package/dist/planner-DwDxdYxi.mjs +390 -0
  81. package/dist/planner-DwDxdYxi.mjs.map +1 -0
  82. package/dist/{planner-ddl-builders-B2wOwLqI.mjs → planner-ddl-builders-BKlmGDJl.mjs} +17 -28
  83. package/dist/planner-ddl-builders-BKlmGDJl.mjs.map +1 -0
  84. package/dist/planner-ddl-builders.d.mts +4 -6
  85. package/dist/planner-ddl-builders.d.mts.map +1 -1
  86. package/dist/planner-ddl-builders.mjs +2 -2
  87. package/dist/planner-identity-values-CJPha2Sz.mjs.map +1 -1
  88. package/dist/planner-identity-values.d.mts +8 -2
  89. package/dist/planner-identity-values.d.mts.map +1 -1
  90. package/dist/planner-identity-values.mjs +2 -2
  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-BGPpq56_.mjs} +3 -3
  94. package/dist/{planner-produced-postgres-migration-Cji5vxUf.mjs.map → planner-produced-postgres-migration-BGPpq56_.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-CDXn2uaS.mjs} +5 -5
  98. package/dist/{planner-sql-checks-jqUUGyQR.mjs.map → planner-sql-checks-CDXn2uaS.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-serializer-k3TAcPMY.mjs → postgres-contract-view-C3LPCLP_.mjs} +45 -41
  109. package/dist/postgres-contract-view-C3LPCLP_.mjs.map +1 -0
  110. package/dist/postgres-contract-view-C9j5cqP0.d.mts +34 -0
  111. package/dist/postgres-contract-view-C9j5cqP0.d.mts.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-et1td40f.mjs} +78 -45
  117. package/dist/postgres-migration-et1td40f.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-DKq6s1P3.d.mts +269 -0
  125. package/dist/postgres-schema-DKq6s1P3.d.mts.map +1 -0
  126. package/dist/{postgres-schema-COGZ1ark.mjs → postgres-schema-DYATroNx.mjs} +200 -11
  127. package/dist/postgres-schema-DYATroNx.mjs.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-DpGte50u.mjs +22 -0
  135. package/dist/resolve-ddl-schema-DpGte50u.mjs.map +1 -0
  136. package/dist/rls-canonicalize.d.mts +20 -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-rHHtr1h0.mjs +75 -0
  154. package/dist/wire-name-rHHtr1h0.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 +509 -2
  160. package/src/core/codec-helpers.ts +33 -7
  161. package/src/core/codec-ids.ts +1 -0
  162. package/src/core/codec-type-map.ts +2 -0
  163. package/src/core/codecs.ts +193 -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 +10 -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 +1273 -0
  206. package/src/core/psl-infer/postgres-default-mapping.ts +16 -0
  207. package/src/core/psl-infer/postgres-type-map.ts +128 -0
  208. package/src/core/rls/canonicalize.ts +48 -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 +3 -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 +7 -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
@@ -0,0 +1,16 @@
1
+ import type { DefaultMappingOptions } from '@prisma-next/family-sql/psl-infer';
2
+
3
+ const POSTGRES_FUNCTION_ATTRIBUTES: Readonly<Record<string, string>> = {
4
+ 'gen_random_uuid()': '@default(dbgenerated("gen_random_uuid()"))',
5
+ };
6
+
7
+ function formatDbGeneratedAttribute(expression: string): string {
8
+ return `@default(dbgenerated(${JSON.stringify(expression)}))`;
9
+ }
10
+
11
+ export function createPostgresDefaultMapping(): DefaultMappingOptions {
12
+ return {
13
+ functionAttributes: POSTGRES_FUNCTION_ATTRIBUTES,
14
+ fallbackFunctionAttribute: formatDbGeneratedAttribute,
15
+ };
16
+ }
@@ -0,0 +1,128 @@
1
+ import type {
2
+ PslNativeTypeAttribute,
3
+ PslTypeMap,
4
+ PslTypeResolution,
5
+ } from '@prisma-next/family-sql/psl-infer';
6
+
7
+ const POSTGRES_TO_PSL: Record<string, string> = {
8
+ text: 'String',
9
+ bool: 'Boolean',
10
+ boolean: 'Boolean',
11
+ int4: 'Int',
12
+ integer: 'Int',
13
+ int8: 'BigInt',
14
+ bigint: 'BigInt',
15
+ float8: 'Float',
16
+ 'double precision': 'Float',
17
+ numeric: 'Decimal',
18
+ decimal: 'Decimal',
19
+ timestamptz: 'DateTime',
20
+ 'timestamp with time zone': 'DateTime',
21
+ jsonb: 'Json',
22
+ bytea: 'Bytes',
23
+ };
24
+
25
+ const PRESERVED_NATIVE_TYPES: Record<
26
+ string,
27
+ { readonly pslType: string; readonly attributeName: string }
28
+ > = {
29
+ 'character varying': { pslType: 'String', attributeName: 'db.VarChar' },
30
+ character: { pslType: 'String', attributeName: 'db.Char' },
31
+ char: { pslType: 'String', attributeName: 'db.Char' },
32
+ varchar: { pslType: 'String', attributeName: 'db.VarChar' },
33
+ uuid: { pslType: 'String', attributeName: 'db.Uuid' },
34
+ int2: { pslType: 'Int', attributeName: 'db.SmallInt' },
35
+ smallint: { pslType: 'Int', attributeName: 'db.SmallInt' },
36
+ float4: { pslType: 'Float', attributeName: 'db.Real' },
37
+ real: { pslType: 'Float', attributeName: 'db.Real' },
38
+ timestamp: { pslType: 'DateTime', attributeName: 'db.Timestamp' },
39
+ 'timestamp without time zone': { pslType: 'DateTime', attributeName: 'db.Timestamp' },
40
+ date: { pslType: 'DateTime', attributeName: 'db.Date' },
41
+ time: { pslType: 'DateTime', attributeName: 'db.Time' },
42
+ 'time without time zone': { pslType: 'DateTime', attributeName: 'db.Time' },
43
+ timetz: { pslType: 'DateTime', attributeName: 'db.Timetz' },
44
+ 'time with time zone': { pslType: 'DateTime', attributeName: 'db.Timetz' },
45
+ json: { pslType: 'Json', attributeName: 'db.Json' },
46
+ };
47
+
48
+ const PARAMETERIZED_NATIVE_TYPES: Record<
49
+ string,
50
+ { readonly pslType: string; readonly attributeName: string }
51
+ > = {
52
+ 'character varying': { pslType: 'String', attributeName: 'db.VarChar' },
53
+ character: { pslType: 'String', attributeName: 'db.Char' },
54
+ char: { pslType: 'String', attributeName: 'db.Char' },
55
+ varchar: { pslType: 'String', attributeName: 'db.VarChar' },
56
+ numeric: { pslType: 'Decimal', attributeName: 'db.Numeric' },
57
+ timestamp: { pslType: 'DateTime', attributeName: 'db.Timestamp' },
58
+ timestamptz: { pslType: 'DateTime', attributeName: 'db.Timestamptz' },
59
+ time: { pslType: 'DateTime', attributeName: 'db.Time' },
60
+ timetz: { pslType: 'DateTime', attributeName: 'db.Timetz' },
61
+ };
62
+
63
+ const PARAMETERIZED_TYPE_PATTERN = /^(.+?)\((.+)\)$/;
64
+
65
+ function getOwnMappingValue(map: Record<string, string>, key: string): string | undefined {
66
+ return Object.hasOwn(map, key) ? map[key] : undefined;
67
+ }
68
+
69
+ function getOwnRecordValue<T>(map: Record<string, T>, key: string): T | undefined {
70
+ return Object.hasOwn(map, key) ? map[key] : undefined;
71
+ }
72
+
73
+ function createNativeTypeAttribute(name: string, args?: readonly string[]): PslNativeTypeAttribute {
74
+ return args && args.length > 0 ? { name, args } : { name };
75
+ }
76
+
77
+ function splitTypeParameterList(params: string): readonly string[] {
78
+ return params
79
+ .split(',')
80
+ .map((part) => part.trim())
81
+ .filter((part) => part.length > 0);
82
+ }
83
+
84
+ export function createPostgresTypeMap(enumTypeNames?: ReadonlySet<string>): PslTypeMap {
85
+ return {
86
+ resolve(nativeType: string): PslTypeResolution {
87
+ if (enumTypeNames?.has(nativeType)) {
88
+ return { pslType: nativeType, nativeType };
89
+ }
90
+
91
+ const paramMatch = nativeType.match(PARAMETERIZED_TYPE_PATTERN);
92
+ if (paramMatch) {
93
+ const [, baseType = nativeType, params = ''] = paramMatch;
94
+ const template = getOwnRecordValue(PARAMETERIZED_NATIVE_TYPES, baseType);
95
+ if (template) {
96
+ return {
97
+ pslType: template.pslType,
98
+ nativeType,
99
+ typeParams: { baseType, params },
100
+ nativeTypeAttribute: createNativeTypeAttribute(
101
+ template.attributeName,
102
+ splitTypeParameterList(params),
103
+ ),
104
+ };
105
+ }
106
+ }
107
+
108
+ const preservedType = getOwnRecordValue(PRESERVED_NATIVE_TYPES, nativeType);
109
+ if (preservedType) {
110
+ return {
111
+ pslType: preservedType.pslType,
112
+ nativeType,
113
+ nativeTypeAttribute: createNativeTypeAttribute(preservedType.attributeName),
114
+ };
115
+ }
116
+
117
+ const pslType = getOwnMappingValue(POSTGRES_TO_PSL, nativeType);
118
+ if (pslType) {
119
+ return {
120
+ pslType,
121
+ nativeType,
122
+ };
123
+ }
124
+
125
+ return { unsupported: true, nativeType };
126
+ },
127
+ };
128
+ }
@@ -0,0 +1,48 @@
1
+ import { createHash } from 'node:crypto';
2
+
3
+ export type RlsPolicyOperation = 'select' | 'insert' | 'update' | 'delete' | 'all';
4
+
5
+ export interface ContentHashParts {
6
+ readonly using?: string;
7
+ readonly withCheck?: string;
8
+ readonly roles: readonly string[];
9
+ readonly operation: RlsPolicyOperation;
10
+ readonly permissive: boolean;
11
+ }
12
+
13
+ /**
14
+ * Stabilizes an authored predicate for hashing: trim, and collapse runs of
15
+ * internal whitespace to a single space.
16
+ *
17
+ * This is deliberately minimal. The content hash is the equivalence relation
18
+ * for a policy, and the wire name (prefix + hash) is the only thing ever
19
+ * compared — we never recompute the hash from an introspected policy body, so
20
+ * there is no need to match Postgres's reprinted form. Minimal normalization
21
+ * also protects the no-collision property: aggressive rewriting (lowercasing,
22
+ * paren-stripping, cast-alias folding) risks collapsing two distinct predicates
23
+ * onto one hash. Out-of-band alteration of a hashed policy is unsupported.
24
+ *
25
+ * The normalizer is a stability commitment: any change re-suffixes all wire names.
26
+ */
27
+ export function normalizePredicate(sql: string): string {
28
+ return sql.replace(/\s+/g, ' ').trim();
29
+ }
30
+
31
+ /**
32
+ * Returns the first 8 lowercase hex characters of the SHA-256 digest over the
33
+ * canonical content tuple for an RLS policy:
34
+ *
35
+ * [normalize(using), normalize(withCheck), sortedRoles, operation, permissive]
36
+ *
37
+ * Schema and table are excluded (they are orthogonal to policy equivalence).
38
+ * Uses `JSON.stringify` for a deterministic encoding.
39
+ */
40
+ export function computeContentHash(parts: ContentHashParts): string {
41
+ const using = normalizePredicate(parts.using ?? '');
42
+ const withCheck = normalizePredicate(parts.withCheck ?? '');
43
+ const roles = [...new Set(parts.roles)].sort();
44
+ const permissive = parts.permissive ? 'permissive' : 'restrictive';
45
+
46
+ const tuple = JSON.stringify([using, withCheck, roles, parts.operation, permissive]);
47
+ return createHash('sha256').update(tuple).digest('hex').slice(0, 8);
48
+ }
@@ -0,0 +1,33 @@
1
+ export interface RlsPolicyWireName {
2
+ /** The user-supplied part before the `_<8hex>` suffix. */
3
+ readonly prefix: string;
4
+ /** The 8-lowercase-hex content-hash suffix. */
5
+ readonly hash: string;
6
+ }
7
+
8
+ const WIRE_NAME_PATTERN = /^(.+)_([0-9a-f]{8})$/;
9
+
10
+ /**
11
+ * Assembles an RLS policy wire name from its user-supplied prefix and its
12
+ * 8-hex content-hash suffix. This module owns the `<prefix>_<hash>` format
13
+ * on both sides — construction here and parsing in
14
+ * {@link parseRlsPolicyWireName} — so the two never drift.
15
+ */
16
+ export function formatRlsPolicyWireName(prefix: string, hash: string): string {
17
+ return `${prefix}_${hash}`;
18
+ }
19
+
20
+ /**
21
+ * Splits an RLS policy wire name (`<prefix>_<8hex>`) into its prefix and
22
+ * content-hash suffix. Returns `undefined` when the name does not follow the
23
+ * wire-name shape (e.g. a policy created outside the toolchain) — callers
24
+ * treat such names as all-prefix. Consumed by introspection (prefix
25
+ * extraction) and by rename pairing (same hash, different prefix).
26
+ */
27
+ export function parseRlsPolicyWireName(name: string): RlsPolicyWireName | undefined {
28
+ const match = WIRE_NAME_PATTERN.exec(name);
29
+ const prefix = match?.[1];
30
+ const hash = match?.[2];
31
+ if (prefix === undefined || hash === undefined) return undefined;
32
+ return { prefix, hash };
33
+ }
@@ -0,0 +1,26 @@
1
+ import type { EntityCoordinate } from '@prisma-next/framework-components/ir';
2
+ import type { SqlSchemaIRNode } from '@prisma-next/sql-schema-ir/types';
3
+ import { PostgresNativeEnumSchemaNode } from './postgres-native-enum-schema-node';
4
+ import { PostgresTableSchemaNode } from './postgres-table-schema-node';
5
+ import { postgresNodeEntityKind } from './schema-node-kinds';
6
+
7
+ /**
8
+ * The storage-`entries` coordinate `(entityKind, entityName)` a Postgres diff
9
+ * node addresses — a table by its name, a native enum by its physical type
10
+ * name. `undefined` for a node that is not a whole storage entity (a namespace,
11
+ * a column, a policy). Lets ownership/subject resolution treat every entity kind
12
+ * uniformly, the node self-describing its storage identity.
13
+ */
14
+ export function postgresNodeStorageCoordinate(
15
+ node: SqlSchemaIRNode,
16
+ ): Pick<EntityCoordinate, 'entityKind' | 'entityName'> | undefined {
17
+ if (PostgresTableSchemaNode.is(node)) {
18
+ const entityKind = postgresNodeEntityKind(node.nodeKind);
19
+ return entityKind === undefined ? undefined : { entityKind, entityName: node.name };
20
+ }
21
+ if (PostgresNativeEnumSchemaNode.is(node)) {
22
+ const entityKind = postgresNodeEntityKind(node.nodeKind);
23
+ return entityKind === undefined ? undefined : { entityKind, entityName: node.typeName };
24
+ }
25
+ return undefined;
26
+ }
@@ -0,0 +1,61 @@
1
+ import type { DiffableNode } from '@prisma-next/framework-components/control';
2
+ import { freezeNode } from '@prisma-next/framework-components/ir';
3
+ import { assertNode, SqlSchemaIRNode } from '@prisma-next/sql-schema-ir/types';
4
+ import type { PostgresNamespaceSchemaNode } from './postgres-namespace-schema-node';
5
+ import type { PostgresRoleSchemaNode } from './postgres-role-schema-node';
6
+ import { PostgresSchemaNodeKind } from './schema-node-kinds';
7
+
8
+ export interface PostgresDatabaseSchemaNodeInput {
9
+ readonly namespaces: Readonly<Record<string, PostgresNamespaceSchemaNode>>;
10
+ readonly roles: readonly PostgresRoleSchemaNode[];
11
+ readonly existingSchemas: readonly string[];
12
+ readonly pgVersion: string;
13
+ }
14
+
15
+ /**
16
+ * The root of the Postgres schema-diff tree: one node per database.
17
+ *
18
+ * `id` is the fixed sentinel `'database'` — the root has no siblings and
19
+ * the value is never emitted into migration paths. `isEqualTo` is identity
20
+ * (roots always share the `'database'` id). `children()` yields the namespace
21
+ * nodes followed by the role nodes — both are root-level diff subjects. The
22
+ * differ pairs siblings by `(nodeKind, id)`, so a role and a namespace may
23
+ * share a name without colliding.
24
+ */
25
+ export class PostgresDatabaseSchemaNode extends SqlSchemaIRNode implements DiffableNode {
26
+ override readonly nodeKind = PostgresSchemaNodeKind.database;
27
+
28
+ readonly namespaces: Readonly<Record<string, PostgresNamespaceSchemaNode>>;
29
+ readonly roles: readonly PostgresRoleSchemaNode[];
30
+ readonly existingSchemas: readonly string[];
31
+ readonly pgVersion: string;
32
+
33
+ constructor(input: PostgresDatabaseSchemaNodeInput) {
34
+ super();
35
+ this.namespaces = Object.freeze({ ...input.namespaces });
36
+ this.roles = Object.freeze([...input.roles]);
37
+ this.existingSchemas = Object.freeze([...input.existingSchemas]);
38
+ this.pgVersion = input.pgVersion;
39
+ freezeNode(this);
40
+ }
41
+
42
+ get id(): string {
43
+ return 'database';
44
+ }
45
+
46
+ isEqualTo(other: DiffableNode): boolean {
47
+ return this.id === other.id;
48
+ }
49
+
50
+ children(): readonly DiffableNode[] {
51
+ return [...Object.values(this.namespaces), ...this.roles];
52
+ }
53
+
54
+ static is(node: SqlSchemaIRNode): node is PostgresDatabaseSchemaNode {
55
+ return node.nodeKind === PostgresSchemaNodeKind.database;
56
+ }
57
+
58
+ static assert(node: SqlSchemaIRNode): asserts node is PostgresDatabaseSchemaNode {
59
+ assertNode(node, 'PostgresDatabaseSchemaNode', PostgresDatabaseSchemaNode.is);
60
+ }
61
+ }
@@ -0,0 +1,70 @@
1
+ import type { DiffableNode } from '@prisma-next/framework-components/control';
2
+ import { freezeNode } from '@prisma-next/framework-components/ir';
3
+ import { assertNode, SqlSchemaIRNode } from '@prisma-next/sql-schema-ir/types';
4
+ import type { PostgresNativeEnumSchemaNode } from './postgres-native-enum-schema-node';
5
+ import type { PostgresTableSchemaNode } from './postgres-table-schema-node';
6
+ import { PostgresSchemaNodeKind } from './schema-node-kinds';
7
+
8
+ export interface PostgresNamespaceSchemaNodeInput {
9
+ readonly schemaName: string;
10
+ readonly tables: Readonly<Record<string, PostgresTableSchemaNode>>;
11
+ /**
12
+ * The native-enum diff nodes belonging to this namespace, member values in
13
+ * `pg_enum.enumsortorder` (declaration) order. The expected
14
+ * (contract-projected) side attaches each node's `control` (the contract
15
+ * entity's grade); introspection builds nodes with no `control`.
16
+ */
17
+ readonly nativeEnums?: readonly PostgresNativeEnumSchemaNode[];
18
+ }
19
+
20
+ /**
21
+ * One-per-Postgres-schema diff-tree node. Groups the tables belonging to a
22
+ * single namespace. Per-schema consumers (the relational planner,
23
+ * toSchemaView) read this node's `tables` field structurally via
24
+ * `blindCast`/`SqlSchemaIRNode` — not through a static `SqlSchemaIR`
25
+ * assignment — because `nodeKind` carries this node's own literal
26
+ * (`postgres-namespace`), distinct from `SqlSchemaIR`'s own (`sql-schema`).
27
+ *
28
+ * `id` is the schema name; `isEqualTo` is identity on it; `children()` returns
29
+ * the table nodes plus `nativeEnums`.
30
+ *
31
+ * `nativeEnums` is the diff-tree representation of native enum types the
32
+ * differ pairs — the sole enum carrier, built directly by both sides: the
33
+ * expected (contract-projected) side and introspection alike hand in
34
+ * `PostgresNativeEnumSchemaNode`s.
35
+ */
36
+ export class PostgresNamespaceSchemaNode extends SqlSchemaIRNode implements DiffableNode {
37
+ override readonly nodeKind = PostgresSchemaNodeKind.namespace;
38
+
39
+ readonly schemaName: string;
40
+ readonly tables: Readonly<Record<string, PostgresTableSchemaNode>>;
41
+ readonly nativeEnums: readonly PostgresNativeEnumSchemaNode[];
42
+
43
+ constructor(input: PostgresNamespaceSchemaNodeInput) {
44
+ super();
45
+ this.schemaName = input.schemaName;
46
+ this.tables = Object.freeze({ ...input.tables });
47
+ this.nativeEnums = Object.freeze([...(input.nativeEnums ?? [])]);
48
+ freezeNode(this);
49
+ }
50
+
51
+ get id(): string {
52
+ return this.schemaName;
53
+ }
54
+
55
+ isEqualTo(other: DiffableNode): boolean {
56
+ return this.id === other.id;
57
+ }
58
+
59
+ children(): readonly DiffableNode[] {
60
+ return [...Object.values(this.tables), ...this.nativeEnums];
61
+ }
62
+
63
+ static is(node: SqlSchemaIRNode): node is PostgresNamespaceSchemaNode {
64
+ return node.nodeKind === PostgresSchemaNodeKind.namespace;
65
+ }
66
+
67
+ static assert(node: SqlSchemaIRNode): asserts node is PostgresNamespaceSchemaNode {
68
+ assertNode(node, 'PostgresNamespaceSchemaNode', PostgresNamespaceSchemaNode.is);
69
+ }
70
+ }
@@ -0,0 +1,83 @@
1
+ import type { ControlPolicy } from '@prisma-next/contract/types';
2
+ import type { DiffableNode } from '@prisma-next/framework-components/control';
3
+ import { freezeNode } from '@prisma-next/framework-components/ir';
4
+ import { assertNode, SqlSchemaIRNode } from '@prisma-next/sql-schema-ir/types';
5
+ import { blindCast } from '@prisma-next/utils/casts';
6
+ import { PostgresSchemaNodeKind } from './schema-node-kinds';
7
+
8
+ export interface PostgresNativeEnumSchemaNodeInput {
9
+ /** The Postgres type name (`CREATE TYPE <typeName> AS ENUM (…)`). */
10
+ readonly typeName: string;
11
+ /** The owning DDL schema name — enum types are schema-scoped. */
12
+ readonly namespaceId: string;
13
+ /** Member values in declaration (`pg_enum.enumsortorder`) order. */
14
+ readonly members: readonly string[];
15
+ /** The contract entity's control grade — expected-side nodes only. */
16
+ readonly control?: ControlPolicy;
17
+ }
18
+
19
+ /**
20
+ * Schema-diff leaf node for a native Postgres enum type.
21
+ *
22
+ * This is a derived, transient node walked by the differ — it is NEVER
23
+ * serialized. Both sides derive it on the namespace node: the expected side
24
+ * from the contract's hydrated `entries.native_enum` entities, the actual
25
+ * side from the adapter's introspected `nativeEnums`.
26
+ *
27
+ * Enum types are schema-scoped, so identity is (namespace, type name): the
28
+ * namespace coordinate comes from tree position (the differ pairs enum nodes
29
+ * only inside an already-paired namespace) and `id` carries the type name,
30
+ * prefixed with the entries-kind vocabulary (`native_enum:<typeName>`) so it
31
+ * cannot collide with a sibling table of the same name — the same
32
+ * sibling-prefix convention relational column nodes use (`column:<name>`).
33
+ *
34
+ * `isEqualTo` compares members POSITIONALLY — `['a','b'] ≠ ['b','a']` —
35
+ * because Postgres enum sort order is semantic. `control` is contract
36
+ * metadata, not database state, and does not participate in equality.
37
+ */
38
+ export class PostgresNativeEnumSchemaNode extends SqlSchemaIRNode implements DiffableNode {
39
+ override readonly nodeKind = PostgresSchemaNodeKind.nativeEnum;
40
+
41
+ readonly typeName: string;
42
+ readonly namespaceId: string;
43
+ readonly members: readonly string[];
44
+ declare readonly control?: ControlPolicy;
45
+
46
+ constructor(input: PostgresNativeEnumSchemaNodeInput) {
47
+ super();
48
+ this.typeName = input.typeName;
49
+ this.namespaceId = input.namespaceId;
50
+ this.members = Object.freeze([...input.members]);
51
+ if (input.control !== undefined) this.control = input.control;
52
+ freezeNode(this);
53
+ }
54
+
55
+ get id(): string {
56
+ return `native_enum:${this.typeName}`;
57
+ }
58
+
59
+ children(): readonly DiffableNode[] {
60
+ return [];
61
+ }
62
+
63
+ isEqualTo(other: DiffableNode): boolean {
64
+ const node = blindCast<
65
+ SqlSchemaIRNode,
66
+ 'every diff-tree node the differ pairs is a SqlSchemaIRNode; the guard rejects non-enum kinds'
67
+ >(other);
68
+ PostgresNativeEnumSchemaNode.assert(node);
69
+ return (
70
+ this.typeName === node.typeName &&
71
+ this.members.length === node.members.length &&
72
+ this.members.every((member, index) => member === node.members[index])
73
+ );
74
+ }
75
+
76
+ static is(node: SqlSchemaIRNode): node is PostgresNativeEnumSchemaNode {
77
+ return node.nodeKind === PostgresSchemaNodeKind.nativeEnum;
78
+ }
79
+
80
+ static assert(node: SqlSchemaIRNode): asserts node is PostgresNativeEnumSchemaNode {
81
+ assertNode(node, 'PostgresNativeEnumSchemaNode', PostgresNativeEnumSchemaNode.is);
82
+ }
83
+ }
@@ -0,0 +1,90 @@
1
+ import type { DiffableNode } from '@prisma-next/framework-components/control';
2
+ import { freezeNode } from '@prisma-next/framework-components/ir';
3
+ import { assertNode, SqlSchemaIRNode } from '@prisma-next/sql-schema-ir/types';
4
+ import { blindCast } from '@prisma-next/utils/casts';
5
+ import type { RlsPolicyOperation } from '../postgres-rls-policy';
6
+ import { PostgresSchemaNodeKind } from './schema-node-kinds';
7
+
8
+ export interface PostgresPolicySchemaNodeInput {
9
+ /** Full wire name: `<prefix>_<8hex>`. */
10
+ readonly name: string;
11
+ /** User-supplied prefix (the part before the `_<8hex>` suffix). */
12
+ readonly prefix: string;
13
+ /** Name of the table this policy attaches to, by name within the same schema. */
14
+ readonly tableName: string;
15
+ /** Namespace coordinate (schema name). */
16
+ readonly namespaceId: string;
17
+ readonly operation: RlsPolicyOperation;
18
+ /** Sorted role names rendered in `TO <roles>`. */
19
+ readonly roles: readonly string[];
20
+ /** USING predicate SQL string, if present. */
21
+ readonly using?: string;
22
+ /** WITH CHECK predicate SQL string, if present. */
23
+ readonly withCheck?: string;
24
+ /** `true` = `AS PERMISSIVE`, `false` = `AS RESTRICTIVE`. */
25
+ readonly permissive: boolean;
26
+ }
27
+
28
+ /**
29
+ * Schema-diff leaf node for a Postgres row-level security policy.
30
+ *
31
+ * This is a derived, transient node walked by the differ — it is NEVER serialized.
32
+ * Built by project-from-contract and project-from-database from their respective
33
+ * `PostgresRlsPolicy` contract entities / introspected rows.
34
+ *
35
+ * `id` is the wire name (`<prefix>_<sha256(body)[0..8]>`), so name-equality is
36
+ * body-equality. `isEqualTo` compares names only — never byte-compare predicate
37
+ * bodies, because Postgres reprints them.
38
+ */
39
+ export class PostgresPolicySchemaNode extends SqlSchemaIRNode implements DiffableNode {
40
+ override readonly nodeKind = PostgresSchemaNodeKind.policy;
41
+
42
+ readonly name: string;
43
+ readonly prefix: string;
44
+ readonly tableName: string;
45
+ readonly namespaceId: string;
46
+ readonly operation: RlsPolicyOperation;
47
+ readonly roles: readonly string[];
48
+ declare readonly using?: string;
49
+ declare readonly withCheck?: string;
50
+ readonly permissive: boolean;
51
+
52
+ constructor(input: PostgresPolicySchemaNodeInput) {
53
+ super();
54
+ this.name = input.name;
55
+ this.prefix = input.prefix;
56
+ this.tableName = input.tableName;
57
+ this.namespaceId = input.namespaceId;
58
+ this.operation = input.operation;
59
+ this.roles = Object.freeze([...input.roles]);
60
+ if (input.using !== undefined) this.using = input.using;
61
+ if (input.withCheck !== undefined) this.withCheck = input.withCheck;
62
+ this.permissive = input.permissive;
63
+ freezeNode(this);
64
+ }
65
+
66
+ get id(): string {
67
+ return this.name;
68
+ }
69
+
70
+ children(): readonly DiffableNode[] {
71
+ return [];
72
+ }
73
+
74
+ isEqualTo(other: DiffableNode): boolean {
75
+ const node = blindCast<
76
+ SqlSchemaIRNode,
77
+ 'every diff-tree node the differ pairs is a SqlSchemaIRNode; the guard rejects non-policy kinds'
78
+ >(other);
79
+ PostgresPolicySchemaNode.assert(node);
80
+ return this.id === node.id;
81
+ }
82
+
83
+ static is(node: SqlSchemaIRNode): node is PostgresPolicySchemaNode {
84
+ return node.nodeKind === PostgresSchemaNodeKind.policy;
85
+ }
86
+
87
+ static assert(node: SqlSchemaIRNode | undefined): asserts node is PostgresPolicySchemaNode {
88
+ assertNode(node, 'PostgresPolicySchemaNode', PostgresPolicySchemaNode.is);
89
+ }
90
+ }
@@ -0,0 +1,65 @@
1
+ import type { DiffableNode } from '@prisma-next/framework-components/control';
2
+ import { freezeNode } from '@prisma-next/framework-components/ir';
3
+ import { assertNode, SqlSchemaIRNode } from '@prisma-next/sql-schema-ir/types';
4
+ import { blindCast } from '@prisma-next/utils/casts';
5
+ import { PostgresSchemaNodeKind } from './schema-node-kinds';
6
+
7
+ export interface PostgresRoleSchemaNodeInput {
8
+ readonly name: string;
9
+ /**
10
+ * Namespace coordinate. Roles are cluster-scoped; callers pass
11
+ * `UNBOUND_NAMESPACE_ID` from `@prisma-next/framework-components/ir`.
12
+ */
13
+ readonly namespaceId: string;
14
+ }
15
+
16
+ /**
17
+ * Schema-diff leaf node for a Postgres database role.
18
+ *
19
+ * This is a derived, transient node walked by the differ — it is NEVER serialized.
20
+ * Built by project-from-contract and project-from-database from their respective
21
+ * `PostgresRole` contract entities / introspected rows.
22
+ *
23
+ * Roles are cluster-scoped, so `id` is the bare role name. The differ pairs
24
+ * siblings by `(nodeKind, id)`, so a role and a namespace may share a name
25
+ * (role `public`, schema `public`) without colliding. `isEqualTo` compares
26
+ * ids — name-equality is role-equality for cluster-scoped objects.
27
+ */
28
+ export class PostgresRoleSchemaNode extends SqlSchemaIRNode implements DiffableNode {
29
+ override readonly nodeKind = PostgresSchemaNodeKind.role;
30
+
31
+ readonly name: string;
32
+ readonly namespaceId: string;
33
+
34
+ constructor(input: PostgresRoleSchemaNodeInput) {
35
+ super();
36
+ this.name = input.name;
37
+ this.namespaceId = input.namespaceId;
38
+ freezeNode(this);
39
+ }
40
+
41
+ get id(): string {
42
+ return this.name;
43
+ }
44
+
45
+ children(): readonly DiffableNode[] {
46
+ return [];
47
+ }
48
+
49
+ isEqualTo(other: DiffableNode): boolean {
50
+ const node = blindCast<
51
+ SqlSchemaIRNode,
52
+ 'every diff-tree node the differ pairs is a SqlSchemaIRNode; the guard rejects non-role kinds'
53
+ >(other);
54
+ PostgresRoleSchemaNode.assert(node);
55
+ return this.id === node.id;
56
+ }
57
+
58
+ static is(node: SqlSchemaIRNode): node is PostgresRoleSchemaNode {
59
+ return node.nodeKind === PostgresSchemaNodeKind.role;
60
+ }
61
+
62
+ static assert(node: SqlSchemaIRNode): asserts node is PostgresRoleSchemaNode {
63
+ assertNode(node, 'PostgresRoleSchemaNode', PostgresRoleSchemaNode.is);
64
+ }
65
+ }