@prisma-next/target-postgres 0.11.0-dev.9 → 0.12.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-D9fJ4HP5.d.mts → codec-ids-DliyCWPY.d.mts} +1 -1
- package/dist/{codec-ids-D9fJ4HP5.d.mts.map → codec-ids-DliyCWPY.d.mts.map} +1 -1
- package/dist/codec-ids.d.mts +1 -1
- package/dist/{codec-types-CRlHq7Cz.d.mts → codec-types-BF1DXTPs.d.mts} +2 -2
- package/dist/codec-types-BF1DXTPs.d.mts.map +1 -0
- package/dist/codec-types.d.mts +1 -1
- package/dist/{codecs-Dud5KDNk.d.mts → codecs-DuP3d9Au.d.mts} +2 -2
- package/dist/{codecs-Dud5KDNk.d.mts.map → codecs-DuP3d9Au.d.mts.map} +1 -1
- package/dist/codecs.d.mts +1 -1
- package/dist/codecs.d.mts.map +1 -1
- package/dist/codecs.mjs.map +1 -1
- package/dist/control.d.mts +1 -1
- package/dist/control.d.mts.map +1 -1
- package/dist/control.mjs +18 -41
- package/dist/control.mjs.map +1 -1
- package/dist/{data-transform-bmOKkygi.d.mts → data-transform-CAPmAdxS.d.mts} +2 -2
- package/dist/data-transform-CAPmAdxS.d.mts.map +1 -0
- package/dist/{data-transform-CdtGUWp2.mjs → data-transform-CRkv2T_U.mjs} +1 -1
- package/dist/{data-transform-CdtGUWp2.mjs.map → data-transform-CRkv2T_U.mjs.map} +1 -1
- package/dist/data-transform.d.mts +1 -1
- package/dist/data-transform.mjs +1 -1
- package/dist/{default-normalizer-DHCsbfjc.mjs → default-normalizer-DaAhmzBV.mjs} +1 -1
- package/dist/{default-normalizer-DHCsbfjc.mjs.map → default-normalizer-DaAhmzBV.mjs.map} +1 -1
- package/dist/default-normalizer.d.mts.map +1 -1
- package/dist/default-normalizer.mjs +1 -1
- package/dist/descriptor-meta-Dvr_77Z3.mjs +13 -0
- package/dist/descriptor-meta-Dvr_77Z3.mjs.map +1 -0
- package/dist/{descriptor-meta-DLA2xV6B.mjs → descriptor-meta-runtime-ByjztWgs.mjs} +81 -77
- package/dist/descriptor-meta-runtime-ByjztWgs.mjs.map +1 -0
- package/dist/enum-planning-DrNWCtCp.mjs +0 -0
- package/dist/enum-planning-DrNWCtCp.mjs.map +1 -0
- package/dist/enum-planning.d.mts +42 -4
- package/dist/enum-planning.d.mts.map +1 -1
- package/dist/enum-planning.mjs +2 -2
- package/dist/{errors--zafB5_n.mjs → errors-BbnITmAD.mjs} +1 -1
- package/dist/{errors--zafB5_n.mjs.map → errors-BbnITmAD.mjs.map} +1 -1
- package/dist/errors.d.mts.map +1 -1
- package/dist/errors.mjs +1 -1
- package/dist/{issue-planner-Ct9xNqbr.mjs → issue-planner-2RgYsjUJ.mjs} +113 -56
- package/dist/issue-planner-2RgYsjUJ.mjs.map +1 -0
- package/dist/issue-planner.d.mts +1 -1
- package/dist/issue-planner.d.mts.map +1 -1
- package/dist/issue-planner.mjs +1 -1
- package/dist/migration.d.mts +3 -3
- package/dist/migration.d.mts.map +1 -1
- package/dist/migration.mjs +3 -3
- package/dist/migration.mjs.map +1 -1
- package/dist/{native-type-normalizer-DMikJJ1V.mjs → native-type-normalizer-BNEQ9VDs.mjs} +1 -1
- package/dist/{native-type-normalizer-DMikJJ1V.mjs.map → native-type-normalizer-BNEQ9VDs.mjs.map} +1 -1
- package/dist/native-type-normalizer.d.mts.map +1 -1
- package/dist/native-type-normalizer.mjs +1 -1
- package/dist/{op-factory-call-Drccm_JD.d.mts → op-factory-call-CDlImOF_.d.mts} +3 -3
- package/dist/op-factory-call-CDlImOF_.d.mts.map +1 -0
- package/dist/{op-factory-call-CB6tPJ3f.mjs → op-factory-call-C_K5ibAY.mjs} +2 -2
- package/dist/{op-factory-call-CB6tPJ3f.mjs.map → op-factory-call-C_K5ibAY.mjs.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 +9 -8
- package/dist/pack.d.mts.map +1 -1
- package/dist/pack.mjs +1 -1
- package/dist/{planner-DlhK35aV.mjs → planner-CC3r_uNJ.mjs} +17 -25
- package/dist/planner-CC3r_uNJ.mjs.map +1 -0
- package/dist/{planner-ddl-builders--0TmW6Ey.mjs → planner-ddl-builders-DgyqpFji.mjs} +3 -3
- package/dist/{planner-ddl-builders--0TmW6Ey.mjs.map → planner-ddl-builders-DgyqpFji.mjs.map} +1 -1
- package/dist/planner-ddl-builders.d.mts +1 -1
- package/dist/planner-ddl-builders.d.mts.map +1 -1
- package/dist/planner-ddl-builders.mjs +1 -1
- package/dist/{planner-identity-values-ojX-6cPV.mjs → planner-identity-values-nhVj0hp-.mjs} +1 -1
- package/dist/{planner-identity-values-ojX-6cPV.mjs.map → planner-identity-values-nhVj0hp-.mjs.map} +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-p-VKkCia.d.mts → planner-produced-postgres-migration-D02NOhVQ.d.mts} +3 -3
- package/dist/planner-produced-postgres-migration-D02NOhVQ.d.mts.map +1 -0
- package/dist/{planner-produced-postgres-migration-TJWH2m_x.mjs → planner-produced-postgres-migration-D_nsXbhl.mjs} +5 -7
- package/dist/planner-produced-postgres-migration-D_nsXbhl.mjs.map +1 -0
- package/dist/planner-produced-postgres-migration.d.mts +1 -1
- package/dist/planner-produced-postgres-migration.mjs +1 -1
- package/dist/{planner-schema-lookup-BGyukuzG.mjs → planner-schema-lookup-CGxxYfnD.mjs} +1 -1
- package/dist/{planner-schema-lookup-BGyukuzG.mjs.map → planner-schema-lookup-CGxxYfnD.mjs.map} +1 -1
- package/dist/planner-schema-lookup.d.mts.map +1 -1
- package/dist/planner-schema-lookup.mjs +1 -1
- package/dist/{planner-sql-checks-BDtJQ9WD.mjs → planner-sql-checks-BMu3fiMc.mjs} +3 -3
- package/dist/{planner-sql-checks-BDtJQ9WD.mjs.map → planner-sql-checks-BMu3fiMc.mjs.map} +1 -1
- package/dist/planner-sql-checks.d.mts.map +1 -1
- package/dist/planner-sql-checks.mjs +1 -1
- package/dist/{planner-target-details-CIj61DUj.d.mts → planner-target-details-a_wuOiYf.d.mts} +1 -1
- package/dist/{planner-target-details-CIj61DUj.d.mts.map → planner-target-details-a_wuOiYf.d.mts.map} +1 -1
- package/dist/planner-target-details.d.mts +1 -1
- package/dist/planner.d.mts +2 -7
- package/dist/planner.d.mts.map +1 -1
- package/dist/planner.mjs +1 -1
- package/dist/{postgres-contract-serializer-CYct4Y7O.mjs → postgres-contract-serializer-C0UtIDB8.mjs} +3 -3
- package/dist/postgres-contract-serializer-C0UtIDB8.mjs.map +1 -0
- package/dist/{postgres-enum-type-CNhPTDhy.d.mts → postgres-enum-type-5MBoKsIj.d.mts} +1 -1
- package/dist/postgres-enum-type-5MBoKsIj.d.mts.map +1 -0
- package/dist/postgres-enum-type-DS-KLVRH.mjs.map +1 -1
- package/dist/{postgres-migration-uADmx0dW.mjs → postgres-migration-BatbEvU6.mjs} +3 -3
- package/dist/{postgres-migration-uADmx0dW.mjs.map → postgres-migration-BatbEvU6.mjs.map} +1 -1
- package/dist/{postgres-migration-Fd4fQkBw.d.mts → postgres-migration-DRY8V-bQ.d.mts} +3 -3
- package/dist/{postgres-migration-Fd4fQkBw.d.mts.map → postgres-migration-DRY8V-bQ.d.mts.map} +1 -1
- package/dist/{postgres-schema-BL0RAvew.mjs → postgres-schema-vp5rvbYg.mjs} +12 -19
- package/dist/postgres-schema-vp5rvbYg.mjs.map +1 -0
- package/dist/{render-ops-BC2PtCkj.mjs → render-ops-XhICjX_P.mjs} +1 -1
- package/dist/{render-ops-BC2PtCkj.mjs.map → render-ops-XhICjX_P.mjs.map} +1 -1
- package/dist/render-ops.d.mts +1 -1
- package/dist/render-ops.d.mts.map +1 -1
- package/dist/render-ops.mjs +1 -1
- package/dist/{render-typescript-CI1wbgUc.mjs → render-typescript-K125n-RZ.mjs} +2 -3
- package/dist/render-typescript-K125n-RZ.mjs.map +1 -0
- package/dist/render-typescript.d.mts +0 -1
- package/dist/render-typescript.d.mts.map +1 -1
- package/dist/render-typescript.mjs +1 -1
- package/dist/runtime.d.mts.map +1 -1
- package/dist/runtime.mjs +3 -3
- package/dist/runtime.mjs.map +1 -1
- package/dist/{shared-ByhSooBS.d.mts → shared-Do_a5ymU.d.mts} +2 -2
- package/dist/shared-Do_a5ymU.d.mts.map +1 -0
- package/dist/{sql-utils-BewXAnsG.mjs → sql-utils-CggjWNij.mjs} +1 -1
- package/dist/{sql-utils-BewXAnsG.mjs.map → sql-utils-CggjWNij.mjs.map} +1 -1
- package/dist/sql-utils.d.mts.map +1 -1
- package/dist/sql-utils.mjs +1 -1
- package/dist/{statement-builders-vImtdfmM.mjs → statement-builders-DVI5IVAa.mjs} +1 -1
- package/dist/statement-builders-DVI5IVAa.mjs.map +1 -0
- package/dist/statement-builders.d.mts +1 -1
- package/dist/statement-builders.d.mts.map +1 -1
- package/dist/statement-builders.mjs +1 -1
- package/dist/{tables-Vhh4k5yz.mjs → tables-C8RrPLUq.mjs} +3 -3
- package/dist/{tables-Vhh4k5yz.mjs.map → tables-C8RrPLUq.mjs.map} +1 -1
- package/dist/{types-D-XIpzHA.d.mts → types-O40IcFV9.d.mts} +1 -1
- package/dist/types-O40IcFV9.d.mts.map +1 -0
- package/dist/types.d.mts +12 -16
- package/dist/types.d.mts.map +1 -1
- package/dist/types.mjs +1 -1
- package/package.json +29 -18
- package/src/core/authoring.ts +1 -1
- package/src/core/descriptor-meta-runtime.ts +28 -0
- package/src/core/descriptor-meta.ts +2 -6
- package/src/core/migrations/enum-planning.ts +134 -14
- package/src/core/migrations/issue-planner.ts +20 -11
- package/src/core/migrations/planner-produced-postgres-migration.ts +0 -2
- package/src/core/migrations/planner-strategies.ts +138 -40
- package/src/core/migrations/planner.ts +9 -21
- package/src/core/migrations/render-typescript.ts +1 -5
- package/src/core/migrations/runner.ts +20 -61
- package/src/core/migrations/statement-builders.ts +1 -1
- package/src/core/migrations/verify-postgres-namespaces.ts +6 -6
- package/src/core/postgres-contract-serializer.ts +4 -4
- package/src/core/postgres-schema.ts +10 -20
- package/src/exports/control.ts +16 -0
- package/src/exports/enum-planning.ts +5 -0
- package/src/exports/runtime.ts +2 -2
- package/dist/codec-types-CRlHq7Cz.d.mts.map +0 -1
- package/dist/data-transform-bmOKkygi.d.mts.map +0 -1
- package/dist/descriptor-meta-DLA2xV6B.mjs.map +0 -1
- package/dist/enum-planning-Bqp96iIw.mjs +0 -63
- package/dist/enum-planning-Bqp96iIw.mjs.map +0 -1
- package/dist/issue-planner-Ct9xNqbr.mjs.map +0 -1
- package/dist/op-factory-call-Drccm_JD.d.mts.map +0 -1
- package/dist/planner-DlhK35aV.mjs.map +0 -1
- package/dist/planner-produced-postgres-migration-TJWH2m_x.mjs.map +0 -1
- package/dist/planner-produced-postgres-migration-p-VKkCia.d.mts.map +0 -1
- package/dist/postgres-contract-serializer-CYct4Y7O.mjs.map +0 -1
- package/dist/postgres-enum-type-CNhPTDhy.d.mts.map +0 -1
- package/dist/postgres-schema-BL0RAvew.mjs.map +0 -1
- package/dist/render-typescript-CI1wbgUc.mjs.map +0 -1
- package/dist/shared-ByhSooBS.d.mts.map +0 -1
- package/dist/statement-builders-vImtdfmM.mjs.map +0 -1
- package/dist/types-D-XIpzHA.d.mts.map +0 -1
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { ContractMarkerRecord } from '@prisma-next/contract/types';
|
|
2
2
|
import type {
|
|
3
3
|
MigrationOperationPolicy,
|
|
4
|
-
MultiSpaceRunnerResult,
|
|
5
4
|
SqlControlFamilyInstance,
|
|
6
5
|
SqlMigrationPlanContractInfo,
|
|
7
6
|
SqlMigrationPlanOperation,
|
|
@@ -14,15 +13,19 @@ import type {
|
|
|
14
13
|
} from '@prisma-next/family-sql/control';
|
|
15
14
|
import { runnerFailure, runnerSuccess } from '@prisma-next/family-sql/control';
|
|
16
15
|
import { verifySqlSchema } from '@prisma-next/family-sql/schema-verify';
|
|
17
|
-
import type {
|
|
16
|
+
import type {
|
|
17
|
+
ControlDriverInstance,
|
|
18
|
+
MigrationRunnerResult,
|
|
19
|
+
} from '@prisma-next/framework-components/control';
|
|
18
20
|
import { APP_SPACE_ID } from '@prisma-next/framework-components/control';
|
|
21
|
+
import { UNBOUND_NAMESPACE_ID } from '@prisma-next/framework-components/ir';
|
|
19
22
|
import { SqlQueryError } from '@prisma-next/sql-errors';
|
|
20
23
|
import { ifDefined } from '@prisma-next/utils/defined';
|
|
21
24
|
import type { Result } from '@prisma-next/utils/result';
|
|
22
25
|
import { notOk, ok, okVoid } from '@prisma-next/utils/result';
|
|
23
26
|
import { parsePostgresDefault } from '../default-normalizer';
|
|
24
27
|
import { normalizeSchemaNativeType } from '../native-type-normalizer';
|
|
25
|
-
import {
|
|
28
|
+
import { createResolveExistingEnumValues } from './enum-planning';
|
|
26
29
|
import type { PostgresPlanTargetDetails } from './planner-target-details';
|
|
27
30
|
import {
|
|
28
31
|
buildLedgerInsertStatement,
|
|
@@ -33,19 +36,11 @@ import {
|
|
|
33
36
|
type SqlStatement,
|
|
34
37
|
} from './statement-builders';
|
|
35
38
|
|
|
36
|
-
interface RunnerConfig {
|
|
37
|
-
readonly defaultSchema: string;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
39
|
interface ApplyPlanSuccessValue {
|
|
41
40
|
readonly operationsExecuted: number;
|
|
42
41
|
readonly executedOperations: readonly SqlMigrationPlanOperation<PostgresPlanTargetDetails>[];
|
|
43
42
|
}
|
|
44
43
|
|
|
45
|
-
const DEFAULT_CONFIG: RunnerConfig = {
|
|
46
|
-
defaultSchema: 'public',
|
|
47
|
-
};
|
|
48
|
-
|
|
49
44
|
const LOCK_DOMAIN = 'prisma_next.contract.marker';
|
|
50
45
|
|
|
51
46
|
/**
|
|
@@ -58,13 +53,10 @@ function cloneAndFreezeRecord<T extends Record<string, unknown>>(value: T): T {
|
|
|
58
53
|
if (val === null || val === undefined) {
|
|
59
54
|
cloned[key] = val;
|
|
60
55
|
} else if (Array.isArray(val)) {
|
|
61
|
-
// Clone array (shallow clone of array elements)
|
|
62
56
|
cloned[key] = Object.freeze([...val]);
|
|
63
57
|
} else if (typeof val === 'object') {
|
|
64
|
-
// Recursively clone nested objects
|
|
65
58
|
cloned[key] = cloneAndFreezeRecord(val as Record<string, unknown>);
|
|
66
59
|
} else {
|
|
67
|
-
// Primitives are copied as-is
|
|
68
60
|
cloned[key] = val;
|
|
69
61
|
}
|
|
70
62
|
}
|
|
@@ -73,61 +65,27 @@ function cloneAndFreezeRecord<T extends Record<string, unknown>>(value: T): T {
|
|
|
73
65
|
|
|
74
66
|
export function createPostgresMigrationRunner(
|
|
75
67
|
family: SqlControlFamilyInstance,
|
|
76
|
-
config: Partial<RunnerConfig> = {},
|
|
77
68
|
): SqlMigrationRunner<PostgresPlanTargetDetails> {
|
|
78
|
-
return new PostgresMigrationRunner(family
|
|
69
|
+
return new PostgresMigrationRunner(family);
|
|
79
70
|
}
|
|
80
71
|
|
|
81
72
|
class PostgresMigrationRunner implements SqlMigrationRunner<PostgresPlanTargetDetails> {
|
|
82
|
-
constructor(
|
|
83
|
-
private readonly family: SqlControlFamilyInstance,
|
|
84
|
-
private readonly config: RunnerConfig,
|
|
85
|
-
) {}
|
|
86
|
-
|
|
87
|
-
async execute(
|
|
88
|
-
options: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>,
|
|
89
|
-
): Promise<SqlMigrationRunnerResult> {
|
|
90
|
-
const driver = options.driver;
|
|
91
|
-
|
|
92
|
-
// Static checks fail fast before any transaction work — no point
|
|
93
|
-
// burning a BEGIN/ROLLBACK round-trip on a destination-contract
|
|
94
|
-
// mismatch the caller can fix locally.
|
|
95
|
-
const destinationCheck = this.ensurePlanMatchesDestinationContract(
|
|
96
|
-
options.plan.destination,
|
|
97
|
-
options.destinationContract,
|
|
98
|
-
);
|
|
99
|
-
if (!destinationCheck.ok) return destinationCheck;
|
|
100
|
-
|
|
101
|
-
const policyCheck = this.enforcePolicyCompatibility(options.policy, options.plan.operations);
|
|
102
|
-
if (!policyCheck.ok) return policyCheck;
|
|
103
|
-
|
|
104
|
-
await this.beginTransaction(driver);
|
|
105
|
-
let committed = false;
|
|
106
|
-
try {
|
|
107
|
-
const result = await this.executeOnConnection(options);
|
|
108
|
-
if (!result.ok) {
|
|
109
|
-
return result;
|
|
110
|
-
}
|
|
111
|
-
await this.commitTransaction(driver);
|
|
112
|
-
committed = true;
|
|
113
|
-
return result;
|
|
114
|
-
} finally {
|
|
115
|
-
if (!committed) {
|
|
116
|
-
await this.rollbackTransaction(driver);
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
}
|
|
73
|
+
constructor(private readonly family: SqlControlFamilyInstance) {}
|
|
120
74
|
|
|
121
75
|
/**
|
|
122
76
|
* Body of the migration runner without transaction management. The
|
|
123
|
-
* caller (
|
|
124
|
-
* outer-tx orchestrator at the SQL family level) owns the
|
|
77
|
+
* caller ({@link PostgresMigrationRunner.execute}) owns the
|
|
125
78
|
* `BEGIN`/`COMMIT`/`ROLLBACK` lifecycle.
|
|
126
79
|
*/
|
|
127
80
|
async executeOnConnection(
|
|
128
81
|
options: SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>,
|
|
129
82
|
): Promise<SqlMigrationRunnerResult> {
|
|
130
|
-
const schema =
|
|
83
|
+
const schema =
|
|
84
|
+
options.schemaName ??
|
|
85
|
+
Object.keys(options.destinationContract.storage.namespaces).find(
|
|
86
|
+
(id) => id !== UNBOUND_NAMESPACE_ID,
|
|
87
|
+
) ??
|
|
88
|
+
UNBOUND_NAMESPACE_ID;
|
|
131
89
|
const driver = options.driver;
|
|
132
90
|
if (options.space !== undefined && options.space !== options.plan.spaceId) {
|
|
133
91
|
throw new Error(
|
|
@@ -188,8 +146,9 @@ class PostgresMigrationRunner implements SqlMigrationRunner<PostgresPlanTargetDe
|
|
|
188
146
|
frameworkComponents: options.frameworkComponents,
|
|
189
147
|
normalizeDefault: parsePostgresDefault,
|
|
190
148
|
normalizeNativeType: normalizeSchemaNativeType,
|
|
191
|
-
resolveExistingEnumValues: (
|
|
192
|
-
|
|
149
|
+
resolveExistingEnumValues: createResolveExistingEnumValues(
|
|
150
|
+
options.destinationContract.storage,
|
|
151
|
+
),
|
|
193
152
|
});
|
|
194
153
|
if (!schemaVerifyResult.ok) {
|
|
195
154
|
return runnerFailure('SCHEMA_VERIFY_FAILED', schemaVerifyResult.summary, {
|
|
@@ -216,12 +175,12 @@ class PostgresMigrationRunner implements SqlMigrationRunner<PostgresPlanTargetDe
|
|
|
216
175
|
});
|
|
217
176
|
}
|
|
218
177
|
|
|
219
|
-
async
|
|
178
|
+
async execute(options: {
|
|
220
179
|
readonly driver: ControlDriverInstance<'sql', string>;
|
|
221
180
|
readonly perSpaceOptions: ReadonlyArray<
|
|
222
181
|
SqlMigrationRunnerExecuteOptions<PostgresPlanTargetDetails>
|
|
223
182
|
>;
|
|
224
|
-
}): Promise<
|
|
183
|
+
}): Promise<MigrationRunnerResult> {
|
|
225
184
|
const driver = options.driver;
|
|
226
185
|
const perSpaceOptions = options.perSpaceOptions;
|
|
227
186
|
|
|
@@ -56,7 +56,7 @@ export interface MergeMarkerInput {
|
|
|
56
56
|
* Logical space identifier for this marker row. Required at every
|
|
57
57
|
* call site so the type system surfaces every place that needs to
|
|
58
58
|
* thread the value (rather than letting an `?? APP_SPACE_ID`
|
|
59
|
-
* fall-through silently collapse
|
|
59
|
+
* fall-through silently collapse per-space markers onto the
|
|
60
60
|
* `'app'` row). App-plan callers pass {@link APP_SPACE_ID}
|
|
61
61
|
* (`'app'`); per-extension callers (planner / runner / verifier
|
|
62
62
|
* extensions over contract spaces) pass the extension's space id.
|
|
@@ -52,12 +52,12 @@ function existingSchemasFromSchema(schema: SqlSchemaIR): readonly string[] {
|
|
|
52
52
|
*
|
|
53
53
|
* A namespace's live container is the schema returned by its
|
|
54
54
|
* polymorphic `ddlSchemaName(storage)` method — named schemas resolve
|
|
55
|
-
* to their own id
|
|
56
|
-
*
|
|
57
|
-
* emitted only when the resolved name is a real,
|
|
58
|
-
* (not the unbound sentinel) and is missing from the
|
|
59
|
-
* list. `public` is suppressed implicitly because the
|
|
60
|
-
* (or its sensible default) always carries it.
|
|
55
|
+
* to their own id; the unbound singleton returns `UNBOUND_NAMESPACE_ID`
|
|
56
|
+
* and is skipped explicitly (late-bound namespaces have no fixed DDL
|
|
57
|
+
* schema). Issues are emitted only when the resolved name is a real,
|
|
58
|
+
* creatable schema (not the unbound sentinel) and is missing from the
|
|
59
|
+
* introspected list. `public` is suppressed implicitly because the
|
|
60
|
+
* introspection (or its sensible default) always carries it.
|
|
61
61
|
*
|
|
62
62
|
* Each emitted issue stamps `namespaceId` with the contract namespace
|
|
63
63
|
* coordinate so the downstream `mapIssueToCall` re-resolves the DDL
|
|
@@ -117,10 +117,10 @@ export class PostgresContractSerializer extends SqlContractSerializerBase<Contra
|
|
|
117
117
|
if (isPostgresSchema(ns)) {
|
|
118
118
|
namespacesJson[nsId] = this.serializePostgresNamespace(ns, ns.id === UNBOUND_NAMESPACE_ID);
|
|
119
119
|
} else {
|
|
120
|
-
// Family-level
|
|
121
|
-
// been promoted to a PostgresSchema instance
|
|
122
|
-
// straight from the TS builder
|
|
123
|
-
//
|
|
120
|
+
// Family-level SqlUnboundNamespace or other family-built SQL
|
|
121
|
+
// namespaces haven't been promoted to a PostgresSchema instance
|
|
122
|
+
// yet (e.g. they came straight from the TS builder before a target
|
|
123
|
+
// `createNamespace` factory ran). Serialise them as postgres-schema /
|
|
124
124
|
// postgres-unbound-schema so the round-trip through
|
|
125
125
|
// deserializeContract hydrates them back into PostgresSchema
|
|
126
126
|
// instances.
|
|
@@ -120,10 +120,11 @@ export class PostgresSchema extends NamespaceBase {
|
|
|
120
120
|
* statements that need to identify this namespace in the live
|
|
121
121
|
* database (e.g. `CREATE TABLE "<ddlSchemaName>"."<table>" …`,
|
|
122
122
|
* catalog filters, planner conflict lookups). Named schemas resolve
|
|
123
|
-
* to their own id
|
|
124
|
-
*
|
|
125
|
-
*
|
|
126
|
-
*
|
|
123
|
+
* to their own id. The `PostgresUnboundSchema` singleton inherits
|
|
124
|
+
* this and returns `UNBOUND_NAMESPACE_ID` — callers that dispatch
|
|
125
|
+
* through `qualifyTableName` / `toRegclassLiteral` route through the
|
|
126
|
+
* polymorphic `PostgresUnboundSchema` overrides and produce
|
|
127
|
+
* unqualified (search-path-resolved) output automatically.
|
|
127
128
|
*/
|
|
128
129
|
ddlSchemaName(_storage: SqlStorage): string {
|
|
129
130
|
return this.id;
|
|
@@ -143,6 +144,11 @@ export class PostgresSchema extends NamespaceBase {
|
|
|
143
144
|
* sentinel; Postgres decides what late-bound means here (the table
|
|
144
145
|
* name, naked — the schema is supplied by the live connection's
|
|
145
146
|
* `search_path`).
|
|
147
|
+
*
|
|
148
|
+
* `ddlSchemaName` is inherited from `PostgresSchema` and returns
|
|
149
|
+
* `UNBOUND_NAMESPACE_ID`. Downstream helpers (`qualifyTableName`,
|
|
150
|
+
* `toRegclassLiteral`) route through the polymorphic factory and
|
|
151
|
+
* produce unqualified output automatically.
|
|
146
152
|
*/
|
|
147
153
|
export class PostgresUnboundSchema extends PostgresSchema {
|
|
148
154
|
static readonly instance: PostgresUnboundSchema = new PostgresUnboundSchema();
|
|
@@ -162,22 +168,6 @@ export class PostgresUnboundSchema extends PostgresSchema {
|
|
|
162
168
|
override schemaSqlExpression(): string {
|
|
163
169
|
return 'current_schema()';
|
|
164
170
|
}
|
|
165
|
-
|
|
166
|
-
/**
|
|
167
|
-
* The unbound slot has no schema name of its own, so DDL emission
|
|
168
|
-
* projects it onto a sibling when one is available: if the contract
|
|
169
|
-
* carries a `public` namespace, the late-bound slot resolves to
|
|
170
|
-
* `'public'` (the default Postgres landing schema); otherwise it
|
|
171
|
-
* resolves to the framework sentinel `UNBOUND_NAMESPACE_ID` so the
|
|
172
|
-
* planner can recognise the unprojected case and route accordingly
|
|
173
|
-
* (e.g. emit a conflict instead of silently picking a schema).
|
|
174
|
-
*/
|
|
175
|
-
override ddlSchemaName(storage: SqlStorage): string {
|
|
176
|
-
if (storage.namespaces['public'] !== undefined) {
|
|
177
|
-
return 'public';
|
|
178
|
-
}
|
|
179
|
-
return UNBOUND_NAMESPACE_ID;
|
|
180
|
-
}
|
|
181
171
|
}
|
|
182
172
|
|
|
183
173
|
PostgresSchema.unbound = PostgresUnboundSchema.instance;
|
package/src/exports/control.ts
CHANGED
|
@@ -12,6 +12,10 @@ import type {
|
|
|
12
12
|
import type { SqlStorage, StorageColumn } from '@prisma-next/sql-contract/types';
|
|
13
13
|
import { ifDefined } from '@prisma-next/utils/defined';
|
|
14
14
|
import { postgresTargetDescriptorMeta } from '../core/descriptor-meta';
|
|
15
|
+
import {
|
|
16
|
+
enumStorageCompoundKey,
|
|
17
|
+
resolveDdlSchemaForNamespaceStorage,
|
|
18
|
+
} from '../core/migrations/enum-planning';
|
|
15
19
|
import { createPostgresMigrationPlanner } from '../core/migrations/planner';
|
|
16
20
|
import { renderDefaultLiteral } from '../core/migrations/planner-ddl-builders';
|
|
17
21
|
import type { PostgresPlanTargetDetails } from '../core/migrations/planner-target-details';
|
|
@@ -78,6 +82,18 @@ const postgresTargetDescriptor: SqlControlTargetDescriptor<'postgres', PostgresP
|
|
|
78
82
|
annotationNamespace: 'pg',
|
|
79
83
|
...ifDefined('expandNativeType', expander),
|
|
80
84
|
renderDefault: postgresRenderDefault,
|
|
85
|
+
// Schema-qualify enum annotation keys so the projected "from" IR's
|
|
86
|
+
// `storageTypes` match `readExistingEnumValues` on the read side
|
|
87
|
+
// (the contract-to-contract `migration plan` path). The DDL-schema
|
|
88
|
+
// resolution + compound-key format stay here in the target layer;
|
|
89
|
+
// the family projector treats the returned string as opaque.
|
|
90
|
+
// `undefined` schema IR ⇒ the unbound coordinate resolves to the
|
|
91
|
+
// default `public` landing schema, matching the read-side fallback.
|
|
92
|
+
resolveEnumStorageKey: (storage, namespaceId, nativeType) =>
|
|
93
|
+
enumStorageCompoundKey(
|
|
94
|
+
resolveDdlSchemaForNamespaceStorage(storage, namespaceId, undefined),
|
|
95
|
+
nativeType,
|
|
96
|
+
),
|
|
81
97
|
});
|
|
82
98
|
},
|
|
83
99
|
},
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
export {
|
|
2
|
+
createResolveExistingEnumValues,
|
|
2
3
|
determineEnumDiff,
|
|
3
4
|
type EnumDiff,
|
|
5
|
+
enumStorageCompoundKey,
|
|
4
6
|
getDesiredEnumValues,
|
|
7
|
+
type PostgresSchemaIrAnnotations,
|
|
5
8
|
readExistingEnumValues,
|
|
9
|
+
readPostgresSchemaIrAnnotations,
|
|
10
|
+
resolveDdlSchemaForNamespaceStorage,
|
|
6
11
|
} from '../core/migrations/enum-planning';
|
package/src/exports/runtime.ts
CHANGED
|
@@ -3,7 +3,7 @@ import type {
|
|
|
3
3
|
RuntimeTargetDescriptor,
|
|
4
4
|
RuntimeTargetInstance,
|
|
5
5
|
} from '@prisma-next/framework-components/execution';
|
|
6
|
-
import {
|
|
6
|
+
import { postgresTargetDescriptorMetaRuntime } from '../core/descriptor-meta-runtime';
|
|
7
7
|
|
|
8
8
|
export { PostgresContractSerializer } from '../core/postgres-contract-serializer';
|
|
9
9
|
|
|
@@ -22,7 +22,7 @@ const postgresRuntimeTargetDescriptor: RuntimeTargetDescriptor<
|
|
|
22
22
|
> & {
|
|
23
23
|
readonly codecs: () => readonly AnyCodecDescriptor[];
|
|
24
24
|
} = {
|
|
25
|
-
...
|
|
25
|
+
...postgresTargetDescriptorMetaRuntime,
|
|
26
26
|
codecs: () => [],
|
|
27
27
|
create(): PostgresRuntimeTargetInstance {
|
|
28
28
|
return {
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"codec-types-CRlHq7Cz.d.mts","names":[],"sources":["../src/core/codec-type-map.ts","../src/exports/codec-types.ts"],"mappings":";;;;;;cA4Ca,kBAAA;EAAA,eA8BH,uCAAA,CAAA,iBAAA;EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAEE,OAAA,6BAAoC,CAAA,0BAA2B,CAAA,CAAE,CAAA,IAAK,CAAA,CAAE,CAAA,EAAG,CAAA;AAAA,KAE3E,kBAAA,UAA4B,kBAAA;AAAA,KAE5B,mBAAA,GAAsB,iBAAA,CAAkB,kBAAA;;;KCrExC,UAAA,GAAa,OAAA,CAAQ,mBAAA;AAAA,KAI5B,OAAA,kBAAyB,MAAA,qBAA2B,CAAA,0BAClC,KAAA,GAAQ,KAAA,CAAM,CAAA;AAAA,KAGhC,aAAA,eAA4B,MAAA,qBAA2B,OAAA,SAAgB,KAAA;AAAA,KAEhE,IAAA,qBAAyB,aAAA;EAAgB,YAAA,EAAc,CAAA;AAAA;AAAA,KACvD,OAAA,qBAA4B,aAAA;EAAgB,eAAA,EAAiB,CAAA;AAAA;AAAA,KAC7D,OAAA,+DAAsE,aAAA;EAChF,kBAAA,EAAoB,CAAA;EACpB,cAAA,EAAgB,CAAA;AAAA;AAAA,KAEN,GAAA,qBAAwB,aAAA;EAAgB,WAAA,EAAa,CAAA;AAAA;AAAA,KACrD,MAAA,qBAA2B,aAAA;EAAgB,cAAA,EAAgB,CAAA;AAAA;AAAA,KAC3D,SAAA,6CAAsD,aAAA;EAChE,oBAAA,EAAsB,CAAA;AAAA;AAAA,KAEZ,WAAA,6CAAwD,aAAA;EAClE,sBAAA,EAAwB,CAAA;AAAA;AAAA,KAEd,IAAA,6CAAiD,aAAA;EAAgB,eAAA,EAAiB,CAAA;AAAA;AAAA,KAClF,MAAA,6CAAmD,aAAA;EAC7D,iBAAA,EAAmB,CAAA;AAAA;AAAA,KAET,QAAA,6CAAqD,aAAA;EAC/D,mBAAA,EAAqB,CAAA;AAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"data-transform-bmOKkygi.d.mts","names":[],"sources":["../src/core/migrations/operations/data-transform.ts"],"mappings":";;;;;;;;UAqEU,SAAA;EACR,KAAA,IAAS,YAAA,CAAa,CAAA;AAAA;;;;;KAOZ,oBAAA,SAA6B,YAAA,GAAe,SAAA;AAAA,UAEvC,oBAAA;;;;;;WAMN,WAAA;;;;;;;;WAQA,KAAA,GAAQ,oBAAA;;WAER,GAAA,EAAK,oBAAA,YAAgC,oBAAA;AAAA;AAAA,iBAGhC,aAAA,mBAAgC,QAAA,CAAS,UAAA,EAAA,CACvD,QAAA,EAAU,SAAA,EACV,IAAA,UACA,OAAA,EAAS,oBAAA,EACT,OAAA,EAAS,iBAAA,eACR,yBAAA,CAA0B,yBAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"descriptor-meta-DLA2xV6B.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 { PostgresEnumTypeSchema } from '@prisma-next/sql-contract/validators';\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 validatorSchema: PostgresEnumTypeSchema,\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":";;;;AAUA,MAAa,yBAAyB,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgCxC,MAAa,+BAA+B,EAC1C,MAAM;CACJ,MAAM;CACN,eAAe;CACf,iBAAiB;CACjB,QAAQ,EACN,UAAU,UACR,IAAI,iBAAiB,MAAM,EAC9B;CACF,EACF;AC/BD,MAAa,+BAET;CAfF,MAAM;CACN,UAAU;CACV,UAAU;CACV,IAAI;CACJ,SAAS;CACT,cAAc,EAAE;CAChB,WAAW;EACT,MAAM;EACN,OAAO;GD+CT,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;GCjHO;EACP,aAAa;EACd;CAKC"}
|
|
@@ -1,63 +0,0 @@
|
|
|
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
|
|
@@ -1 +0,0 @@
|
|
|
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"}
|