@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
@@ -1,13 +1,373 @@
1
1
  import { temporalAuthoringPresets } from '@prisma-next/family-sql/control';
2
2
  import type {
3
+ AuthoringEntityContext,
4
+ AuthoringEntityTypeFactoryOutput,
3
5
  AuthoringEntityTypeNamespace,
4
6
  AuthoringFieldNamespace,
7
+ AuthoringModelAttributeContext,
8
+ AuthoringModelAttributeDescriptorNamespace,
9
+ AuthoringPslBlockDescriptorNamespace,
5
10
  AuthoringTypeNamespace,
11
+ PslExtensionBlock,
6
12
  } from '@prisma-next/framework-components/authoring';
13
+ import { UNBOUND_NAMESPACE_ID } from '@prisma-next/framework-components/ir';
14
+ import { modelAttribute } from '@prisma-next/psl-parser';
15
+ import type { SqlValueSetDerivingEntityTypeOutput } from '@prisma-next/sql-contract/value-set-derivation-hook';
16
+ import { ifDefined } from '@prisma-next/utils/defined';
17
+ import { PG_ENUM_CODEC_ID } from './codec-ids';
18
+ import { PostgresNativeEnum } from './postgres-native-enum';
19
+ import { PostgresRlsEnablement, type PostgresRlsEnablementInput } from './postgres-rls-enablement';
20
+ import { PostgresRlsPolicy, type RlsPolicyOperation } from './postgres-rls-policy';
21
+ import { PostgresRole } from './postgres-role';
22
+ import {
23
+ PostgresNativeEnumSchema,
24
+ PostgresRlsEnablementSchema,
25
+ PostgresRlsPolicySchema,
26
+ PostgresRoleSchema,
27
+ } from './postgres-validators';
28
+ import { computeContentHash, normalizePredicate } from './rls/canonicalize';
29
+ import { formatRlsPolicyWireName } from './rls/wire-name';
7
30
 
