@forestadmin/datasource-sql 1.2.4 → 1.2.5
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/introspection/introspector.js +6 -6
- package/dist/introspection/types.d.ts +1 -2
- package/dist/orm-builder/helpers/relation-extractor.d.ts +1 -0
- package/dist/orm-builder/helpers/relation-extractor.js +5 -2
- package/dist/orm-builder/model.d.ts +6 -0
- package/dist/orm-builder/model.js +49 -14
- package/package.json +1 -1
|
@@ -56,24 +56,25 @@ class Introspector {
|
|
|
56
56
|
]);
|
|
57
57
|
// Create columns
|
|
58
58
|
const columns = Object.entries(columnDescriptions).map(([name, description]) => {
|
|
59
|
-
const indexes = tableIndexes.filter(i => i.fields.find(f => f.attribute === name));
|
|
60
59
|
const references = tableReferences.filter(r => r.columnName === name);
|
|
61
|
-
const options = { name, description,
|
|
60
|
+
const options = { name, description, references };
|
|
62
61
|
return this.getColumn(sequelize, logger, tableName, options);
|
|
63
62
|
});
|
|
64
63
|
return {
|
|
65
64
|
name: tableName,
|
|
66
65
|
columns: (await Promise.all(columns)).filter(Boolean),
|
|
66
|
+
unique: tableIndexes
|
|
67
|
+
.filter(i => i.unique || i.primary)
|
|
68
|
+
.map(i => i.fields.map(f => f.attribute)),
|
|
67
69
|
};
|
|
68
70
|
}
|
|
69
71
|
static async getColumn(sequelize, logger, tableName, options) {
|
|
70
|
-
const { name, description,
|
|
72
|
+
const { name, description, references } = options;
|
|
71
73
|
const dialect = sequelize.getDialect();
|
|
72
74
|
const typeConverter = new sql_type_converter_1.default(sequelize);
|
|
73
75
|
try {
|
|
74
76
|
const type = await typeConverter.convert(tableName, name, description);
|
|
75
77
|
const defaultValue = new default_value_parser_1.default(dialect).parse(description.defaultValue, type);
|
|
76
|
-
const unique = !!indexes.find(i => i.fields.length === 1 && i.fields[0].attribute === name && i.unique);
|
|
77
78
|
// Workaround autoincrement flag not being properly set when using postgres
|
|
78
79
|
const autoIncrement = Boolean(description.autoIncrement || description.defaultValue?.match?.(/^nextval\(.+\)$/));
|
|
79
80
|
return {
|
|
@@ -82,7 +83,6 @@ class Introspector {
|
|
|
82
83
|
defaultValue: autoIncrement ? null : defaultValue,
|
|
83
84
|
name,
|
|
84
85
|
allowNull: description.allowNull,
|
|
85
|
-
unique,
|
|
86
86
|
primaryKey: description.primaryKey,
|
|
87
87
|
constraints: references.map(r => ({
|
|
88
88
|
table: r.referencedTableName,
|
|
@@ -96,4 +96,4 @@ class Introspector {
|
|
|
96
96
|
}
|
|
97
97
|
}
|
|
98
98
|
exports.default = Introspector;
|
|
99
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
99
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW50cm9zcGVjdG9yLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2ludHJvc3BlY3Rpb24vaW50cm9zcGVjdG9yLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBR0EscUNBU2tCO0FBQ2xCLDBGQUFnRTtBQUNoRSxzRkFBNEQ7QUFHNUQsTUFBcUIsWUFBWTtJQUMvQixNQUFNLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxTQUFvQixFQUFFLE1BQWU7UUFDM0QsSUFBSTtZQUNGLE1BQU0sVUFBVSxHQUFHLE1BQU0sSUFBSSxDQUFDLGFBQWEsQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUV2RCxPQUFPLE1BQU0sT0FBTyxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxTQUFTLEVBQUUsTUFBTSxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztTQUMxRjtRQUFDLE9BQU8sQ0FBQyxFQUFFO1lBQ1YsUUFBUyxDQUE4QixDQUFDLElBQUksRUFBRTtnQkFDNUMsS0FBSywwQkFBMEI7b0JBQzdCLE1BQU0sSUFBSSx3QkFBZSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQztnQkFDdkMsS0FBSyw0QkFBNEI7b0JBQy9CLE1BQU0sSUFBSSwwQkFBaUIsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUM7Z0JBQ3pDLEtBQUssaUNBQWlDO29CQUNwQyxNQUFNLElBQUksK0JBQXNCLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDO2dCQUM5QyxLQUFLLGdDQUFnQztvQkFDbkMsTUFBTSxJQUFJLDhCQUFxQixDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQztnQkFDN0MsS0FBSyw0QkFBNEI7b0JBQy9CLE1BQU0sSUFBSSwwQkFBaUIsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUM7Z0JBQ3pDLEtBQUssd0NBQXdDO29CQUMz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
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { AbstractDataType, AbstractDataTypeConstructor, QueryInterface } from 'sequelize/types';
|
|
2
|
-
export type SequelizeIndex = Awaited<ReturnType<QueryInterface['showIndex']>>[number];
|
|
3
2
|
export type SequelizeColumn = Awaited<ReturnType<QueryInterface['describeTable']>>[number];
|
|
4
3
|
export type SequelizeColumnType = AbstractDataType | AbstractDataTypeConstructor;
|
|
5
4
|
export type SequelizeReference = Awaited<ReturnType<QueryInterface['getForeignKeyReferencesForTable']>>[number];
|
|
@@ -27,12 +26,12 @@ export type ColumnType = {
|
|
|
27
26
|
};
|
|
28
27
|
export type Table = {
|
|
29
28
|
name: string;
|
|
29
|
+
unique: string[][];
|
|
30
30
|
columns: {
|
|
31
31
|
name: string;
|
|
32
32
|
type: ColumnType;
|
|
33
33
|
defaultValue: unknown;
|
|
34
34
|
allowNull: boolean;
|
|
35
|
-
unique: boolean;
|
|
36
35
|
autoIncrement: boolean;
|
|
37
36
|
primaryKey: boolean;
|
|
38
37
|
constraints: {
|
|
@@ -23,7 +23,7 @@ class RelationExtractor {
|
|
|
23
23
|
// Skip HasMany to junction tables
|
|
24
24
|
if (!this.isJunctionTable(table))
|
|
25
25
|
relations.push({
|
|
26
|
-
type: column.
|
|
26
|
+
type: this.isUnique(table, column.name) ? 'HasOne' : 'HasMany',
|
|
27
27
|
from: constraint.table,
|
|
28
28
|
to: table.name,
|
|
29
29
|
originKey: column.name,
|
|
@@ -64,6 +64,9 @@ class RelationExtractor {
|
|
|
64
64
|
static isJunctionTable(table) {
|
|
65
65
|
return table.columns.filter(c => c.primaryKey && c.constraints.length === 1).length === 2;
|
|
66
66
|
}
|
|
67
|
+
static isUnique(table, columnName) {
|
|
68
|
+
return table.unique.some(u => u.length === 1 && u[0] === columnName);
|
|
69
|
+
}
|
|
67
70
|
}
|
|
68
71
|
exports.default = RelationExtractor;
|
|
69
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
72
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVsYXRpb24tZXh0cmFjdG9yLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL29ybS1idWlsZGVyL2hlbHBlcnMvcmVsYXRpb24tZXh0cmFjdG9yLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBR0EsTUFBcUIsaUJBQWlCO0lBQ3BDLE1BQU0sQ0FBQyxhQUFhLENBQUMsU0FBaUIsRUFBRSxNQUFlO1FBQ3JELE1BQU0sU0FBUyxHQUFlLEVBQUUsQ0FBQztRQUVqQyxLQUFLLE1BQU0sS0FBSyxJQUFJLE1BQU0sRUFBRTtZQUMxQixTQUFTLENBQUMsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7WUFDbkQsU0FBUyxDQUFDLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO1NBQ3REO1FBRUQsT0FBTyxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksS0FBSyxTQUFTLENBQUMsQ0FBQztJQUNyRCxDQUFDO0lBRU8sTUFBTSxDQUFDLG1CQUFtQixDQUFDLEtBQVk7UUFDN0MsTUFBTSxTQUFTLEdBQWUsRUFBRSxDQUFDO1FBRWpDLEtBQUssTUFBTSxNQUFNLElBQUksS0FBSyxDQUFDLE9BQU8sRUFBRTtZQUNsQyxLQUFLLE1BQU0sVUFBVSxJQUFJLE1BQU0sQ0FBQyxXQUFXLEVBQUU7Z0JBQzNDLFNBQVMsQ0FBQyxJQUFJLENBQUM7b0JBQ2IsSUFBSSxFQUFFLFdBQVc7b0JBQ2pCLElBQUksRUFBRSxLQUFLLENBQUMsSUFBSTtvQkFDaEIsRUFBRSxFQUFFLFVBQVUsQ0FBQyxLQUFLO29CQUNwQixVQUFVLEVBQUUsTUFBTSxDQUFDLElBQUk7b0JBQ3ZCLGdCQUFnQixFQUFFLFVBQVUsQ0FBQyxNQUFNO2lCQUNwQyxDQUFDLENBQUM7Z0JBRUgsa0NBQWtDO2dCQUNsQyxJ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
|
|
@@ -4,6 +4,12 @@ import { Table } from '../introspection/types';
|
|
|
4
4
|
export default class ModelBuilder {
|
|
5
5
|
static defineModels(sequelize: Sequelize, logger: Logger, tables: Table[]): void;
|
|
6
6
|
private static defineModel;
|
|
7
|
+
private static buildModelAttributes;
|
|
8
|
+
/**
|
|
9
|
+
* When the primary key is missing, we attempt to find a column that may act as such.
|
|
10
|
+
* This enables us to support tables that have no primary key.
|
|
11
|
+
*/
|
|
12
|
+
private static guessPrimaryKeyInPlace;
|
|
7
13
|
private static hasTimestamps;
|
|
8
14
|
private static isParanoid;
|
|
9
15
|
}
|
|
@@ -11,22 +11,12 @@ class ModelBuilder {
|
|
|
11
11
|
}
|
|
12
12
|
}
|
|
13
13
|
static defineModel(sequelize, logger, table) {
|
|
14
|
-
const modelAttrs = {};
|
|
15
14
|
const hasTimestamps = this.hasTimestamps(table);
|
|
16
15
|
const isParanoid = this.isParanoid(table);
|
|
17
16
|
const dialect = sequelize.getDialect();
|
|
18
|
-
|
|
19
|
-
const isExplicit = !(hasTimestamps && (column.name === 'updatedAt' || column.name === 'createdAt')) &&
|
|
20
|
-
!(isParanoid && column.name === 'deletedAt');
|
|
21
|
-
// Clone object, because sequelize modifies it.
|
|
22
|
-
if (isExplicit)
|
|
23
|
-
modelAttrs[column.name] = {
|
|
24
|
-
...column,
|
|
25
|
-
type: sequelize_type_1.default.makeType(dialect, column.type, table.name, column.name),
|
|
26
|
-
};
|
|
27
|
-
}
|
|
17
|
+
const attributes = this.buildModelAttributes(logger, table, hasTimestamps, isParanoid, dialect);
|
|
28
18
|
try {
|
|
29
|
-
const model = sequelize.define(table.name,
|
|
19
|
+
const model = sequelize.define(table.name, attributes, {
|
|
30
20
|
tableName: table.name,
|
|
31
21
|
timestamps: hasTimestamps,
|
|
32
22
|
paranoid: isParanoid,
|
|
@@ -34,14 +24,59 @@ class ModelBuilder {
|
|
|
34
24
|
// @see https://sequelize.org/docs/v6/other-topics/legacy/#primary-keys
|
|
35
25
|
// Tell sequelize NOT to invent primary keys when we don't provide them.
|
|
36
26
|
// (Note that this does not seem to work)
|
|
37
|
-
if (!
|
|
27
|
+
if (!attributes.id && model.getAttributes().id) {
|
|
38
28
|
model.removeAttribute('id');
|
|
39
29
|
}
|
|
40
30
|
}
|
|
41
31
|
catch (e) {
|
|
32
|
+
// In practice, now that we added the primary key guessing, this should not happen anymore.
|
|
33
|
+
// But we keep it here just in case.
|
|
42
34
|
logger?.('Warn', `Skipping table "${table.name}" because of error: ${e.message}`);
|
|
43
35
|
}
|
|
44
36
|
}
|
|
37
|
+
static buildModelAttributes(logger, table, hasTimestamps, isParanoid, dialect) {
|
|
38
|
+
const modelAttrs = {};
|
|
39
|
+
for (const column of table.columns) {
|
|
40
|
+
const isExplicit = !(hasTimestamps && (column.name === 'updatedAt' || column.name === 'createdAt')) &&
|
|
41
|
+
!(isParanoid && column.name === 'deletedAt');
|
|
42
|
+
// Clone object, because sequelize modifies it.
|
|
43
|
+
if (isExplicit)
|
|
44
|
+
modelAttrs[column.name] = {
|
|
45
|
+
...column,
|
|
46
|
+
type: sequelize_type_1.default.makeType(dialect, column.type, table.name, column.name),
|
|
47
|
+
unique: table.unique.some(u => u.length === 1 && u[0] === column.name),
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
// If there is no primary key, we try to guess one.
|
|
51
|
+
if (!table.columns.some(c => c.primaryKey)) {
|
|
52
|
+
this.guessPrimaryKeyInPlace(logger, table, modelAttrs);
|
|
53
|
+
}
|
|
54
|
+
return modelAttrs;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* When the primary key is missing, we attempt to find a column that may act as such.
|
|
58
|
+
* This enables us to support tables that have no primary key.
|
|
59
|
+
*/
|
|
60
|
+
static guessPrimaryKeyInPlace(logger, table, attributes) {
|
|
61
|
+
// Try to find a column named "id".
|
|
62
|
+
let primaryKeys = table.columns.some(c => c.name === 'id') ? ['id'] : [];
|
|
63
|
+
// If there is no id column, look at unique indexes, and use the shortest one.
|
|
64
|
+
// (hopefully only one column, but this can also be a composite key for many-to-many tables)
|
|
65
|
+
if (!primaryKeys.length && table.unique.length) {
|
|
66
|
+
[primaryKeys] = [...table.unique].sort((a, b) => a.length - b.length);
|
|
67
|
+
}
|
|
68
|
+
// If all the columns have contraints (e.g. foreign keys), use all of them as a composite key.
|
|
69
|
+
if (!primaryKeys.length &&
|
|
70
|
+
table.columns.length === 2 &&
|
|
71
|
+
table.columns.every(c => c.constraints.length)) {
|
|
72
|
+
primaryKeys = table.columns.map(c => c.name);
|
|
73
|
+
}
|
|
74
|
+
for (const column of primaryKeys)
|
|
75
|
+
attributes[column].primaryKey = true;
|
|
76
|
+
if (primaryKeys.length) {
|
|
77
|
+
logger?.('Warn', `Table "${table.name}" has no primary key. Using "${primaryKeys.join(', ')}".`);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
45
80
|
static hasTimestamps(table) {
|
|
46
81
|
return (!!table.columns.find(c => c.name === 'createdAt') &&
|
|
47
82
|
!!table.columns.find(c => c.name === 'updatedAt'));
|
|
@@ -51,4 +86,4 @@ class ModelBuilder {
|
|
|
51
86
|
}
|
|
52
87
|
}
|
|
53
88
|
exports.default = ModelBuilder;
|
|
54
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
89
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9kZWwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvb3JtLWJ1aWxkZXIvbW9kZWwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFJQSw4RUFBNEQ7QUFHNUQsTUFBcUIsWUFBWTtJQUMvQixNQUFNLENBQUMsWUFBWSxDQUFDLFNBQW9CLEVBQUUsTUFBYyxFQUFFLE1BQWU7UUFDdkUsS0FBSyxNQUFNLEtBQUssSUFBSSxNQUFNLEVBQUU7WUFDMUIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxTQUFTLEVBQUUsTUFBTSxFQUFFLEtBQUssQ0FBQyxDQUFDO1NBQzVDO0lBQ0gsQ0FBQztJQUVPLE1BQU0sQ0FBQyxXQUFXLENBQUMsU0FBb0IsRUFBRSxNQUFjLEVBQUUsS0FBWTtRQUMzRSxNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ2hELE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDMUMsTUFBTSxPQUFPLEdBQUcsU0FBUyxDQUFDLFVBQVUsRUFBRSxDQUFDO1FBQ3ZDLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxNQUFNLEVBQUUsS0FBSyxFQUFFLGFBQWEsRUFBRSxVQUFVLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFFaEcsSUFBSTtZQUNGLE1BQU0sS0FBSyxHQUFHLFNBQVMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxVQUFVLEVBQUU7Z0JBQ3JELFNBQVMsRUFBRSxLQUFLLENBQUMsSUFBSTtnQkFDckIsVUFBVSxFQUFFLGFBQWE7Z0JBQ3pCLFFBQVEsRUFBRSxVQUFVO2FBQ3JCLENBQUMsQ0FBQztZQUVILHVFQUF1RTtZQUN2RSx3RUFBd0U7WUFDeEUseUNBQXlDO1lBQ3pDLElBQUksQ0FBQyxVQUFVLENBQUMsRUFBRSxJQUFJLEtBQUssQ0FBQyxhQUFhLEVBQUUsQ0FBQyxFQUFFLEVB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
|