@prisma-next/target-postgres 0.13.0-dev.3 → 0.13.0-dev.31

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 (175) hide show
  1. package/dist/{codec-ids-CTikp1if.mjs → codec-ids-BvytN2P8.mjs} +3 -3
  2. package/dist/codec-ids-BvytN2P8.mjs.map +1 -0
  3. package/dist/{codec-ids-B1vOchLE.d.mts → codec-ids-CnXu9Qy3.d.mts} +3 -3
  4. package/dist/codec-ids-CnXu9Qy3.d.mts.map +1 -0
  5. package/dist/codec-ids.d.mts +2 -2
  6. package/dist/codec-ids.mjs +2 -2
  7. package/dist/{codec-types-CnFiNML4.d.mts → codec-types-DHCkwPKE.d.mts} +3 -3
  8. package/dist/{codec-types-CnFiNML4.d.mts.map → codec-types-DHCkwPKE.d.mts.map} +1 -1
  9. package/dist/codec-types.d.mts +1 -1
  10. package/dist/{codecs-CBpEv4s5.d.mts → codecs--0A5_4Bq.d.mts} +26 -23
  11. package/dist/codecs--0A5_4Bq.d.mts.map +1 -0
  12. package/dist/codecs.d.mts +2 -2
  13. package/dist/codecs.mjs +28 -35
  14. package/dist/codecs.mjs.map +1 -1
  15. package/dist/contract-free.d.mts +17 -2
  16. package/dist/contract-free.d.mts.map +1 -1
  17. package/dist/contract-free.mjs +3 -3
  18. package/dist/control.d.mts.map +1 -1
  19. package/dist/control.mjs +21 -27
  20. package/dist/control.mjs.map +1 -1
  21. package/dist/{data-transform-D25tLeYU.mjs → data-transform-BOWpliq8.mjs} +9 -17
  22. package/dist/data-transform-BOWpliq8.mjs.map +1 -0
  23. package/dist/{data-transform-DGOqcLrf.d.mts → data-transform-DDgWdB5o.d.mts} +2 -2
  24. package/dist/data-transform-DDgWdB5o.d.mts.map +1 -0
  25. package/dist/data-transform.d.mts +1 -1
  26. package/dist/data-transform.mjs +1 -1
  27. package/dist/{ddl-77SyXgFt.mjs → ddl-DY2R_Yqz.mjs} +18 -3
  28. package/dist/ddl-DY2R_Yqz.mjs.map +1 -0
  29. package/dist/ddl.d.mts +2 -2
  30. package/dist/ddl.mjs +2 -2
  31. package/dist/{descriptor-meta-DKmj-IMN.mjs → descriptor-meta-BKma_hQ5.mjs} +2 -2
  32. package/dist/{descriptor-meta-DKmj-IMN.mjs.map → descriptor-meta-BKma_hQ5.mjs.map} +1 -1
  33. package/dist/descriptor-meta-runtime-e5f2tscJ.mjs +131 -0
  34. package/dist/descriptor-meta-runtime-e5f2tscJ.mjs.map +1 -0
  35. package/dist/{issue-planner-Br0pt1Ea.mjs → issue-planner-DsjB7xDj.mjs} +48 -252
  36. package/dist/issue-planner-DsjB7xDj.mjs.map +1 -0
  37. package/dist/issue-planner.d.mts +8 -11
  38. package/dist/issue-planner.d.mts.map +1 -1
  39. package/dist/issue-planner.mjs +1 -1
  40. package/dist/migration.d.mts +4 -15
  41. package/dist/migration.d.mts.map +1 -1
  42. package/dist/migration.mjs +4 -4
  43. package/dist/{nodes-DZk2JZG3.mjs → nodes-Bbhs2rwj.mjs} +31 -2
  44. package/dist/nodes-Bbhs2rwj.mjs.map +1 -0
  45. package/dist/{nodes-779hmCfL.d.mts → nodes-pLeLgdis.d.mts} +30 -3
  46. package/dist/nodes-pLeLgdis.d.mts.map +1 -0
  47. package/dist/{op-factory-call-DMA86_2D.d.mts → op-factory-call-CdtMyrlU.d.mts} +12 -56
  48. package/dist/op-factory-call-CdtMyrlU.d.mts.map +1 -0
  49. package/dist/{op-factory-call-D2aAUhmS.mjs → op-factory-call-CjR846f7.mjs} +70 -198
  50. package/dist/op-factory-call-CjR846f7.mjs.map +1 -0
  51. package/dist/op-factory-call.d.mts +2 -2
  52. package/dist/op-factory-call.mjs +2 -2
  53. package/dist/pack.d.mts +36 -15
  54. package/dist/pack.d.mts.map +1 -1
  55. package/dist/pack.mjs +1 -1
  56. package/dist/{planner-CAYPJObw.mjs → planner-_FOL4I21.mjs} +25 -45
  57. package/dist/planner-_FOL4I21.mjs.map +1 -0
  58. package/dist/{planner-ddl-builders-Cw2n2llW.mjs → planner-ddl-builders-B2wOwLqI.mjs} +2 -2
  59. package/dist/planner-ddl-builders-B2wOwLqI.mjs.map +1 -0
  60. package/dist/planner-ddl-builders.d.mts +4 -4
  61. package/dist/planner-ddl-builders.d.mts.map +1 -1
  62. package/dist/planner-ddl-builders.mjs +1 -1
  63. package/dist/{planner-identity-values-BIpa5p2I.mjs → planner-identity-values-CJPha2Sz.mjs} +3 -9
  64. package/dist/planner-identity-values-CJPha2Sz.mjs.map +1 -0
  65. package/dist/planner-identity-values.d.mts +1 -1
  66. package/dist/planner-identity-values.d.mts.map +1 -1
  67. package/dist/planner-identity-values.mjs +1 -1
  68. package/dist/{planner-produced-postgres-migration-NSEhWL0L.mjs → planner-produced-postgres-migration-BmCpyWLJ.mjs} +6 -4
  69. package/dist/planner-produced-postgres-migration-BmCpyWLJ.mjs.map +1 -0
  70. package/dist/{planner-produced-postgres-migration-B4EDvLdz.d.mts → planner-produced-postgres-migration-wLhnJMMA.d.mts} +5 -6
  71. package/dist/planner-produced-postgres-migration-wLhnJMMA.d.mts.map +1 -0
  72. package/dist/planner-produced-postgres-migration.d.mts +1 -1
  73. package/dist/planner-produced-postgres-migration.mjs +1 -1
  74. package/dist/{planner-sql-checks-DAdhnI2c.mjs → planner-sql-checks-CJJtPfDH.mjs} +3 -3
  75. package/dist/planner-sql-checks-CJJtPfDH.mjs.map +1 -0
  76. package/dist/planner-sql-checks.d.mts +2 -2
  77. package/dist/planner-sql-checks.d.mts.map +1 -1
  78. package/dist/planner-sql-checks.mjs +1 -1
  79. package/dist/{planner-type-resolution-836DExFN.mjs → planner-type-resolution-Bt2f_q-F.mjs} +1 -6
  80. package/dist/planner-type-resolution-Bt2f_q-F.mjs.map +1 -0
  81. package/dist/planner.d.mts +4 -4
  82. package/dist/planner.d.mts.map +1 -1
  83. package/dist/planner.mjs +1 -1
  84. package/dist/{postgres-contract-serializer-DYTyXjPf.mjs → postgres-contract-serializer-CyAe8ZFv.mjs} +27 -37
  85. package/dist/postgres-contract-serializer-CyAe8ZFv.mjs.map +1 -0
  86. package/dist/{postgres-migration-DZ_gLUOW.d.mts → postgres-migration-DLXL0GBf.d.mts} +10 -5
  87. package/dist/postgres-migration-DLXL0GBf.d.mts.map +1 -0
  88. package/dist/{postgres-migration-COore9Mz.mjs → postgres-migration-dG-J0aI8.mjs} +7 -3
  89. package/dist/postgres-migration-dG-J0aI8.mjs.map +1 -0
  90. package/dist/{postgres-schema-BuxCxbvB.mjs → postgres-schema-CTKYiTHu.mjs} +30 -13
  91. package/dist/postgres-schema-CTKYiTHu.mjs.map +1 -0
  92. package/dist/{render-ops-BpjstrKQ.mjs → render-ops-BREh1kHe.mjs} +10 -5
  93. package/dist/render-ops-BREh1kHe.mjs.map +1 -0
  94. package/dist/render-ops.d.mts +2 -2
  95. package/dist/render-ops.d.mts.map +1 -1
  96. package/dist/render-ops.mjs +1 -1
  97. package/dist/runtime.d.mts.map +1 -1
  98. package/dist/runtime.mjs +2 -2
  99. package/dist/{shared-DarONYBZ.d.mts → shared-jcsbXxiW.d.mts} +2 -20
  100. package/dist/shared-jcsbXxiW.d.mts.map +1 -0
  101. package/dist/types.d.mts +8 -13
  102. package/dist/types.d.mts.map +1 -1
  103. package/dist/types.mjs +2 -3
  104. package/package.json +17 -18
  105. package/src/contract-free/ddl.ts +28 -1
  106. package/src/core/authoring.ts +43 -44
  107. package/src/core/codec-helpers.ts +0 -17
  108. package/src/core/codec-ids.ts +1 -1
  109. package/src/core/codec-type-map.ts +2 -2
  110. package/src/core/codecs.ts +43 -48
  111. package/src/core/ddl/nodes.ts +59 -1
  112. package/src/core/migrations/control-policy.ts +17 -47
  113. package/src/core/migrations/issue-planner.ts +34 -70
  114. package/src/core/migrations/op-factory-call.ts +89 -142
  115. package/src/core/migrations/operations/data-transform.ts +15 -18
  116. package/src/core/migrations/planner-ddl-builders.ts +3 -4
  117. package/src/core/migrations/planner-identity-values.ts +4 -28
  118. package/src/core/migrations/planner-produced-postgres-migration.ts +15 -7
  119. package/src/core/migrations/planner-recipes.ts +2 -6
  120. package/src/core/migrations/planner-sql-checks.ts +2 -6
  121. package/src/core/migrations/planner-strategies.ts +51 -376
  122. package/src/core/migrations/planner-type-resolution.ts +2 -20
  123. package/src/core/migrations/planner.ts +6 -6
  124. package/src/core/migrations/postgres-migration.ts +19 -4
  125. package/src/core/migrations/render-ops.ts +26 -13
  126. package/src/core/migrations/runner.ts +26 -20
  127. package/src/core/postgres-contract-serializer.ts +32 -54
  128. package/src/core/postgres-enum-type-schema.ts +17 -0
  129. package/src/core/postgres-schema.ts +56 -34
  130. package/src/exports/codecs.ts +2 -2
  131. package/src/exports/contract-free.ts +1 -1
  132. package/src/exports/control.ts +0 -22
  133. package/src/exports/ddl.ts +4 -0
  134. package/src/exports/migration.ts +0 -7
  135. package/src/exports/op-factory-call.ts +0 -4
  136. package/src/exports/types.ts +0 -1
  137. package/dist/codec-ids-B1vOchLE.d.mts.map +0 -1
  138. package/dist/codec-ids-CTikp1if.mjs.map +0 -1
  139. package/dist/codecs-CBpEv4s5.d.mts.map +0 -1
  140. package/dist/data-transform-D25tLeYU.mjs.map +0 -1
  141. package/dist/data-transform-DGOqcLrf.d.mts.map +0 -1
  142. package/dist/ddl-77SyXgFt.mjs.map +0 -1
  143. package/dist/descriptor-meta-runtime-My8_s4cs.mjs +0 -130
  144. package/dist/descriptor-meta-runtime-My8_s4cs.mjs.map +0 -1
  145. package/dist/enum-planning-BCyvlFHk.mjs +0 -0
  146. package/dist/enum-planning-BCyvlFHk.mjs.map +0 -1
  147. package/dist/enum-planning.d.mts +0 -86
  148. package/dist/enum-planning.d.mts.map +0 -1
  149. package/dist/enum-planning.mjs +0 -2
  150. package/dist/issue-planner-Br0pt1Ea.mjs.map +0 -1
  151. package/dist/nodes-779hmCfL.d.mts.map +0 -1
  152. package/dist/nodes-DZk2JZG3.mjs.map +0 -1
  153. package/dist/op-factory-call-D2aAUhmS.mjs.map +0 -1
  154. package/dist/op-factory-call-DMA86_2D.d.mts.map +0 -1
  155. package/dist/planner-CAYPJObw.mjs.map +0 -1
  156. package/dist/planner-ddl-builders-Cw2n2llW.mjs.map +0 -1
  157. package/dist/planner-identity-values-BIpa5p2I.mjs.map +0 -1
  158. package/dist/planner-produced-postgres-migration-B4EDvLdz.d.mts.map +0 -1
  159. package/dist/planner-produced-postgres-migration-NSEhWL0L.mjs.map +0 -1
  160. package/dist/planner-sql-checks-DAdhnI2c.mjs.map +0 -1
  161. package/dist/planner-type-resolution-836DExFN.mjs.map +0 -1
  162. package/dist/postgres-contract-serializer-DYTyXjPf.mjs.map +0 -1
  163. package/dist/postgres-enum-type-BVn63a89.d.mts +0 -72
  164. package/dist/postgres-enum-type-BVn63a89.d.mts.map +0 -1
  165. package/dist/postgres-enum-type-DPKqCBem.mjs +0 -62
  166. package/dist/postgres-enum-type-DPKqCBem.mjs.map +0 -1
  167. package/dist/postgres-migration-COore9Mz.mjs.map +0 -1
  168. package/dist/postgres-migration-DZ_gLUOW.d.mts.map +0 -1
  169. package/dist/postgres-schema-BuxCxbvB.mjs.map +0 -1
  170. package/dist/render-ops-BpjstrKQ.mjs.map +0 -1
  171. package/dist/shared-DarONYBZ.d.mts.map +0 -1
  172. package/src/core/migrations/enum-planning.ts +0 -213
  173. package/src/core/migrations/operations/enums.ts +0 -114
  174. package/src/core/postgres-enum-type.ts +0 -89
  175. package/src/exports/enum-planning.ts +0 -11
