@vibeorm/migrate 2.6.0 → 2.7.0
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/fs.js +56 -14
- package/dist/fs.js.map +7 -7
- package/dist/index.js +56 -14
- package/dist/index.js.map +7 -7
- package/dist/inspect-objects.d.ts.map +1 -1
- package/dist/normalize.d.ts +19 -1
- package/dist/normalize.d.ts.map +1 -1
- package/dist/postgres-types.d.ts +24 -0
- package/dist/postgres-types.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/fs.js
CHANGED
|
@@ -172,6 +172,9 @@ var SCALAR_TO_PG = {
|
|
|
172
172
|
var CANONICAL_EQUIVALENTS = {
|
|
173
173
|
DateTime: ["timestamptz(3)", "timestamptz(6)"]
|
|
174
174
|
};
|
|
175
|
+
var EXACT_CANONICAL_EQUIVALENTS = {
|
|
176
|
+
DateTime: ["timestamptz(6)"]
|
|
177
|
+
};
|
|
175
178
|
var CANONICAL_UDT = {
|
|
176
179
|
text: "String",
|
|
177
180
|
bool: "Boolean",
|
|
@@ -240,13 +243,15 @@ var NATIVE_ALIASES = {
|
|
|
240
243
|
var IMPLICIT_MODIFIERS = {
|
|
241
244
|
bit: "(1)"
|
|
242
245
|
};
|
|
246
|
+
var DEFAULT_PRECISION_SIX = new Set(["timestamp", "time", "timetz"]);
|
|
243
247
|
function normalizeNativeType(params) {
|
|
244
248
|
const compact = params.raw.toLowerCase().replace(/\s+/g, "");
|
|
245
249
|
const match = compact.match(/^([a-z_0-9]+)(\(.*\))?(\[\])?$/);
|
|
246
250
|
if (match === null)
|
|
247
251
|
return compact;
|
|
248
252
|
const base = NATIVE_ALIASES[match[1]] ?? match[1];
|
|
249
|
-
|
|
253
|
+
const modifier = DEFAULT_PRECISION_SIX.has(base) && match[2] === "(6)" ? "" : match[2] ?? IMPLICIT_MODIFIERS[base] ?? "";
|
|
254
|
+
return `${base}${modifier}${match[3] ?? ""}`;
|
|
250
255
|
}
|
|
251
256
|
function parseUnsupportedPostgresType(params) {
|
|
252
257
|
const temporal = /^\s*(time(?:stamp)?)\s*(\(\s*\d+\s*\))?\s+(with|without)\s+time\s+zone\s*((?:\[\s*\]\s*)*)$/i.exec(params.raw);
|
|
@@ -259,7 +264,7 @@ function parseUnsupportedPostgresType(params) {
|
|
|
259
264
|
return NATIVE_ALIASES[base] === undefined ? undefined : parsePostgresTypeName({ raw: normalizeNativeType(params) });
|
|
260
265
|
}
|
|
261
266
|
function columnTypeKey(params) {
|
|
262
|
-
const { field } = params;
|
|
267
|
+
const { field, exact } = params;
|
|
263
268
|
const listSuffix = field.isList ? "[]" : "";
|
|
264
269
|
if (field.isUnsupported === true) {
|
|
265
270
|
const parsed = parseUnsupportedPostgresType({ raw: field.nativeType ?? "" });
|
|
@@ -270,7 +275,7 @@ function columnTypeKey(params) {
|
|
|
270
275
|
const scalar = namespace === undefined || namespace === "pg_catalog" ? scalarForBuiltinType({ name: parsed.name }) : undefined;
|
|
271
276
|
if (scalar !== undefined) {
|
|
272
277
|
const { isUnsupported: _unsupported, nativeTypeIdentity: _identity, ...rest } = field;
|
|
273
|
-
return columnTypeKey({ field: { ...rest, type: scalar, nativeType: `${parsed.name}${parsed.modifier ?? ""}`, isList: parsed.array || field.isList } });
|
|
278
|
+
return columnTypeKey({ field: { ...rest, type: scalar, nativeType: `${parsed.name}${parsed.modifier ?? ""}`, isList: parsed.array || field.isList }, ...exact === undefined ? {} : { exact } });
|
|
274
279
|
}
|
|
275
280
|
return `u:${JSON.stringify([namespace ?? null, parsed.name, parsed.modifier, parsed.array || field.isList])}`;
|
|
276
281
|
}
|
|
@@ -281,12 +286,37 @@ function columnTypeKey(params) {
|
|
|
281
286
|
if (field.nativeType !== undefined) {
|
|
282
287
|
const normalized = normalizeNativeType({ raw: field.nativeType });
|
|
283
288
|
const canonical = normalizeNativeType({ raw: SCALAR_TO_PG[field.type] });
|
|
284
|
-
const
|
|
289
|
+
const equivalents = exact === true ? EXACT_CANONICAL_EQUIVALENTS : CANONICAL_EQUIVALENTS;
|
|
290
|
+
const isCanonical = normalized === canonical || (equivalents[field.type]?.includes(normalized) ?? false);
|
|
285
291
|
if (!isCanonical)
|
|
286
292
|
return `n:${normalized}${listSuffix}`;
|
|
287
293
|
}
|
|
288
294
|
return `s:${field.type}${listSuffix}`;
|
|
289
295
|
}
|
|
296
|
+
function declaresExactColumnType(params) {
|
|
297
|
+
const { field } = params;
|
|
298
|
+
if (field.isUnsupported === true || field.nativeType === undefined || isEnumType(field.type))
|
|
299
|
+
return false;
|
|
300
|
+
return CANONICAL_EQUIVALENTS[field.type]?.includes(normalizeNativeType({ raw: field.nativeType })) ?? false;
|
|
301
|
+
}
|
|
302
|
+
function timestamptzPrecision(params) {
|
|
303
|
+
const { field } = params;
|
|
304
|
+
if (field.type !== "DateTime" || field.isUnsupported === true)
|
|
305
|
+
return;
|
|
306
|
+
const normalized = field.nativeType === undefined ? "timestamptz" : normalizeNativeType({ raw: field.nativeType });
|
|
307
|
+
if (normalized === "timestamptz")
|
|
308
|
+
return 6;
|
|
309
|
+
const match = /^timestamptz\((\d)\)$/.exec(normalized);
|
|
310
|
+
return match === null ? undefined : Number(match[1]);
|
|
311
|
+
}
|
|
312
|
+
function isTimestamptzPrecisionWidening(params) {
|
|
313
|
+
const { from, to } = params;
|
|
314
|
+
if (from.isList !== to.isList)
|
|
315
|
+
return false;
|
|
316
|
+
const before = timestamptzPrecision({ field: from });
|
|
317
|
+
const after = timestamptzPrecision({ field: to });
|
|
318
|
+
return before !== undefined && after !== undefined && after >= before;
|
|
319
|
+
}
|
|
290
320
|
function isScalarToArrayChange(params) {
|
|
291
321
|
const { from, to } = params;
|
|
292
322
|
if (from.isList || !to.isList)
|
|
@@ -829,16 +859,20 @@ function assertStringEnumLabelsFit(params) {
|
|
|
829
859
|
}
|
|
830
860
|
}
|
|
831
861
|
function columnTypeKeyFor(params) {
|
|
832
|
-
const { field, dialect, enums } = params;
|
|
862
|
+
const { field, dialect, enums, exact } = params;
|
|
833
863
|
switch (dialect) {
|
|
834
864
|
case "postgres":
|
|
835
|
-
return columnTypeKey({ field });
|
|
865
|
+
return columnTypeKey({ field, ...exact === undefined ? {} : { exact } });
|
|
836
866
|
case "sqlite":
|
|
837
867
|
return sqliteColumnTypeKey({ field, enums });
|
|
838
868
|
case "mysql":
|
|
839
869
|
return mysqlColumnTypeKey({ field, enums });
|
|
840
870
|
}
|
|
841
871
|
}
|
|
872
|
+
function columnTypeChanged(params) {
|
|
873
|
+
const { declared, actual } = params;
|
|
874
|
+
return declared.pinsExactType ? declared.exactTypeKey !== actual.exactTypeKey : declared.typeKey !== actual.typeKey;
|
|
875
|
+
}
|
|
842
876
|
function defaultFingerprintFor(params) {
|
|
843
877
|
const { field, dialect } = params;
|
|
844
878
|
switch (dialect) {
|
|
@@ -861,6 +895,8 @@ function normalizeModel(params) {
|
|
|
861
895
|
name,
|
|
862
896
|
field,
|
|
863
897
|
typeKey: columnTypeKeyFor({ field, dialect, enums }),
|
|
898
|
+
exactTypeKey: columnTypeKeyFor({ field, dialect, enums, exact: true }),
|
|
899
|
+
pinsExactType: dialect === "postgres" && declaresExactColumnType({ field }),
|
|
864
900
|
nullable: field.isOptional,
|
|
865
901
|
defaultKey: defaultFingerprintFor({ field, dialect })
|
|
866
902
|
});
|
|
@@ -2720,8 +2756,9 @@ function reverseMapType(params) {
|
|
|
2720
2756
|
function nonCanonicalModifier(params) {
|
|
2721
2757
|
const { column, udt, scalar } = params;
|
|
2722
2758
|
if (column.dataType === "ARRAY" && column.fullType !== null) {
|
|
2723
|
-
const
|
|
2724
|
-
|
|
2759
|
+
const temporal = parseUnsupportedPostgresType({ raw: column.fullType });
|
|
2760
|
+
const element = temporal?.name === "timestamptz" ? `timestamptz${temporal.modifier}` : normalizeNativeType({ raw: column.fullType }).replace(/\[\]$/, "");
|
|
2761
|
+
if (element !== "timestamptz(6)" && /^(numeric|timestamptz)\([\d,]+\)$/.test(element))
|
|
2725
2762
|
return element;
|
|
2726
2763
|
}
|
|
2727
2764
|
if (scalar === "DateTime" && udt === "timestamptz") {
|
|
@@ -2738,9 +2775,9 @@ function nonCanonicalModifier(params) {
|
|
|
2738
2775
|
}
|
|
2739
2776
|
function withModifier(params) {
|
|
2740
2777
|
const { column, udt } = params;
|
|
2741
|
-
if (udt === "varchar" && column.dataType === "ARRAY" && column.fullType !== null) {
|
|
2778
|
+
if ((udt === "varchar" || udt === "bpchar" || udt === "bit" || udt === "varbit") && column.dataType === "ARRAY" && column.fullType !== null) {
|
|
2742
2779
|
const elementType = normalizeNativeType({ raw: column.fullType }).replace(/\[\]$/, "");
|
|
2743
|
-
if (/^varchar\(\d+\)$/.test(elementType))
|
|
2780
|
+
if (/^(varchar|char|bit|varbit)\(\d+\)$/.test(elementType))
|
|
2744
2781
|
return elementType;
|
|
2745
2782
|
}
|
|
2746
2783
|
if ((udt === "varchar" || udt === "bpchar") && column.charMaxLength !== null) {
|
|
@@ -2750,6 +2787,10 @@ function withModifier(params) {
|
|
|
2750
2787
|
return "char";
|
|
2751
2788
|
if ((udt === "bit" || udt === "varbit") && column.charMaxLength !== null)
|
|
2752
2789
|
return `${udt}(${column.charMaxLength})`;
|
|
2790
|
+
if ((udt === "timestamp" || udt === "time" || udt === "timetz") && column.dataType === "ARRAY" && column.fullType !== null) {
|
|
2791
|
+
const element = parseUnsupportedPostgresType({ raw: column.fullType });
|
|
2792
|
+
return element === undefined || element.modifier === "" || element.modifier === "(6)" ? udt : `${udt}${element.modifier}`;
|
|
2793
|
+
}
|
|
2753
2794
|
if ((udt === "timestamp" || udt === "time" || udt === "timetz") && column.datetimePrecision !== null && column.datetimePrecision !== 6) {
|
|
2754
2795
|
return `${udt}(${column.datetimePrecision})`;
|
|
2755
2796
|
}
|
|
@@ -4248,7 +4289,8 @@ async function verifySchemaObjects(params) {
|
|
|
4248
4289
|
pin("primaryKey", desired.pk, live.pk);
|
|
4249
4290
|
for (const [column, field] of desired.columns) {
|
|
4250
4291
|
const stored = live.columns.get(column);
|
|
4251
|
-
|
|
4292
|
+
const exactType = field.pinsExactType;
|
|
4293
|
+
pin(`columns.${column}.type`, exactType ? field.exactTypeKey : field.typeKey, exactType ? stored?.exactTypeKey : stored?.typeKey);
|
|
4252
4294
|
pin(`columns.${column}.nullable`, field.nullable, stored?.nullable);
|
|
4253
4295
|
if (params.dialect === "mysql" && field.field.collation !== undefined) {
|
|
4254
4296
|
pin(`columns.${column}.collation`, field.field.collation.toLowerCase(), stored?.field.collation?.toLowerCase());
|
|
@@ -6044,7 +6086,7 @@ function diffOneTable(params) {
|
|
|
6044
6086
|
continue;
|
|
6045
6087
|
}
|
|
6046
6088
|
const changes = [];
|
|
6047
|
-
if (
|
|
6089
|
+
if (columnTypeChanged({ declared: column, actual: before }))
|
|
6048
6090
|
changes.push("type");
|
|
6049
6091
|
if (before.nullable !== column.nullable)
|
|
6050
6092
|
changes.push("nullability");
|
|
@@ -6067,7 +6109,7 @@ function diffOneTable(params) {
|
|
|
6067
6109
|
assertStringEnumLabelsFit({ field: column.field, values, dialect, table });
|
|
6068
6110
|
}
|
|
6069
6111
|
}
|
|
6070
|
-
let narrowingType = changes.includes("type") && !isScalarToArrayChange({ from: before.field, to: column.field }) && !(storageChange && column.field.type === "String");
|
|
6112
|
+
let narrowingType = changes.includes("type") && !isScalarToArrayChange({ from: before.field, to: column.field }) && !(dialect === "postgres" && isTimestamptzPrecisionWidening({ from: before.field, to: column.field })) && !(storageChange && column.field.type === "String");
|
|
6071
6113
|
if (dialect !== "postgres" && changes.includes("type") && isEnumType6(before.field.type) && isEnumType6(column.field.type)) {
|
|
6072
6114
|
const fromValues = resolveEnumValues({ name: before.field.type.enum, enums: fromEnums });
|
|
6073
6115
|
const toValues = resolveEnumValues({ name: column.field.type.enum, enums: toEnums });
|
|
@@ -8701,4 +8743,4 @@ export {
|
|
|
8701
8743
|
splitSqlStatements
|
|
8702
8744
|
};
|
|
8703
8745
|
|
|
8704
|
-
//# debugId=
|
|
8746
|
+
//# debugId=000F8CFDEDF957F264756E2164756E21
|