@forestadmin/datasource-sql 1.0.0-alpha.1
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/LICENSE +674 -0
- package/README.md +0 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +41 -0
- package/dist/introspection/helpers/array-type-getter.d.ts +12 -0
- package/dist/introspection/helpers/array-type-getter.js +67 -0
- package/dist/introspection/helpers/default-value-parser.d.ts +12 -0
- package/dist/introspection/helpers/default-value-parser.js +78 -0
- package/dist/introspection/helpers/sql-type-converter.d.ts +15 -0
- package/dist/introspection/helpers/sql-type-converter.js +101 -0
- package/dist/introspection/introspector.d.ts +12 -0
- package/dist/introspection/introspector.js +74 -0
- package/dist/introspection/types.d.ts +32 -0
- package/dist/introspection/types.js +3 -0
- package/dist/orm-builder/helpers/relation-extractor.d.ts +9 -0
- package/dist/orm-builder/helpers/relation-extractor.js +69 -0
- package/dist/orm-builder/helpers/relation-name-generator.d.ts +8 -0
- package/dist/orm-builder/helpers/relation-name-generator.js +61 -0
- package/dist/orm-builder/helpers/sequelize-type.d.ts +5 -0
- package/dist/orm-builder/helpers/sequelize-type.js +21 -0
- package/dist/orm-builder/model.d.ts +10 -0
- package/dist/orm-builder/model.js +53 -0
- package/dist/orm-builder/relations.d.ts +9 -0
- package/dist/orm-builder/relations.js +64 -0
- package/dist/orm-builder/types.d.ts +11 -0
- package/dist/orm-builder/types.js +3 -0
- package/package.json +34 -0
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const pluralize_1 = require("pluralize");
|
|
4
|
+
class RelationNameGenerator {
|
|
5
|
+
static getUniqueRelationNames(table, relations) {
|
|
6
|
+
var _a;
|
|
7
|
+
const names = relations.map(this.getSimpleName);
|
|
8
|
+
// Search for duplicates
|
|
9
|
+
const indexesByName = {};
|
|
10
|
+
for (let i = 0; i < names.length; i += 1) {
|
|
11
|
+
indexesByName[_a = names[i]] ?? (indexesByName[_a] = []);
|
|
12
|
+
indexesByName[names[i]].push(i);
|
|
13
|
+
}
|
|
14
|
+
// When a duplicate is found, use long names for all of them
|
|
15
|
+
for (const [name, indexes] of Object.entries(indexesByName)) {
|
|
16
|
+
// Legit conflicts we need to handle
|
|
17
|
+
const conflictsWithColumn = !!table.columns.find(c => c.name === name);
|
|
18
|
+
const conflictsWithOtherRelation = indexes.length > 1;
|
|
19
|
+
// Workaround sequelize bugs
|
|
20
|
+
// @see https://github.com/sequelize/sequelize/issues/8263
|
|
21
|
+
const conflictsWithTable = name === table.name;
|
|
22
|
+
const conflictsWithThroughTable = relations.find(r => r.through === name);
|
|
23
|
+
if (conflictsWithColumn ||
|
|
24
|
+
conflictsWithTable ||
|
|
25
|
+
conflictsWithOtherRelation ||
|
|
26
|
+
conflictsWithThroughTable) {
|
|
27
|
+
for (const index of indexes) {
|
|
28
|
+
names[index] = this.getUniqueName(relations[index]);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return names;
|
|
33
|
+
}
|
|
34
|
+
static getSimpleName(relation) {
|
|
35
|
+
const { foreignKey } = relation;
|
|
36
|
+
let name = relation.to;
|
|
37
|
+
if (foreignKey?.length > 3 && foreignKey?.endsWith('_id'))
|
|
38
|
+
name = foreignKey.substring(0, foreignKey.length - 3);
|
|
39
|
+
if (foreignKey?.length > 2 && foreignKey?.endsWith('Id'))
|
|
40
|
+
name = foreignKey.substring(0, foreignKey.length - 2);
|
|
41
|
+
return relation.type === 'HasMany' || relation.type === 'BelongsToMany'
|
|
42
|
+
? (0, pluralize_1.plural)(name)
|
|
43
|
+
: (0, pluralize_1.singular)(name);
|
|
44
|
+
}
|
|
45
|
+
static getUniqueName(relation) {
|
|
46
|
+
switch (relation.type) {
|
|
47
|
+
case 'BelongsTo':
|
|
48
|
+
return `${(0, pluralize_1.singular)(relation.to)}_through_${relation.foreignKey}`;
|
|
49
|
+
case 'HasOne':
|
|
50
|
+
return `${(0, pluralize_1.singular)(relation.to)}_through_${relation.from}_${relation.originKey}`;
|
|
51
|
+
case 'BelongsToMany':
|
|
52
|
+
return `${(0, pluralize_1.plural)(relation.to)}_through_${relation.through}`;
|
|
53
|
+
case 'HasMany':
|
|
54
|
+
return `${(0, pluralize_1.plural)(relation.to)}_through_${relation.from}_${relation.originKey}`;
|
|
55
|
+
default:
|
|
56
|
+
throw new Error(`Invalid relation type ${relation.type}`);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
exports.default = RelationNameGenerator;
|
|
61
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVsYXRpb24tbmFtZS1nZW5lcmF0b3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvb3JtLWJ1aWxkZXIvaGVscGVycy9yZWxhdGlvbi1uYW1lLWdlbmVyYXRvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLHlDQUE2QztBQUs3QyxNQUFxQixxQkFBcUI7SUFDeEMsTUFBTSxDQUFDLHNCQUFzQixDQUFDLEtBQVksRUFBRSxTQUFxQjs7UUFDL0QsTUFBTSxLQUFLLEdBQUcsU0FBUyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUM7UUFFaEQsd0JBQXdCO1FBQ3hCLE1BQU0sYUFBYSxHQUE2QixFQUFFLENBQUM7UUFFbkQsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQyxJQUFJLENBQUMsRUFBRTtZQUN4QyxhQUFhLE1BQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxNQUF0QixhQUFhLE9BQWUsRUFBRSxFQUFDO1lBQy9CLGFBQWEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7U0FDakM7UUFFRCw0REFBNEQ7UUFDNUQsS0FBSyxNQUFNLENBQUMsSUFBSSxFQUFFLE9BQU8sQ0FBQyxJQUFJLE1BQU0sQ0FBQyxPQUFPLENBQUMsYUFBYSxDQUFDLEVBQUU7WUFDM0Qsb0NBQW9DO1lBQ3BDLE1BQU0sbUJBQW1CLEdBQUcsQ0FBQyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksS0FBSyxJQUFJLENBQUMsQ0FBQztZQUN2RSxNQUFNLDBCQUEwQixHQUFHLE9BQU8sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO1lBRXRELDRCQUE0QjtZQUM1QiwwREFBMEQ7WUFDMUQsTUFBTSxrQkFBa0IsR0FB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
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const sequelize_1 = require("sequelize");
|
|
4
|
+
class SequelizeTypeFactory {
|
|
5
|
+
static makeSequelizeType(type) {
|
|
6
|
+
switch (type.type) {
|
|
7
|
+
case 'scalar':
|
|
8
|
+
if (sequelize_1.DataTypes[type.subType])
|
|
9
|
+
return sequelize_1.DataTypes[type.subType];
|
|
10
|
+
throw new Error(`Unexpected type: ${type.subType}`);
|
|
11
|
+
case 'enum':
|
|
12
|
+
return sequelize_1.DataTypes.ENUM(...type.values);
|
|
13
|
+
case 'array':
|
|
14
|
+
return sequelize_1.DataTypes.ARRAY(this.makeSequelizeType(type.subType));
|
|
15
|
+
default:
|
|
16
|
+
throw new Error();
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
exports.default = SequelizeTypeFactory;
|
|
21
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VxdWVsaXplLXR5cGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvb3JtLWJ1aWxkZXIvaGVscGVycy9zZXF1ZWxpemUtdHlwZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLHlDQUFzQztBQUl0QyxNQUFxQixvQkFBb0I7SUFDdkMsTUFBTSxDQUFDLGlCQUFpQixDQUFDLElBQWdCO1FBQ3ZDLFFBQVEsSUFBSSxDQUFDLElBQUksRUFBRTtZQUNqQixLQUFLLFFBQVE7Z0JBQ1gsSUFBSSxxQkFBUyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUM7b0JBQUUsT0FBTyxxQkFBUyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztnQkFDNUQsTUFBTSxJQUFJLEtBQUssQ0FBQyxvQkFBb0IsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUM7WUFFdEQsS0FBSyxNQUFNO2dCQUNULE9BQU8scUJBQVMsQ0FBQyxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7WUFFeEMsS0FBSyxPQUFPO2dCQUNWLE9BQU8scUJBQVMsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO1lBRS9EO2dCQUNFLE1BQU0sSUFBSSxLQUFLLEVBQUUsQ0FBQztTQUNyQjtJQUNILENBQUM7Q0FDRjtBQWpCRCx1Q0FpQkMifQ==
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Logger } from '@forestadmin/datasource-toolkit';
|
|
2
|
+
import { Sequelize } from 'sequelize';
|
|
3
|
+
import { Table } from '../introspection/types';
|
|
4
|
+
export default class ModelBuilder {
|
|
5
|
+
static defineModels(sequelize: Sequelize, logger: Logger, tables: Table[]): void;
|
|
6
|
+
private static defineModel;
|
|
7
|
+
private static hasTimestamps;
|
|
8
|
+
private static isParanoid;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=model.d.ts.map
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const sequelize_type_1 = __importDefault(require("./helpers/sequelize-type"));
|
|
7
|
+
class ModelBuilder {
|
|
8
|
+
static defineModels(sequelize, logger, tables) {
|
|
9
|
+
for (const table of tables) {
|
|
10
|
+
this.defineModel(sequelize, logger, table);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
static defineModel(sequelize, logger, table) {
|
|
14
|
+
const modelAttrs = {};
|
|
15
|
+
const hasTimestamps = this.hasTimestamps(table);
|
|
16
|
+
const isParanoid = this.isParanoid(table);
|
|
17
|
+
for (const column of table.columns) {
|
|
18
|
+
const isExplicit = !(hasTimestamps && (column.name === 'updatedAt' || column.name === 'createdAt')) &&
|
|
19
|
+
!(isParanoid && column.name === 'deletedAt');
|
|
20
|
+
// Clone object, because sequelize modifies it.
|
|
21
|
+
if (isExplicit)
|
|
22
|
+
modelAttrs[column.name] = {
|
|
23
|
+
...column,
|
|
24
|
+
type: sequelize_type_1.default.makeSequelizeType(column.type),
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
try {
|
|
28
|
+
const model = sequelize.define(table.name, modelAttrs, {
|
|
29
|
+
tableName: table.name,
|
|
30
|
+
timestamps: hasTimestamps,
|
|
31
|
+
paranoid: isParanoid,
|
|
32
|
+
});
|
|
33
|
+
// @see https://sequelize.org/docs/v6/other-topics/legacy/#primary-keys
|
|
34
|
+
// Tell sequelize NOT to invent primary keys when we don't provide them.
|
|
35
|
+
// (Note that this does not seem to work)
|
|
36
|
+
if (!modelAttrs.id && model.getAttributes().id) {
|
|
37
|
+
model.removeAttribute('id');
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
catch (e) {
|
|
41
|
+
logger?.('Warn', `Skipping table "${table.name}" because of error: ${e.message}`);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
static hasTimestamps(table) {
|
|
45
|
+
return (!!table.columns.find(c => c.name === 'createdAt') &&
|
|
46
|
+
!!table.columns.find(c => c.name === 'updatedAt'));
|
|
47
|
+
}
|
|
48
|
+
static isParanoid(table) {
|
|
49
|
+
return !!table.columns.find(c => c.name === 'deletedAt');
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
exports.default = ModelBuilder;
|
|
53
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9kZWwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvb3JtLWJ1aWxkZXIvbW9kZWwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFHQSw4RUFBNEQ7QUFFNUQsTUFBcUIsWUFBWTtJQUMvQixNQUFNLENBQUMsWUFBWSxDQUFDLFNBQW9CLEVBQUUsTUFBYyxFQUFFLE1BQWU7UUFDdkUsS0FBSyxNQUFNLEtBQUssSUFBSSxNQUFNLEVBQUU7WUFDMUIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxTQUFTLEVBQUUsTUFBTSxFQUFFLEtBQUssQ0FBQyxDQUFDO1NBQzVDO0lBQ0gsQ0FBQztJQUVPLE1BQU0sQ0FBQyxXQUFXLENBQUMsU0FBb0IsRUFBRSxNQUFjLEVBQUUsS0FBWTtRQUMzRSxNQUFNLFVBQVUsR0FBb0IsRUFBRSxDQUFDO1FBQ3ZDLE1BQU0sYUFBYSxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDaEQsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUUxQyxLQUFLLE1BQU0sTUFBTSxJQUFJLEtBQUssQ0FBQyxPQUFPLEVBQUU7WUFDbEMsTUFBTSxVQUFVLEdBQ2QsQ0FBQyxDQUFDLGFBQWEsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEtBQUssV0FBVyxJQUFJLE1BQU0sQ0FBQyxJQUFJLEtBQUssV0FBVyxDQUFDLENBQUM7Z0JBQ2hGLENBQUMsQ0FBQyxVQUFVLElBQUksTUFBTSxDQUFDLElBQUksS0FBSyxXQUFXLENBQUMsQ0FBQztZQUUvQywrQ0FBK0M7WUFDL0MsSUFBSSxVQUFVO2dCQUNaLFVBQVUsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUc7b0JBQ3hCLEdBQUcsTUFBTTtvQkFDVCxJQUFJLEVBQUUsd0JBQW9CLENBQUMsaUJBQWlCLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQztpQkFDMUQsQ0FBQztTQUNMO1FBRUQsSUFBSTtZQUNGLE1BQU0sS0FBSyxHQUFHLFNBQVMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxVQUFVLEVBQUU7Z0JBQ3JELFNBQVMsRUFBRSxLQUFLLENBQUMsSUFBSTtnQkFDckIsVUFBVSxFQUFFLGFBQWE7Z0JBQ3pCLFFBQVEsRUFBRSxVQUFVO2FBQ3JCLENBQUMsQ0FBQztZQUVILHVFQUF1RTtZQUN2RSx3RUFBd0U7WUFDeEUseUNBQXlDO1lBQ3pDLElBQUksQ0FBQyxVQUFVLENBQUMsRUFBRSxJQUFJLEtBQUssQ0FBQyxhQUFhLEVBQUUsQ0FBQyxFQUFFLEVBQUU7Z0JBQzlDLEtBQUssQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLENBQUM7YUFDN0I7U0FDRjtRQUFDLE9BQU8sQ0FBQyxFQUFFO1lBQ1YsTUFBTSxFQUFFLENBQUMsTUFBTSxFQUFFLG1CQUFtQixLQUFLLENBQUMsSUFBSSx1QkFBdUIsQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUM7U0FDbkY7SUFDSCxDQUFDO0lBRU8sTUFBTSxDQUFDLGFBQWEsQ0FBQyxLQUFZO1FBQ3ZDLE9BQU8sQ0FDTCxDQUFDLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxLQUFLLFdBQVcsQ0FBQztZQUNqRCxDQUFDLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxLQUFLLFdBQVcsQ0FBQyxDQUNsRCxDQUFDO0lBQ0osQ0FBQztJQUVPLE1BQU0sQ0FBQyxVQUFVLENBQUMsS0FBWTtRQUNwQyxPQUFPLENBQUMsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLEtBQUssV0FBVyxDQUFDLENBQUM7SUFDM0QsQ0FBQztDQUNGO0FBckRELCtCQXFEQyJ9
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Logger } from '@forestadmin/datasource-toolkit';
|
|
2
|
+
import { Sequelize } from 'sequelize';
|
|
3
|
+
import { Table } from '../introspection/types';
|
|
4
|
+
export default class RelationBuilder {
|
|
5
|
+
static defineRelations(sequelize: Sequelize, logger: Logger, tables: Table[]): void;
|
|
6
|
+
private static defineTableRelations;
|
|
7
|
+
private static defineRelation;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=relations.d.ts.map
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const relation_extractor_1 = __importDefault(require("./helpers/relation-extractor"));
|
|
7
|
+
const relation_name_generator_1 = __importDefault(require("./helpers/relation-name-generator"));
|
|
8
|
+
class RelationBuilder {
|
|
9
|
+
static defineRelations(sequelize, logger, tables) {
|
|
10
|
+
for (const table of tables) {
|
|
11
|
+
this.defineTableRelations(sequelize, logger, table, tables);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
static defineTableRelations(sequelize, logger, table, tables) {
|
|
15
|
+
const relations = relation_extractor_1.default.listRelations(table.name, tables);
|
|
16
|
+
const relationNames = relation_name_generator_1.default.getUniqueRelationNames(table, relations);
|
|
17
|
+
for (const [index, relation] of relations.entries()) {
|
|
18
|
+
const as = relationNames[index];
|
|
19
|
+
try {
|
|
20
|
+
this.defineRelation(sequelize, relation, as);
|
|
21
|
+
}
|
|
22
|
+
catch (e) {
|
|
23
|
+
logger?.('Warn', `Skipping relation "${table.name}.${as}" because of error: ${e.message}`);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
static defineRelation(sequelize, relation, as) {
|
|
28
|
+
const sourceModel = sequelize.model(relation.from);
|
|
29
|
+
const targetModel = sequelize.model(relation.to);
|
|
30
|
+
if (relation.type === 'BelongsTo') {
|
|
31
|
+
sourceModel.belongsTo(targetModel, {
|
|
32
|
+
as,
|
|
33
|
+
foreignKey: relation.foreignKey,
|
|
34
|
+
targetKey: relation.foreignKeyTarget,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
else if (relation.type === 'HasMany') {
|
|
38
|
+
sourceModel.hasMany(targetModel, {
|
|
39
|
+
as,
|
|
40
|
+
foreignKey: relation.originKey,
|
|
41
|
+
sourceKey: relation.originKeyTarget,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
else if (relation.type === 'BelongsToMany') {
|
|
45
|
+
sourceModel.belongsToMany(targetModel, {
|
|
46
|
+
as,
|
|
47
|
+
through: relation.through,
|
|
48
|
+
otherKey: relation.foreignKey,
|
|
49
|
+
foreignKey: relation.originKey,
|
|
50
|
+
targetKey: relation.foreignKeyTarget,
|
|
51
|
+
sourceKey: relation.originKeyTarget,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
else if (relation.type === 'HasOne') {
|
|
55
|
+
sourceModel.hasOne(targetModel, {
|
|
56
|
+
as,
|
|
57
|
+
foreignKey: relation.originKey,
|
|
58
|
+
sourceKey: relation.originKeyTarget,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
exports.default = RelationBuilder;
|
|
64
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVsYXRpb25zLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL29ybS1idWlsZGVyL3JlbGF0aW9ucy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQU1BLHNGQUE2RDtBQUM3RCxnR0FBc0U7QUFFdEUsTUFBcUIsZUFBZTtJQUNsQyxNQUFNLENBQUMsZUFBZSxDQUFDLFNBQW9CLEVBQUUsTUFBYyxFQUFFLE1BQWU7UUFDMUUsS0FBSyxNQUFNLEtBQUssSUFBSSxNQUFNLEVBQUU7WUFDMUIsSUFBSSxDQUFDLG9CQUFvQixDQUFDLFNBQVMsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLE1BQU0sQ0FBQyxDQUFDO1NBQzdEO0lBQ0gsQ0FBQztJQUVPLE1BQU0sQ0FBQyxvQkFBb0IsQ0FDakMsU0FBb0IsRUFDcEIsTUFBYyxFQUNkLEtBQVksRUFDWixNQUFlO1FBRWYsTUFBTSxTQUFTLEdBQUcsNEJBQWlCLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDdEUsTUFBTSxhQUFhLEdBQUcsaUNBQXFCLENBQUMsc0JBQXNCLENBQUMsS0FBSyxFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBRXJGLEtBQUssTUFBTSxDQUFDLEtBQUssRUFBRSxRQUFRLENBQUMsSUFBSSxTQUFTLENBQUMsT0FBTyxFQUFFLEVBQUU7WUFDbkQsTUFBTSxFQUFFLEdBQUcsYUFBYSxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBRWhDLElBQUk7Z0JBQ0YsSUFBSSxDQUFDLGNBQWMsQ0FBQyxTQUFTLEVBQUUsUUFBUSxFQUFFLEVBQUUsQ0FBQyxDQUFDO2FBQzlDO1lBQUMsT0FBTyxDQUFDLEVBQUU7Z0JBQ1YsTUFBTSxFQUFFLENBQUMsTUFBTSxFQUFFLHNCQUFzQixLQUFLLENBQUMsSUFBSSxJQUFJLEVBQUUsdUJBQXVCLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDO2FBQzVGO1NBQ0Y7SUFDSCxDQUFDO0lBRU8sTUFBTSxDQUFDLGNBQWMsQ0FBQyxTQUFvQixFQUFFLFFBQWtCLEVBQUUsRUFBVTtRQUNoRixNQUFNLFdBQVcsR0FBRyxTQUFTLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNuRCxNQUFNLFdBQVcsR0FBRyxTQUFTLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUVqRCxJQUFJLFFBQVEsQ0FBQyxJQUFJLEtBQUssV0FBVyxFQUFFO1lBQ2pDLFdBQVcsQ0FBQyxTQUFTLENBQUMsV0FBVyxFQUFFO2dCQUNqQyxFQUFFO2dCQUNGLFVBQVUsRUFBRSxRQUFRLENBQUMsVUFBVTtnQkFDL0IsU0FBUyxFQUFFLFFBQVEsQ0FBQyxnQkFBZ0I7YUFDckMsQ0FBQyxDQUFDO1NBQ0o7YUFBTSxJQUFJLFFBQVEsQ0FBQyxJQUFJLEtBQUssU0FBUyxFQUFFO1lBQ3RDLFdBQVcsQ0FBQyxPQUFPLENBQUMsV0FBVyxFQUFFO2dCQUMvQixFQUFFO2dCQUNGLFVBQVUsRUFBRSxRQUFRLENBQUMsU0FBUztnQkFDOUIsU0FBUyxFQUFFLFFBQVEsQ0FBQyxlQUFlO2FBQ3BDLENBQUMsQ0FBQztTQUNKO2FBQU0sSUFBSSxRQUFRLENBQUMsSUFBSSxLQUFLLGVBQWUsRUFBRTtZQUM1QyxXQUFXLENBQUMsYUFBYSxDQUFDLFdBQVcsRUFBRTtnQkFDckMsRUFBRTtnQkFDRixPQUFPLEVBQUUsUUFBUSxDQUFDLE9BQU87Z0JBQ3pCLFFBQVEsRUFBRSxRQUFRLENBQUMsVUFBVTtnQkFDN0IsVUFBVSxFQUFFLFFBQVEsQ0FBQyxTQUFTO2dCQUM5QixTQUFTLEVBQUUsUUFBUSxDQUFDLGdCQUFnQjtnQkFDcEMsU0FBUyxFQUFFLFFBQVEsQ0FBQyxlQUFlO2FBQ3BDLENBQUMsQ0FBQztTQUNKO2FBQU0sSUFBSSxRQUFRLENBQUMsSUFBSSxLQUFLLFFBQVEsRUFBRTtZQUNyQyxXQUFXLENBQUMsTUFBTSxDQUFDLFdBQVcsRUFBRTtnQkFDOUIsRUFBRTtnQkFDRixVQUFVLEVBQUUsUUFBUSxDQUFDLFNBQVM7Z0JBQzlCLFNBQVMsRUFBRSxRQUFRLENBQUMsZUFBZTthQUNwQyxDQUFDLENBQUM7U0FDSjtJQUNILENBQUM7Q0FDRjtBQTVERCxrQ0E0REMifQ==
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare type Relation = {
|
|
2
|
+
type: 'BelongsTo' | 'HasOne' | 'BelongsToMany' | 'HasMany';
|
|
3
|
+
from: string;
|
|
4
|
+
to: string;
|
|
5
|
+
through?: string;
|
|
6
|
+
foreignKey?: string;
|
|
7
|
+
originKey?: string;
|
|
8
|
+
foreignKeyTarget?: string;
|
|
9
|
+
originKeyTarget?: string;
|
|
10
|
+
};
|
|
11
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvb3JtLWJ1aWxkZXIvdHlwZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiJ9
|
package/package.json
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@forestadmin/datasource-sql",
|
|
3
|
+
"version": "1.0.0-alpha.1",
|
|
4
|
+
"main": "dist/index.js",
|
|
5
|
+
"license": "GPL-3.0",
|
|
6
|
+
"publishConfig": {
|
|
7
|
+
"access": "public"
|
|
8
|
+
},
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+https://github.com/ForestAdmin/agent-nodejs.git",
|
|
12
|
+
"directory": "packages/datasource-sql"
|
|
13
|
+
},
|
|
14
|
+
"dependencies": {
|
|
15
|
+
"@forestadmin/datasource-sequelize": "1.0.0-alpha.1",
|
|
16
|
+
"@forestadmin/datasource-toolkit": "1.0.0-alpha.1",
|
|
17
|
+
"pluralize": "^8.0.0",
|
|
18
|
+
"sequelize": "6.21.3"
|
|
19
|
+
},
|
|
20
|
+
"files": [
|
|
21
|
+
"dist/**/*.js",
|
|
22
|
+
"dist/**/*.d.ts"
|
|
23
|
+
],
|
|
24
|
+
"scripts": {
|
|
25
|
+
"build": "tsc",
|
|
26
|
+
"build:watch": "tsc --watch",
|
|
27
|
+
"clean": "rm -rf coverage dist",
|
|
28
|
+
"lint": "eslint src test",
|
|
29
|
+
"test": "jest"
|
|
30
|
+
},
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"lodash": "^4.17.21"
|
|
33
|
+
}
|
|
34
|
+
}
|