8
- export const postgresAuthoringTypes = {} as const satisfies AuthoringTypeNamespace;
31
+ /**
32
+ * `pg.enum(<ref>)` registers as an ordinary type constructor whose sole
33
+ * positional argument names a `native_enum` entity instead of carrying a
34
+ * literal value. The interpreter resolves the ref to the `native_enum`
35
+ * entity generically (driven by `entityRefArg`); the `pg/enum@1` codec
36
+ * descriptor's `columnFromEntity` hook (see `codecs.ts`) converts that
37
+ * entity into the column's `typeParams` and native type.
38
+ */
39
+ export const postgresAuthoringTypes = {
40
+ pg: {
41
+ enum: {
42
+ kind: 'typeConstructor',
43
+ entityRefArg: { index: 0, entityKind: 'native_enum' },
44
+ output: {
45
+ codecId: PG_ENUM_CODEC_ID,
46
+ },
47
+ },
48
+ },
49
+ } as const satisfies AuthoringTypeNamespace;
50
+
51
+ export interface RlsPolicyExtensionBlock extends PslExtensionBlock {
52
+ readonly namespaceId: string;
53
+ }
54
+
55
+ /** A parsed `role` block annotated with its lexical namespace id by the interpreter. */
56
+ export interface RoleExtensionBlock extends PslExtensionBlock {
57
+ readonly namespaceId: string;
58
+ }
59
+
60
+ /**
61
+ * Maps a `policy_<op>` keyword to the RLS operation it authors. The keyword
62
+ * IS the operation (per the project's rejection of a `policy { operation = … }`
63
+ * conditional block).
64
+ */
65
+ const POLICY_KEYWORD_OPERATION: Readonly<Record<string, RlsPolicyOperation>> = {
66
+ policy_select: 'select',
67
+ policy_insert: 'insert',
68
+ policy_update: 'update',
69
+ policy_delete: 'delete',
70
+ policy_all: 'all',
71
+ };
72
+
73
+ /**
74
+ * Which predicate each RLS operation admits, mirroring Postgres: SELECT and
75
+ * DELETE decide row visibility/eligibility with `USING` only; INSERT validates
76
+ * the new row with `WITH CHECK` only; UPDATE and ALL take both. A predicate
77
+ * outside this set is a load-time error (see {@link lowerRlsPolicyFromBlock}).
78
+ */
79
+ const POLICY_OPERATION_PREDICATES: Readonly<
80
+ Record<RlsPolicyOperation, { readonly using: boolean; readonly withCheck: boolean }>
81
+ > = {
82
+ select: { using: true, withCheck: false },
83
+ insert: { using: false, withCheck: true },
84
+ update: { using: true, withCheck: true },
85
+ delete: { using: true, withCheck: false },
86
+ all: { using: true, withCheck: true },
87
+ };
88
+
89
+ function readRefParam(block: PslExtensionBlock, key: string): string | undefined {
90
+ const param = block.parameters[key];
91
+ return param?.kind === 'ref' ? param.identifier : undefined;
92
+ }
93
+
94
+ function readValueParam(block: PslExtensionBlock, key: string): string | undefined {
95
+ const param = block.parameters[key];
96
+ return param?.kind === 'value' ? param.raw : undefined;
97
+ }
98
+
99
+ function readListRefParams(block: PslExtensionBlock, key: string): string[] {
100
+ const param = block.parameters[key];
101
+ if (param?.kind !== 'list') return [];
102
+ return param.items.flatMap((item) => (item.kind === 'ref' ? [item.identifier] : []));
103
+ }
104
+
105
+ /**
106
+ * Unwraps a quoted PSL string argument, inverting the printer's
107
+ * `escapePslString` escapes (`\\`, `\"`, `\n`, `\r`). An unknown escape
108
+ * sequence is kept verbatim, matching the printer-side `unescapePslString`
109
+ * convention.
110
+ */
111
+ function unwrapQuotedString(raw: string): string {
112
+ if (!(raw.startsWith('"') && raw.endsWith('"') && raw.length >= 2)) {
113
+ return raw;
114
+ }
115
+ const inner = raw.slice(1, -1);
116
+ let result = '';
117
+ for (let i = 0; i < inner.length; i++) {
118
+ if (inner[i] !== '\\' || i + 1 >= inner.length) {
119
+ result += inner[i];
120
+ continue;
121
+ }
122
+ const next = inner[i + 1];
123
+ if (next === '\\' || next === '"') {
124
+ result += next;
125
+ } else if (next === 'n') {
126
+ result += '\n';
127
+ } else if (next === 'r') {
128
+ result += '\r';
129
+ } else {
130
+ result += '\\';
131
+ result += next;
132
+ }
133
+ i++;
134
+ }
135
+ return result;
136
+ }
137
+
138
+ function lowerRlsPolicyFromBlock(
139
+ block: RlsPolicyExtensionBlock,
140
+ ctx: AuthoringEntityContext,
141
+ ): PostgresRlsPolicy | undefined {
142
+ const prefix = block.name;
143
+ const operation = POLICY_KEYWORD_OPERATION[block.keyword] ?? 'select';
144
+ const targetModelName = readRefParam(block, 'target') ?? '';
145
+ const tableName = targetModelName.charAt(0).toLowerCase() + targetModelName.slice(1);
146
+ const roles = [...readListRefParams(block, 'roles')].sort();
147
+
148
+ const usingRaw = readValueParam(block, 'using');
149
+ const withCheckRaw = readValueParam(block, 'withCheck');
150
+
151
+ // Reject a predicate the operation does not take (e.g. `using` on INSERT, or
152
+ // `withCheck` on SELECT/DELETE). The descriptor's param set already omits it,
153
+ // but the generic descriptor validator is not wired into the SQL-family
154
+ // interpreter, so the lowering enforces the per-operation predicate matrix
155
+ // directly — a wrong predicate is a load-time diagnostic, not a silent drop.
156
+ const support = POLICY_OPERATION_PREDICATES[operation];
157
+ const rejectPredicate = (predicate: 'using' | 'withCheck'): undefined => {
158
+ ctx.diagnostics?.push({
159
+ code: 'PSL_RLS_PREDICATE_NOT_FOR_OPERATION',
160
+ message: `\`${block.keyword}\` policy "${block.name}" does not take a \`${predicate}\` predicate; the ${operation.toUpperCase()} operation uses ${support.using ? '`using`' : '`withCheck`'}${support.using && support.withCheck ? ' and `withCheck`' : ' only'}.`,
161
+ sourceId: ctx.sourceId ?? 'unknown',
162
+ span: block.parameters[predicate]?.span ?? block.span,
163
+ });
164
+ return undefined;
165
+ };
166
+ if (usingRaw !== undefined && !support.using) return rejectPredicate('using');
167
+ if (withCheckRaw !== undefined && !support.withCheck) return rejectPredicate('withCheck');
168
+
169
+ const using = usingRaw !== undefined ? unwrapQuotedString(usingRaw) : undefined;
170
+ const withCheck = withCheckRaw !== undefined ? unwrapQuotedString(withCheckRaw) : undefined;
171
+
172
+ const wireHash = computeContentHash({
173
+ ...ifDefined('using', using !== undefined ? normalizePredicate(using) : undefined),
174
+ ...ifDefined('withCheck', withCheck !== undefined ? normalizePredicate(withCheck) : undefined),
175
+ roles,
176
+ operation,
177
+ permissive: true,
178
+ });
179
+ const wireName = formatRlsPolicyWireName(prefix, wireHash);
180
+
181
+ return new PostgresRlsPolicy({
182
+ name: wireName,
183
+ prefix,
184
+ tableName,
185
+ namespaceId: block.namespaceId,
186
+ operation,
187
+ roles,
188
+ ...ifDefined('using', using),
189
+ ...ifDefined('withCheck', withCheck),
190
+ permissive: true,
191
+ });
192
+ }
193
+
194
+ /**
195
+ * Lowers a `native_enum { memberName = "value" … @@map("type_name") }` block
196
+ * into a {@link PostgresNativeEnum}. Members must be authored as explicit
197
+ * `key = "value"` pairs — a bare (value-less) member is a diagnostic, not
198
+ * accepted (authoring-design.md §2.1). The parsed `memberName` is only used
199
+ * to duplicate-check and report diagnostics; the lowered entity carries just
200
+ * the member values (a native enum is value-only — the member "name" isn't
201
+ * a separate authoring concept from the value). `typeName` comes from
202
+ * `@@map` or defaults to the block name verbatim.
203
+ */
204
+ function lowerNativeEnumFromBlock(
205
+ block: PslExtensionBlock,
206
+ ctx: AuthoringEntityContext,
207
+ ): PostgresNativeEnum | undefined {
208
+ const sourceId = ctx.sourceId ?? 'unknown';
209
+ const diagnostics = ctx.diagnostics;
210
+
211
+ const mapAttr = block.blockAttributes.find((a) => a.name === 'map');
212
+ let typeName = block.name;
213
+ if (mapAttr) {
214
+ const rawArg = mapAttr.args[0]?.value;
215
+ const mapped = rawArg !== undefined ? unwrapQuotedString(rawArg) : undefined;
216
+ if (mapped === undefined) {
217
+ diagnostics?.push({
218
+ code: 'PSL_NATIVE_ENUM_INVALID_MAP',
219
+ message: `native_enum "${block.name}" @@map attribute must have a quoted type-name argument`,
220
+ sourceId,
221
+ span: mapAttr.span,
222
+ });
223
+ return undefined;
224
+ }
225
+ typeName = mapped;
226
+ }
227
+
228
+ let memberError = false;
229
+ const seenValues = new Set<string>();
230
+ const members: string[] = [];
231
+ for (const [memberName, paramValue] of Object.entries(block.parameters)) {
232
+ if (paramValue.kind === 'bare') {
233
+ diagnostics?.push({
234
+ code: 'PSL_NATIVE_ENUM_BARE_MEMBER',
235
+ message: `native_enum "${block.name}" member "${memberName}" has no value; members must be authored as "${memberName} = \\"value\\""`,
236
+ sourceId,
237
+ span: paramValue.span,
238
+ });
239
+ memberError = true;
240
+ continue;
241
+ }
242
+ if (paramValue.kind !== 'value') continue;
243
+
244
+ let jsonValue: unknown;
245
+ try {
246
+ jsonValue = JSON.parse(paramValue.raw);
247
+ } catch {
248
+ diagnostics?.push({
249
+ code: 'PSL_EXTENSION_INVALID_VALUE',
250
+ message: `native_enum "${block.name}" member "${memberName}" value "${paramValue.raw}" is not valid JSON`,
251
+ sourceId,
252
+ span: paramValue.span,
253
+ });
254
+ memberError = true;
255
+ continue;
256
+ }
257
+ if (typeof jsonValue !== 'string') {
258
+ diagnostics?.push({
259
+ code: 'PSL_EXTENSION_INVALID_VALUE',
260
+ message: `native_enum "${block.name}" member "${memberName}" value must be a string`,
261
+ sourceId,
262
+ span: paramValue.span,
263
+ });
264
+ memberError = true;
265
+ continue;
266
+ }
267
+ if (seenValues.has(jsonValue)) {
268
+ diagnostics?.push({
269
+ code: 'PSL_NATIVE_ENUM_DUPLICATE_MEMBER_VALUE',
270
+ message: `native_enum "${block.name}": duplicate member value "${jsonValue}"`,
271
+ sourceId,
272
+ span: paramValue.span,
273
+ });
274
+ memberError = true;
275
+ continue;
276
+ }
277
+ seenValues.add(jsonValue);
278
+ members.push(jsonValue);
279
+ }
280
+
281
+ if (memberError) return undefined;
282
+
283
+ if (members.length === 0) {
284
+ diagnostics?.push({
285
+ code: 'PSL_NATIVE_ENUM_MISSING_MEMBERS',
286
+ message: `native_enum "${block.name}" must have at least one member`,
287
+ sourceId,
288
+ span: block.span,
289
+ });
290
+ return undefined;
291
+ }
292
+
293
+ // `control` stays unset — the effective grade is resolved at read time via `effectiveControlPolicy`, like `StorageTable`/`StorageColumn`.
294
+ return new PostgresNativeEnum({ typeName, members });
295
+ }
296
+
297
+ /**
298
+ * `native_enum`'s entity-type factory output, checked separately from the assembled
299
+ * `postgresAuthoringEntityTypes` map below: `deriveValueSet` is SQL-family surface
300
+ * ({@link SqlValueSetDerivingEntityTypeOutput}), not part of the framework
301
+ * `AuthoringEntityTypeFactoryOutput` shape, so folding it directly into the map's single
302
+ * `satisfies AuthoringEntityTypeNamespace` check would trip an excess-property error. Checking it
303
+ * here against the intersection of both shapes keeps it structurally valid against each without
304
+ * widening the map's own check.
305
+ */
306
+ const nativeEnumEntityTypeOutput = {
307
+ factory: lowerNativeEnumFromBlock,
308
+ deriveValueSet: (entity: PostgresNativeEnum) => ({
309
+ kind: 'valueSet' as const,
310
+ values: [...entity.members],
311
+ }),
312
+ } satisfies AuthoringEntityTypeFactoryOutput<PslExtensionBlock, PostgresNativeEnum | undefined> &
313
+ SqlValueSetDerivingEntityTypeOutput;
9
314
 
