@prisma-next/target-postgres 0.12.0-dev.40 → 0.12.0-dev.42
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-Cx7C07Y_.d.mts → codec-ids-FtNuF4-j.d.mts} +1 -1
- package/dist/{codec-ids-Cx7C07Y_.d.mts.map → codec-ids-FtNuF4-j.d.mts.map} +1 -1
- package/dist/codec-ids.d.mts +1 -1
- package/dist/{codec-types-BoxMGJk-.d.mts → codec-types-dvHkxz5r.d.mts} +2 -2
- package/dist/{codec-types-BoxMGJk-.d.mts.map → codec-types-dvHkxz5r.d.mts.map} +1 -1
- package/dist/codec-types.d.mts +1 -1
- package/dist/{codecs-DCSyTOCb.d.mts → codecs-DTYQIuS9.d.mts} +2 -2
- package/dist/{codecs-DCSyTOCb.d.mts.map → codecs-DTYQIuS9.d.mts.map} +1 -1
- package/dist/codecs.d.mts +1 -1
- package/dist/contract-free.d.mts +1 -1
- package/dist/contract-free.mjs +1 -1
- package/dist/control.d.mts +1 -1
- package/dist/control.mjs +7 -9
- package/dist/control.mjs.map +1 -1
- package/dist/{data-transform-DIYwbe4S.mjs → data-transform-4QL41_vQ.mjs} +1 -1
- package/dist/{data-transform-DIYwbe4S.mjs.map → data-transform-4QL41_vQ.mjs.map} +1 -1
- package/dist/{data-transform-5gLOgP68.d.mts → data-transform-DI2h0oin.d.mts} +2 -2
- package/dist/{data-transform-5gLOgP68.d.mts.map → data-transform-DI2h0oin.d.mts.map} +1 -1
- package/dist/data-transform.d.mts +1 -1
- package/dist/data-transform.mjs +1 -1
- package/dist/ddl.d.mts +1 -1
- package/dist/ddl.mjs +1 -1
- package/dist/{default-normalizer-DFHtpCPH.mjs → default-normalizer-DaAhmzBV.mjs} +1 -1
- package/dist/{default-normalizer-DFHtpCPH.mjs.map → default-normalizer-DaAhmzBV.mjs.map} +1 -1
- package/dist/default-normalizer.mjs +1 -1
- package/dist/{descriptor-meta-BqATo5Dz.mjs → descriptor-meta-C_03xPpF.mjs} +2 -2
- package/dist/{descriptor-meta-BqATo5Dz.mjs.map → descriptor-meta-C_03xPpF.mjs.map} +1 -1
- package/dist/{descriptor-meta-runtime-BBL7VdnR.mjs → descriptor-meta-runtime-DMRX39kp.mjs} +2 -2
- package/dist/{descriptor-meta-runtime-BBL7VdnR.mjs.map → descriptor-meta-runtime-DMRX39kp.mjs.map} +1 -1
- package/dist/{enum-planning-Nt9TYPHe.mjs → enum-planning-BiM4ayjv.mjs} +0 -0
- package/dist/{enum-planning-Nt9TYPHe.mjs.map → enum-planning-BiM4ayjv.mjs.map} +1 -1
- package/dist/enum-planning.d.mts +1 -1
- package/dist/enum-planning.mjs +1 -1
- package/dist/{errors-De185dnO.mjs → errors-BhiZYTWZ.mjs} +1 -1
- package/dist/{errors-De185dnO.mjs.map → errors-BhiZYTWZ.mjs.map} +1 -1
- package/dist/errors.mjs +1 -1
- package/dist/{issue-planner-SUBi9fH8.mjs → issue-planner-CSI6tqIH.mjs} +22 -23
- package/dist/issue-planner-CSI6tqIH.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.mjs +3 -3
- package/dist/{native-type-normalizer-BUUe8USD.mjs → native-type-normalizer-BNEQ9VDs.mjs} +1 -1
- package/dist/{native-type-normalizer-BUUe8USD.mjs.map → native-type-normalizer-BNEQ9VDs.mjs.map} +1 -1
- package/dist/native-type-normalizer.mjs +1 -1
- package/dist/{nodes-DCC8-DhV.mjs → nodes-Bh9HwoPz.mjs} +1 -1
- package/dist/{nodes-DCC8-DhV.mjs.map → nodes-Bh9HwoPz.mjs.map} +1 -1
- package/dist/{nodes-DflxwrE8.d.mts → nodes-CpRAsb10.d.mts} +1 -1
- package/dist/{nodes-DflxwrE8.d.mts.map → nodes-CpRAsb10.d.mts.map} +1 -1
- package/dist/{op-factory-call-B-HEOf41.d.mts → op-factory-call-CPgAPA7b.d.mts} +3 -3
- package/dist/{op-factory-call-B-HEOf41.d.mts.map → op-factory-call-CPgAPA7b.d.mts.map} +1 -1
- package/dist/{op-factory-call-D8XePTfV.mjs → op-factory-call-iwM_BC7t.mjs} +2 -2
- package/dist/{op-factory-call-D8XePTfV.mjs.map → op-factory-call-iwM_BC7t.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 +2 -2
- package/dist/pack.mjs +1 -1
- package/dist/{planner-BruD4_LM.mjs → planner-DJy7-gh_.mjs} +9 -11
- package/dist/planner-DJy7-gh_.mjs.map +1 -0
- package/dist/{planner-ddl-builders-BcRMeGgx.mjs → planner-ddl-builders-CI0BrI_f.mjs} +3 -3
- package/dist/{planner-ddl-builders-BcRMeGgx.mjs.map → planner-ddl-builders-CI0BrI_f.mjs.map} +1 -1
- package/dist/planner-ddl-builders.d.mts +1 -1
- package/dist/planner-ddl-builders.mjs +1 -1
- package/dist/{planner-identity-values-DmwlJe_z.mjs → planner-identity-values-DfiMb2C9.mjs} +1 -1
- package/dist/{planner-identity-values-DmwlJe_z.mjs.map → planner-identity-values-DfiMb2C9.mjs.map} +1 -1
- package/dist/planner-identity-values.mjs +1 -1
- package/dist/{planner-produced-postgres-migration-Co71_VbU.d.mts → planner-produced-postgres-migration-BRH1Dj_Q.d.mts} +3 -3
- package/dist/{planner-produced-postgres-migration-Co71_VbU.d.mts.map → planner-produced-postgres-migration-BRH1Dj_Q.d.mts.map} +1 -1
- package/dist/{planner-produced-postgres-migration-D6KXC2DH.mjs → planner-produced-postgres-migration-x3hafaGC.mjs} +4 -4
- package/dist/{planner-produced-postgres-migration-D6KXC2DH.mjs.map → planner-produced-postgres-migration-x3hafaGC.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-Bm4S3LvB.mjs → planner-schema-lookup-DLJbkU7-.mjs} +1 -1
- package/dist/{planner-schema-lookup-Bm4S3LvB.mjs.map → planner-schema-lookup-DLJbkU7-.mjs.map} +1 -1
- package/dist/planner-schema-lookup.mjs +1 -1
- package/dist/{planner-sql-checks-lxWZQCFz.mjs → planner-sql-checks-QkUTY_jl.mjs} +39 -12
- package/dist/planner-sql-checks-QkUTY_jl.mjs.map +1 -0
- package/dist/planner-sql-checks.mjs +1 -1
- package/dist/{planner-target-details-Dv5N6x6k.d.mts → planner-target-details-C9s0m35x.d.mts} +1 -1
- package/dist/{planner-target-details-Dv5N6x6k.d.mts.map → planner-target-details-C9s0m35x.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-OfORJ-GY.mjs → postgres-contract-serializer-BqsjtSGT.mjs} +33 -24
- package/dist/postgres-contract-serializer-BqsjtSGT.mjs.map +1 -0
- package/dist/{postgres-enum-type-CaGZ2mfI.mjs → postgres-enum-type-BMgyxNyy.mjs} +1 -1
- package/dist/{postgres-enum-type-CaGZ2mfI.mjs.map → postgres-enum-type-BMgyxNyy.mjs.map} +1 -1
- package/dist/{postgres-enum-type-CWwVGBNK.d.mts → postgres-enum-type-DrjytBxL.d.mts} +1 -1
- package/dist/{postgres-enum-type-CWwVGBNK.d.mts.map → postgres-enum-type-DrjytBxL.d.mts.map} +1 -1
- package/dist/{postgres-migration-BnDg_Nj0.mjs → postgres-migration-BDaWGYDu.mjs} +3 -3
- package/dist/{postgres-migration-BnDg_Nj0.mjs.map → postgres-migration-BDaWGYDu.mjs.map} +1 -1
- package/dist/{postgres-migration-BcKS2Lqq.d.mts → postgres-migration-CTtX2IXX.d.mts} +3 -3
- package/dist/{postgres-migration-BcKS2Lqq.d.mts.map → postgres-migration-CTtX2IXX.d.mts.map} +1 -1
- package/dist/{postgres-schema-Dky_Jff8.mjs → postgres-schema-CJH-1qeX.mjs} +29 -14
- package/dist/postgres-schema-CJH-1qeX.mjs.map +1 -0
- package/dist/{render-ops-BpU-Qv06.mjs → render-ops-Da7bQcyv.mjs} +1 -1
- package/dist/{render-ops-BpU-Qv06.mjs.map → render-ops-Da7bQcyv.mjs.map} +1 -1
- package/dist/render-ops.d.mts +1 -1
- package/dist/render-ops.mjs +1 -1
- package/dist/{render-typescript-D9O7aOS_.mjs → render-typescript-DTpTcoNZ.mjs} +1 -1
- package/dist/{render-typescript-D9O7aOS_.mjs.map → render-typescript-DTpTcoNZ.mjs.map} +1 -1
- package/dist/render-typescript.mjs +1 -1
- package/dist/runtime.d.mts.map +1 -1
- package/dist/runtime.mjs +2 -2
- package/dist/{shared-CMqM-2BA.d.mts → shared-CHtU3piZ.d.mts} +2 -2
- package/dist/{shared-CMqM-2BA.d.mts.map → shared-CHtU3piZ.d.mts.map} +1 -1
- package/dist/{sql-utils-DR_F9aHR.mjs → sql-utils-CggjWNij.mjs} +1 -1
- package/dist/{sql-utils-DR_F9aHR.mjs.map → sql-utils-CggjWNij.mjs.map} +1 -1
- package/dist/sql-utils.mjs +1 -1
- package/dist/{tables-Cuy4VIgu.mjs → tables-DhBnvtOj.mjs} +3 -3
- package/dist/{tables-Cuy4VIgu.mjs.map → tables-DhBnvtOj.mjs.map} +1 -1
- package/dist/{types-kggVJs6C.d.mts → types-BFF73W84.d.mts} +1 -1
- package/dist/types-BFF73W84.d.mts.map +1 -0
- package/dist/types.d.mts +16 -11
- package/dist/types.d.mts.map +1 -1
- package/dist/types.mjs +2 -2
- package/package.json +17 -18
- package/src/core/migrations/control-policy.ts +2 -3
- package/src/core/migrations/issue-planner.ts +3 -3
- package/src/core/migrations/planner-sql-checks.ts +9 -9
- package/src/core/migrations/planner-strategies.ts +16 -10
- package/src/core/migrations/planner.ts +0 -2
- package/src/core/migrations/runner.ts +0 -2
- package/src/core/postgres-contract-serializer.ts +52 -46
- package/src/core/postgres-schema.ts +43 -25
- package/dist/column-type-compatibility-Dzxz_CkP.mjs +0 -11
- package/dist/column-type-compatibility-Dzxz_CkP.mjs.map +0 -1
- package/dist/column-type-compatibility.d.mts +0 -5
- package/dist/column-type-compatibility.d.mts.map +0 -1
- package/dist/column-type-compatibility.mjs +0 -2
- package/dist/issue-planner-SUBi9fH8.mjs.map +0 -1
- package/dist/planner-BruD4_LM.mjs.map +0 -1
- package/dist/planner-sql-checks-lxWZQCFz.mjs.map +0 -1
- package/dist/postgres-contract-serializer-OfORJ-GY.mjs.map +0 -1
- package/dist/postgres-schema-Dky_Jff8.mjs.map +0 -1
- package/dist/types-kggVJs6C.d.mts.map +0 -1
- package/src/core/column-type-compatibility.ts +0 -13
- package/src/exports/column-type-compatibility.ts +0 -1
|
@@ -20,11 +20,11 @@ import { resolveColumnTypeMetadata } from './planner-type-resolution';
|
|
|
20
20
|
* site.
|
|
21
21
|
*/
|
|
22
22
|
export function qualifyTableName(schema: string, table: string): string {
|
|
23
|
-
return postgresCreateNamespace({ id: schema }).qualifyTable(table);
|
|
23
|
+
return postgresCreateNamespace({ id: schema, entries: { table: {} } }).qualifyTable(table);
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
export function toRegclassLiteral(schema: string, name: string): string {
|
|
27
|
-
return postgresCreateNamespace({ id: schema }).regclassLiteral(name);
|
|
27
|
+
return postgresCreateNamespace({ id: schema, entries: { table: {} } }).regclassLiteral(name);
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
/**
|
|
@@ -43,7 +43,7 @@ export function constraintExistsCheck({
|
|
|
43
43
|
table?: string;
|
|
44
44
|
exists?: boolean;
|
|
45
45
|
}): string {
|
|
46
|
-
const namespace = postgresCreateNamespace({ id: schema });
|
|
46
|
+
const namespace = postgresCreateNamespace({ id: schema, entries: { table: {} } });
|
|
47
47
|
const existsClause = exists ? 'EXISTS' : 'NOT EXISTS';
|
|
48
48
|
const tableFilter = table
|
|
49
49
|
? `AND c.conrelid = to_regclass(${namespace.regclassLiteral(table)})`
|
|
@@ -68,7 +68,7 @@ export function columnExistsCheck({
|
|
|
68
68
|
column: string;
|
|
69
69
|
exists?: boolean;
|
|
70
70
|
}): string {
|
|
71
|
-
const namespace = postgresCreateNamespace({ id: schema });
|
|
71
|
+
const namespace = postgresCreateNamespace({ id: schema, entries: { table: {} } });
|
|
72
72
|
const existsClause = exists ? '' : 'NOT ';
|
|
73
73
|
return `SELECT ${existsClause}EXISTS (
|
|
74
74
|
SELECT 1
|
|
@@ -90,7 +90,7 @@ export function columnNullabilityCheck({
|
|
|
90
90
|
column: string;
|
|
91
91
|
nullable: boolean;
|
|
92
92
|
}): string {
|
|
93
|
-
const namespace = postgresCreateNamespace({ id: schema });
|
|
93
|
+
const namespace = postgresCreateNamespace({ id: schema, entries: { table: {} } });
|
|
94
94
|
const expected = nullable ? 'YES' : 'NO';
|
|
95
95
|
return `SELECT EXISTS (
|
|
96
96
|
SELECT 1
|
|
@@ -111,7 +111,7 @@ export function columnHasNoDefaultCheck(opts: {
|
|
|
111
111
|
table: string;
|
|
112
112
|
column: string;
|
|
113
113
|
}): string {
|
|
114
|
-
const namespace = postgresCreateNamespace({ id: opts.schema });
|
|
114
|
+
const namespace = postgresCreateNamespace({ id: opts.schema, entries: { table: {} } });
|
|
115
115
|
return `SELECT NOT EXISTS (
|
|
116
116
|
SELECT 1
|
|
117
117
|
FROM information_schema.columns
|
|
@@ -282,7 +282,7 @@ export function columnTypeCheck({
|
|
|
282
282
|
column: string;
|
|
283
283
|
expectedType: string;
|
|
284
284
|
}): string {
|
|
285
|
-
const namespace = postgresCreateNamespace({ id: schema });
|
|
285
|
+
const namespace = postgresCreateNamespace({ id: schema, entries: { table: {} } });
|
|
286
286
|
return `SELECT EXISTS (
|
|
287
287
|
SELECT 1
|
|
288
288
|
FROM pg_attribute a
|
|
@@ -307,7 +307,7 @@ export function columnDefaultExistsCheck({
|
|
|
307
307
|
column: string;
|
|
308
308
|
exists?: boolean;
|
|
309
309
|
}): string {
|
|
310
|
-
const namespace = postgresCreateNamespace({ id: schema });
|
|
310
|
+
const namespace = postgresCreateNamespace({ id: schema, entries: { table: {} } });
|
|
311
311
|
const nullCheck = exists ? 'IS NOT NULL' : 'IS NULL';
|
|
312
312
|
return `SELECT EXISTS (
|
|
313
313
|
SELECT 1
|
|
@@ -325,7 +325,7 @@ export function tableHasPrimaryKeyCheck(
|
|
|
325
325
|
exists: boolean,
|
|
326
326
|
constraintName?: string,
|
|
327
327
|
): string {
|
|
328
|
-
const namespace = postgresCreateNamespace({ id: schema });
|
|
328
|
+
const namespace = postgresCreateNamespace({ id: schema, entries: { table: {} } });
|
|
329
329
|
const comparison = exists ? '' : 'NOT ';
|
|
330
330
|
const constraintFilter = constraintName
|
|
331
331
|
? `AND c2.relname = '${escapeLiteral(constraintName)}'`
|
|
@@ -35,6 +35,7 @@ import {
|
|
|
35
35
|
type StorageTypeInstance,
|
|
36
36
|
} from '@prisma-next/sql-contract/types';
|
|
37
37
|
import type { SqlSchemaIR } from '@prisma-next/sql-schema-ir/types';
|
|
38
|
+
import { blindCast } from '@prisma-next/utils/casts';
|
|
38
39
|
import { PostgresEnumType } from '../postgres-enum-type';
|
|
39
40
|
import { isPostgresSchema } from '../postgres-schema';
|
|
40
41
|
import {
|
|
@@ -93,7 +94,7 @@ export function tableAt(
|
|
|
93
94
|
): StorageTable | undefined {
|
|
94
95
|
// Namespace.tables is typed as Record<string, IRNode> at the interface level;
|
|
95
96
|
// SQL family namespaces always hold StorageTable instances.
|
|
96
|
-
return storage.namespaces[namespaceId]?.
|
|
97
|
+
return storage.namespaces[namespaceId]?.entries.table[tableName] as StorageTable | undefined;
|
|
97
98
|
}
|
|
98
99
|
|
|
99
100
|
/**
|
|
@@ -134,8 +135,8 @@ const DEFAULT_ENUM_NAMESPACE_ID = 'public';
|
|
|
134
135
|
|
|
135
136
|
function namespaceHasEnum(storage: SqlStorage, namespaceId: string, typeName: string): boolean {
|
|
136
137
|
const ns = storage.namespaces[namespaceId];
|
|
137
|
-
if (!
|
|
138
|
-
return
|
|
138
|
+
if (!isPostgresSchema(ns)) return false;
|
|
139
|
+
return ns.entries.type[typeName] !== undefined;
|
|
139
140
|
}
|
|
140
141
|
|
|
141
142
|
/**
|
|
@@ -166,7 +167,7 @@ function resolveColumnEnumNamespace(
|
|
|
166
167
|
|
|
167
168
|
/**
|
|
168
169
|
* Finds a type entry by explicit namespace coordinate. Namespace types (e.g.
|
|
169
|
-
* Postgres enums) live under `storage.namespaces[nsId].
|
|
170
|
+
* Postgres enums) live under `storage.namespaces[nsId].entries.type`. Returns the
|
|
170
171
|
* entry from the named namespace only — never scans other namespaces, so two
|
|
171
172
|
* namespaces that hold an enum with the same name resolve independently.
|
|
172
173
|
*/
|
|
@@ -176,8 +177,12 @@ function locateNamespaceType(
|
|
|
176
177
|
typeName: string,
|
|
177
178
|
): PostgresEnumStorageEntry | undefined {
|
|
178
179
|
const ns = storage.namespaces[namespaceId];
|
|
179
|
-
|
|
180
|
-
|
|
180
|
+
const raw = ns?.entries['type']?.[typeName];
|
|
181
|
+
if (raw === undefined) return undefined;
|
|
182
|
+
return blindCast<
|
|
183
|
+
PostgresEnumStorageEntry,
|
|
184
|
+
'postgres type slot carries PostgresEnumStorageEntry at the postgres target layer'
|
|
185
|
+
>(raw);
|
|
181
186
|
}
|
|
182
187
|
|
|
183
188
|
// ============================================================================
|
|
@@ -436,7 +441,7 @@ function enumRebuildCallRecipe(
|
|
|
436
441
|
// same-named enums in distinct namespaces keep their columns disjoint.
|
|
437
442
|
const columnRefs: { namespaceId: string; table: string; column: string }[] = [];
|
|
438
443
|
for (const [nsId, ns] of Object.entries(ctx.toContract.storage.namespaces)) {
|
|
439
|
-
for (const [tableName, tableNode] of Object.entries(ns.
|
|
444
|
+
for (const [tableName, tableNode] of Object.entries(ns.entries.table)) {
|
|
440
445
|
const table = tableNode as StorageTable;
|
|
441
446
|
for (const [columnName, column] of Object.entries(table.columns)) {
|
|
442
447
|
if (
|
|
@@ -639,9 +644,10 @@ export const nativeEnumPlanCallStrategy: CallMigrationStrategy = (issues, ctx) =
|
|
|
639
644
|
function collectPostgresEnumTypes(storage: SqlStorage): ReadonlyMap<string, PostgresEnumType> {
|
|
640
645
|
const result = new Map<string, PostgresEnumType>();
|
|
641
646
|
for (const [nsId, ns] of Object.entries(storage.namespaces)) {
|
|
642
|
-
if (!(
|
|
643
|
-
const
|
|
644
|
-
|
|
647
|
+
if (!isPostgresSchema(ns)) continue;
|
|
648
|
+
for (const [name, instance] of Object.entries(ns.entries.type).sort(([a], [b]) =>
|
|
649
|
+
a.localeCompare(b),
|
|
650
|
+
)) {
|
|
645
651
|
if (instance instanceof PostgresEnumType) {
|
|
646
652
|
result.set(enumCompoundKey(nsId, name), instance);
|
|
647
653
|
}
|
|
@@ -22,7 +22,6 @@ import type {
|
|
|
22
22
|
} from '@prisma-next/framework-components/control';
|
|
23
23
|
import { UNBOUND_NAMESPACE_ID } from '@prisma-next/framework-components/ir';
|
|
24
24
|
import { blindCast } from '@prisma-next/utils/casts';
|
|
25
|
-
import { postgresColumnsCompatible } from '../column-type-compatibility';
|
|
26
25
|
import { parsePostgresDefault } from '../default-normalizer';
|
|
27
26
|
import { normalizeSchemaNativeType } from '../native-type-normalizer';
|
|
28
27
|
import {
|
|
@@ -258,7 +257,6 @@ export class PostgresMigrationPlanner implements MigrationPlanner<'sql', 'postgr
|
|
|
258
257
|
frameworkComponents: options.frameworkComponents,
|
|
259
258
|
normalizeDefault: parsePostgresDefault,
|
|
260
259
|
normalizeNativeType: normalizeSchemaNativeType,
|
|
261
|
-
columnsCompatible: postgresColumnsCompatible,
|
|
262
260
|
resolveExistingEnumValues: createResolveExistingEnumValues(options.contract.storage),
|
|
263
261
|
};
|
|
264
262
|
const verifyResult = verifySqlSchema(verifyOptions);
|
|
@@ -25,7 +25,6 @@ import type { LoweredStatement } from '@prisma-next/sql-relational-core/ast';
|
|
|
25
25
|
import { ifDefined } from '@prisma-next/utils/defined';
|
|
26
26
|
import type { Result } from '@prisma-next/utils/result';
|
|
27
27
|
import { notOk, ok, okVoid } from '@prisma-next/utils/result';
|
|
28
|
-
import { postgresColumnsCompatible } from '../column-type-compatibility';
|
|
29
28
|
import { parsePostgresDefault } from '../default-normalizer';
|
|
30
29
|
import { normalizeSchemaNativeType } from '../native-type-normalizer';
|
|
31
30
|
import { createResolveExistingEnumValues } from './enum-planning';
|
|
@@ -141,7 +140,6 @@ class PostgresMigrationRunner implements SqlMigrationRunner<PostgresPlanTargetDe
|
|
|
141
140
|
frameworkComponents: options.frameworkComponents,
|
|
142
141
|
normalizeDefault: parsePostgresDefault,
|
|
143
142
|
normalizeNativeType: normalizeSchemaNativeType,
|
|
144
|
-
columnsCompatible: postgresColumnsCompatible,
|
|
145
143
|
resolveExistingEnumValues: createResolveExistingEnumValues(
|
|
146
144
|
options.destinationContract.storage,
|
|
147
145
|
),
|
|
@@ -14,12 +14,8 @@ import {
|
|
|
14
14
|
NamespaceBase,
|
|
15
15
|
UNBOUND_NAMESPACE_ID,
|
|
16
16
|
} from '@prisma-next/framework-components/ir';
|
|
17
|
-
import type {
|
|
18
|
-
|
|
19
|
-
SqlStorage,
|
|
20
|
-
SqlStorageTypeEntry,
|
|
21
|
-
StorageTable,
|
|
22
|
-
} from '@prisma-next/sql-contract/types';
|
|
17
|
+
import type { SqlNamespaceTablesInput, SqlStorage } from '@prisma-next/sql-contract/types';
|
|
18
|
+
import { blindCast } from '@prisma-next/utils/casts';
|
|
23
19
|
import type { JsonObject } from '@prisma-next/utils/json';
|
|
24
20
|
import type { Type } from 'arktype';
|
|
25
21
|
import { postgresAuthoringEntityTypes } from './authoring';
|
|
@@ -57,9 +53,8 @@ function collectEntityRegistryContributions(namespace: AuthoringEntityTypeNamesp
|
|
|
57
53
|
if (isAuthoringEntityTypeDescriptor(value)) {
|
|
58
54
|
if (isAuthoringEntityTypeFactoryOutput(value.output)) {
|
|
59
55
|
const { factory } = value.output;
|
|
60
|
-
entityTypeRegistry.set(
|
|
61
|
-
|
|
62
|
-
(raw) => factory(raw, POSTGRES_AUTHORING_CTX) as SqlStorageTypeEntry,
|
|
56
|
+
entityTypeRegistry.set(value.discriminator, (raw) =>
|
|
57
|
+
factory(raw, POSTGRES_AUTHORING_CTX),
|
|
63
58
|
);
|
|
64
59
|
}
|
|
65
60
|
if (value.validatorSchema !== undefined) {
|
|
@@ -91,22 +86,43 @@ export class PostgresContractSerializer extends SqlContractSerializerBase<Contra
|
|
|
91
86
|
if (raw instanceof NamespaceBase) {
|
|
92
87
|
return raw;
|
|
93
88
|
}
|
|
94
|
-
const hydrated =
|
|
95
|
-
|
|
96
|
-
tables
|
|
97
|
-
|
|
98
|
-
};
|
|
99
|
-
|
|
89
|
+
const hydrated = blindCast<
|
|
90
|
+
SqlNamespaceTablesInput,
|
|
91
|
+
'super.hydrateSqlNamespaceEntry returns the tables form when raw is not a NamespaceBase'
|
|
92
|
+
>(super.hydrateSqlNamespaceEntry(nsId, raw));
|
|
93
|
+
const { id, entries } = hydrated;
|
|
94
|
+
|
|
95
|
+
// Extract the postgres-specific `type` slot directly from raw input.
|
|
96
|
+
// The family base handles the `table` slot; the postgres target owns `type`.
|
|
97
|
+
const rawRecord = raw as Record<string, unknown>;
|
|
98
|
+
const rawEntries = rawRecord['entries'];
|
|
99
|
+
let typeSlot: Record<string, PostgresEnumType> | undefined;
|
|
100
|
+
if (rawEntries !== null && typeof rawEntries === 'object' && !Array.isArray(rawEntries)) {
|
|
101
|
+
const rawTypeSlot = (rawEntries as Record<string, unknown>)['type'];
|
|
102
|
+
if (rawTypeSlot !== null && typeof rawTypeSlot === 'object' && !Array.isArray(rawTypeSlot)) {
|
|
103
|
+
const enumFactory = this.entityTypeRegistry.get('postgres-enum');
|
|
104
|
+
typeSlot = Object.fromEntries(
|
|
105
|
+
Object.entries(rawTypeSlot as Record<string, unknown>).map(([name, entry]) => [
|
|
106
|
+
name,
|
|
107
|
+
blindCast<PostgresEnumType, 'postgres-enum factory returns PostgresEnumType'>(
|
|
108
|
+
enumFactory !== undefined ? enumFactory(entry) : entry,
|
|
109
|
+
),
|
|
110
|
+
]),
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
100
114
|
|
|
101
|
-
const emptyTables = Object.keys(
|
|
102
|
-
const
|
|
103
|
-
if (id === UNBOUND_NAMESPACE_ID && emptyTables &&
|
|
115
|
+
const emptyTables = Object.keys(entries.table).length === 0;
|
|
116
|
+
const emptyTypes = !typeSlot || Object.keys(typeSlot).length === 0;
|
|
117
|
+
if (id === UNBOUND_NAMESPACE_ID && emptyTables && emptyTypes) {
|
|
104
118
|
return PostgresSchema.unbound;
|
|
105
119
|
}
|
|
106
120
|
return new PostgresSchema({
|
|
107
121
|
id,
|
|
108
|
-
|
|
109
|
-
|
|
122
|
+
entries: {
|
|
123
|
+
table: entries.table,
|
|
124
|
+
type: typeSlot ?? {},
|
|
125
|
+
},
|
|
110
126
|
});
|
|
111
127
|
}
|
|
112
128
|
|
|
@@ -117,30 +133,18 @@ export class PostgresContractSerializer extends SqlContractSerializerBase<Contra
|
|
|
117
133
|
if (isPostgresSchema(ns)) {
|
|
118
134
|
namespacesJson[nsId] = this.serializePostgresNamespace(ns, ns.id === UNBOUND_NAMESPACE_ID);
|
|
119
135
|
} else {
|
|
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
|
-
// postgres-unbound-schema so the round-trip through
|
|
125
|
-
// deserializeContract hydrates them back into PostgresSchema
|
|
126
|
-
// instances.
|
|
127
136
|
const isUnboundSlot = nsId === UNBOUND_NAMESPACE_ID;
|
|
128
|
-
const nsEnums = (ns as { readonly enum?: Readonly<Record<string, unknown>> }).enum ?? {};
|
|
129
137
|
namespacesJson[nsId] = {
|
|
130
138
|
id: nsId,
|
|
131
139
|
kind: isUnboundSlot ? 'postgres-unbound-schema' : 'postgres-schema',
|
|
132
|
-
|
|
133
|
-
Object.
|
|
134
|
-
tableName,
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
typeName,
|
|
141
|
-
this.serializeJsonValue(entry) as JsonObject,
|
|
142
|
-
]),
|
|
143
|
-
),
|
|
140
|
+
entries: {
|
|
141
|
+
table: Object.fromEntries(
|
|
142
|
+
Object.entries(ns.entries.table).map(([tableName, table]) => [
|
|
143
|
+
tableName,
|
|
144
|
+
this.serializeJsonValue(table) as JsonObject,
|
|
145
|
+
]),
|
|
146
|
+
),
|
|
147
|
+
},
|
|
144
148
|
};
|
|
145
149
|
}
|
|
146
150
|
}
|
|
@@ -163,18 +167,20 @@ export class PostgresContractSerializer extends SqlContractSerializerBase<Contra
|
|
|
163
167
|
|
|
164
168
|
private serializePostgresNamespace(ns: PostgresSchema, isUnboundSlot: boolean): JsonObject {
|
|
165
169
|
const tablesOut: Record<string, JsonObject> = {};
|
|
166
|
-
for (const [tableName, table] of Object.entries(ns.
|
|
170
|
+
for (const [tableName, table] of Object.entries(ns.entries.table)) {
|
|
167
171
|
tablesOut[tableName] = this.serializeJsonValue(table) as JsonObject;
|
|
168
172
|
}
|
|
169
|
-
const
|
|
170
|
-
for (const [typeName, ty] of Object.entries(ns.
|
|
171
|
-
|
|
173
|
+
const typeOut: Record<string, JsonObject> = {};
|
|
174
|
+
for (const [typeName, ty] of Object.entries(ns.entries.type)) {
|
|
175
|
+
typeOut[typeName] = this.serializeJsonValue(ty) as JsonObject;
|
|
172
176
|
}
|
|
173
177
|
return {
|
|
174
178
|
id: ns.id,
|
|
175
179
|
kind: isUnboundSlot ? 'postgres-unbound-schema' : 'postgres-schema',
|
|
176
|
-
|
|
177
|
-
|
|
180
|
+
entries: {
|
|
181
|
+
table: tablesOut,
|
|
182
|
+
type: typeOut,
|
|
183
|
+
},
|
|
178
184
|
};
|
|
179
185
|
}
|
|
180
186
|
|
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
UNBOUND_NAMESPACE_ID,
|
|
5
5
|
} from '@prisma-next/framework-components/ir';
|
|
6
6
|
import {
|
|
7
|
+
type PostgresEnumStorageEntry,
|
|
7
8
|
type SqlNamespaceTablesInput,
|
|
8
9
|
type SqlStorage,
|
|
9
10
|
StorageTable,
|
|
@@ -14,8 +15,10 @@ import { escapeLiteral } from './sql-utils';
|
|
|
14
15
|
|
|
15
16
|
export interface PostgresSchemaInput {
|
|
16
17
|
readonly id: string;
|
|
17
|
-
readonly
|
|
18
|
-
|
|
18
|
+
readonly entries: {
|
|
19
|
+
readonly table: Record<string, StorageTable | StorageTableInput>;
|
|
20
|
+
readonly type: Record<string, PostgresEnumType | PostgresEnumTypeInput>;
|
|
21
|
+
};
|
|
19
22
|
}
|
|
20
23
|
|
|
21
24
|
/**
|
|
@@ -24,9 +27,10 @@ export interface PostgresSchemaInput {
|
|
|
24
27
|
* `namespaces: Record<NamespaceId, PostgresSchema>` map populated by
|
|
25
28
|
* the Postgres PSL interpreter from `namespace { … }` AST buckets.
|
|
26
29
|
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
+
* `entries` holds entity-kind slot maps (`table`, `type`). Qualifier
|
|
31
|
+
* emission is the rendering seam: DDL / SQL emission asks the namespace
|
|
32
|
+
* for its qualifier (`"<schema>"`) or for a qualified table name
|
|
33
|
+
* (`"<schema>"."<table>"`) and consumes the result polymorphically.
|
|
30
34
|
* The unbound singleton below overrides these methods to elide the
|
|
31
35
|
* prefix entirely — call sites stay polymorphic and never branch on
|
|
32
36
|
* `id === UNBOUND_NAMESPACE_ID`.
|
|
@@ -43,28 +47,32 @@ export class PostgresSchema extends NamespaceBase {
|
|
|
43
47
|
|
|
44
48
|
declare readonly kind: 'schema';
|
|
45
49
|
readonly id: string;
|
|
46
|
-
readonly
|
|
47
|
-
|
|
50
|
+
readonly entries: Readonly<{
|
|
51
|
+
readonly table: Readonly<Record<string, StorageTable>>;
|
|
52
|
+
readonly type: Readonly<Record<string, PostgresEnumType>>;
|
|
53
|
+
}>;
|
|
48
54
|
|
|
49
55
|
constructor(input: PostgresSchemaInput) {
|
|
50
56
|
super();
|
|
51
57
|
this.id = input.id;
|
|
52
|
-
this.
|
|
53
|
-
Object.
|
|
54
|
-
Object.
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
+
this.entries = Object.freeze({
|
|
59
|
+
table: Object.freeze(
|
|
60
|
+
Object.fromEntries(
|
|
61
|
+
Object.entries(input.entries.table).map(([k, v]) => [
|
|
62
|
+
k,
|
|
63
|
+
v instanceof StorageTable ? v : new StorageTable(v as StorageTableInput),
|
|
64
|
+
]),
|
|
65
|
+
),
|
|
58
66
|
),
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
67
|
+
type: Object.freeze(
|
|
68
|
+
Object.fromEntries(
|
|
69
|
+
Object.entries(input.entries.type).map(([k, v]) => [
|
|
70
|
+
k,
|
|
71
|
+
v instanceof PostgresEnumType ? v : new PostgresEnumType(v as PostgresEnumTypeInput),
|
|
72
|
+
]),
|
|
73
|
+
),
|
|
66
74
|
),
|
|
67
|
-
);
|
|
75
|
+
});
|
|
68
76
|
Object.defineProperty(this, 'kind', {
|
|
69
77
|
value: 'schema',
|
|
70
78
|
writable: false,
|
|
@@ -154,7 +162,7 @@ export class PostgresUnboundSchema extends PostgresSchema {
|
|
|
154
162
|
static readonly instance: PostgresUnboundSchema = new PostgresUnboundSchema();
|
|
155
163
|
|
|
156
164
|
constructor(input?: PostgresSchemaInput) {
|
|
157
|
-
super(input ?? { id: UNBOUND_NAMESPACE_ID });
|
|
165
|
+
super(input ?? { id: UNBOUND_NAMESPACE_ID, entries: { table: {}, type: {} } });
|
|
158
166
|
}
|
|
159
167
|
|
|
160
168
|
override qualifier(): string {
|
|
@@ -196,9 +204,19 @@ export function isPostgresSchema(ns: unknown): ns is PostgresSchema {
|
|
|
196
204
|
* by reference and trust the resulting `SqlStorage.namespaces` map to
|
|
197
205
|
* be value-stable for a given input set.
|
|
198
206
|
*/
|
|
199
|
-
export function postgresCreateNamespace(
|
|
207
|
+
export function postgresCreateNamespace(
|
|
208
|
+
input: SqlNamespaceTablesInput,
|
|
209
|
+
enumTypes?: Readonly<Record<string, PostgresEnumStorageEntry>>,
|
|
210
|
+
): PostgresSchema {
|
|
211
|
+
const schemaInput: PostgresSchemaInput = {
|
|
212
|
+
id: input.id,
|
|
213
|
+
entries: {
|
|
214
|
+
table: input.entries.table,
|
|
215
|
+
type: (enumTypes ?? {}) as Record<string, PostgresEnumTypeInput>,
|
|
216
|
+
},
|
|
217
|
+
};
|
|
200
218
|
if (input.id === UNBOUND_NAMESPACE_ID) {
|
|
201
|
-
return new PostgresUnboundSchema(
|
|
219
|
+
return new PostgresUnboundSchema(schemaInput);
|
|
202
220
|
}
|
|
203
|
-
return new PostgresSchema(
|
|
221
|
+
return new PostgresSchema(schemaInput);
|
|
204
222
|
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
//#region src/core/column-type-compatibility.ts
|
|
2
|
-
const EXPLICIT_COMPATIBLE_TYPE_PAIRS = [];
|
|
3
|
-
function postgresColumnsCompatible(declared, live) {
|
|
4
|
-
if (declared === live) return true;
|
|
5
|
-
for (const [a, b] of EXPLICIT_COMPATIBLE_TYPE_PAIRS) if (declared === a && live === b || declared === b && live === a) return true;
|
|
6
|
-
return false;
|
|
7
|
-
}
|
|
8
|
-
//#endregion
|
|
9
|
-
export { postgresColumnsCompatible as t };
|
|
10
|
-
|
|
11
|
-
//# sourceMappingURL=column-type-compatibility-Dzxz_CkP.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"column-type-compatibility-Dzxz_CkP.mjs","names":[],"sources":["../src/core/column-type-compatibility.ts"],"sourcesContent":["const EXPLICIT_COMPATIBLE_TYPE_PAIRS: ReadonlyArray<readonly [string, string]> = [];\n\nexport function postgresColumnsCompatible(declared: string, live: string): boolean {\n if (declared === live) {\n return true;\n }\n for (const [a, b] of EXPLICIT_COMPATIBLE_TYPE_PAIRS) {\n if ((declared === a && live === b) || (declared === b && live === a)) {\n return true;\n }\n }\n return false;\n}\n"],"mappings":";AAAA,MAAM,iCAA2E,CAAC;AAElF,SAAgB,0BAA0B,UAAkB,MAAuB;CACjF,IAAI,aAAa,MACf,OAAO;CAET,KAAK,MAAM,CAAC,GAAG,MAAM,gCACnB,IAAK,aAAa,KAAK,SAAS,KAAO,aAAa,KAAK,SAAS,GAChE,OAAO;CAGX,OAAO;AACT"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"column-type-compatibility.d.mts","names":[],"sources":["../src/core/column-type-compatibility.ts"],"mappings":";iBAEgB,yBAAA,CAA0B,QAAA,UAAkB,IAAY"}
|