@prisma-next/target-postgres 0.16.0-dev.27 → 0.16.0-dev.29
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/control.mjs
CHANGED
|
@@ -17,7 +17,7 @@ import { notOk, ok, okVoid } from "@prisma-next/utils/result";
|
|
|
17
17
|
import { InternalError } from "@prisma-next/utils/internal-error";
|
|
18
18
|
import { SqlSchemaVerifierBase } from "@prisma-next/family-sql/ir";
|
|
19
19
|
import { SqlQueryError } from "@prisma-next/sql-errors";
|
|
20
|
-
import { buildChildRelationField, deriveRelationFieldName, inferRelations, mapDefault, parseRawDefault, toEnumMemberName, toEnumName, toFieldName, toModelName
|
|
20
|
+
import { buildChildRelationField, deriveRelationFieldName, inferRelations, mapDefault, parseRawDefault, toEnumMemberName, toEnumName, toFieldName, toModelName } from "@prisma-next/family-sql/psl-infer";
|
|
21
21
|
import { UNSPECIFIED_PSL_NAMESPACE_ID, makePslNamespace, makePslNamespaceEntries } from "@prisma-next/framework-components/psl-ast";
|
|
22
22
|
//#region src/core/migrations/runner.ts
|
|
23
23
|
const LOCK_DOMAIN = "prisma_next.contract.marker";
|
|
@@ -437,170 +437,82 @@ const POSTGRES_TO_PSL = {
|
|
|
437
437
|
bigint: "BigInt",
|
|
438
438
|
float8: "Float",
|
|
439
439
|
"double precision": "Float",
|
|
440
|
-
numeric: "Decimal",
|
|
441
|
-
decimal: "Decimal",
|
|
442
|
-
timestamptz: "DateTime",
|
|
443
|
-
"timestamp with time zone": "DateTime",
|
|
444
440
|
jsonb: "Jsonb",
|
|
445
441
|
bytea: "Bytes"
|
|
446
442
|
};
|
|
447
443
|
const PRESERVED_NATIVE_TYPES = {
|
|
448
|
-
"character varying":
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
attributeName: "db.Inet"
|
|
471
|
-
},
|
|
472
|
-
int2: {
|
|
473
|
-
pslType: "Int",
|
|
474
|
-
attributeName: "db.SmallInt"
|
|
475
|
-
},
|
|
476
|
-
smallint: {
|
|
477
|
-
pslType: "Int",
|
|
478
|
-
attributeName: "db.SmallInt"
|
|
479
|
-
},
|
|
480
|
-
float4: {
|
|
481
|
-
pslType: "Float",
|
|
482
|
-
attributeName: "db.Real"
|
|
483
|
-
},
|
|
484
|
-
real: {
|
|
485
|
-
pslType: "Float",
|
|
486
|
-
attributeName: "db.Real"
|
|
487
|
-
},
|
|
488
|
-
timestamp: {
|
|
489
|
-
pslType: "DateTime",
|
|
490
|
-
attributeName: "db.Timestamp"
|
|
491
|
-
},
|
|
492
|
-
"timestamp without time zone": {
|
|
493
|
-
pslType: "DateTime",
|
|
494
|
-
attributeName: "db.Timestamp"
|
|
495
|
-
},
|
|
496
|
-
date: {
|
|
497
|
-
pslType: "DateTime",
|
|
498
|
-
attributeName: "db.Date"
|
|
499
|
-
},
|
|
500
|
-
time: {
|
|
501
|
-
pslType: "DateTime",
|
|
502
|
-
attributeName: "db.Time"
|
|
503
|
-
},
|
|
504
|
-
"time without time zone": {
|
|
505
|
-
pslType: "DateTime",
|
|
506
|
-
attributeName: "db.Time"
|
|
507
|
-
},
|
|
508
|
-
timetz: {
|
|
509
|
-
pslType: "DateTime",
|
|
510
|
-
attributeName: "db.Timetz"
|
|
511
|
-
},
|
|
512
|
-
"time with time zone": {
|
|
513
|
-
pslType: "DateTime",
|
|
514
|
-
attributeName: "db.Timetz"
|
|
515
|
-
},
|
|
516
|
-
json: {
|
|
517
|
-
pslType: "Json",
|
|
518
|
-
attributeName: "db.Json"
|
|
519
|
-
}
|
|
444
|
+
"character varying": "VarChar",
|
|
445
|
+
character: "Char",
|
|
446
|
+
char: "Char",
|
|
447
|
+
varchar: "VarChar",
|
|
448
|
+
uuid: "Uuid",
|
|
449
|
+
inet: "Inet",
|
|
450
|
+
int2: "SmallInt",
|
|
451
|
+
smallint: "SmallInt",
|
|
452
|
+
float4: "Real",
|
|
453
|
+
real: "Real",
|
|
454
|
+
numeric: "Numeric",
|
|
455
|
+
decimal: "Numeric",
|
|
456
|
+
timestamp: "Timestamp",
|
|
457
|
+
"timestamp without time zone": "Timestamp",
|
|
458
|
+
timestamptz: "Timestamptz",
|
|
459
|
+
"timestamp with time zone": "Timestamptz",
|
|
460
|
+
date: "Date",
|
|
461
|
+
time: "Time",
|
|
462
|
+
"time without time zone": "Time",
|
|
463
|
+
timetz: "Timetz",
|
|
464
|
+
"time with time zone": "Timetz",
|
|
465
|
+
json: "Json"
|
|
520
466
|
};
|
|
521
467
|
const PARAMETERIZED_NATIVE_TYPES = {
|
|
522
|
-
"character varying":
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
attributeName: "db.Char"
|
|
533
|
-
},
|
|
534
|
-
varchar: {
|
|
535
|
-
pslType: "String",
|
|
536
|
-
attributeName: "db.VarChar"
|
|
537
|
-
},
|
|
538
|
-
numeric: {
|
|
539
|
-
pslType: "Decimal",
|
|
540
|
-
attributeName: "db.Numeric"
|
|
541
|
-
},
|
|
542
|
-
timestamp: {
|
|
543
|
-
pslType: "DateTime",
|
|
544
|
-
attributeName: "db.Timestamp"
|
|
545
|
-
},
|
|
546
|
-
timestamptz: {
|
|
547
|
-
pslType: "DateTime",
|
|
548
|
-
attributeName: "db.Timestamptz"
|
|
549
|
-
},
|
|
550
|
-
time: {
|
|
551
|
-
pslType: "DateTime",
|
|
552
|
-
attributeName: "db.Time"
|
|
553
|
-
},
|
|
554
|
-
timetz: {
|
|
555
|
-
pslType: "DateTime",
|
|
556
|
-
attributeName: "db.Timetz"
|
|
557
|
-
}
|
|
468
|
+
"character varying": "VarChar",
|
|
469
|
+
character: "Char",
|
|
470
|
+
char: "Char",
|
|
471
|
+
varchar: "VarChar",
|
|
472
|
+
numeric: "Numeric",
|
|
473
|
+
decimal: "Numeric",
|
|
474
|
+
timestamp: "Timestamp",
|
|
475
|
+
timestamptz: "Timestamptz",
|
|
476
|
+
time: "Time",
|
|
477
|
+
timetz: "Timetz"
|
|
558
478
|
};
|
|
559
479
|
const PARAMETERIZED_TYPE_PATTERN = /^(.+?)\((.+)\)$/;
|
|
560
480
|
function getOwnMappingValue(map, key) {
|
|
561
481
|
return Object.hasOwn(map, key) ? map[key] : void 0;
|
|
562
482
|
}
|
|
563
|
-
function getOwnRecordValue(map, key) {
|
|
564
|
-
return Object.hasOwn(map, key) ? map[key] : void 0;
|
|
565
|
-
}
|
|
566
|
-
function createNativeTypeAttribute(name, args) {
|
|
567
|
-
return args && args.length > 0 ? {
|
|
568
|
-
name,
|
|
569
|
-
args
|
|
570
|
-
} : { name };
|
|
571
|
-
}
|
|
572
483
|
function splitTypeParameterList(params) {
|
|
573
484
|
return params.split(",").map((part) => part.trim()).filter((part) => part.length > 0);
|
|
574
485
|
}
|
|
575
486
|
function createPostgresTypeMap(enumTypeNames) {
|
|
576
487
|
return { resolve(nativeType) {
|
|
577
488
|
if (enumTypeNames?.has(nativeType)) return {
|
|
578
|
-
pslType: nativeType,
|
|
489
|
+
pslType: { name: nativeType },
|
|
579
490
|
nativeType
|
|
580
491
|
};
|
|
581
492
|
const paramMatch = nativeType.match(PARAMETERIZED_TYPE_PATTERN);
|
|
582
493
|
if (paramMatch) {
|
|
583
494
|
const [, baseType = nativeType, params = ""] = paramMatch;
|
|
584
|
-
const
|
|
585
|
-
if (
|
|
586
|
-
pslType:
|
|
495
|
+
const typeName = getOwnMappingValue(PARAMETERIZED_NATIVE_TYPES, baseType);
|
|
496
|
+
if (typeName) return {
|
|
497
|
+
pslType: {
|
|
498
|
+
name: typeName,
|
|
499
|
+
args: splitTypeParameterList(params)
|
|
500
|
+
},
|
|
587
501
|
nativeType,
|
|
588
502
|
typeParams: {
|
|
589
503
|
baseType,
|
|
590
504
|
params
|
|
591
|
-
}
|
|
592
|
-
nativeTypeAttribute: createNativeTypeAttribute(template.attributeName, splitTypeParameterList(params))
|
|
505
|
+
}
|
|
593
506
|
};
|
|
594
507
|
}
|
|
595
|
-
const preservedType =
|
|
508
|
+
const preservedType = getOwnMappingValue(PRESERVED_NATIVE_TYPES, nativeType);
|
|
596
509
|
if (preservedType) return {
|
|
597
|
-
pslType: preservedType
|
|
598
|
-
nativeType
|
|
599
|
-
nativeTypeAttribute: createNativeTypeAttribute(preservedType.attributeName)
|
|
510
|
+
pslType: { name: preservedType },
|
|
511
|
+
nativeType
|
|
600
512
|
};
|
|
601
513
|
const pslType = getOwnMappingValue(POSTGRES_TO_PSL, nativeType);
|
|
602
514
|
if (pslType) return {
|
|
603
|
-
pslType,
|
|
515
|
+
pslType: { name: pslType },
|
|
604
516
|
nativeType
|
|
605
517
|
};
|
|
606
518
|
return {
|
|
@@ -852,19 +764,11 @@ function buildPslDocumentAst(schemaIR, options, foreignKeyExtras, namespaceName)
|
|
|
852
764
|
const { enumNameMap: bareEnumNameMap, enumBlocks } = buildNativeEnumBlocks(options.enumInfo?.definitions ?? /* @__PURE__ */ new Map(), modelNames);
|
|
853
765
|
const enumNameMap = new Map(bareEnumNameMap);
|
|
854
766
|
if (namespaceName !== void 0) for (const [typeName, pslName] of bareEnumNameMap) enumNameMap.set(`${namespaceName}.${typeName}`, pslName);
|
|
855
|
-
const reservedNamedTypeNames = createReservedNamedTypeNames(modelNames, enumNameMap);
|
|
856
767
|
const fieldNamesByTable = new Map([...crossSpaceFieldNamesByTable, ...buildFieldNamesByTable(schemaIR.tables)]);
|
|
857
768
|
const { relationsByTable } = inferRelations(schemaIR.tables, modelNameMap);
|
|
858
|
-
const namedTypes = seedNamedTypeRegistry(schemaIR, typeMap, enumNameMap, reservedNamedTypeNames);
|
|
859
769
|
const models = [];
|
|
860
|
-
for (const table of Object.values(schemaIR.tables)) models.push(buildModel(table, typeMap, enumNameMap, fieldNamesByTable,
|
|
770
|
+
for (const table of Object.values(schemaIR.tables)) models.push(buildModel(table, typeMap, enumNameMap, fieldNamesByTable, defaultMapping, rawDefaultParser, [...relationsByTable.get(table.name) ?? [], ...extraRelationsByTable.get(table.name) ?? []], danglingForeignKeysByTable.get(table.name) ?? []));
|
|
861
771
|
const sortedModels = topologicalSort(models, schemaIR.tables, modelNameMap);
|
|
862
|
-
const namedTypeEntries = [...namedTypes.entriesByKey.values()].sort((a, b) => a.name.localeCompare(b.name));
|
|
863
|
-
const types = namedTypeEntries.length > 0 ? {
|
|
864
|
-
kind: "types",
|
|
865
|
-
declarations: namedTypeEntries.map(buildNamedTypeDeclaration),
|
|
866
|
-
span: SYNTHETIC_SPAN
|
|
867
|
-
} : void 0;
|
|
868
772
|
return {
|
|
869
773
|
kind: "document",
|
|
870
774
|
sourceId: "<sql-schema-ir>",
|
|
@@ -874,7 +778,6 @@ function buildPslDocumentAst(schemaIR, options, foreignKeyExtras, namespaceName)
|
|
|
874
778
|
entries: makePslNamespaceEntries(sortedModels, [], enumBlocks),
|
|
875
779
|
span: SYNTHETIC_SPAN
|
|
876
780
|
})],
|
|
877
|
-
...types ? { types } : {},
|
|
878
781
|
span: SYNTHETIC_SPAN
|
|
879
782
|
};
|
|
880
783
|
}
|
|
@@ -934,7 +837,7 @@ function buildNativeEnumBlock(name, typeName, values) {
|
|
|
934
837
|
span: SYNTHETIC_SPAN
|
|
935
838
|
};
|
|
936
839
|
}
|
|
937
|
-
function buildModel(table, typeMap, enumNameMap, fieldNamesByTable,
|
|
840
|
+
function buildModel(table, typeMap, enumNameMap, fieldNamesByTable, defaultMapping, rawDefaultParser, relationFields, danglingForeignKeys) {
|
|
938
841
|
const { name: modelName, map: mapName } = toModelName(table.name);
|
|
939
842
|
const fieldNameMap = fieldNamesByTable.get(table.name);
|
|
940
843
|
const pkColumns = new Set(table.primaryKey?.columns ?? []);
|
|
@@ -947,7 +850,7 @@ function buildModel(table, typeMap, enumNameMap, fieldNamesByTable, namedTypes,
|
|
|
947
850
|
if (!uniqueColumns.has(columnName) || existingConstraintName === void 0 && unique.name) uniqueColumns.set(columnName, unique.name);
|
|
948
851
|
}
|
|
949
852
|
const fields = [];
|
|
950
|
-
for (const column of Object.values(table.columns)) fields.push(buildScalarField(column, table, typeMap, enumNameMap, fieldNameMap,
|
|
853
|
+
for (const column of Object.values(table.columns)) fields.push(buildScalarField(column, table, typeMap, enumNameMap, fieldNameMap, defaultMapping, rawDefaultParser, pkColumns, isSinglePk, singlePkConstraintName, uniqueColumns));
|
|
951
854
|
const usedFieldNames = new Set(fields.map((field) => field.name));
|
|
952
855
|
for (const rel of relationFields) fields.push(buildRelationField(rel, table.name, fieldNamesByTable, usedFieldNames));
|
|
953
856
|
const modelAttributes = [];
|
|
@@ -994,7 +897,7 @@ function buildDanglingForeignKeyWarning(danglingForeignKeys, fieldNamesByTable,
|
|
|
994
897
|
return `"${fieldNames.join(", ")}" -> "${target}"`;
|
|
995
898
|
}).join(", ")} exists in the database, but its target schema is outside the introspected scope, so no relation field was generated. If the target schema is described by an extension pack, add it to extensions and re-run infer.`;
|
|
996
899
|
}
|
|
997
|
-
function buildScalarField(column, table, typeMap, enumNameMap, fieldNameMap,
|
|
900
|
+
function buildScalarField(column, table, typeMap, enumNameMap, fieldNameMap, defaultMapping, rawDefaultParser, pkColumns, isSinglePk, singlePkConstraintName, uniqueColumns) {
|
|
998
901
|
const resolvedField = fieldNameMap?.get(column.name);
|
|
999
902
|
const fieldName = resolvedField?.fieldName ?? toFieldName(column.name).name;
|
|
1000
903
|
const fieldMap = resolvedField?.fieldMap;
|
|
@@ -1012,8 +915,13 @@ function buildScalarField(column, table, typeMap, enumNameMap, fieldNameMap, nam
|
|
|
1012
915
|
span: SYNTHETIC_SPAN
|
|
1013
916
|
};
|
|
1014
917
|
}
|
|
1015
|
-
let typeName = resolution.pslType;
|
|
1016
|
-
let typeConstructor
|
|
918
|
+
let typeName = resolution.pslType.name;
|
|
919
|
+
let typeConstructor = resolution.pslType.args ? {
|
|
920
|
+
kind: "typeConstructor",
|
|
921
|
+
path: [resolution.pslType.name],
|
|
922
|
+
args: resolution.pslType.args.map(positionalArg),
|
|
923
|
+
span: SYNTHETIC_SPAN
|
|
924
|
+
} : void 0;
|
|
1017
925
|
const enumPslName = enumNameMap.get(column.nativeType);
|
|
1018
926
|
if (enumPslName) {
|
|
1019
927
|
typeName = enumPslName;
|
|
@@ -1024,7 +932,6 @@ function buildScalarField(column, table, typeMap, enumNameMap, fieldNameMap, nam
|
|
|
1024
932
|
span: SYNTHETIC_SPAN
|
|
1025
933
|
};
|
|
1026
934
|
}
|
|
1027
|
-
if (resolution.nativeTypeAttribute && !enumPslName) typeName = resolveNamedTypeName(namedTypes, resolution);
|
|
1028
935
|
const attributes = [];
|
|
1029
936
|
const isId = isSinglePk && pkColumns.has(column.name);
|
|
1030
937
|
if (isId) attributes.push(buildSimpleConstraintFieldAttribute("id", singlePkConstraintName));
|
|
@@ -1129,16 +1036,6 @@ function namedArg(name, value) {
|
|
|
1129
1036
|
span: SYNTHETIC_SPAN
|
|
1130
1037
|
};
|
|
1131
1038
|
}
|
|
1132
|
-
function buildNamedTypeDeclaration(entry) {
|
|
1133
|
-
const attribute = buildAttribute("namedType", entry.nativeTypeAttribute.name, (entry.nativeTypeAttribute.args ?? []).map(positionalArg));
|
|
1134
|
-
return {
|
|
1135
|
-
kind: "namedType",
|
|
1136
|
-
name: entry.name,
|
|
1137
|
-
baseType: entry.baseType,
|
|
1138
|
-
attributes: [attribute],
|
|
1139
|
-
span: SYNTHETIC_SPAN
|
|
1140
|
-
};
|
|
1141
|
-
}
|
|
1142
1039
|
function escapePslString(value) {
|
|
1143
1040
|
return value.replace(/\\/g, "\\\\").replace(/"/g, "\\\"").replace(/\n/g, "\\n").replace(/\r/g, "\\r");
|
|
1144
1041
|
}
|
|
@@ -1222,65 +1119,6 @@ function buildTopLevelNameMap(sources, normalize, kind, sourceKind) {
|
|
|
1222
1119
|
} });
|
|
1223
1120
|
return results;
|
|
1224
1121
|
}
|
|
1225
|
-
function createReservedNamedTypeNames(modelNames, enumNameMap) {
|
|
1226
|
-
const reservedNames = new Set(PSL_SCALAR_TYPE_NAMES);
|
|
1227
|
-
for (const result of modelNames.values()) reservedNames.add(result.name);
|
|
1228
|
-
for (const enumPslName of enumNameMap.values()) reservedNames.add(enumPslName);
|
|
1229
|
-
return reservedNames;
|
|
1230
|
-
}
|
|
1231
|
-
function seedNamedTypeRegistry(schemaIR, typeMap, enumNameMap, reservedNames) {
|
|
1232
|
-
const seeds = /* @__PURE__ */ new Map();
|
|
1233
|
-
for (const tableName of Object.keys(schemaIR.tables).sort()) {
|
|
1234
|
-
const table = schemaIR.tables[tableName];
|
|
1235
|
-
if (!table) continue;
|
|
1236
|
-
for (const columnName of Object.keys(table.columns).sort()) {
|
|
1237
|
-
const column = table.columns[columnName];
|
|
1238
|
-
if (!column) continue;
|
|
1239
|
-
const resolution = typeMap.resolve(column.nativeType, table.annotations);
|
|
1240
|
-
if ("unsupported" in resolution || enumNameMap.has(column.nativeType) || !resolution.nativeTypeAttribute) continue;
|
|
1241
|
-
const signatureKey = createNamedTypeSignatureKey(resolution);
|
|
1242
|
-
if (!seeds.has(signatureKey)) seeds.set(signatureKey, {
|
|
1243
|
-
baseType: resolution.pslType,
|
|
1244
|
-
desiredName: toNamedTypeName(column.name),
|
|
1245
|
-
nativeTypeAttribute: resolution.nativeTypeAttribute
|
|
1246
|
-
});
|
|
1247
|
-
}
|
|
1248
|
-
}
|
|
1249
|
-
const registry = {
|
|
1250
|
-
entriesByKey: /* @__PURE__ */ new Map(),
|
|
1251
|
-
usedNames: new Set(reservedNames)
|
|
1252
|
-
};
|
|
1253
|
-
const sortedSeeds = [...seeds.entries()].sort((left, right) => {
|
|
1254
|
-
const desiredNameComparison = left[1].desiredName.localeCompare(right[1].desiredName);
|
|
1255
|
-
if (desiredNameComparison !== 0) return desiredNameComparison;
|
|
1256
|
-
return left[0].localeCompare(right[0]);
|
|
1257
|
-
});
|
|
1258
|
-
for (const [signatureKey, seed] of sortedSeeds) {
|
|
1259
|
-
const name = createUniqueFieldName(seed.desiredName, registry.usedNames);
|
|
1260
|
-
registry.entriesByKey.set(signatureKey, {
|
|
1261
|
-
name,
|
|
1262
|
-
baseType: seed.baseType,
|
|
1263
|
-
nativeTypeAttribute: seed.nativeTypeAttribute
|
|
1264
|
-
});
|
|
1265
|
-
registry.usedNames.add(name);
|
|
1266
|
-
}
|
|
1267
|
-
return registry;
|
|
1268
|
-
}
|
|
1269
|
-
function resolveNamedTypeName(registry, resolution) {
|
|
1270
|
-
const key = createNamedTypeSignatureKey(resolution);
|
|
1271
|
-
const existing = registry.entriesByKey.get(key);
|
|
1272
|
-
if (existing) return existing.name;
|
|
1273
|
-
throw new InternalError(`Named type registry was not seeded for native type "${resolution.nativeType}"`);
|
|
1274
|
-
}
|
|
1275
|
-
function createNamedTypeSignatureKey(resolution) {
|
|
1276
|
-
return JSON.stringify({
|
|
1277
|
-
baseType: resolution.pslType,
|
|
1278
|
-
nativeTypeAttribute: resolution.nativeTypeAttribute ? {
|
|
1279
|
-
name: resolution.nativeTypeAttribute.name,
|
|
1280
|
-
args: resolution.nativeTypeAttribute.args ?? null
|
|
1281
|
-
} : null
|
|
1282
|
-
});
|
|
1283
|
-
}
|
|
1284
1122
|
function topologicalSort(models, tables, modelNameMap) {
|
|
1285
1123
|
const modelByName = /* @__PURE__ */ new Map();
|
|
1286
1124
|
for (const model of models) modelByName.set(model.name, model);
|