package/package.json CHANGED
@@ -1,32 +1,32 @@
1
1
  {
2
2
  "name": "@prisma-next/target-postgres",
3
- "version": "0.13.0-dev.3",
3
+ "version": "0.13.0-dev.31",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "sideEffects": false,
7
7
  "description": "Postgres target pack for Prisma Next",
8
8
  "dependencies": {
9
- "@prisma-next/cli": "0.13.0-dev.3",
10
- "@prisma-next/contract": "0.13.0-dev.3",
11
- "@prisma-next/errors": "0.13.0-dev.3",
12
- "@prisma-next/family-sql": "0.13.0-dev.3",
13
- "@prisma-next/framework-components": "0.13.0-dev.3",
14
- "@prisma-next/migration-tools": "0.13.0-dev.3",
15
- "@prisma-next/ts-render": "0.13.0-dev.3",
16
- "@prisma-next/sql-contract": "0.13.0-dev.3",
17
- "@prisma-next/sql-errors": "0.13.0-dev.3",
18
- "@prisma-next/sql-operations": "0.13.0-dev.3",
19
- "@prisma-next/sql-relational-core": "0.13.0-dev.3",
20
- "@prisma-next/sql-schema-ir": "0.13.0-dev.3",
21
- "@prisma-next/utils": "0.13.0-dev.3",
9
+ "@prisma-next/cli": "0.13.0-dev.31",
10
+ "@prisma-next/contract": "0.13.0-dev.31",
11
+ "@prisma-next/errors": "0.13.0-dev.31",
12
+ "@prisma-next/family-sql": "0.13.0-dev.31",
13
+ "@prisma-next/framework-components": "0.13.0-dev.31",
14
+ "@prisma-next/migration-tools": "0.13.0-dev.31",
15
+ "@prisma-next/ts-render": "0.13.0-dev.31",
16
+ "@prisma-next/sql-contract": "0.13.0-dev.31",
17
+ "@prisma-next/sql-errors": "0.13.0-dev.31",
18
+ "@prisma-next/sql-operations": "0.13.0-dev.31",
19
+ "@prisma-next/sql-relational-core": "0.13.0-dev.31",
20
+ "@prisma-next/sql-schema-ir": "0.13.0-dev.31",
21
+ "@prisma-next/utils": "0.13.0-dev.31",
22
22
  "@standard-schema/spec": "^1.1.0",
23
23
  "arktype": "^2.2.0",
24
24
  "pathe": "^2.0.3"
25
25
  },
26
26
  "devDependencies": {
27
- "@prisma-next/test-utils": "0.13.0-dev.3",
28
- "@prisma-next/tsconfig": "0.13.0-dev.3",
29
- "@prisma-next/tsdown": "0.13.0-dev.3",
27
+ "@prisma-next/test-utils": "0.13.0-dev.31",
28
+ "@prisma-next/tsconfig": "0.13.0-dev.31",
29
+ "@prisma-next/tsdown": "0.13.0-dev.31",
30
30
  "tsdown": "0.22.1",
31
31
  "typescript": "5.9.3",
32
32
  "vitest": "4.1.8"
@@ -53,7 +53,6 @@
53
53
  "./data-transform": "./dist/data-transform.mjs",
54
54
  "./ddl": "./dist/ddl.mjs",
55
55
  "./default-normalizer": "./dist/default-normalizer.mjs",
56
- "./enum-planning": "./dist/enum-planning.mjs",
57
56
  "./errors": "./dist/errors.mjs",
58
57
  "./issue-planner": "./dist/issue-planner.mjs",
59
58
  "./migration": "./dist/migration.mjs",
@@ -1,5 +1,11 @@
1
1
  import type { DdlColumn, DdlTableConstraint } from '@prisma-next/sql-relational-core/ast';
2
- import { PostgresCreateSchema, PostgresCreateTable } from '../core/ddl/nodes';
2
+ import {
3
+ AddColumnAction,
4
+ type AnyAlterTableAction,
5
+ PostgresAlterTable,
6
+ PostgresCreateSchema,
7
+ PostgresCreateTable,
8
+ } from '../core/ddl/nodes';
3
9
 
4
10
  /**
5
11
  * Build a Postgres `CREATE TABLE` query node.
@@ -35,3 +41,24 @@ export function createSchema(options: {
35
41
  }): PostgresCreateSchema {
36
42
  return new PostgresCreateSchema(options);
37
43
  }
44
+
45
+ /**
46
+ * Build an `ADD COLUMN` action for use inside {@link alterTable}.
47
+ * The column is a structured `DdlColumn` so codec-encoded defaults flow
48
+ * through the adapter's `pgRenderDdlColumn` → `pgRenderDdlColumnDefault` path.
49
+ */
50
+ export function addColumnAction(column: DdlColumn): AddColumnAction {
51
+ return new AddColumnAction(column);
52
+ }
53
+
54
+ /**
55
+ * Build a Postgres `ALTER TABLE` query node carrying one or more actions.
56
+ * See {@link addColumnAction} for building actions.
57
+ */
58
+ export function alterTable(options: {
59
+ readonly table: string;
60
+ readonly schema?: string;
61
+ readonly actions: readonly AnyAlterTableAction[];
62
+ }): PostgresAlterTable {
63
+ return new PostgresAlterTable(options);
64
+ }
@@ -4,53 +4,10 @@ import type {
4
4
  AuthoringFieldNamespace,
5
5
  AuthoringTypeNamespace,
6
6
  } from '@prisma-next/framework-components/authoring';
7
- import type { PostgresEnumStorageEntry } from '@prisma-next/sql-contract/types';
8
- import { PostgresEnumTypeSchema } from '@prisma-next/sql-contract/validators';
9
- import { PostgresEnumType, type PostgresEnumTypeInput } from './postgres-enum-type';
10
7
 
11
8
  export const postgresAuthoringTypes = {} as const satisfies AuthoringTypeNamespace;
12
9
 
13
- /**
14
- * Entity type contributions surface as top-level helpers on the
15
- * composed-helpers shape (e.g. `helpers.enum({...})`), flattened
16
- * alongside the built-in `model` / `rel` helpers. Pack contributions
17
- * still ship via the contribution data structure
18
- * `authoring.entityTypes.<name>`; the composed-helpers template
19
- * performs the rename in the type system.
20
- *
21
- * `enum` is the first real consumer of the entities-namespace mechanism:
22
- * the factory constructs a `PostgresEnumType` IR-class instance from
23
- * the user-supplied input. Both authoring runtimes (TS DSL and PSL)
24
- * dispatch through this single contribution — PSL `enum Status { … }`
25
- * declarations are lowered by the interpreter into a factory call
26
- * with the parsed name + value list; TS DSL `helpers.enum({...})`
27
- * resolves through the same path. Removing this contribution makes
28
- * both surfaces fail with a "no entity helper named `enum`" type
29
- * error at the contract-definition site.
30
- */
31
- /**
32
- * The factory constructs a `PostgresEnumType` instance natively — the
33
- * `SqlStorage.types` slot accepts polymorphic IR (the framework
34
- * `StorageType` alphabet), so no cast is needed at the contribution
35
- * surface. The declared return type is the structural
36
- * `PostgresEnumStorageEntry` so the inferred contract type stays
37
- * portable (it names a type exported from
38
- * `@prisma-next/sql-contract/types`, a public surface every consumer
39
- * already imports). Sharpening the inferred contract type to surface
40
- * enum-specific narrowing through `EntityHelperFunction` is a
41
- * separable refinement and lives outside this PR.
42
- */
43
- export const postgresAuthoringEntityTypes = {
44
- enum: {
45
- kind: 'entity',
46
- discriminator: 'postgres-enum',
47
- validatorSchema: PostgresEnumTypeSchema,
48
- output: {
49
- factory: (input: PostgresEnumTypeInput): PostgresEnumStorageEntry =>
50
- new PostgresEnumType(input),
51
- },
52
- },
53
- } as const satisfies AuthoringEntityTypeNamespace;
10
+ export const postgresAuthoringEntityTypes = {} as const satisfies AuthoringEntityTypeNamespace;
54
11
 
55
12
  /**
56
13
  * Field presets contributed by the Postgres target pack.
@@ -59,6 +16,11 @@ export const postgresAuthoringEntityTypes = {
59
16
  * (see `createPostgresPslScalarTypeDescriptors`), so that authoring a field
60
17
  * via the TS callback surface (e.g. `field.int()`) and via the PSL scalar
61
18
  * surface (e.g. `Int`) lowers to byte-identical contracts.
19
+ *
20
+ * The `uuidNative` / `id.uuidv4Native` / `id.uuidv7Native` presets use the
21
+ * native Postgres `uuid` type (codecId `pg/uuid@1`). For cross-target
22
+ * portability use `uuidString` / `id.uuidv4String` / `id.uuidv7String` from
23
+ * the family pack instead.
62
24
  */
63
25
  export const postgresAuthoringFieldPresets = {
64
26
  text: {
@@ -128,4 +90,41 @@ export const postgresAuthoringFieldPresets = {
128
90
  codecId: 'pg/timestamptz@1',
129
91
  nativeType: 'timestamptz',
130
92
  }),
93
+ uuidNative: {
94
+ kind: 'fieldPreset',
95
+ output: {
96
+ codecId: 'pg/uuid@1',
97
+ nativeType: 'uuid',
98
+ },
99
+ },
100
+ id: {
101
+ uuidv4Native: {
102
+ kind: 'fieldPreset',
103
+ output: {
104
+ codecId: 'pg/uuid@1',
105
+ nativeType: 'uuid',
106
+ executionDefaults: {
107
+ onCreate: {
108
+ kind: 'generator',
109
+ id: 'uuidv4',
110
+ },
111
+ },
112
+ id: true,
113
+ },
114
+ },
115
+ uuidv7Native: {
116
+ kind: 'fieldPreset',
117
+ output: {
118
+ codecId: 'pg/uuid@1',
119
+ nativeType: 'uuid',
120
+ executionDefaults: {
121
+ onCreate: {
122
+ kind: 'generator',
123
+ id: 'uuidv7',
124
+ },
125
+ },
126
+ id: true,
127
+ },
128
+ },
129
+ },
131
130
  } as const satisfies AuthoringFieldNamespace;
@@ -109,23 +109,6 @@ export const pgIntervalDecode = (wire: string | Record<string, unknown>): string
109
109
  return JSON.stringify(wire);
110
110
  };
111
111
 
112
- export const pgEnumRenderOutputType = (typeParams: {
113
- readonly values?: readonly unknown[];
114
- }): string => {
115
- const values = typeParams.values;
116
- if (!Array.isArray(values)) {
117
- throw new Error(
118
- `renderOutputType: expected array "values" in typeParams for enum, got ${typeof values}`,
119
- );
120
- }
121
- if (!values.every((v): v is string => typeof v === 'string')) {
122
- throw new Error(`renderOutputType: expected string[] "values" in typeParams for enum`);
123
- }
124
- return values
125
- .map((value) => `'${value.replace(/\\/g, '\\\\').replace(/'/g, "\\'")}'`)
126
- .join(' | ');
127
- };
128
-
129
112
  export const pgJsonEncode = (value: string | JsonValue): string => JSON.stringify(value);
130
113
  export const pgJsonDecode = (wire: string | JsonValue): JsonValue =>
131
114
  typeof wire === 'string' ? JSON.parse(wire) : wire;
@@ -8,7 +8,6 @@ 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;
12
11
  export const PG_CHAR_CODEC_ID = 'pg/char@1' as const;
13
12
  export const PG_VARCHAR_CODEC_ID = 'pg/varchar@1' as const;
14
13
  export const PG_INT_CODEC_ID = 'pg/int@1' as const;
@@ -30,3 +29,4 @@ export const PG_INTERVAL_CODEC_ID = 'pg/interval@1' as const;
30
29
  export const PG_JSON_CODEC_ID = 'pg/json@1' as const;
31
30
  export const PG_JSONB_CODEC_ID = 'pg/jsonb@1' as const;
32
31
  export const PG_BYTEA_CODEC_ID = 'pg/bytea@1' as const;
32
+ export const PG_UUID_CODEC_ID = 'pg/uuid@1' as const;
@@ -21,7 +21,6 @@ import {
21
21
  pgBoolDescriptor,
22
22
  pgByteaDescriptor,
23
23
  pgCharDescriptor,
24
- pgEnumDescriptor,
25
24
  pgFloat4Descriptor,
26
25
  pgFloat8Descriptor,
27
26
  pgFloatDescriptor,
@@ -38,6 +37,7 @@ import {
38
37
  pgTimestampDescriptor,
39
38
  pgTimestamptzDescriptor,
40
39
  pgTimetzDescriptor,
40
+ pgUuidDescriptor,
41
41
  pgVarbitDescriptor,
42
42
  pgVarcharDescriptor,
43
43
  } from './codecs';
@@ -68,8 +68,8 @@ export const codecDescriptorMap = {
68
68
  bit: pgBitDescriptor,
69
69
  'bit varying': pgVarbitDescriptor,
70
70
  bytea: pgByteaDescriptor,
71
+ uuid: pgUuidDescriptor,
71
72
  interval: pgIntervalDescriptor,
72
- enum: pgEnumDescriptor,
73
73
  json: pgJsonDescriptor,
74
74
  jsonb: pgJsonbDescriptor,
75
75
  } as const;
@@ -36,10 +36,10 @@ import {
36
36
  sqlTimestampDescriptor,
37
37
  sqlVarcharDescriptor,
38
38
  } from '@prisma-next/sql-relational-core/ast';
39
+ import { blindCast } from '@prisma-next/utils/casts';
39
40
  import type { StandardSchemaV1 } from '@standard-schema/spec';
40
41
  import { type as arktype } from 'arktype';
41
42
  import {
42
- pgEnumRenderOutputType,
43
43
  pgIntervalDecode,
44
44
  pgJsonbDecode,
45
45
  pgJsonbEncode,
@@ -59,7 +59,6 @@ import {
59
59
  PG_BOOL_CODEC_ID,
60
60
  PG_BYTEA_CODEC_ID,
61
61
  PG_CHAR_CODEC_ID,
62
- PG_ENUM_CODEC_ID,
63
62
  PG_FLOAT_CODEC_ID,
64
63
  PG_FLOAT4_CODEC_ID,
65
64
  PG_FLOAT8_CODEC_ID,
@@ -77,6 +76,7 @@ import {
77
76
  PG_TIMESTAMP_CODEC_ID,
78
77
  PG_TIMESTAMPTZ_CODEC_ID,
79
78
  PG_TIMETZ_CODEC_ID,
79
+ PG_UUID_CODEC_ID,
80
80
  PG_VARBIT_CODEC_ID,
81
81
  PG_VARCHAR_CODEC_ID,
82
82
  } from './codec-ids';
@@ -84,7 +84,6 @@ import {
84
84
  type LengthParams = { readonly length?: number };
85
85
  type PrecisionParams = { readonly precision?: number };
86
86
  type NumericParams = { readonly precision: number; readonly scale?: number };
87
- type EnumParams = { readonly values?: readonly string[] };
88
87
 
89
88
  const lengthParamsSchema = arktype({
90
89
  'length?': 'number.integer > 0',
@@ -789,64 +788,58 @@ export const pgByteaColumn = () =>
789
788
  pgByteaColumn satisfies ColumnHelperFor<PgByteaDescriptor>;
790
789
  pgByteaColumn satisfies ColumnHelperForStrict<PgByteaDescriptor>;
791
790
 
792
- export class PgIntervalCodec extends CodecImpl<
793
- typeof PG_INTERVAL_CODEC_ID,
791
+ const PG_UUID_META = { db: { sql: { postgres: { nativeType: 'uuid' } } } } as const;
792
+
793
+ export class PgUuidCodec extends CodecImpl<
794
+ typeof PG_UUID_CODEC_ID,
794
795
  readonly ['equality', 'order'],
795
- string | Record<string, unknown>,
796
+ string,
796
797
  string
797
798
  > {
798
799
  async encode(value: string, _ctx: CodecCallContext): Promise<string> {
799
800
  return value;
800
801
  }
801
- async decode(wire: string | Record<string, unknown>, _ctx: CodecCallContext): Promise<string> {
802
- return pgIntervalDecode(wire);
802
+ async decode(wire: string, _ctx: CodecCallContext): Promise<string> {
803
+ return wire;
803
804
  }
804
805
  encodeJson(value: string): JsonValue {
805
806
  return value;
806
807
  }
807
808
  decodeJson(json: JsonValue): string {
808
- return json as string;
809
+ return blindCast<string, 'uuid columns serialize to JSON as their wire string form'>(json);
809
810
  }
810
811
  }
811
812
 
812
- export class PgIntervalDescriptor extends CodecDescriptorImpl<PrecisionParams> {
813
- override readonly codecId = PG_INTERVAL_CODEC_ID;
813
+ export class PgUuidDescriptor extends CodecDescriptorImpl<void> {
814
+ override readonly codecId = PG_UUID_CODEC_ID;
814
815
  override readonly traits = ['equality', 'order'] as const;
815
- override readonly targetTypes = ['interval'] as const;
816
- override readonly meta = PG_INTERVAL_META;
817
- override readonly paramsSchema =
818
- precisionParamsSchema satisfies StandardSchemaV1<PrecisionParams>;
819
- override renderOutputType(params: PrecisionParams): string | undefined {
820
- return renderPrecision('Interval', params as Record<string, unknown>);
821
- }
822
- override factory(_params: PrecisionParams): (ctx: CodecInstanceContext) => PgIntervalCodec {
823
- return () => new PgIntervalCodec(this);
816
+ override readonly targetTypes = ['uuid'] as const;
817
+ override readonly meta = PG_UUID_META;
818
+ override readonly paramsSchema: StandardSchemaV1<void> = voidParamsSchema;
819
+ override factory(): (ctx: CodecInstanceContext) => PgUuidCodec {
820
+ return () => new PgUuidCodec(this);
824
821
  }
825
822
  }
826
823
 
827
- export const pgIntervalDescriptor = new PgIntervalDescriptor();
824
+ export const pgUuidDescriptor = new PgUuidDescriptor();
828
825
 
829
- export const pgIntervalColumn = (params: PrecisionParams = {}) =>
830
- column(pgIntervalDescriptor.factory(params), pgIntervalDescriptor.codecId, params, 'interval');
826
+ export const pgUuidColumn = () =>
827
+ column(pgUuidDescriptor.factory(), pgUuidDescriptor.codecId, undefined, 'uuid');
831
828
 
832
- pgIntervalColumn satisfies ColumnHelperFor<PgIntervalDescriptor>;
833
- pgIntervalColumn satisfies ColumnHelperForStrict<PgIntervalDescriptor>;
834
-
835
- const enumParamsSchema = arktype({
836
- 'values?': 'string[]',
837
- });
829
+ pgUuidColumn satisfies ColumnHelperFor<PgUuidDescriptor>;
830
+ pgUuidColumn satisfies ColumnHelperForStrict<PgUuidDescriptor>;
838
831
 
839
- export class PgEnumCodec extends CodecImpl<
840
- typeof PG_ENUM_CODEC_ID,
832
+ export class PgIntervalCodec extends CodecImpl<
833
+ typeof PG_INTERVAL_CODEC_ID,
841
834
  readonly ['equality', 'order'],
842
- string,
835
+ string | Record<string, unknown>,
843
836
  string
844
837
  > {
845
838
  async encode(value: string, _ctx: CodecCallContext): Promise<string> {
846
839
  return value;
847
840
  }
848
- async decode(wire: string, _ctx: CodecCallContext): Promise<string> {
849
- return wire;
841
+ async decode(wire: string | Record<string, unknown>, _ctx: CodecCallContext): Promise<string> {
842
+ return pgIntervalDecode(wire);
850
843
  }
851
844
  encodeJson(value: string): JsonValue {
852
845
  return value;
@@ -856,26 +849,28 @@ export class PgEnumCodec extends CodecImpl<
856
849
  }
857
850
  }
858
851
 
859
- export class PgEnumDescriptor extends CodecDescriptorImpl<EnumParams> {
860
- override readonly codecId = PG_ENUM_CODEC_ID;
852
+ export class PgIntervalDescriptor extends CodecDescriptorImpl<PrecisionParams> {
853
+ override readonly codecId = PG_INTERVAL_CODEC_ID;
861
854
  override readonly traits = ['equality', 'order'] as const;
862
- override readonly targetTypes = ['enum'] as const;
863
- override readonly paramsSchema = enumParamsSchema satisfies StandardSchemaV1<EnumParams>;
864
- override renderOutputType(params: EnumParams): string | undefined {
865
- return pgEnumRenderOutputType(params);
855
+ override readonly targetTypes = ['interval'] as const;
856
+ override readonly meta = PG_INTERVAL_META;
857
+ override readonly paramsSchema =
858
+ precisionParamsSchema satisfies StandardSchemaV1<PrecisionParams>;
859
+ override renderOutputType(params: PrecisionParams): string | undefined {
860
+ return renderPrecision('Interval', params as Record<string, unknown>);
866
861
  }
867
- override factory(_params: EnumParams): (ctx: CodecInstanceContext) => PgEnumCodec {
868
- return () => new PgEnumCodec(this);
862
+ override factory(_params: PrecisionParams): (ctx: CodecInstanceContext) => PgIntervalCodec {
863
+ return () => new PgIntervalCodec(this);
869
864
  }
870
865
  }
871
866
 
872
- export const pgEnumDescriptor = new PgEnumDescriptor();
867
+ export const pgIntervalDescriptor = new PgIntervalDescriptor();
873
868
 
874
- export const pgEnumColumn = (params: EnumParams = {}) =>
875
- column(pgEnumDescriptor.factory(params), pgEnumDescriptor.codecId, params, 'enum');
869
+ export const pgIntervalColumn = (params: PrecisionParams = {}) =>
870
+ column(pgIntervalDescriptor.factory(params), pgIntervalDescriptor.codecId, params, 'interval');
876
871
 
877
- pgEnumColumn satisfies ColumnHelperFor<PgEnumDescriptor>;
878
- pgEnumColumn satisfies ColumnHelperForStrict<PgEnumDescriptor>;
872
+ pgIntervalColumn satisfies ColumnHelperFor<PgIntervalDescriptor>;
873
+ pgIntervalColumn satisfies ColumnHelperForStrict<PgIntervalDescriptor>;
879
874
 
880
875
  export class PgJsonCodec extends CodecImpl<
881
876
  typeof PG_JSON_CODEC_ID,
@@ -1075,8 +1070,8 @@ export const codecDescriptors: readonly AnyCodecDescriptor[] = [
1075
1070
  pgBitDescriptor,
1076
1071
  pgVarbitDescriptor,
1077
1072
  pgByteaDescriptor,
1073
+ pgUuidDescriptor,
1078
1074
  pgIntervalDescriptor,
1079
- pgEnumDescriptor,
1080
1075
  pgJsonDescriptor,
1081
1076
  pgJsonbDescriptor,
1082
1077
  pgTextArrayDescriptor,
@@ -4,9 +4,44 @@ import {
4
4
  type DdlTableConstraint,
5
5
  } from '@prisma-next/sql-relational-core/ast';
6
6
 
7
+ // ---------------------------------------------------------------------------
8
+ // AlterTableAction — nested polymorphic hierarchy
9
+ // ---------------------------------------------------------------------------
10
+
11
+ export interface AlterTableActionVisitor<R> {
12
+ addColumn(action: AddColumnAction): R;
13
+ }
14
+
15
+ export abstract class AlterTableAction {
16
+ abstract readonly kind: string;
17
+ abstract accept<R>(visitor: AlterTableActionVisitor<R>): R;
18
+ }
19
+
20
+ export class AddColumnAction extends AlterTableAction {
21
+ readonly kind = 'add-column' as const;
22
+ readonly column: DdlColumn;
23
+
24
+ constructor(column: DdlColumn) {
25
+ super();
26
+ this.column = column;
27
+ Object.freeze(this);
28
+ }
29
+
30
+ override accept<R>(visitor: AlterTableActionVisitor<R>): R {
31
+ return visitor.addColumn(this);
32
+ }
33
+ }
34
+
35
+ export type AnyAlterTableAction = AddColumnAction;
36
+
37
+ // ---------------------------------------------------------------------------
38
+ // Top-level DDL visitor
39
+ // ---------------------------------------------------------------------------
40
+
7
41
  export interface PostgresDdlVisitor<R> {
8
42
  createTable(node: PostgresCreateTable): R;
9
43
  createSchema(node: PostgresCreateSchema): R;
44
+ alterTable(node: PostgresAlterTable): R;
10
45
  }
11
46
 
12
47
  export abstract class PostgresDdlNode extends DdlNode {
@@ -69,4 +104,27 @@ export class PostgresCreateSchema extends PostgresDdlNode {
69
104
  }
70
105
  }
71
106
 
72
- export type AnyPostgresDdlNode = PostgresCreateTable | PostgresCreateSchema;
107
+ export class PostgresAlterTable extends PostgresDdlNode {
108
+ readonly kind = 'alter-table' as const;
109
+ readonly table: string;
110
+ readonly schema: string | undefined;
111
+ readonly actions: ReadonlyArray<AnyAlterTableAction>;
112
+
113
+ constructor(options: {
114
+ readonly table: string;
115
+ readonly schema?: string;
116
+ readonly actions: readonly AnyAlterTableAction[];
117
+ }) {
118
+ super();
119
+ this.table = options.table;
120
+ this.schema = options.schema;
121
+ this.actions = Object.freeze([...options.actions]);
122
+ this.freeze();
123
+ }
124
+
125
+ override accept<R>(visitor: PostgresDdlVisitor<R>): R {
126
+ return visitor.alterTable(this);
127
+ }
128
+ }
129
+
130
+ export type AnyPostgresDdlNode = PostgresCreateTable | PostgresCreateSchema | PostgresAlterTable;
@@ -1,12 +1,8 @@
1
1
  import type { Contract } from '@prisma-next/contract/types';
2
2
  import type { ControlPolicySubject } from '@prisma-next/family-sql/control';
3
3
  import type { SchemaIssue } from '@prisma-next/framework-components/control';
4
- import { UNBOUND_NAMESPACE_ID } from '@prisma-next/framework-components/ir';
5
- import {
6
- isPostgresEnumStorageEntry,
7
- type SqlStorage,
8
- storageTableAt,
9
- } from '@prisma-next/sql-contract/types';
4
+ import { entityAt, UNBOUND_NAMESPACE_ID } from '@prisma-next/framework-components/ir';
5
+ import type { SqlStorage, StorageTable } from '@prisma-next/sql-contract/types';
10
6
  import { ifDefined } from '@prisma-next/utils/defined';
11
7
  import { isPostgresSchema } from '../postgres-schema';
12
8
  import type { PostgresOpFactoryCall } from './op-factory-call';
@@ -24,7 +20,6 @@ import type { PostgresOpFactoryCall } from './op-factory-call';
24
20
  */
25
21
  const OBJECT_CREATION_FACTORIES: ReadonlySet<string> = new Set<string>([
26
22
  'createTable',
27
- 'createEnumType',
28
23
  'createSchema',
29
24
  ]);
30
25
 
@@ -43,7 +38,11 @@ function resolveNamespaceIdForTable(
43
38
  ddlSchemaName: string | undefined,
44
39
  ): string {
45
40
  for (const namespaceId of Object.keys(contract.storage.namespaces)) {
46
- const table = storageTableAt(contract.storage, namespaceId, tableName);
41
+ const table = entityAt<StorageTable>(contract.storage, {
42
+ namespaceId,
43
+ entityKind: 'table',
44
+ entityName: tableName,
45
+ });
47
46
  if (!table) continue;
48
47
  if (
49
48
  ddlSchemaName === undefined ||
@@ -75,7 +74,6 @@ interface PostgresCallFields {
75
74
  readonly schemaName?: string;
76
75
  readonly tableName?: string;
77
76
  readonly columnName?: string;
78
- readonly typeName?: string;
79
77
  }
80
78
 
81
79
  function postgresCallFields(call: PostgresOpFactoryCall): PostgresCallFields {
@@ -83,7 +81,6 @@ function postgresCallFields(call: PostgresOpFactoryCall): PostgresCallFields {
83
81
  ...ifDefined('schemaName', 'schemaName' in call ? call.schemaName : undefined),
84
82
  ...ifDefined('tableName', 'tableName' in call ? call.tableName : undefined),
85
83
  ...ifDefined('columnName', 'columnName' in call ? call.columnName : undefined),
86
- ...ifDefined('typeName', 'typeName' in call ? call.typeName : undefined),
87
84
  };
88
85
  }
89
86
 
@@ -96,10 +93,6 @@ export function formatPostgresControlPolicySubjectLabel(
96
93
  const ddlSchema = ddlSchemaNameForNamespace(contract, subject.namespaceId);
97
94
  return `${factoryName}(${ddlSchema}.${subject.table})`;
98
95
  }
99
- if (subject?.typeName) {
100
- const ddlSchema = ddlSchemaNameForNamespace(contract, subject.namespaceId);
101
- return `${factoryName}(${ddlSchema}.${subject.typeName})`;
102
- }
103
96
  return factoryName;
104
97
  }
105
98
 
@@ -117,29 +110,17 @@ export function resolvePostgresCallControlPolicySubject(
117
110
  };
118
111
  }
119
112
 
120
- if (callFields.typeName && call.factoryName !== 'addColumn') {
121
- const namespaceId = callFields.schemaName
122
- ? resolveNamespaceIdForDdlSchema(contract, callFields.schemaName)
123
- : UNBOUND_NAMESPACE_ID;
124
- const ns = contract.storage.namespaces[namespaceId];
125
- const rawEnum = isPostgresSchema(ns) ? ns.entries.type[callFields.typeName] : undefined;
126
- const controlPolicy = isPostgresEnumStorageEntry(rawEnum) ? rawEnum.control : undefined;
127
- return {
128
- namespaceId,
129
- ...ifDefined('explicitNodeControlPolicy', controlPolicy),
130
- typeName: callFields.typeName,
131
- createsNewObject,
132
- };
133
- }
134
-
135
113
  if (callFields.tableName) {
136
114
  const namespaceId = resolveNamespaceIdForTable(
137
115
  contract,
138
116
  callFields.tableName,
139
117
  callFields.schemaName,
140
118
  );
141
- const table = storageTableAt(contract.storage, namespaceId, callFields.tableName);
142
- const tableControlPolicy = table?.control;
119
+ const tableControlPolicy = entityAt<StorageTable>(contract.storage, {
120
+ namespaceId,
121
+ entityKind: 'table',
122
+ entityName: callFields.tableName,
123
+ })?.control;
143
124
  return {
144
125
  namespaceId,
145
126
  ...ifDefined('explicitNodeControlPolicy', tableControlPolicy),
@@ -170,7 +151,6 @@ export function resolvePostgresCallControlPolicySubject(
170
151
  const POSTGRES_ISSUE_CREATION_FACTORY: Readonly<Record<string, string>> = Object.freeze({
171
152
  missing_schema: 'createSchema',
172
153
  missing_table: 'createTable',
173
- type_missing: 'createEnumType',
174
154
  });
175
155
 
176
156
  export function resolvePostgresIssueCreationFactoryName(issue: SchemaIssue): string | undefined {
@@ -201,26 +181,16 @@ export function resolvePostgresIssueControlPolicySubject(
201
181
  return { namespaceId: issue.namespaceId, createsNewObject };
202
182
  }
203
183
 
204
- if ('typeName' in issue && issue.typeName) {
205
- const namespaceId =
206
- 'namespaceId' in issue && issue.namespaceId ? issue.namespaceId : UNBOUND_NAMESPACE_ID;
207
- const ns = contract.storage.namespaces[namespaceId];
208
- const rawEnum = isPostgresSchema(ns) ? ns.entries.type[issue.typeName] : undefined;
209
- const controlPolicy = isPostgresEnumStorageEntry(rawEnum) ? rawEnum.control : undefined;
210
- return {
211
- namespaceId,
212
- ...ifDefined('explicitNodeControlPolicy', controlPolicy),
213
- typeName: issue.typeName,
214
- createsNewObject,
215
- };
216
- }
217
-
218
184
  if ('table' in issue && issue.table) {
219
185
  const namespaceId =
220
186
  'namespaceId' in issue && issue.namespaceId
221
187
  ? issue.namespaceId
222
188
  : resolveNamespaceIdForTable(contract, issue.table, undefined);
223
- const table = storageTableAt(contract.storage, namespaceId, issue.table);
189
+ const table = entityAt<StorageTable>(contract.storage, {
190
+ namespaceId,
191
+ entityKind: 'table',
192
+ entityName: issue.table,
193
+ });
224
194
  return {
225
195
  namespaceId,
226
196
  ...ifDefined('explicitNodeControlPolicy', table?.control),