@prisma-next/target-postgres 0.8.0 → 0.9.0-dev.1
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.
- package/dist/{codec-ids-CplrEfmx.d.mts → codec-ids-RvYfmUmi.d.mts} +1 -1
- package/dist/{codec-ids-CplrEfmx.d.mts.map → codec-ids-RvYfmUmi.d.mts.map} +1 -1
- package/dist/codec-ids.d.mts +1 -1
- package/dist/{codec-types-lrsb3N07.d.mts → codec-types-667FxIW8.d.mts} +2 -2
- package/dist/{codec-types-lrsb3N07.d.mts.map → codec-types-667FxIW8.d.mts.map} +1 -1
- package/dist/codec-types.d.mts +1 -1
- package/dist/{codecs-Cue97Xqf.d.mts → codecs-DXeDABSO.d.mts} +2 -2
- package/dist/{codecs-Cue97Xqf.d.mts.map → codecs-DXeDABSO.d.mts.map} +1 -1
- package/dist/codecs.d.mts +1 -1
- package/dist/control.d.mts +2 -2
- package/dist/control.d.mts.map +1 -1
- package/dist/control.mjs +38 -7
- package/dist/control.mjs.map +1 -1
- package/dist/{data-transform-bIeAcZIJ.d.mts → data-transform-B6p02mFJ.d.mts} +3 -3
- package/dist/{data-transform-bIeAcZIJ.d.mts.map → data-transform-B6p02mFJ.d.mts.map} +1 -1
- package/dist/{data-transform-DKWXdHuZ.mjs → data-transform-aF9az88u.mjs} +1 -1
- package/dist/{data-transform-DKWXdHuZ.mjs.map → data-transform-aF9az88u.mjs.map} +1 -1
- package/dist/data-transform.d.mts +1 -1
- package/dist/data-transform.mjs +1 -1
- package/dist/{default-normalizer-C8XyZj85.mjs → default-normalizer-DHCsbfjc.mjs} +1 -1
- package/dist/{default-normalizer-C8XyZj85.mjs.map → default-normalizer-DHCsbfjc.mjs.map} +1 -1
- package/dist/default-normalizer.mjs +1 -1
- package/dist/descriptor-meta-DFUCClk_.mjs +124 -0
- package/dist/descriptor-meta-DFUCClk_.mjs.map +1 -0
- package/dist/enum-planning-Bqp96iIw.mjs +63 -0
- package/dist/enum-planning-Bqp96iIw.mjs.map +1 -0
- package/dist/enum-planning.d.mts +48 -0
- package/dist/enum-planning.d.mts.map +1 -0
- package/dist/enum-planning.mjs +2 -0
- package/dist/{errors-Chm2bKcS.mjs → errors-BiOloWUh.mjs} +1 -1
- package/dist/{errors-Chm2bKcS.mjs.map → errors-BiOloWUh.mjs.map} +1 -1
- package/dist/errors.mjs +1 -1
- package/dist/{issue-planner-DQ6WJkad.mjs → issue-planner-BhWVYyE1.mjs} +114 -49
- package/dist/issue-planner-BhWVYyE1.mjs.map +1 -0
- package/dist/issue-planner.d.mts +11 -9
- package/dist/issue-planner.d.mts.map +1 -1
- package/dist/issue-planner.mjs +1 -1
- package/dist/migration.d.mts +4 -4
- package/dist/migration.d.mts.map +1 -1
- package/dist/migration.mjs +3 -3
- package/dist/{native-type-normalizer-Cry4QoLf.mjs → native-type-normalizer-DMikJJ1V.mjs} +1 -1
- package/dist/{native-type-normalizer-Cry4QoLf.mjs.map → native-type-normalizer-DMikJJ1V.mjs.map} +1 -1
- package/dist/native-type-normalizer.mjs +1 -1
- package/dist/{op-factory-call-DeaFxa8_.mjs → op-factory-call-DerP9BoT.mjs} +8 -5
- package/dist/{op-factory-call-DeaFxa8_.mjs.map → op-factory-call-DerP9BoT.mjs.map} +1 -1
- package/dist/{op-factory-call-UFpUPJL6.d.mts → op-factory-call-c1zELk3U.d.mts} +5 -4
- package/dist/{op-factory-call-UFpUPJL6.d.mts.map → op-factory-call-c1zELk3U.d.mts.map} +1 -1
- package/dist/op-factory-call.d.mts +1 -1
- package/dist/op-factory-call.mjs +1 -1
- package/dist/pack.d.mts +13 -24
- package/dist/pack.d.mts.map +1 -1
- package/dist/pack.mjs +1 -1
- package/dist/{planner-CYtKhLYa.mjs → planner-DSDXUbQ4.mjs} +8 -6
- package/dist/planner-DSDXUbQ4.mjs.map +1 -0
- package/dist/{planner-ddl-builders-CLB7Umhh.mjs → planner-ddl-builders-5QIyhBUF.mjs} +3 -3
- package/dist/planner-ddl-builders-5QIyhBUF.mjs.map +1 -0
- package/dist/planner-ddl-builders.d.mts +5 -5
- package/dist/planner-ddl-builders.d.mts.map +1 -1
- package/dist/planner-ddl-builders.mjs +1 -1
- package/dist/{planner-identity-values-DTx0gePL.mjs → planner-identity-values-BUYNOCwb.mjs} +9 -3
- package/dist/planner-identity-values-BUYNOCwb.mjs.map +1 -0
- package/dist/planner-identity-values.d.mts +1 -1
- package/dist/planner-identity-values.d.mts.map +1 -1
- package/dist/planner-identity-values.mjs +1 -1
- package/dist/{planner-produced-postgres-migration-CjxWIVgh.d.mts → planner-produced-postgres-migration-D34ftfEK.d.mts} +3 -3
- package/dist/{planner-produced-postgres-migration-CjxWIVgh.d.mts.map → planner-produced-postgres-migration-D34ftfEK.d.mts.map} +1 -1
- package/dist/{planner-produced-postgres-migration-DphktB2N.mjs → planner-produced-postgres-migration-D8OCSSLM.mjs} +4 -4
- package/dist/{planner-produced-postgres-migration-DphktB2N.mjs.map → planner-produced-postgres-migration-D8OCSSLM.mjs.map} +1 -1
- package/dist/planner-produced-postgres-migration.d.mts +1 -1
- package/dist/planner-produced-postgres-migration.mjs +1 -1
- package/dist/{planner-schema-lookup-B1ags8ys.mjs → planner-schema-lookup--u9whY_Y.mjs} +1 -1
- package/dist/{planner-schema-lookup-B1ags8ys.mjs.map → planner-schema-lookup--u9whY_Y.mjs.map} +1 -1
- package/dist/planner-schema-lookup.mjs +1 -1
- package/dist/{planner-sql-checks-DwZvGlV4.mjs → planner-sql-checks-Cd016Ycs.mjs} +7 -2
- package/dist/planner-sql-checks-Cd016Ycs.mjs.map +1 -0
- package/dist/planner-sql-checks.d.mts +2 -2
- package/dist/planner-sql-checks.d.mts.map +1 -1
- package/dist/planner-sql-checks.mjs +1 -1
- package/dist/{planner-target-details-bVVcanWh.d.mts → planner-target-details-iYJwzFHP.d.mts} +1 -1
- package/dist/{planner-target-details-bVVcanWh.d.mts.map → planner-target-details-iYJwzFHP.d.mts.map} +1 -1
- package/dist/planner-target-details.d.mts +1 -1
- package/dist/planner.d.mts +1 -1
- package/dist/planner.d.mts.map +1 -1
- package/dist/planner.mjs +1 -1
- package/dist/postgres-contract-serializer-D5VJk6lo.mjs +61 -0
- package/dist/postgres-contract-serializer-D5VJk6lo.mjs.map +1 -0
- package/dist/postgres-enum-type-CrKq8au9.d.mts +69 -0
- package/dist/postgres-enum-type-CrKq8au9.d.mts.map +1 -0
- package/dist/postgres-enum-type-DS-KLVRH.mjs +61 -0
- package/dist/postgres-enum-type-DS-KLVRH.mjs.map +1 -0
- package/dist/{postgres-migration-UkcHfZAA.d.mts → postgres-migration-CiQzhcMe.d.mts} +4 -4
- package/dist/{postgres-migration-UkcHfZAA.d.mts.map → postgres-migration-CiQzhcMe.d.mts.map} +1 -1
- package/dist/{postgres-migration-Bkv140RW.mjs → postgres-migration-Fdxzo6l2.mjs} +3 -3
- package/dist/{postgres-migration-Bkv140RW.mjs.map → postgres-migration-Fdxzo6l2.mjs.map} +1 -1
- package/dist/{render-ops--1nnfNus.mjs → render-ops-CkiuHSNj.mjs} +1 -1
- package/dist/{render-ops--1nnfNus.mjs.map → render-ops-CkiuHSNj.mjs.map} +1 -1
- package/dist/render-ops.d.mts +1 -1
- package/dist/render-ops.mjs +1 -1
- package/dist/{render-typescript-D3doH-vX.mjs → render-typescript-C9XWI8Ld.mjs} +1 -1
- package/dist/{render-typescript-D3doH-vX.mjs.map → render-typescript-C9XWI8Ld.mjs.map} +1 -1
- package/dist/render-typescript.mjs +1 -1
- package/dist/runtime.d.mts +25 -1
- package/dist/runtime.d.mts.map +1 -1
- package/dist/runtime.mjs +3 -2
- package/dist/runtime.mjs.map +1 -1
- package/dist/{shared-MpwjwAjM.d.mts → shared-DLYdmYo-.d.mts} +2 -2
- package/dist/{shared-MpwjwAjM.d.mts.map → shared-DLYdmYo-.d.mts.map} +1 -1
- package/dist/{sql-utils-CggjWNij.mjs → sql-utils-BewXAnsG.mjs} +1 -1
- package/dist/{sql-utils-CggjWNij.mjs.map → sql-utils-BewXAnsG.mjs.map} +1 -1
- package/dist/sql-utils.mjs +1 -1
- package/dist/{statement-builders-BT889jV0.mjs → statement-builders-BSIQMClE.mjs} +1 -1
- package/dist/{statement-builders-BT889jV0.mjs.map → statement-builders-BSIQMClE.mjs.map} +1 -1
- package/dist/statement-builders.mjs +1 -1
- package/dist/{tables-DgYIXjUt.mjs → tables-Ce_Q0I8B.mjs} +7 -7
- package/dist/{tables-DgYIXjUt.mjs.map → tables-Ce_Q0I8B.mjs.map} +1 -1
- package/dist/{types-CTqpysRY.d.mts → types-Dq74Z3eu.d.mts} +1 -1
- package/dist/types-Dq74Z3eu.d.mts.map +1 -0
- package/dist/types.d.mts +3 -2
- package/dist/types.mjs +2 -1
- package/package.json +18 -17
- package/src/core/authoring.ts +41 -9
- package/src/core/descriptor-meta.ts +6 -1
- package/src/core/migrations/enum-planning.ts +93 -0
- package/src/core/migrations/issue-planner.ts +25 -13
- package/src/core/migrations/op-factory-call.ts +12 -3
- package/src/core/migrations/operations/enums.ts +5 -4
- package/src/core/migrations/planner-ddl-builders.ts +4 -3
- package/src/core/migrations/planner-identity-values.ts +28 -4
- package/src/core/migrations/planner-recipes.ts +6 -2
- package/src/core/migrations/planner-sql-checks.ts +6 -2
- package/src/core/migrations/planner-strategies.ts +187 -74
- package/src/core/migrations/planner-type-resolution.ts +20 -2
- package/src/core/migrations/planner.ts +3 -0
- package/src/core/migrations/runner.ts +3 -0
- package/src/core/postgres-contract-serializer.ts +70 -0
- package/src/core/postgres-enum-type.ts +85 -0
- package/src/core/postgres-schema-verifier.ts +37 -0
- package/src/exports/control.ts +13 -1
- package/src/exports/enum-planning.ts +6 -0
- package/src/exports/runtime.ts +2 -0
- package/src/exports/types.ts +1 -0
- package/dist/descriptor-meta-Dde_BS3K.mjs +0 -99
- package/dist/descriptor-meta-Dde_BS3K.mjs.map +0 -1
- package/dist/issue-planner-DQ6WJkad.mjs.map +0 -1
- package/dist/planner-CYtKhLYa.mjs.map +0 -1
- package/dist/planner-ddl-builders-CLB7Umhh.mjs.map +0 -1
- package/dist/planner-identity-values-DTx0gePL.mjs.map +0 -1
- package/dist/planner-sql-checks-DwZvGlV4.mjs.map +0 -1
- package/dist/types-CTqpysRY.d.mts.map +0 -1
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { t as PostgresEnumType } from "./postgres-enum-type-DS-KLVRH.mjs";
|
|
2
|
+
import { temporalAuthoringPresets } from "@prisma-next/family-sql/control";
|
|
3
|
+
//#region src/core/authoring.ts
|
|
4
|
+
const postgresAuthoringTypes = {};
|
|
5
|
+
/**
|
|
6
|
+
* Entity type contributions surface as top-level helpers on the
|
|
7
|
+
* composed-helpers shape (e.g. `helpers.enum({...})`), flattened
|
|
8
|
+
* alongside the built-in `model` / `rel` helpers. Pack contributions
|
|
9
|
+
* still ship via the contribution data structure
|
|
10
|
+
* `authoring.entityTypes.<name>`; the composed-helpers template
|
|
11
|
+
* performs the rename in the type system.
|
|
12
|
+
*
|
|
13
|
+
* `enum` is the first real consumer of the entities-namespace mechanism:
|
|
14
|
+
* the factory constructs a `PostgresEnumType` IR-class instance from
|
|
15
|
+
* the user-supplied input. Both authoring runtimes (TS DSL and PSL)
|
|
16
|
+
* dispatch through this single contribution — PSL `enum Status { … }`
|
|
17
|
+
* declarations are lowered by the interpreter into a factory call
|
|
18
|
+
* with the parsed name + value list; TS DSL `helpers.enum({...})`
|
|
19
|
+
* resolves through the same path. Removing this contribution makes
|
|
20
|
+
* both surfaces fail with a "no entity helper named `enum`" type
|
|
21
|
+
* error at the contract-definition site.
|
|
22
|
+
*/
|
|
23
|
+
/**
|
|
24
|
+
* The factory constructs a `PostgresEnumType` instance natively — the
|
|
25
|
+
* `SqlStorage.types` slot accepts polymorphic IR (the framework
|
|
26
|
+
* `StorageType` alphabet), so no cast is needed at the contribution
|
|
27
|
+
* surface. The declared return type is the structural
|
|
28
|
+
* `PostgresEnumStorageEntry` so the inferred contract type stays
|
|
29
|
+
* portable (it names a type exported from
|
|
30
|
+
* `@prisma-next/sql-contract/types`, a public surface every consumer
|
|
31
|
+
* already imports). Sharpening the inferred contract type to surface
|
|
32
|
+
* enum-specific narrowing through `EntityHelperFunction` is a
|
|
33
|
+
* separable refinement and lives outside this PR.
|
|
34
|
+
*/
|
|
35
|
+
const postgresAuthoringEntityTypes = { enum: {
|
|
36
|
+
kind: "entity",
|
|
37
|
+
discriminator: "postgres-enum",
|
|
38
|
+
output: { factory: (input) => new PostgresEnumType(input) }
|
|
39
|
+
} };
|
|
40
|
+
const postgresTargetDescriptorMeta = {
|
|
41
|
+
kind: "target",
|
|
42
|
+
familyId: "sql",
|
|
43
|
+
targetId: "postgres",
|
|
44
|
+
id: "postgres",
|
|
45
|
+
version: "0.0.1",
|
|
46
|
+
capabilities: {},
|
|
47
|
+
authoring: {
|
|
48
|
+
type: postgresAuthoringTypes,
|
|
49
|
+
field: {
|
|
50
|
+
text: {
|
|
51
|
+
kind: "fieldPreset",
|
|
52
|
+
output: {
|
|
53
|
+
codecId: "pg/text@1",
|
|
54
|
+
nativeType: "text"
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
int: {
|
|
58
|
+
kind: "fieldPreset",
|
|
59
|
+
output: {
|
|
60
|
+
codecId: "pg/int4@1",
|
|
61
|
+
nativeType: "int4"
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
bigint: {
|
|
65
|
+
kind: "fieldPreset",
|
|
66
|
+
output: {
|
|
67
|
+
codecId: "pg/int8@1",
|
|
68
|
+
nativeType: "int8"
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
float: {
|
|
72
|
+
kind: "fieldPreset",
|
|
73
|
+
output: {
|
|
74
|
+
codecId: "pg/float8@1",
|
|
75
|
+
nativeType: "float8"
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
decimal: {
|
|
79
|
+
kind: "fieldPreset",
|
|
80
|
+
output: {
|
|
81
|
+
codecId: "pg/numeric@1",
|
|
82
|
+
nativeType: "numeric"
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
boolean: {
|
|
86
|
+
kind: "fieldPreset",
|
|
87
|
+
output: {
|
|
88
|
+
codecId: "pg/bool@1",
|
|
89
|
+
nativeType: "bool"
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
json: {
|
|
93
|
+
kind: "fieldPreset",
|
|
94
|
+
output: {
|
|
95
|
+
codecId: "pg/jsonb@1",
|
|
96
|
+
nativeType: "jsonb"
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
bytes: {
|
|
100
|
+
kind: "fieldPreset",
|
|
101
|
+
output: {
|
|
102
|
+
codecId: "pg/bytea@1",
|
|
103
|
+
nativeType: "bytea"
|
|
104
|
+
}
|
|
105
|
+
},
|
|
106
|
+
dateTime: {
|
|
107
|
+
kind: "fieldPreset",
|
|
108
|
+
output: {
|
|
109
|
+
codecId: "pg/timestamptz@1",
|
|
110
|
+
nativeType: "timestamptz"
|
|
111
|
+
}
|
|
112
|
+
},
|
|
113
|
+
temporal: temporalAuthoringPresets({
|
|
114
|
+
codecId: "pg/timestamptz@1",
|
|
115
|
+
nativeType: "timestamptz"
|
|
116
|
+
})
|
|
117
|
+
},
|
|
118
|
+
entityTypes: postgresAuthoringEntityTypes
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
//#endregion
|
|
122
|
+
export { postgresAuthoringEntityTypes as n, postgresTargetDescriptorMeta as t };
|
|
123
|
+
|
|
124
|
+
//# sourceMappingURL=descriptor-meta-DFUCClk_.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"descriptor-meta-DFUCClk_.mjs","names":[],"sources":["../src/core/authoring.ts","../src/core/descriptor-meta.ts"],"sourcesContent":["import { temporalAuthoringPresets } from '@prisma-next/family-sql/control';\nimport type {\n AuthoringEntityTypeNamespace,\n AuthoringFieldNamespace,\n AuthoringTypeNamespace,\n} from '@prisma-next/framework-components/authoring';\nimport type { PostgresEnumStorageEntry } from '@prisma-next/sql-contract/types';\nimport { PostgresEnumType, type PostgresEnumTypeInput } from './postgres-enum-type';\n\nexport const postgresAuthoringTypes = {} as const satisfies AuthoringTypeNamespace;\n\n/**\n * Entity type contributions surface as top-level helpers on the\n * composed-helpers shape (e.g. `helpers.enum({...})`), flattened\n * alongside the built-in `model` / `rel` helpers. Pack contributions\n * still ship via the contribution data structure\n * `authoring.entityTypes.<name>`; the composed-helpers template\n * performs the rename in the type system.\n *\n * `enum` is the first real consumer of the entities-namespace mechanism:\n * the factory constructs a `PostgresEnumType` IR-class instance from\n * the user-supplied input. Both authoring runtimes (TS DSL and PSL)\n * dispatch through this single contribution — PSL `enum Status { … }`\n * declarations are lowered by the interpreter into a factory call\n * with the parsed name + value list; TS DSL `helpers.enum({...})`\n * resolves through the same path. Removing this contribution makes\n * both surfaces fail with a \"no entity helper named `enum`\" type\n * error at the contract-definition site.\n */\n/**\n * The factory constructs a `PostgresEnumType` instance natively — the\n * `SqlStorage.types` slot accepts polymorphic IR (the framework\n * `StorageType` alphabet), so no cast is needed at the contribution\n * surface. The declared return type is the structural\n * `PostgresEnumStorageEntry` so the inferred contract type stays\n * portable (it names a type exported from\n * `@prisma-next/sql-contract/types`, a public surface every consumer\n * already imports). Sharpening the inferred contract type to surface\n * enum-specific narrowing through `EntityHelperFunction` is a\n * separable refinement and lives outside this PR.\n */\nexport const postgresAuthoringEntityTypes = {\n enum: {\n kind: 'entity',\n discriminator: 'postgres-enum',\n output: {\n factory: (input: PostgresEnumTypeInput): PostgresEnumStorageEntry =>\n new PostgresEnumType(input),\n },\n },\n} as const satisfies AuthoringEntityTypeNamespace;\n\n/**\n * Field presets contributed by the Postgres target pack.\n *\n * These mirror the PSL scalar-to-codec mapping used by the Postgres adapter\n * (see `createPostgresPslScalarTypeDescriptors`), so that authoring a field\n * via the TS callback surface (e.g. `field.int()`) and via the PSL scalar\n * surface (e.g. `Int`) lowers to byte-identical contracts.\n */\nexport const postgresAuthoringFieldPresets = {\n text: {\n kind: 'fieldPreset',\n output: {\n codecId: 'pg/text@1',\n nativeType: 'text',\n },\n },\n int: {\n kind: 'fieldPreset',\n output: {\n codecId: 'pg/int4@1',\n nativeType: 'int4',\n },\n },\n bigint: {\n kind: 'fieldPreset',\n output: {\n codecId: 'pg/int8@1',\n nativeType: 'int8',\n },\n },\n float: {\n kind: 'fieldPreset',\n output: {\n codecId: 'pg/float8@1',\n nativeType: 'float8',\n },\n },\n decimal: {\n kind: 'fieldPreset',\n output: {\n codecId: 'pg/numeric@1',\n nativeType: 'numeric',\n },\n },\n boolean: {\n kind: 'fieldPreset',\n output: {\n codecId: 'pg/bool@1',\n nativeType: 'bool',\n },\n },\n json: {\n kind: 'fieldPreset',\n output: {\n codecId: 'pg/jsonb@1',\n nativeType: 'jsonb',\n },\n },\n bytes: {\n kind: 'fieldPreset',\n output: {\n codecId: 'pg/bytea@1',\n nativeType: 'bytea',\n },\n },\n dateTime: {\n kind: 'fieldPreset',\n output: {\n codecId: 'pg/timestamptz@1',\n nativeType: 'timestamptz',\n },\n },\n temporal: temporalAuthoringPresets({\n codecId: 'pg/timestamptz@1',\n nativeType: 'timestamptz',\n }),\n} as const satisfies AuthoringFieldNamespace;\n","import type { CodecTypes } from '../exports/codec-types';\nimport {\n postgresAuthoringEntityTypes,\n postgresAuthoringFieldPresets,\n postgresAuthoringTypes,\n} from './authoring';\n\nconst postgresTargetDescriptorMetaBase = {\n kind: 'target',\n familyId: 'sql',\n targetId: 'postgres',\n id: 'postgres',\n version: '0.0.1',\n capabilities: {},\n authoring: {\n type: postgresAuthoringTypes,\n field: postgresAuthoringFieldPresets,\n entityTypes: postgresAuthoringEntityTypes,\n },\n} as const;\n\nexport const postgresTargetDescriptorMeta: typeof postgresTargetDescriptorMetaBase & {\n readonly __codecTypes?: CodecTypes;\n} = postgresTargetDescriptorMetaBase;\n"],"mappings":";;;AASA,MAAa,yBAAyB,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgCxC,MAAa,+BAA+B,EAC1C,MAAM;CACJ,MAAM;CACN,eAAe;CACf,QAAQ,EACN,UAAU,UACR,IAAI,iBAAiB,MAAM,EAC9B;CACF,EACF;AC7BD,MAAa,+BAET;CAfF,MAAM;CACN,UAAU;CACV,UAAU;CACV,IAAI;CACJ,SAAS;CACT,cAAc,EAAE;CAChB,WAAW;EACT,MAAM;EACN,OAAO;GD6CT,MAAM;IACJ,MAAM;IACN,QAAQ;KACN,SAAS;KACT,YAAY;KACb;IACF;GACD,KAAK;IACH,MAAM;IACN,QAAQ;KACN,SAAS;KACT,YAAY;KACb;IACF;GACD,QAAQ;IACN,MAAM;IACN,QAAQ;KACN,SAAS;KACT,YAAY;KACb;IACF;GACD,OAAO;IACL,MAAM;IACN,QAAQ;KACN,SAAS;KACT,YAAY;KACb;IACF;GACD,SAAS;IACP,MAAM;IACN,QAAQ;KACN,SAAS;KACT,YAAY;KACb;IACF;GACD,SAAS;IACP,MAAM;IACN,QAAQ;KACN,SAAS;KACT,YAAY;KACb;IACF;GACD,MAAM;IACJ,MAAM;IACN,QAAQ;KACN,SAAS;KACT,YAAY;KACb;IACF;GACD,OAAO;IACL,MAAM;IACN,QAAQ;KACN,SAAS;KACT,YAAY;KACb;IACF;GACD,UAAU;IACR,MAAM;IACN,QAAQ;KACN,SAAS;KACT,YAAY;KACb;IACF;GACD,UAAU,yBAAyB;IACjC,SAAS;IACT,YAAY;IACb,CAAC;GC/GO;EACP,aAAa;EACd;CAKC"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import "./codec-ids-C5qzBqus.mjs";
|
|
2
|
+
import { arraysEqual } from "@prisma-next/family-sql/schema-verify";
|
|
3
|
+
//#region src/core/migrations/enum-planning.ts
|
|
4
|
+
/**
|
|
5
|
+
* Pure planning helpers for Postgres enum types: the diff/rebuild logic
|
|
6
|
+
* that the verifier and planner use to walk `PostgresEnumType` instances
|
|
7
|
+
* natively. Op builders live in `./operations/enums.ts`.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Reads existing enum values for `nativeType` from the
|
|
11
|
+
* Postgres-introspected `schema.annotations.pg.storageTypes` map.
|
|
12
|
+
*
|
|
13
|
+
* Schema IR's `storageTypes` slots are always codec-typed
|
|
14
|
+
* (`{codecId: PG_ENUM_CODEC_ID, typeParams.values}`): the introspector
|
|
15
|
+
* writes that shape, and the Contract→Schema IR projector resolves
|
|
16
|
+
* `PostgresEnumType` instances down to the same codec-typed triple before
|
|
17
|
+
* they ever land in Schema IR. There is no second on-disk shape to
|
|
18
|
+
* accept here.
|
|
19
|
+
*
|
|
20
|
+
* Returns `null` when no enum entry exists for the given native type.
|
|
21
|
+
*/
|
|
22
|
+
function readExistingEnumValues(schema, nativeType) {
|
|
23
|
+
const existing = ((schema.annotations?.["pg"])?.["storageTypes"])?.[nativeType];
|
|
24
|
+
if (!existing || existing.codecId !== "pg/enum@1") return null;
|
|
25
|
+
const enumValues = existing.typeParams?.values;
|
|
26
|
+
if (!Array.isArray(enumValues) || !enumValues.every((v) => typeof v === "string")) return null;
|
|
27
|
+
return enumValues;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Determines what changes are needed to transform existing enum values to
|
|
31
|
+
* desired values.
|
|
32
|
+
*
|
|
33
|
+
* Postgres enums can only have values added (not removed or reordered)
|
|
34
|
+
* without a full type rebuild involving temp type creation and column
|
|
35
|
+
* migration; `'rebuild'` covers the value-removal and reorder cases.
|
|
36
|
+
*/
|
|
37
|
+
function determineEnumDiff(existing, desired) {
|
|
38
|
+
if (arraysEqual(existing, desired)) return { kind: "unchanged" };
|
|
39
|
+
const existingSet = new Set(existing);
|
|
40
|
+
const desiredSet = new Set(desired);
|
|
41
|
+
const missingValues = desired.filter((value) => !existingSet.has(value));
|
|
42
|
+
const removedValues = existing.filter((value) => !desiredSet.has(value));
|
|
43
|
+
const orderMismatch = missingValues.length === 0 && removedValues.length === 0 && !arraysEqual(existing, desired);
|
|
44
|
+
if (removedValues.length > 0 || orderMismatch) return {
|
|
45
|
+
kind: "rebuild",
|
|
46
|
+
removedValues
|
|
47
|
+
};
|
|
48
|
+
return {
|
|
49
|
+
kind: "add_values",
|
|
50
|
+
values: missingValues
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Convenience accessor — returns the enum's desired values from a
|
|
55
|
+
* `PostgresEnumType` IR instance.
|
|
56
|
+
*/
|
|
57
|
+
function getDesiredEnumValues(typeInstance) {
|
|
58
|
+
return typeInstance.values;
|
|
59
|
+
}
|
|
60
|
+
//#endregion
|
|
61
|
+
export { getDesiredEnumValues as n, readExistingEnumValues as r, determineEnumDiff as t };
|
|
62
|
+
|
|
63
|
+
//# sourceMappingURL=enum-planning-Bqp96iIw.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"enum-planning-Bqp96iIw.mjs","names":[],"sources":["../src/core/migrations/enum-planning.ts"],"sourcesContent":["/**\n * Pure planning helpers for Postgres enum types: the diff/rebuild logic\n * that the verifier and planner use to walk `PostgresEnumType` instances\n * natively. Op builders live in `./operations/enums.ts`.\n */\n\nimport { arraysEqual } from '@prisma-next/family-sql/schema-verify';\nimport type { SqlSchemaIR } from '@prisma-next/sql-schema-ir/types';\nimport { PG_ENUM_CODEC_ID } from '../codec-ids';\nimport type { PostgresEnumType } from '../postgres-enum-type';\n\n/**\n * Categorisation of how an existing enum type's values relate to the\n * desired set in the contract.\n */\nexport type EnumDiff =\n | { readonly kind: 'unchanged' }\n | { readonly kind: 'add_values'; readonly values: readonly string[] }\n | { readonly kind: 'rebuild'; readonly removedValues: readonly string[] };\n\n/**\n * Reads existing enum values for `nativeType` from the\n * Postgres-introspected `schema.annotations.pg.storageTypes` map.\n *\n * Schema IR's `storageTypes` slots are always codec-typed\n * (`{codecId: PG_ENUM_CODEC_ID, typeParams.values}`): the introspector\n * writes that shape, and the Contract→Schema IR projector resolves\n * `PostgresEnumType` instances down to the same codec-typed triple before\n * they ever land in Schema IR. There is no second on-disk shape to\n * accept here.\n *\n * Returns `null` when no enum entry exists for the given native type.\n */\nexport function readExistingEnumValues(\n schema: SqlSchemaIR,\n nativeType: string,\n): readonly string[] | null {\n const storageTypes = (schema.annotations?.['pg'] as Record<string, unknown> | undefined)?.[\n 'storageTypes'\n ] as\n | Record<\n string,\n {\n codecId?: string;\n typeParams?: { values?: unknown };\n }\n >\n | undefined;\n const existing = storageTypes?.[nativeType];\n if (!existing || existing.codecId !== PG_ENUM_CODEC_ID) {\n return null;\n }\n const enumValues = existing.typeParams?.values;\n if (!Array.isArray(enumValues) || !enumValues.every((v) => typeof v === 'string')) {\n return null;\n }\n return enumValues as readonly string[];\n}\n\n/**\n * Determines what changes are needed to transform existing enum values to\n * desired values.\n *\n * Postgres enums can only have values added (not removed or reordered)\n * without a full type rebuild involving temp type creation and column\n * migration; `'rebuild'` covers the value-removal and reorder cases.\n */\nexport function determineEnumDiff(\n existing: readonly string[],\n desired: readonly string[],\n): EnumDiff {\n if (arraysEqual(existing, desired)) {\n return { kind: 'unchanged' };\n }\n const existingSet = new Set(existing);\n const desiredSet = new Set(desired);\n const missingValues = desired.filter((value) => !existingSet.has(value));\n const removedValues = existing.filter((value) => !desiredSet.has(value));\n const orderMismatch =\n missingValues.length === 0 && removedValues.length === 0 && !arraysEqual(existing, desired);\n if (removedValues.length > 0 || orderMismatch) {\n return { kind: 'rebuild', removedValues };\n }\n return { kind: 'add_values', values: missingValues };\n}\n\n/**\n * Convenience accessor — returns the enum's desired values from a\n * `PostgresEnumType` IR instance.\n */\nexport function getDesiredEnumValues(typeInstance: PostgresEnumType): readonly string[] {\n return typeInstance.values;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAiCA,SAAgB,uBACd,QACA,YAC0B;CAY1B,MAAM,aAXgB,OAAO,cAAc,SACzC,mBAU8B;CAChC,IAAI,CAAC,YAAY,SAAS,YAAA,aACxB,OAAO;CAET,MAAM,aAAa,SAAS,YAAY;CACxC,IAAI,CAAC,MAAM,QAAQ,WAAW,IAAI,CAAC,WAAW,OAAO,MAAM,OAAO,MAAM,SAAS,EAC/E,OAAO;CAET,OAAO;;;;;;;;;;AAWT,SAAgB,kBACd,UACA,SACU;CACV,IAAI,YAAY,UAAU,QAAQ,EAChC,OAAO,EAAE,MAAM,aAAa;CAE9B,MAAM,cAAc,IAAI,IAAI,SAAS;CACrC,MAAM,aAAa,IAAI,IAAI,QAAQ;CACnC,MAAM,gBAAgB,QAAQ,QAAQ,UAAU,CAAC,YAAY,IAAI,MAAM,CAAC;CACxE,MAAM,gBAAgB,SAAS,QAAQ,UAAU,CAAC,WAAW,IAAI,MAAM,CAAC;CACxE,MAAM,gBACJ,cAAc,WAAW,KAAK,cAAc,WAAW,KAAK,CAAC,YAAY,UAAU,QAAQ;CAC7F,IAAI,cAAc,SAAS,KAAK,eAC9B,OAAO;EAAE,MAAM;EAAW;EAAe;CAE3C,OAAO;EAAE,MAAM;EAAc,QAAQ;EAAe;;;;;;AAOtD,SAAgB,qBAAqB,cAAmD;CACtF,OAAO,aAAa"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { t as PostgresEnumType } from "./postgres-enum-type-CrKq8au9.mjs";
|
|
2
|
+
import { SqlSchemaIR } from "@prisma-next/sql-schema-ir/types";
|
|
3
|
+
|
|
4
|
+
//#region src/core/migrations/enum-planning.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* Categorisation of how an existing enum type's values relate to the
|
|
7
|
+
* desired set in the contract.
|
|
8
|
+
*/
|
|
9
|
+
type EnumDiff = {
|
|
10
|
+
readonly kind: 'unchanged';
|
|
11
|
+
} | {
|
|
12
|
+
readonly kind: 'add_values';
|
|
13
|
+
readonly values: readonly string[];
|
|
14
|
+
} | {
|
|
15
|
+
readonly kind: 'rebuild';
|
|
16
|
+
readonly removedValues: readonly string[];
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Reads existing enum values for `nativeType` from the
|
|
20
|
+
* Postgres-introspected `schema.annotations.pg.storageTypes` map.
|
|
21
|
+
*
|
|
22
|
+
* Schema IR's `storageTypes` slots are always codec-typed
|
|
23
|
+
* (`{codecId: PG_ENUM_CODEC_ID, typeParams.values}`): the introspector
|
|
24
|
+
* writes that shape, and the Contract→Schema IR projector resolves
|
|
25
|
+
* `PostgresEnumType` instances down to the same codec-typed triple before
|
|
26
|
+
* they ever land in Schema IR. There is no second on-disk shape to
|
|
27
|
+
* accept here.
|
|
28
|
+
*
|
|
29
|
+
* Returns `null` when no enum entry exists for the given native type.
|
|
30
|
+
*/
|
|
31
|
+
declare function readExistingEnumValues(schema: SqlSchemaIR, nativeType: string): readonly string[] | null;
|
|
32
|
+
/**
|
|
33
|
+
* Determines what changes are needed to transform existing enum values to
|
|
34
|
+
* desired values.
|
|
35
|
+
*
|
|
36
|
+
* Postgres enums can only have values added (not removed or reordered)
|
|
37
|
+
* without a full type rebuild involving temp type creation and column
|
|
38
|
+
* migration; `'rebuild'` covers the value-removal and reorder cases.
|
|
39
|
+
*/
|
|
40
|
+
declare function determineEnumDiff(existing: readonly string[], desired: readonly string[]): EnumDiff;
|
|
41
|
+
/**
|
|
42
|
+
* Convenience accessor — returns the enum's desired values from a
|
|
43
|
+
* `PostgresEnumType` IR instance.
|
|
44
|
+
*/
|
|
45
|
+
declare function getDesiredEnumValues(typeInstance: PostgresEnumType): readonly string[];
|
|
46
|
+
//#endregion
|
|
47
|
+
export { type EnumDiff, determineEnumDiff, getDesiredEnumValues, readExistingEnumValues };
|
|
48
|
+
//# sourceMappingURL=enum-planning.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"enum-planning.d.mts","names":[],"sources":["../src/core/migrations/enum-planning.ts"],"mappings":";;;;;;;;KAeY,QAAA;EAAA,SACG,IAAA;AAAA;EAAA,SACA,IAAA;EAAA,SAA6B,MAAA;AAAA;EAAA,SAC7B,IAAA;EAAA,SAA0B,aAAA;AAAA;;;;;AAiDzC;;;;;;;;;iBAlCgB,sBAAA,CACd,MAAA,EAAQ,WAAA,EACR,UAAA;;;;;;;;;iBAgCc,iBAAA,CACd,QAAA,qBACA,OAAA,sBACC,QAAA;;;;;iBAoBa,oBAAA,CAAqB,YAAA,EAAc,gBAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors-
|
|
1
|
+
{"version":3,"file":"errors-BiOloWUh.mjs","names":[],"sources":["../src/core/errors.ts"],"sourcesContent":["import { CliStructuredError } from '@prisma-next/errors/control';\n\n/**\n * A `PostgresMigration` instance method that needs the materialized control\n * adapter (currently only `this.dataTransform(...)`) was invoked, but the\n * migration was constructed without a `ControlStack`. Concrete authoring\n * usage always goes through the migration CLI entrypoint, which assembles\n * a stack from the loaded `prisma-next.config.ts`; reaching this error\n * means a test fixture or ad-hoc consumer instantiated `PostgresMigration`\n * with the no-arg form (legal for `operations` / `describe` introspection\n * only).\n *\n * Distinct from `PN-MIG-2001` (placeholder not filled) and `PN-MIG-2005`\n * (data-transform query plan against wrong contract) because the missing\n * input is the stack itself, not the per-operation contract.\n *\n * Lives in `@prisma-next/target-postgres/errors` rather than the shared\n * framework migration errors module because the failure is target-specific:\n * the contract it talks about (`PostgresMigration`, the Postgres control\n * adapter, the Postgres-target stack) only exists in this package.\n */\nexport function errorPostgresMigrationStackMissing(): CliStructuredError {\n return new CliStructuredError(\n '2007',\n 'PostgresMigration.dataTransform requires a control adapter',\n {\n domain: 'MIG',\n why: 'PostgresMigration.dataTransform was invoked on an instance constructed without a ControlStack. The stored controlAdapter is undefined, so dataTransform cannot lower its query plan.',\n fix: 'Construct the migration via the migration CLI entrypoint (which assembles a ControlStack from the loaded prisma-next.config.ts), or pass a ControlStack containing a Postgres adapter to the migration constructor in test fixtures.',\n meta: {},\n },\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAqBA,SAAgB,qCAAyD;CACvE,OAAO,IAAI,mBACT,QACA,8DACA;EACE,QAAQ;EACR,KAAK;EACL,KAAK;EACL,MAAM,EAAE;EACT,CACF"}
|
package/dist/errors.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as errorPostgresMigrationStackMissing } from "./errors-
|
|
1
|
+
import { t as errorPostgresMigrationStackMissing } from "./errors-BiOloWUh.mjs";
|
|
2
2
|
export { errorPostgresMigrationStackMissing };
|
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { n as
|
|
6
|
-
import {
|
|
1
|
+
import { t as PostgresEnumType } from "./postgres-enum-type-DS-KLVRH.mjs";
|
|
2
|
+
import { r as readExistingEnumValues, t as determineEnumDiff } from "./enum-planning-Bqp96iIw.mjs";
|
|
3
|
+
import { i as quoteIdentifier } from "./sql-utils-BewXAnsG.mjs";
|
|
4
|
+
import { a as columnNullabilityCheck, c as qualifyTableName, i as columnHasNoDefaultCheck, r as columnExistsCheck, t as buildExpectedFormatType, u as tableIsEmptyCheck } from "./planner-sql-checks-Cd016Ycs.mjs";
|
|
5
|
+
import { C as SetNotNullCall, S as SetDefaultCall, _ as DropIndexCall, a as AddUniqueCall, b as RawSqlCall, d as CreateTableCall, f as DataTransformCall, g as DropEnumTypeCall, h as DropDefaultCall, i as AddPrimaryKeyCall, l as CreateIndexCall, m as DropConstraintCall, n as AddEnumValuesCall, o as AlterColumnTypeCall, p as DropColumnCall, r as AddForeignKeyCall, s as CreateEnumTypeCall, t as AddColumnCall, v as DropNotNullCall, x as RenameTypeCall, y as DropTableCall } from "./op-factory-call-DerP9BoT.mjs";
|
|
6
|
+
import { n as buildColumnDefaultSql, r as buildColumnTypeSql, t as buildAddColumnSql } from "./planner-ddl-builders-5QIyhBUF.mjs";
|
|
7
|
+
import { n as resolveIdentityValue } from "./planner-identity-values-BUYNOCwb.mjs";
|
|
8
|
+
import { i as hasUniqueConstraint, n as hasForeignKey, t as buildSchemaLookupMap } from "./planner-schema-lookup--u9whY_Y.mjs";
|
|
7
9
|
import { ifDefined } from "@prisma-next/utils/defined";
|
|
10
|
+
import { isPostgresEnumStorageEntry } from "@prisma-next/sql-contract/types";
|
|
8
11
|
import { arraysEqual } from "@prisma-next/family-sql/schema-verify";
|
|
9
12
|
import { notOk, ok } from "@prisma-next/utils/result";
|
|
10
13
|
//#region src/core/migrations/planner-target-details.ts
|
|
@@ -186,8 +189,9 @@ const nullableTighteningCallStrategy = (issues, ctx) => {
|
|
|
186
189
|
function enumRebuildCallRecipe(typeName, ctx) {
|
|
187
190
|
const toType = ctx.toContract.storage.types?.[typeName];
|
|
188
191
|
if (!toType) return [];
|
|
192
|
+
const isEnum = isPostgresEnumStorageEntry(toType);
|
|
189
193
|
const nativeType = toType.nativeType;
|
|
190
|
-
const desiredValues = toType.typeParams["values"] ?? [];
|
|
194
|
+
const desiredValues = isEnum ? toType.values : toType.typeParams["values"] ?? [];
|
|
191
195
|
const tempName = `${nativeType}${REBUILD_SUFFIX}`;
|
|
192
196
|
const columnRefs = [];
|
|
193
197
|
for (const [tableName, table] of Object.entries(ctx.toContract.storage.tables)) for (const [columnName, column] of Object.entries(table.columns)) if (column.typeRef === typeName) columnRefs.push({
|
|
@@ -209,38 +213,92 @@ function enumRebuildCallRecipe(typeName, ctx) {
|
|
|
209
213
|
new RenameTypeCall(ctx.schemaName, tempName, nativeType)
|
|
210
214
|
];
|
|
211
215
|
}
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
216
|
+
/**
|
|
217
|
+
* Single planner strategy for `PostgresEnumType` instances. Walks
|
|
218
|
+
* `toContract.storage.types` directly (no codec-hook dispatch) and
|
|
219
|
+
* resolves existing values via `readExistingEnumValues`, the same
|
|
220
|
+
* Postgres bridging adapter the verifier uses.
|
|
221
|
+
*
|
|
222
|
+
* Per-enum dispatch:
|
|
223
|
+
*
|
|
224
|
+
* - No existing type → `CreateEnumTypeCall` with the contract's desired
|
|
225
|
+
* values.
|
|
226
|
+
* - Diff is `unchanged` → no calls emitted (consumes the matching
|
|
227
|
+
* `enum_values_changed` issue if present).
|
|
228
|
+
* - Diff is `add_values` → `AddEnumValuesCall` with the new labels.
|
|
229
|
+
* - Diff is `rebuild` → the create-temp / migrate-columns /
|
|
230
|
+
* drop-original / rename rebuild recipe. When
|
|
231
|
+
* `policy.allowedOperationClasses` includes `'data'` and the rebuild
|
|
232
|
+
* removes labels (`removedValues.length > 0`), prepend a
|
|
233
|
+
* `DataTransformCall` placeholder so the user can author the value
|
|
234
|
+
* remap before the destructive recipe runs. Without `'data'` in the
|
|
235
|
+
* policy (`db update` / `db init`), the rebuild's PG `USING ::text`
|
|
236
|
+
* cast surfaces any value-removal data loss as a runtime error rather
|
|
237
|
+
* than silent loss.
|
|
238
|
+
*
|
|
239
|
+
* Returns `recipe: true` only when a rebuild recipe was emitted (its
|
|
240
|
+
* `createEnumType(temp) → alterColumnType → dropEnumType(orig) →
|
|
241
|
+
* renameType` sequence mixes `dep`-class and `alter`-class calls that
|
|
242
|
+
* would mis-order if the planner hoisted them into its DDL sequencing
|
|
243
|
+
* buckets). For the create-only and add-values paths the strategy
|
|
244
|
+
* returns `recipe: false` so the planner hoists `CreateEnumTypeCall`
|
|
245
|
+
* into the `dep` bucket — i.e. `CREATE TYPE` runs before any
|
|
246
|
+
* `CreateTableCall` that references the new enum.
|
|
247
|
+
*/
|
|
248
|
+
const nativeEnumPlanCallStrategy = (issues, ctx) => {
|
|
249
|
+
const enumTypes = collectPostgresEnumTypes(ctx.toContract.storage.types);
|
|
250
|
+
if (enumTypes.size === 0) return { kind: "no_match" };
|
|
251
|
+
const dataAllowed = ctx.policy.allowedOperationClasses.includes("data");
|
|
215
252
|
const calls = [];
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
253
|
+
const handledTypeNames = /* @__PURE__ */ new Set();
|
|
254
|
+
const introducedTypeNames = /* @__PURE__ */ new Set();
|
|
255
|
+
const rebuiltTypeNames = /* @__PURE__ */ new Set();
|
|
256
|
+
let emittedRebuildRecipe = false;
|
|
257
|
+
for (const [typeName, enumType] of enumTypes) {
|
|
258
|
+
const desired = enumType.values;
|
|
259
|
+
const existing = readExistingEnumValues(ctx.schema, enumType.nativeType);
|
|
260
|
+
if (!existing) {
|
|
261
|
+
calls.push(new CreateEnumTypeCall(ctx.schemaName, typeName, desired, enumType.nativeType));
|
|
262
|
+
handledTypeNames.add(typeName);
|
|
263
|
+
introducedTypeNames.add(typeName);
|
|
264
|
+
continue;
|
|
224
265
|
}
|
|
266
|
+
const diff = determineEnumDiff(existing, desired);
|
|
267
|
+
if (diff.kind === "unchanged") {
|
|
268
|
+
handledTypeNames.add(typeName);
|
|
269
|
+
continue;
|
|
270
|
+
}
|
|
271
|
+
if (diff.kind === "add_values") {
|
|
272
|
+
calls.push(new AddEnumValuesCall(ctx.schemaName, typeName, enumType.nativeType, diff.values));
|
|
273
|
+
handledTypeNames.add(typeName);
|
|
274
|
+
continue;
|
|
275
|
+
}
|
|
276
|
+
if (dataAllowed && diff.removedValues.length > 0) calls.push(new DataTransformCall(`migrate-${typeName}-values`, `migrate-${typeName}-values:check`, `migrate-${typeName}-values:run`));
|
|
277
|
+
calls.push(...enumRebuildCallRecipe(typeName, ctx));
|
|
278
|
+
emittedRebuildRecipe = true;
|
|
279
|
+
handledTypeNames.add(typeName);
|
|
280
|
+
rebuiltTypeNames.add(typeName);
|
|
225
281
|
}
|
|
226
|
-
if (
|
|
282
|
+
if (introducedTypeNames.size > 0 && rebuiltTypeNames.size > 0) throw new Error(`nativeEnumPlanCallStrategy: cannot emit both a brand-new enum and a rebuild on a different enum in the same plan; the single recipe flag cannot route them to different buckets. Introduced: [${[...introducedTypeNames].sort().join(", ")}]; rebuilt: [${[...rebuiltTypeNames].sort().join(", ")}]. Split the strategy or grow the \`match\` return type before this case lands.`);
|
|
283
|
+
const remaining = issues.filter((issue) => !((issue.kind === "type_missing" || issue.kind === "enum_values_changed") && issue.typeName && handledTypeNames.has(issue.typeName)));
|
|
284
|
+
if (calls.length === 0 && remaining.length === issues.length) return { kind: "no_match" };
|
|
227
285
|
return {
|
|
228
286
|
kind: "match",
|
|
229
|
-
issues:
|
|
287
|
+
issues: remaining,
|
|
230
288
|
calls,
|
|
231
|
-
recipe:
|
|
289
|
+
recipe: emittedRebuildRecipe
|
|
232
290
|
};
|
|
233
291
|
};
|
|
292
|
+
function collectPostgresEnumTypes(storageTypes) {
|
|
293
|
+
const result = /* @__PURE__ */ new Map();
|
|
294
|
+
for (const [name, instance] of Object.entries(storageTypes ?? {}).sort(([a], [b]) => a.localeCompare(b))) if (instance instanceof PostgresEnumType) result.set(name, instance);
|
|
295
|
+
return result;
|
|
296
|
+
}
|
|
234
297
|
/**
|
|
235
|
-
* Dispatches storage types through their codec's
|
|
236
|
-
*
|
|
237
|
-
*
|
|
238
|
-
*
|
|
239
|
-
*
|
|
240
|
-
* Runs after `enumChangeCallStrategy` so the structured enum path (value
|
|
241
|
-
* add, rebuild recipe) gets first pick at `enum_values_changed` issues;
|
|
242
|
-
* this strategy then handles remaining `type_missing` / `enum_values_changed`
|
|
243
|
-
* issues for types whose hook produced at least one op.
|
|
298
|
+
* Dispatches non-enum codec-typed storage types through their codec's
|
|
299
|
+
* `planTypeOperations` hook (the authoritative source for codec-driven DDL
|
|
300
|
+
* such as custom type creation). Enum dispatch lives in
|
|
301
|
+
* `nativeEnumPlanCallStrategy` and no longer relies on codec hooks.
|
|
244
302
|
*/
|
|
245
303
|
const storageTypePlanCallStrategy = (issues, ctx) => {
|
|
246
304
|
const storageTypes = ctx.toContract.storage.types ?? {};
|
|
@@ -248,11 +306,13 @@ const storageTypePlanCallStrategy = (issues, ctx) => {
|
|
|
248
306
|
const calls = [];
|
|
249
307
|
const handledTypeNames = /* @__PURE__ */ new Set();
|
|
250
308
|
for (const [typeName, typeInstance] of Object.entries(storageTypes).sort(([a], [b]) => a.localeCompare(b))) {
|
|
251
|
-
|
|
309
|
+
if (isPostgresEnumStorageEntry(typeInstance)) continue;
|
|
310
|
+
const codecInstance = typeInstance;
|
|
311
|
+
const hook = ctx.codecHooks.get(codecInstance.codecId);
|
|
252
312
|
if (!hook?.planTypeOperations) continue;
|
|
253
313
|
const planResult = hook.planTypeOperations({
|
|
254
314
|
typeName,
|
|
255
|
-
typeInstance,
|
|
315
|
+
typeInstance: codecInstance,
|
|
256
316
|
contract: ctx.toContract,
|
|
257
317
|
schema: ctx.schema,
|
|
258
318
|
schemaName: ctx.schemaName,
|
|
@@ -397,25 +457,33 @@ function canUseSharedTemporaryDefaultStrategy(options) {
|
|
|
397
457
|
* `policy.allowedOperationClasses`:
|
|
398
458
|
*
|
|
399
459
|
* - When `'data'` is allowed (`migration plan`), the data-safe strategies
|
|
400
|
-
* (`
|
|
401
|
-
* `
|
|
402
|
-
* matching issues and emit
|
|
460
|
+
* (`notNullBackfillCallStrategy`, `typeChangeCallStrategy`,
|
|
461
|
+
* `nullableTighteningCallStrategy`) and the enum walk
|
|
462
|
+
* (`nativeEnumPlanCallStrategy`) consume their matching issues and emit
|
|
463
|
+
* `DataTransformCall` placeholders or recipe ops.
|
|
403
464
|
*
|
|
404
|
-
* - When `'data'` is not allowed (`db update` / `db init`),
|
|
405
|
-
*
|
|
406
|
-
* downstream walk-schema strategies
|
|
407
|
-
* `notNullAddColumnCallStrategy`) or the
|
|
408
|
-
* with direct DDL.
|
|
465
|
+
* - When `'data'` is not allowed (`db update` / `db init`), the
|
|
466
|
+
* placeholder-emitting strategies short-circuit to `no_match`, leaving
|
|
467
|
+
* the issue for the downstream walk-schema strategies
|
|
468
|
+
* (`storageTypePlanCallStrategy`, `notNullAddColumnCallStrategy`) or the
|
|
469
|
+
* `mapIssueToCall` default to handle with direct DDL.
|
|
470
|
+
* `nativeEnumPlanCallStrategy` runs in both modes; under `db update` /
|
|
471
|
+
* `db init` it emits the rebuild recipe without the data-transform
|
|
472
|
+
* placeholder so value-removal data loss surfaces as a runtime cast
|
|
473
|
+
* error rather than silent loss.
|
|
409
474
|
*
|
|
410
|
-
*
|
|
411
|
-
*
|
|
412
|
-
* `
|
|
475
|
+
* Enum dispatch is unified into a single strategy: the
|
|
476
|
+
* `nativeEnumPlanCallStrategy` decides per-emission whether to emit a
|
|
477
|
+
* rebuild recipe (`recipe: true`, contiguous slot) or hoist the call
|
|
478
|
+
* into the `dep` bucket (`recipe: false`, so a brand-new
|
|
479
|
+
* `CreateEnumTypeCall` runs before any `CreateTableCall` referencing
|
|
480
|
+
* it). Codec-typed entries continue through `storageTypePlanCallStrategy`.
|
|
413
481
|
*/
|
|
414
482
|
const postgresPlannerStrategies = [
|
|
415
|
-
enumChangeCallStrategy,
|
|
416
483
|
notNullBackfillCallStrategy,
|
|
417
484
|
typeChangeCallStrategy,
|
|
418
485
|
nullableTighteningCallStrategy,
|
|
486
|
+
nativeEnumPlanCallStrategy,
|
|
419
487
|
storageTypePlanCallStrategy,
|
|
420
488
|
notNullAddColumnCallStrategy
|
|
421
489
|
];
|
|
@@ -637,10 +705,7 @@ function mapIssueToCall(issue, ctx) {
|
|
|
637
705
|
if (!issue.typeName) return notOk(issueConflict("unsupportedOperation", "Type missing issue has no typeName"));
|
|
638
706
|
const typeInstance = ctx.toContract.storage.types?.[issue.typeName];
|
|
639
707
|
if (!typeInstance) return notOk(issueConflict("unsupportedOperation", `Type "${issue.typeName}" reported missing but not found in destination contract`));
|
|
640
|
-
if (typeInstance.
|
|
641
|
-
const values = typeInstance.typeParams["values"] ?? [];
|
|
642
|
-
return ok([new CreateEnumTypeCall(schemaName, typeInstance.nativeType, values)]);
|
|
643
|
-
}
|
|
708
|
+
if (typeInstance instanceof PostgresEnumType) return ok([new CreateEnumTypeCall(schemaName, issue.typeName, typeInstance.values, typeInstance.nativeType)]);
|
|
644
709
|
return notOk(issueConflict("unsupportedOperation", `Type "${issue.typeName}" uses codec "${typeInstance.codecId}" — only enum types are supported`));
|
|
645
710
|
}
|
|
646
711
|
case "type_values_mismatch": return notOk(issueConflict("unsupportedOperation", `Type "${issue.typeName ?? "unknown"}" values differ — type alteration not yet supported`));
|
|
@@ -809,4 +874,4 @@ function planIssues(options) {
|
|
|
809
874
|
//#endregion
|
|
810
875
|
export { postgresPlannerStrategies as n, planIssues as t };
|
|
811
876
|
|
|
812
|
-
//# sourceMappingURL=issue-planner-
|
|
877
|
+
//# sourceMappingURL=issue-planner-BhWVYyE1.mjs.map
|