10
- export const postgresAuthoringEntityTypes = {} as const satisfies AuthoringEntityTypeNamespace;
315
+ /**
316
+ * Lowers a `role <name> {}` block into a {@link PostgresRole}. Roles are
317
+ * cluster-scoped in Postgres, so the block must be declared inside
318
+ * `namespace unbound { … }` — any other lexical namespace (a named schema,
319
+ * or the default bucket top-level declarations resolve to) is a load-time
320
+ * diagnostic. The lowered entity carries the unbound coordinate.
321
+ */
322
+ function lowerRoleFromBlock(
323
+ block: RoleExtensionBlock,
324
+ ctx: AuthoringEntityContext,
325
+ ): PostgresRole | undefined {
326
+ if (block.namespaceId !== UNBOUND_NAMESPACE_ID) {
327
+ ctx.diagnostics?.push({
328
+ code: 'PSL_ROLE_BLOCK_OUTSIDE_UNBOUND_NAMESPACE',
329
+ message: `\`role\` block "${block.name}" must be declared inside \`namespace unbound { }\`, not in namespace "${block.namespaceId}"`,
330
+ sourceId: ctx.sourceId ?? 'unknown',
331
+ span: block.span,
332
+ });
333
+ return undefined;
334
+ }
335
+ return new PostgresRole({ name: block.name, namespaceId: UNBOUND_NAMESPACE_ID });
336
+ }
337
+
338
+ export const postgresAuthoringEntityTypes = {
339
+ role: {
340
+ kind: 'entity',
341
+ discriminator: 'role',
342
+ validatorSchema: PostgresRoleSchema,
343
+ output: {
344
+ factory: lowerRoleFromBlock,
345
+ },
346
+ },
347
+ rls: {
348
+ kind: 'entity',
349
+ discriminator: 'rls',
350
+ validatorSchema: PostgresRlsEnablementSchema,
351
+ output: {
352
+ factory: (input: PostgresRlsEnablementInput): PostgresRlsEnablement =>
353
+ new PostgresRlsEnablement(input),
354
+ },
355
+ },
356
+ policy: {
357
+ kind: 'entity',
358
+ discriminator: 'policy',
359
+ validatorSchema: PostgresRlsPolicySchema,
360
+ output: {
361
+ factory: lowerRlsPolicyFromBlock,
362
+ },
363
+ },
364
+ native_enum: {
365
+ kind: 'entity',
366
+ discriminator: 'native_enum',
367
+ validatorSchema: PostgresNativeEnumSchema,
368
+ output: nativeEnumEntityTypeOutput,
369
+ },
370
+ } as const satisfies AuthoringEntityTypeNamespace;
11
371
 
