mutano 3.4.0 → 3.5.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/main.d.ts +2 -0
- package/dist/main.js +37 -25
- package/package.json +1 -1
package/dist/main.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ interface Desc {
|
|
|
7
7
|
Extra: string;
|
|
8
8
|
Null: string;
|
|
9
9
|
Type: string;
|
|
10
|
+
DataType?: string;
|
|
10
11
|
Comment: string;
|
|
11
12
|
EnumOptions?: string[];
|
|
12
13
|
}
|
|
@@ -48,6 +49,7 @@ interface Config {
|
|
|
48
49
|
password: string;
|
|
49
50
|
database: string;
|
|
50
51
|
ssl?: Record<string, any>;
|
|
52
|
+
tinyIntAsBoolean?: boolean;
|
|
51
53
|
} | {
|
|
52
54
|
type: 'postgres';
|
|
53
55
|
host: string;
|
package/dist/main.js
CHANGED
|
@@ -43,8 +43,8 @@ function filterViews(views, includedViews, ignoredViews) {
|
|
|
43
43
|
}
|
|
44
44
|
function createEntityList(tables, views) {
|
|
45
45
|
const allEntities = [
|
|
46
|
-
...tables.map((name) => ({ name, type: "table" })),
|
|
47
|
-
...views.map((name) => ({ name, type: "view" }))
|
|
46
|
+
...tables.filter((name) => typeof name === "string" && name.length > 0).map((name) => ({ name, type: "table" })),
|
|
47
|
+
...views.filter((name) => typeof name === "string" && name.length > 0).map((name) => ({ name, type: "view" }))
|
|
48
48
|
];
|
|
49
49
|
return allEntities.sort((a, b) => a.name.localeCompare(b.name));
|
|
50
50
|
}
|
|
@@ -60,7 +60,7 @@ function applyInflection(name, inflection) {
|
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
const dateTypes = {
|
|
63
|
-
mysql: ["date", "datetime", "timestamp"],
|
|
63
|
+
mysql: ["date", "datetime", "datetime(3)", "timestamp", "timestamp(3)"],
|
|
64
64
|
postgres: [
|
|
65
65
|
"timestamp",
|
|
66
66
|
"timestamp with time zone",
|
|
@@ -219,9 +219,16 @@ const hasTableIgnoreDirective = (comment) => {
|
|
|
219
219
|
};
|
|
220
220
|
|
|
221
221
|
function getType(op, desc, config, destination, entityName) {
|
|
222
|
-
const { Default, Extra, Null, Type, Comment, EnumOptions } = desc;
|
|
222
|
+
const { Default, Extra, Null, Type, DataType, Comment, EnumOptions } = desc;
|
|
223
223
|
const schemaType = config.origin.type;
|
|
224
224
|
const type = schemaType === "prisma" ? Type : Type.toLowerCase();
|
|
225
|
+
let dataType = DataType ? schemaType === "prisma" ? DataType : DataType.toLowerCase() : type;
|
|
226
|
+
const isMySQL = schemaType === "mysql";
|
|
227
|
+
const tinyIntAsBoolean = isMySQL && config.origin.tinyIntAsBoolean !== false;
|
|
228
|
+
const isTinyInt1 = isMySQL && dataType === "tinyint" && Type.toLowerCase().includes("(1)");
|
|
229
|
+
if (tinyIntAsBoolean && isTinyInt1) {
|
|
230
|
+
dataType = "boolean";
|
|
231
|
+
}
|
|
225
232
|
const isNull = Null === "YES";
|
|
226
233
|
const hasDefaultValue = Default !== null;
|
|
227
234
|
const isGenerated = Extra.toLowerCase().includes("auto_increment") || Extra.toLowerCase().includes("default_generated");
|
|
@@ -278,18 +285,18 @@ function getType(op, desc, config, destination, entityName) {
|
|
|
278
285
|
}
|
|
279
286
|
}
|
|
280
287
|
if (isTsDestination || isKyselyDestination) {
|
|
281
|
-
const isJsonField = isJsonType(
|
|
288
|
+
const isJsonField = isJsonType(dataType);
|
|
282
289
|
if (isKyselyDestination && isJsonField) {
|
|
283
290
|
const shouldBeNullable = isNull || ["insertable", "updateable"].includes(op) && (hasDefaultValue || isGenerated) || op === "updateable" && !isNull && !hasDefaultValue;
|
|
284
291
|
return shouldBeNullable ? "Json | null" : "Json";
|
|
285
292
|
}
|
|
286
293
|
}
|
|
287
|
-
const enumTypesForSchema = typeMappings.enumTypes
|
|
288
|
-
const isEnum = enumTypesForSchema.includes(
|
|
294
|
+
const enumTypesForSchema = typeMappings.enumTypes || [];
|
|
295
|
+
const isEnum = enumTypesForSchema.includes(dataType);
|
|
289
296
|
const isPrismaEnum = schemaType === "prisma" && config.enumDeclarations && config.enumDeclarations[type];
|
|
290
297
|
if (isEnum || isPrismaEnum) {
|
|
291
298
|
let enumValues = [];
|
|
292
|
-
if (schemaType === "mysql" &&
|
|
299
|
+
if (schemaType === "mysql" && dataType === "enum") {
|
|
293
300
|
const match = Type.match(enumRegex);
|
|
294
301
|
if (match) {
|
|
295
302
|
enumValues = match[1].split(",").map((v) => v.trim().replace(/'/g, ""));
|
|
@@ -343,12 +350,12 @@ function getType(op, desc, config, destination, entityName) {
|
|
|
343
350
|
}
|
|
344
351
|
}
|
|
345
352
|
}
|
|
346
|
-
return generateStandardType(op, desc, config, destination, typeMappings);
|
|
353
|
+
return generateStandardType(op, desc, config, destination, typeMappings, dataType);
|
|
347
354
|
}
|
|
348
|
-
function generateStandardType(op, desc, config, destination, typeMappings) {
|
|
355
|
+
function generateStandardType(op, desc, config, destination, typeMappings, dataType) {
|
|
349
356
|
const { Default, Extra, Null, Type } = desc;
|
|
350
357
|
const schemaType = config.origin.type;
|
|
351
|
-
|
|
358
|
+
schemaType === "prisma" ? Type : Type.toLowerCase();
|
|
352
359
|
const isNull = Null === "YES";
|
|
353
360
|
const hasDefaultValue = Default !== null;
|
|
354
361
|
const isGenerated = Extra.toLowerCase().includes("auto_increment") || Extra.toLowerCase().includes("default_generated");
|
|
@@ -357,7 +364,7 @@ function generateStandardType(op, desc, config, destination, typeMappings) {
|
|
|
357
364
|
const shouldBeNullable = isNull;
|
|
358
365
|
const shouldBeOptional = op === "insertable" && (hasDefaultValue || isGenerated) || op === "updateable";
|
|
359
366
|
let baseType;
|
|
360
|
-
if (typeMappings.dateTypes.includes(
|
|
367
|
+
if (typeMappings.dateTypes.includes(dataType)) {
|
|
361
368
|
if (isZodDestination) {
|
|
362
369
|
const useDateType = destination.useDateType;
|
|
363
370
|
if (useDateType) {
|
|
@@ -368,7 +375,7 @@ function generateStandardType(op, desc, config, destination, typeMappings) {
|
|
|
368
375
|
} else {
|
|
369
376
|
baseType = "Date";
|
|
370
377
|
}
|
|
371
|
-
} else if (typeMappings.bigIntTypes.includes(
|
|
378
|
+
} else if (typeMappings.bigIntTypes.includes(dataType)) {
|
|
372
379
|
if (isZodDestination) {
|
|
373
380
|
baseType = "z.string()";
|
|
374
381
|
} else if (isKyselyDestination) {
|
|
@@ -376,7 +383,7 @@ function generateStandardType(op, desc, config, destination, typeMappings) {
|
|
|
376
383
|
} else {
|
|
377
384
|
baseType = "string";
|
|
378
385
|
}
|
|
379
|
-
} else if (typeMappings.decimalTypes.includes(
|
|
386
|
+
} else if (typeMappings.decimalTypes.includes(dataType)) {
|
|
380
387
|
if (isZodDestination) {
|
|
381
388
|
baseType = "z.string()";
|
|
382
389
|
if (op !== "selectable") {
|
|
@@ -390,13 +397,13 @@ function generateStandardType(op, desc, config, destination, typeMappings) {
|
|
|
390
397
|
} else {
|
|
391
398
|
baseType = "string";
|
|
392
399
|
}
|
|
393
|
-
} else if (typeMappings.numberTypes.includes(
|
|
400
|
+
} else if (typeMappings.numberTypes.includes(dataType)) {
|
|
394
401
|
if (isZodDestination) {
|
|
395
402
|
baseType = "z.number()";
|
|
396
403
|
} else {
|
|
397
404
|
baseType = "number";
|
|
398
405
|
}
|
|
399
|
-
} else if (typeMappings.booleanTypes.includes(
|
|
406
|
+
} else if (typeMappings.booleanTypes.includes(dataType)) {
|
|
400
407
|
if (isZodDestination) {
|
|
401
408
|
const useBooleanType = destination.useBooleanType;
|
|
402
409
|
if (useBooleanType) {
|
|
@@ -407,7 +414,7 @@ function generateStandardType(op, desc, config, destination, typeMappings) {
|
|
|
407
414
|
} else {
|
|
408
415
|
baseType = "boolean";
|
|
409
416
|
}
|
|
410
|
-
} else if (typeMappings.stringTypes.includes(
|
|
417
|
+
} else if (typeMappings.stringTypes.includes(dataType)) {
|
|
411
418
|
if (isZodDestination) {
|
|
412
419
|
const useTrim = destination.useTrim;
|
|
413
420
|
const requiredString = destination.requiredString;
|
|
@@ -425,11 +432,11 @@ function generateStandardType(op, desc, config, destination, typeMappings) {
|
|
|
425
432
|
const nullableMethod = nullishOption && op !== "selectable" ? "nullish" : "nullable";
|
|
426
433
|
if ((op === "table" || op === "insertable" || op === "updateable") && hasDefaultValue && Default !== null && !isGenerated) {
|
|
427
434
|
let defaultValueFormatted = Default;
|
|
428
|
-
if (typeMappings.stringTypes.includes(
|
|
435
|
+
if (typeMappings.stringTypes.includes(dataType) || typeMappings.dateTypes.includes(dataType)) {
|
|
429
436
|
defaultValueFormatted = `'${Default}'`;
|
|
430
|
-
} else if (typeMappings.booleanTypes.includes(
|
|
437
|
+
} else if (typeMappings.booleanTypes.includes(dataType)) {
|
|
431
438
|
defaultValueFormatted = Default.toLowerCase() === "true" ? "true" : "false";
|
|
432
|
-
} else if (typeMappings.numberTypes.includes(
|
|
439
|
+
} else if (typeMappings.numberTypes.includes(dataType)) {
|
|
433
440
|
defaultValueFormatted = Default;
|
|
434
441
|
} else {
|
|
435
442
|
defaultValueFormatted = `'${Default}'`;
|
|
@@ -444,9 +451,9 @@ function generateStandardType(op, desc, config, destination, typeMappings) {
|
|
|
444
451
|
return `${baseType}.default(${defaultValueFormatted})`;
|
|
445
452
|
}
|
|
446
453
|
}
|
|
447
|
-
const isDateField = typeMappings.dateTypes.includes(
|
|
454
|
+
const isDateField = typeMappings.dateTypes.includes(dataType);
|
|
448
455
|
const shouldDateBeOptional = isDateField && (hasDefaultValue || isGenerated) && (op === "table" || op === "selectable");
|
|
449
|
-
const isIdField = typeMappings.numberTypes.includes(
|
|
456
|
+
const isIdField = typeMappings.numberTypes.includes(dataType) || typeMappings.bigIntTypes.includes(dataType) || typeMappings.stringTypes.includes(dataType);
|
|
450
457
|
const shouldIdBeOptional = isIdField && isGenerated && (op === "table" || op === "selectable");
|
|
451
458
|
if (shouldBeNullable && shouldBeOptional) {
|
|
452
459
|
return `${baseType}.${nullableMethod}()`;
|
|
@@ -808,7 +815,7 @@ async function extractTables(db, config) {
|
|
|
808
815
|
FROM information_schema.tables
|
|
809
816
|
WHERE table_schema = ? AND table_type = 'BASE TABLE'
|
|
810
817
|
`, [origin.database]);
|
|
811
|
-
return mysqlTables[0].filter((row) => !hasTableIgnoreDirective(row.table_comment || "")).map((row) => row.table_name);
|
|
818
|
+
return mysqlTables[0].filter((row) => !hasTableIgnoreDirective(row.TABLE_COMMENT || row.table_comment || "")).map((row) => row.TABLE_NAME || row.table_name).filter((name) => typeof name === "string" && name.length > 0);
|
|
812
819
|
case "postgres":
|
|
813
820
|
const schema = origin.schema || "public";
|
|
814
821
|
const postgresTables = await db.raw(`
|
|
@@ -837,7 +844,7 @@ async function extractViews(db, config) {
|
|
|
837
844
|
FROM information_schema.tables
|
|
838
845
|
WHERE table_schema = ? AND table_type = 'VIEW'
|
|
839
846
|
`, [origin.database]);
|
|
840
|
-
return mysqlViews[0].filter((row) => !hasTableIgnoreDirective(row.table_comment || "")).map((row) => row.table_name);
|
|
847
|
+
return mysqlViews[0].filter((row) => !hasTableIgnoreDirective(row.TABLE_COMMENT || row.table_comment || "")).map((row) => row.TABLE_NAME || row.table_name).filter((name) => typeof name === "string" && name.length > 0);
|
|
841
848
|
case "postgres":
|
|
842
849
|
const schema = origin.schema || "public";
|
|
843
850
|
const postgresViews = await db.raw(`
|
|
@@ -867,6 +874,7 @@ async function extractColumnDescriptions(db, config, tableName) {
|
|
|
867
874
|
column_default as \`Default\`,
|
|
868
875
|
extra as \`Extra\`,
|
|
869
876
|
is_nullable as \`Null\`,
|
|
877
|
+
data_type as \`DataType\`,
|
|
870
878
|
column_type as \`Type\`,
|
|
871
879
|
column_comment as \`Comment\`
|
|
872
880
|
FROM information_schema.columns
|
|
@@ -878,6 +886,7 @@ async function extractColumnDescriptions(db, config, tableName) {
|
|
|
878
886
|
Default: row.Default,
|
|
879
887
|
Extra: row.Extra || "",
|
|
880
888
|
Null: row.Null,
|
|
889
|
+
DataType: row.DataType,
|
|
881
890
|
Type: row.Type,
|
|
882
891
|
Comment: row.Comment || ""
|
|
883
892
|
}));
|
|
@@ -951,6 +960,9 @@ function extractPrismaEntities(config) {
|
|
|
951
960
|
if (e.type === "attribute") {
|
|
952
961
|
return false;
|
|
953
962
|
}
|
|
963
|
+
if (!e.name || typeof e.name !== "string") {
|
|
964
|
+
return false;
|
|
965
|
+
}
|
|
954
966
|
if ("attributes" in e && e.attributes) {
|
|
955
967
|
const hasIgnore = e.attributes.some((attr) => attr.name === "ignore");
|
|
956
968
|
if (hasIgnore) {
|
|
@@ -975,7 +987,7 @@ function extractPrismaEntities(config) {
|
|
|
975
987
|
}
|
|
976
988
|
}
|
|
977
989
|
return e.name;
|
|
978
|
-
});
|
|
990
|
+
}).filter((value) => typeof value === "string" && value !== "undefined");
|
|
979
991
|
enumDeclarations[enumName] = filteredEnumValues;
|
|
980
992
|
}
|
|
981
993
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mutano",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "3.
|
|
4
|
+
"version": "3.5.0",
|
|
5
5
|
"description": "Converts Prisma/MySQL/PostgreSQL/SQLite schemas to Zod/TS/Kysely interfaces",
|
|
6
6
|
"author": "Alisson Cavalcante Agiani <thelinuxlich@gmail.com>",
|
|
7
7
|
"license": "MIT",
|