12
372
  /**
13
373
  * Field presets contributed by the Postgres target pack.
@@ -22,6 +382,153 @@ export const postgresAuthoringEntityTypes = {} as const satisfies AuthoringEntit
22
382
  * portability use `uuidString` / `id.uuidv4String` / `id.uuidv7String` from
23
383
  * the family pack instead.
24
384
  */
385
+ /**
386
+ * Shared parameter descriptors for the five `policy_<op>` PSL block
387
+ * keywords. All five share the `policy` discriminator — the parser
388
+ * dispatches by keyword (see the framework's PSL-block SPI), and every
389
+ * keyword's factory lowers to `PostgresRlsPolicy` via `lowerRlsPolicyFromBlock`.
390
+ *
391
+ * The `roles` list uses `scope:'cross-space'` because same-namespace
392
+ * role ref resolution requires PSL namespace entries keyed by `refKind`
393
+ * (i.e. `'role'`), which in turn requires the role block discriminator to
394
+ * equal `'role'`. Aligning discriminator with refKind is tracked for
395
+ * slice 4 (cross-space roles). Until then cross-space passes validation
396
+ * unconditionally and the authored role names flow through unchanged.
397
+ */
398
+ const policyTargetParam = {
399
+ kind: 'ref',
400
+ refKind: 'model',
401
+ scope: 'same-namespace',
402
+ required: true,
403
+ } as const;
404
+ const policyRolesParam = {
405
+ kind: 'list',
406
+ of: { kind: 'ref', refKind: 'role', scope: 'cross-space' },
407
+ } as const;
408
+ const policyPredicateParam = { kind: 'value', codecId: 'pg/text@1', required: true } as const;
409
+ // A policy may only target an RLS-controlled model: the model named by
410
+ // `target` must declare `@@rls`, or the load fails with a diagnostic naming
411
+ // the model and the policy prefix.
412
+ const policyRequiresRls = { parameter: 'target', attribute: 'rls' } as const;
413
+
414
+ export const postgresAuthoringPslBlockDescriptors = {
415
+ // The predicate param set per keyword mirrors Postgres: SELECT/DELETE take
416
+ // USING only; INSERT takes WITH CHECK only; UPDATE/ALL take both. The
417
+ // per-operation predicate matrix is enforced in `lowerRlsPolicyFromBlock`
418
+ // (a wrong predicate for the operation is a load-time diagnostic there),
419
+ // since the generic descriptor validator is not wired into the SQL-family
420
+ // interpreter.
421
+ policy_select: {
422
+ kind: 'pslBlock',
423
+ keyword: 'policy_select',
424
+ discriminator: 'policy',
425
+ name: { required: true },
426
+ parameters: { target: policyTargetParam, roles: policyRolesParam, using: policyPredicateParam },
427
+ requiresModelAttribute: policyRequiresRls,
428
+ },
429
+ policy_delete: {
430
+ kind: 'pslBlock',
431
+ keyword: 'policy_delete',
432
+ discriminator: 'policy',
433
+ name: { required: true },
434
+ parameters: { target: policyTargetParam, roles: policyRolesParam, using: policyPredicateParam },
435
+ requiresModelAttribute: policyRequiresRls,
436
+ },
437
+ policy_insert: {
438
+ kind: 'pslBlock',
439
+ keyword: 'policy_insert',
440
+ discriminator: 'policy',
441
+ name: { required: true },
442
+ parameters: {
443
+ target: policyTargetParam,
444
+ roles: policyRolesParam,
445
+ withCheck: policyPredicateParam,
446
+ },
447
+ requiresModelAttribute: policyRequiresRls,
448
+ },
449
+ policy_update: {
450
+ kind: 'pslBlock',
451
+ keyword: 'policy_update',
452
+ discriminator: 'policy',
453
+ name: { required: true },
454
+ parameters: {
455
+ target: policyTargetParam,
456
+ roles: policyRolesParam,
457
+ using: policyPredicateParam,
458
+ withCheck: policyPredicateParam,
459
+ },
460
+ requiresModelAttribute: policyRequiresRls,
461
+ },
462
+ policy_all: {
463
+ kind: 'pslBlock',
464
+ keyword: 'policy_all',
465
+ discriminator: 'policy',
466
+ name: { required: true },
467
+ parameters: {
468
+ target: policyTargetParam,
469
+ roles: policyRolesParam,
470
+ using: policyPredicateParam,
471
+ withCheck: policyPredicateParam,
472
+ },
473
+ requiresModelAttribute: policyRequiresRls,
474
+ },
475
+ /**
476
+ * PSL block descriptor for `native_enum`.
477
+ *
478
+ * Reuses the existing variadic-block mechanism (the same shape the SQL
479
+ * family's `enum` block ships): the body is an open `memberName = "value"`
480
+ * list. `variadicParameters: true` opens the block to arbitrary keys
481
+ * beyond the declared (empty) `parameters` set — the lowering factory
482
+ * (`lowerNativeEnumFromBlock`) turns the variadic entries into ordered
483
+ * members and rejects a bare (value-less) member.
484
+ */
485
+ native_enum: {
486
+ kind: 'pslBlock',
487
+ keyword: 'native_enum',
488
+ discriminator: 'native_enum',
489
+ name: { required: true },
490
+ parameters: {},
491
+ variadicParameters: true,
492
+ },
493
+ /**
494
+ * PSL block descriptor for `role` (e.g. `role anon {}`). Name-only, no
495
+ * parameters and no body content. Declared inside `namespace unbound { }`
496
+ * — see {@link lowerRoleFromBlock} for the placement check and the
497
+ * coordinate the lowered entity carries.
498
+ */
499
+ role: {
500
+ kind: 'pslBlock',
501
+ keyword: 'role',
502
+ discriminator: 'role',
503
+ name: { required: true },
504
+ parameters: {},
505
+ },
506
+ } as const satisfies AuthoringPslBlockDescriptorNamespace;
507
+
508
+ /**
509
+ * `@@` model attributes contributed by the Postgres target pack.
510
+ *
511
+ * `@@rls` is argument-less: presence marks the model's table
512
+ * RLS-controlled. It lowers to a {@link PostgresRlsEnablement} marker in
513
+ * the namespace's `entries.rls`, keyed by the model's table name — the
514
+ * marker (never the policy set) is what drives
515
+ * `ENABLE`/`DISABLE ROW LEVEL SECURITY` planning.
516
+ */
517
+ export const postgresAuthoringModelAttributes = {
518
+ rls: {
519
+ kind: 'modelAttribute',
520
+ attribute: 'rls',
521
+ spec: modelAttribute('rls', {}),
522
+ lower: (_parsed: Record<never, never>, ctx: AuthoringModelAttributeContext) => ({
523
+ key: ctx.storageName,
524
+ entity: new PostgresRlsEnablement({
525
+ tableName: ctx.storageName,
526
+ namespaceId: ctx.namespaceId,
527
+ }),
528
+ }),
529
+ },
530
+ } as const satisfies AuthoringModelAttributeDescriptorNamespace;
531
+
25
532
  export const postgresAuthoringFieldPresets = {
26
533
  text: {
27
534
  kind: 'fieldPreset',
@@ -71,30 +71,32 @@ export const pgNumericRenderOutputType = (typeParams: {
71
71
  return `Numeric<${precision}, ${scale}>`;
72
72
  };
73
73
 
74
- // ISO 8601 UTC: `YYYY-MM-DDTHH:MM:SS[.mmm…]Z`. Trailing `Z` is required; fractional seconds are optional. Other `Date`-parseable formats (`January 15, 2024`, `01/15/2024`, etc.) are intentionally rejected because those formats are implementation-defined and not the documented contract for `pg/timestamp@1` / `pg/timestamptz@1`.
75
- const ISO_8601_UTC = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{1,9})?Z$/;
74
+ const ISO_8601_TIMESTAMP = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{1,9})?$/;
75
+ const ISO_8601_TIMESTAMPTZ =
76
+ /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{1,9})?(?:Z|[+-]\d{2}:\d{2})$/;
76
77
 
77
- export const pgTimestampEncodeJson = (value: Date): JsonValue => value.toISOString();
78
+ export const pgTimestampEncodeJson = (value: Date): JsonValue => value.toISOString().slice(0, -1);
78
79
  export const pgTimestampDecodeJson = (json: JsonValue): Date => {
79
80
  if (typeof json !== 'string') {
80
81
  throw new Error(`Expected ISO date string for pg/timestamp@1, got ${typeof json}`);
81
82
  }
82
- if (!ISO_8601_UTC.test(json)) {
83
+ if (!ISO_8601_TIMESTAMP.test(json)) {
83
84
  throw new Error(`Invalid ISO date string for pg/timestamp@1: ${json}`);
84
85
  }
85
- const date = new Date(json);
86
+ const date = new Date(`${json}Z`);
86
87
  if (Number.isNaN(date.getTime())) {
87
88
  throw new Error(`Invalid ISO date string for pg/timestamp@1: ${json}`);
88
89
  }
89
90
  return date;
90
91
  };
91
92
 
92
- export const pgTimestamptzEncodeJson = (value: Date): JsonValue => value.toISOString();
93
+ export const pgTimestamptzEncodeJson = (value: Date): JsonValue =>
94
+ value.toISOString().replace(/Z$/, '+00:00');
93
95
  export const pgTimestamptzDecodeJson = (json: JsonValue): Date => {
94
96
  if (typeof json !== 'string') {
95
97
  throw new Error(`Expected ISO date string for pg/timestamptz@1, got ${typeof json}`);
96
98
  }
97
- if (!ISO_8601_UTC.test(json)) {
99
+ if (!ISO_8601_TIMESTAMPTZ.test(json)) {
98
100
  throw new Error(`Invalid ISO date string for pg/timestamptz@1: ${json}`);
99
101
  }
100
102
  const date = new Date(json);
@@ -109,6 +111,30 @@ export const pgIntervalDecode = (wire: string | Record<string, unknown>): string
109
111
  return JSON.stringify(wire);
110
112
  };
111
113
 
114
+ export const pgByteaEncodeJson = (value: Uint8Array): JsonValue =>
115
+ `\\x${Buffer.from(value).toString('hex')}`;
116
+
117
+ export const pgByteaDecodeJson = (value: JsonValue): Uint8Array => {
118
+ if (typeof value !== 'string' || !value.startsWith('\\x')) {
119
+ throw new Error(`Expected Postgres bytea hex text to start with "\\x"`);
120
+ }
121
+
122
+ const hex = value.slice(2);
123
+ if (hex.length % 2 !== 0) {
124
+ throw new Error(`Invalid Postgres bytea hex text length: ${hex.length}`);
125
+ }
126
+
127
+ const bytes = new Uint8Array(hex.length / 2);
128
+ for (let offset = 0; offset < hex.length; offset += 2) {
129
+ const pair = hex.slice(offset, offset + 2);
130
+ if (!/^[0-9a-fA-F]{2}$/.test(pair)) {
131
+ throw new Error(`Invalid Postgres bytea hex pair "${pair}" at offset ${offset}`);
132
+ }
133
+ bytes[offset / 2] = Number.parseInt(pair, 16);
134
+ }
135
+ return bytes;
136
+ };
137
+
112
138
  export const pgJsonEncode = (value: string | JsonValue): string => JSON.stringify(value);
113
139
  export const pgJsonDecode = (wire: string | JsonValue): JsonValue =>
114
140
  typeof wire === 'string' ? JSON.parse(wire) : wire;
@@ -8,6 +8,7 @@ export {
8
8
  } from '@prisma-next/sql-relational-core/ast';
9
9
  export const PG_TEXT_CODEC_ID = 'pg/text@1' as const;
10
10
  export const PG_TEXT_ARRAY_CODEC_ID = 'pg/text-array@1' as const;
11
+ export const PG_ENUM_CODEC_ID = 'pg/enum@1' as const;
11
12
  export const PG_CHAR_CODEC_ID = 'pg/char@1' as const;
12
13
  export const PG_VARCHAR_CODEC_ID = 'pg/varchar@1' as const;
13
14
  export const PG_INT_CODEC_ID = 'pg/int@1' as const;
@@ -21,6 +21,7 @@ import {
21
21
  pgBoolDescriptor,
22
22
  pgByteaDescriptor,
23
23
  pgCharDescriptor,
24
+ pgEnumDescriptor,
24
25
  pgFloat4Descriptor,
25
26
  pgFloat8Descriptor,
26
27
  pgFloatDescriptor,
@@ -50,6 +51,7 @@ export const codecDescriptorMap = {
50
51
  'sql-text': sqlTextDescriptor,
51
52
  'sql-timestamp': sqlTimestampDescriptor,
52
53
  text: pgTextDescriptor,
54
+ enum: pgEnumDescriptor,
53
55
  character: pgCharDescriptor,
54
56
  'character varying': pgVarcharDescriptor,
55
57
  integer: pgIntDescriptor,