@forestadmin/datasource-sequelize 1.0.0-beta.9 → 1.0.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/collection.d.ts +9 -6
- package/dist/collection.js +33 -26
- package/dist/datasource.d.ts +6 -0
- package/dist/datasource.js +7 -1
- package/dist/index.d.ts +1 -1
- package/dist/utils/aggregation.d.ts +7 -5
- package/dist/utils/aggregation.js +17 -31
- package/dist/utils/date-aggregation-converter.d.ts +11 -6
- package/dist/utils/date-aggregation-converter.js +26 -21
- package/dist/utils/error-handler.d.ts +4 -0
- package/dist/utils/error-handler.js +30 -0
- package/dist/utils/model-to-collection-schema-converter.js +5 -3
- package/dist/utils/query-converter.d.ts +14 -7
- package/dist/utils/query-converter.js +59 -33
- package/dist/utils/serializer.d.ts +6 -0
- package/dist/utils/serializer.js +29 -0
- package/dist/utils/type-converter.d.ts +2 -2
- package/dist/utils/type-converter.js +29 -31
- package/dist/utils/un-ambigous.d.ts +3 -0
- package/dist/utils/un-ambigous.js +24 -0
- package/package.json +4 -5
- package/CHANGELOG.md +0 -105
package/dist/collection.d.ts
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
import { ModelDefined } from 'sequelize';
|
|
2
|
-
import { AggregateResult, Aggregation, BaseCollection, DataSource, Filter, Logger, PaginatedFilter, Projection, RecordData } from '@forestadmin/datasource-toolkit';
|
|
2
|
+
import { AggregateResult, Aggregation, BaseCollection, Caller, DataSource, Filter, Logger, PaginatedFilter, Projection, RecordData } from '@forestadmin/datasource-toolkit';
|
|
3
3
|
export default class SequelizeCollection extends BaseCollection {
|
|
4
4
|
protected model: ModelDefined<any, any>;
|
|
5
|
+
private col;
|
|
6
|
+
private fn;
|
|
5
7
|
private aggregationUtils;
|
|
8
|
+
private queryConverter;
|
|
6
9
|
constructor(name: string, datasource: DataSource, model: ModelDefined<any, any>, logger?: Logger);
|
|
7
|
-
create(data: RecordData[]): Promise<RecordData[]>;
|
|
8
|
-
list(filter: PaginatedFilter, projection: Projection): Promise<RecordData[]>;
|
|
9
|
-
update(filter: Filter, patch: RecordData): Promise<void>;
|
|
10
|
-
delete(filter: Filter): Promise<void>;
|
|
11
|
-
aggregate(filter: Filter, aggregation: Aggregation, limit?: number): Promise<AggregateResult[]>;
|
|
10
|
+
create(caller: Caller, data: RecordData[]): Promise<RecordData[]>;
|
|
11
|
+
list(caller: Caller, filter: PaginatedFilter, projection: Projection): Promise<RecordData[]>;
|
|
12
|
+
update(caller: Caller, filter: Filter, patch: RecordData): Promise<void>;
|
|
13
|
+
delete(caller: Caller, filter: Filter): Promise<void>;
|
|
14
|
+
aggregate(caller: Caller, filter: Filter, aggregation: Aggregation, limit?: number): Promise<AggregateResult[]>;
|
|
12
15
|
}
|
|
13
16
|
//# sourceMappingURL=collection.d.ts.map
|
package/dist/collection.js
CHANGED
|
@@ -3,11 +3,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const sequelize_1 = require("sequelize");
|
|
7
6
|
const datasource_toolkit_1 = require("@forestadmin/datasource-toolkit");
|
|
8
7
|
const aggregation_1 = __importDefault(require("./utils/aggregation"));
|
|
9
8
|
const model_to_collection_schema_converter_1 = __importDefault(require("./utils/model-to-collection-schema-converter"));
|
|
10
9
|
const query_converter_1 = __importDefault(require("./utils/query-converter"));
|
|
10
|
+
const serializer_1 = __importDefault(require("./utils/serializer"));
|
|
11
|
+
const error_handler_1 = __importDefault(require("./utils/error-handler"));
|
|
11
12
|
class SequelizeCollection extends datasource_toolkit_1.BaseCollection {
|
|
12
13
|
constructor(name, datasource,
|
|
13
14
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -16,69 +17,75 @@ class SequelizeCollection extends datasource_toolkit_1.BaseCollection {
|
|
|
16
17
|
if (!model)
|
|
17
18
|
throw new Error('Invalid (null) model instance.');
|
|
18
19
|
this.model = model;
|
|
20
|
+
this.col = this.model.sequelize.col;
|
|
21
|
+
this.fn = this.model.sequelize.fn;
|
|
19
22
|
this.aggregationUtils = new aggregation_1.default(this.model);
|
|
23
|
+
this.queryConverter = new query_converter_1.default(this.model);
|
|
20
24
|
const modelSchema = model_to_collection_schema_converter_1.default.convert(this.model, logger);
|
|
25
|
+
this.enableCount();
|
|
21
26
|
this.addFields(modelSchema.fields);
|
|
22
27
|
this.addSegments(modelSchema.segments);
|
|
23
28
|
}
|
|
24
|
-
async create(data) {
|
|
25
|
-
const records = await this.model.bulkCreate(data);
|
|
26
|
-
return records.map(record => record.get({ plain: true }));
|
|
29
|
+
async create(caller, data) {
|
|
30
|
+
const records = await (0, error_handler_1.default)('create', () => this.model.bulkCreate(data));
|
|
31
|
+
return records.map(record => serializer_1.default.serialize(record.get({ plain: true })));
|
|
27
32
|
}
|
|
28
|
-
async list(filter, projection) {
|
|
29
|
-
let include =
|
|
33
|
+
async list(caller, filter, projection) {
|
|
34
|
+
let include = this.queryConverter.getIncludeWithAttributesFromProjection(projection);
|
|
30
35
|
if (filter.conditionTree) {
|
|
31
|
-
include = include.concat(
|
|
36
|
+
include = include.concat(this.queryConverter.getIncludeFromProjection(filter.conditionTree.projection));
|
|
32
37
|
}
|
|
33
38
|
if (filter.sort) {
|
|
34
|
-
include = include.concat(
|
|
39
|
+
include = include.concat(this.queryConverter.getIncludeFromProjection(filter.sort.projection));
|
|
35
40
|
}
|
|
36
41
|
const query = {
|
|
37
42
|
attributes: projection.columns,
|
|
38
|
-
where:
|
|
43
|
+
where: this.queryConverter.getWhereFromConditionTree(filter.conditionTree),
|
|
39
44
|
include,
|
|
40
45
|
limit: filter.page?.limit,
|
|
41
46
|
offset: filter.page?.skip,
|
|
42
|
-
order:
|
|
47
|
+
order: this.queryConverter.getOrderFromSort(filter.sort),
|
|
43
48
|
subQuery: false,
|
|
44
49
|
};
|
|
45
50
|
const records = await this.model.findAll(query);
|
|
46
|
-
return records.map(record => record.get({ plain: true }));
|
|
51
|
+
return records.map(record => serializer_1.default.serialize(record.get({ plain: true })));
|
|
47
52
|
}
|
|
48
|
-
async update(filter, patch) {
|
|
49
|
-
|
|
50
|
-
where:
|
|
53
|
+
async update(caller, filter, patch) {
|
|
54
|
+
const options = {
|
|
55
|
+
where: await this.queryConverter.getWhereFromConditionTreeToByPassInclude(filter.conditionTree),
|
|
51
56
|
fields: Object.keys(patch),
|
|
52
|
-
}
|
|
57
|
+
};
|
|
58
|
+
await (0, error_handler_1.default)('update', () => this.model.update(patch, options));
|
|
53
59
|
}
|
|
54
|
-
async delete(filter) {
|
|
55
|
-
|
|
56
|
-
where:
|
|
57
|
-
}
|
|
60
|
+
async delete(caller, filter) {
|
|
61
|
+
const options = {
|
|
62
|
+
where: await this.queryConverter.getWhereFromConditionTreeToByPassInclude(filter.conditionTree),
|
|
63
|
+
};
|
|
64
|
+
await (0, error_handler_1.default)('delete', () => this.model.destroy(options));
|
|
58
65
|
}
|
|
59
|
-
async aggregate(filter, aggregation, limit) {
|
|
66
|
+
async aggregate(caller, filter, aggregation, limit) {
|
|
60
67
|
let aggregationField = aggregation.field;
|
|
61
68
|
if (aggregation.operation === 'Count' || !aggregationField) {
|
|
62
69
|
aggregationField = '*';
|
|
63
70
|
}
|
|
64
71
|
else {
|
|
65
|
-
aggregationField = this.aggregationUtils.
|
|
72
|
+
aggregationField = this.aggregationUtils.quoteField(aggregationField);
|
|
66
73
|
}
|
|
67
|
-
const aggregationFunction =
|
|
74
|
+
const aggregationFunction = this.fn(aggregation.operation.toUpperCase(), this.col(aggregationField));
|
|
68
75
|
const aggregationAttribute = [
|
|
69
76
|
aggregationFunction,
|
|
70
77
|
this.aggregationUtils.aggregateFieldName,
|
|
71
78
|
];
|
|
72
79
|
const { groups, attributes: groupAttributes } = this.aggregationUtils.getGroupAndAttributesFromAggregation(aggregation.groups);
|
|
73
|
-
let include =
|
|
80
|
+
let include = this.queryConverter.getIncludeFromProjection(aggregation.projection);
|
|
74
81
|
if (filter.conditionTree) {
|
|
75
|
-
include = include.concat(
|
|
82
|
+
include = include.concat(this.queryConverter.getIncludeFromProjection(filter.conditionTree.projection));
|
|
76
83
|
}
|
|
77
84
|
const order = this.aggregationUtils.getOrder(aggregationFunction);
|
|
78
85
|
const query = {
|
|
79
86
|
attributes: [...groupAttributes, aggregationAttribute],
|
|
80
87
|
group: groups,
|
|
81
|
-
where:
|
|
88
|
+
where: this.queryConverter.getWhereFromConditionTree(filter.conditionTree),
|
|
82
89
|
include,
|
|
83
90
|
limit,
|
|
84
91
|
order: [order],
|
|
@@ -90,4 +97,4 @@ class SequelizeCollection extends datasource_toolkit_1.BaseCollection {
|
|
|
90
97
|
}
|
|
91
98
|
}
|
|
92
99
|
exports.default = SequelizeCollection;
|
|
93
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
100
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29sbGVjdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9jb2xsZWN0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBRUEsd0VBV3lDO0FBRXpDLHNFQUFtRDtBQUNuRCx3SEFBMEU7QUFDMUUsOEVBQXFEO0FBQ3JELG9FQUE0QztBQUM1QywwRUFBaUQ7QUFFakQsTUFBcUIsbUJBQW9CLFNBQVEsbUNBQWM7SUFTN0QsWUFDRSxJQUFZLEVBQ1osVUFBc0I7SUFDdEIsOERBQThEO0lBQzlELEtBQTZCLEVBQzdCLE1BQWU7UUFFZixLQUFLLENBQUMsSUFBSSxFQUFFLFVBQVUsQ0FBQyxDQUFDO1FBRXhCLElBQUksQ0FBQyxLQUFLO1lBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQyxnQ0FBZ0MsQ0FBQyxDQUFDO1FBRTlELElBQUksQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDO1FBQ25CLElBQUksQ0FBQyxHQUFHLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDO1FBQ3BDLElBQUksQ0FBQyxFQUFFLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDO1FBRWxDLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxJQUFJLHFCQUFnQixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUN6RCxJQUFJLENBQUMsY0FBYyxHQUFHLElBQUkseUJBQWMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7UUFFckQsTUFBTSxXQUFXLEdBQUcsOENBQWMsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxNQUFNLENBQUMsQ0FBQztRQUUvRCxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDbkIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDbkMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxXQUFXLENBQUMsUUFBUSxDQUFDLENB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
|
package/dist/datasource.d.ts
CHANGED
|
@@ -2,6 +2,12 @@ import { BaseDataSource, Logger } from '@forestadmin/datasource-toolkit';
|
|
|
2
2
|
import { Sequelize } from 'sequelize';
|
|
3
3
|
import SequelizeCollection from './collection';
|
|
4
4
|
export default class SequelizeDataSource extends BaseDataSource<SequelizeCollection> {
|
|
5
|
+
/**
|
|
6
|
+
* We can't directly use the Sequelize version we install in the package.json
|
|
7
|
+
* as the customer's version may be different.
|
|
8
|
+
* To ensure compatibility, we need to only import types from Sequelize,
|
|
9
|
+
* and use the customer sequelize version to deal with the data manipulation.
|
|
10
|
+
*/
|
|
5
11
|
protected sequelize: Sequelize;
|
|
6
12
|
constructor(sequelize: Sequelize, logger?: Logger);
|
|
7
13
|
protected createCollections(models: Sequelize['models'], logger?: Logger): void;
|
package/dist/datasource.js
CHANGED
|
@@ -8,6 +8,12 @@ const collection_1 = __importDefault(require("./collection"));
|
|
|
8
8
|
class SequelizeDataSource extends datasource_toolkit_1.BaseDataSource {
|
|
9
9
|
constructor(sequelize, logger) {
|
|
10
10
|
super();
|
|
11
|
+
/**
|
|
12
|
+
* We can't directly use the Sequelize version we install in the package.json
|
|
13
|
+
* as the customer's version may be different.
|
|
14
|
+
* To ensure compatibility, we need to only import types from Sequelize,
|
|
15
|
+
* and use the customer sequelize version to deal with the data manipulation.
|
|
16
|
+
*/
|
|
11
17
|
this.sequelize = null;
|
|
12
18
|
if (!sequelize)
|
|
13
19
|
throw new Error('Invalid (null) Sequelize instance.');
|
|
@@ -25,4 +31,4 @@ class SequelizeDataSource extends datasource_toolkit_1.BaseDataSource {
|
|
|
25
31
|
}
|
|
26
32
|
}
|
|
27
33
|
exports.default = SequelizeDataSource;
|
|
28
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
34
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0YXNvdXJjZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9kYXRhc291cmNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsd0VBQXlFO0FBR3pFLDhEQUErQztBQUUvQyxNQUFxQixtQkFBb0IsU0FBUSxtQ0FBbUM7SUFTbEYsWUFBWSxTQUFvQixFQUFFLE1BQWU7UUFDL0MsS0FBSyxFQUFFLENBQUM7UUFUVjs7Ozs7V0FLRztRQUNPLGNBQVMsR0FBYyxJQUFJLENBQUM7UUFLcEMsSUFBSSxDQUFDLFNBQVM7WUFBRSxNQUFNLElBQUksS0FBSyxDQUFDLG9DQUFvQyxDQUFDLENBQUM7UUFFdEUsSUFBSSxDQUFDLFNBQVMsR0FBRyxTQUFTLENBQUM7UUFFM0IsSUFBSSxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxDQUFDO0lBQ3hELENBQUM7SUFFUyxpQkFBaUIsQ0FBQyxNQUEyQixFQUFFLE1BQWU7UUFDdEUsTUFBTSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUM7WUFDbkIsMEJBQTBCO2FBQ3pCLElBQUksQ0FBQyxDQUFDLE1BQU0sRUFBRSxNQUFNLEVBQUUsRUFBRSxDQUFDLENBQUMsTUFBTSxDQUFDLElBQUksR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7YUFDOUQsT0FBTyxDQUFDLEtBQUssQ0FBQyxFQUFFO1lBQ2YsTUFBTSxVQUFVLEdBQUcsSUFBSSxvQkFBbUIsQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsTUFBTSxDQUFDLENBQUM7WUFDNUUsSUFBSSxDQUFDLGFBQWEsQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUNqQyxDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7Q0FDRjtBQTVCRCxzQ0E0QkMifQ==
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { DataSourceFactory } from '@forestadmin/datasource-toolkit';
|
|
2
|
-
import { Sequelize } from 'sequelize
|
|
2
|
+
import { Sequelize } from 'sequelize';
|
|
3
3
|
export { default as SequelizeCollection } from './collection';
|
|
4
4
|
export { default as SequelizeDataSource } from './datasource';
|
|
5
5
|
export { default as TypeConverter } from './utils/type-converter';
|
|
@@ -1,18 +1,20 @@
|
|
|
1
|
+
import { AggregateResult, Aggregation } from '@forestadmin/datasource-toolkit';
|
|
1
2
|
import { GroupOption, Model, ModelDefined, ProjectionAlias } from 'sequelize';
|
|
2
3
|
import { Fn } from 'sequelize/types/utils';
|
|
3
|
-
import { AggregateResult, AggregationGroup } from '@forestadmin/datasource-toolkit';
|
|
4
4
|
export default class AggregationUtils {
|
|
5
5
|
private model;
|
|
6
6
|
private dialect;
|
|
7
|
+
private col;
|
|
8
|
+
private dateAggregationConverter;
|
|
7
9
|
readonly aggregateFieldName = "__aggregate__";
|
|
8
10
|
constructor(model: ModelDefined<any, any>);
|
|
9
|
-
getGroupFieldName
|
|
10
|
-
|
|
11
|
-
getGroupAndAttributesFromAggregation(aggregationQueryGroup:
|
|
11
|
+
private getGroupFieldName;
|
|
12
|
+
quoteField(field: string): string;
|
|
13
|
+
getGroupAndAttributesFromAggregation(aggregationQueryGroup: Aggregation['groups']): {
|
|
12
14
|
groups: GroupOption;
|
|
13
15
|
attributes: ProjectionAlias[];
|
|
14
16
|
};
|
|
15
17
|
getOrder(aggregationFunction: Fn): [string | Fn | import("sequelize/types/utils").Col | import("sequelize/types/utils").Literal, string];
|
|
16
|
-
computeResult(rows: Model<any, any>[], aggregationQueryGroup:
|
|
18
|
+
computeResult(rows: Model<any, any>[], aggregationQueryGroup: Aggregation['groups']): AggregateResult[];
|
|
17
19
|
}
|
|
18
20
|
//# sourceMappingURL=aggregation.d.ts.map
|
|
@@ -3,57 +3,43 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const sequelize_1 = require("sequelize");
|
|
7
6
|
const datasource_toolkit_1 = require("@forestadmin/datasource-toolkit");
|
|
8
7
|
const date_aggregation_converter_1 = __importDefault(require("./date-aggregation-converter"));
|
|
8
|
+
const serializer_1 = __importDefault(require("./serializer"));
|
|
9
|
+
const un_ambigous_1 = __importDefault(require("./un-ambigous"));
|
|
9
10
|
class AggregationUtils {
|
|
10
11
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
11
12
|
constructor(model) {
|
|
12
13
|
this.aggregateFieldName = '__aggregate__';
|
|
13
14
|
this.model = model;
|
|
14
15
|
this.dialect = this.model.sequelize.getDialect();
|
|
16
|
+
this.col = this.model.sequelize.col;
|
|
17
|
+
this.dateAggregationConverter = new date_aggregation_converter_1.default(this.model.sequelize);
|
|
15
18
|
}
|
|
16
19
|
getGroupFieldName(groupField) {
|
|
17
20
|
return `${groupField}__grouped__`;
|
|
18
21
|
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
const [associationName, nestedField] = field.split(':');
|
|
24
|
-
const association = this.model.associations[associationName];
|
|
25
|
-
if (!association) {
|
|
26
|
-
throw new datasource_toolkit_1.ValidationError(`${this.model.name} model does not have association "${associationName}".`);
|
|
27
|
-
}
|
|
28
|
-
const associationField = association.target.getAttributes()[nestedField];
|
|
29
|
-
if (!associationField) {
|
|
30
|
-
throw new datasource_toolkit_1.ValidationError(`${associationName} model does not have field "${nestedField}".`);
|
|
31
|
-
}
|
|
32
|
-
tableName = associationName;
|
|
33
|
-
fieldName = associationField.field;
|
|
22
|
+
quoteField(field) {
|
|
23
|
+
try {
|
|
24
|
+
const safeField = (0, un_ambigous_1.default)(this.model, field, true);
|
|
25
|
+
return this.model.sequelize.getQueryInterface().quoteIdentifiers(safeField);
|
|
34
26
|
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
if (!modelField) {
|
|
38
|
-
throw new datasource_toolkit_1.ValidationError(`${this.model.name} model does not have field "${field}".`);
|
|
39
|
-
}
|
|
40
|
-
tableName = this.model.name;
|
|
41
|
-
fieldName = modelField.field;
|
|
27
|
+
catch {
|
|
28
|
+
throw new datasource_toolkit_1.ValidationError(`Invalid access: "${field}" on "${this.model.name}" does not exist.`);
|
|
42
29
|
}
|
|
43
|
-
return this.model.sequelize.getQueryInterface().quoteIdentifiers(`${tableName}.${fieldName}`);
|
|
44
30
|
}
|
|
45
31
|
getGroupAndAttributesFromAggregation(aggregationQueryGroup) {
|
|
46
32
|
const attributes = [];
|
|
47
33
|
const groups = aggregationQueryGroup?.map(group => {
|
|
48
34
|
const { field } = group;
|
|
49
35
|
const groupFieldName = this.getGroupFieldName(field);
|
|
50
|
-
const groupField = this.
|
|
36
|
+
const groupField = this.quoteField(field);
|
|
51
37
|
if (group.operation) {
|
|
52
|
-
const groupFunction =
|
|
38
|
+
const groupFunction = this.dateAggregationConverter.convertToDialect(groupField, group.operation);
|
|
53
39
|
attributes.push([groupFunction, groupFieldName]);
|
|
54
40
|
return this.dialect === 'mssql' ? groupFunction : groupFieldName;
|
|
55
41
|
}
|
|
56
|
-
attributes.push([
|
|
42
|
+
attributes.push([this.col(groupField), groupFieldName]);
|
|
57
43
|
return this.dialect === 'mssql' ? groupField : groupFieldName;
|
|
58
44
|
});
|
|
59
45
|
return { groups, attributes };
|
|
@@ -63,13 +49,13 @@ class AggregationUtils {
|
|
|
63
49
|
// FIXME handle properly order
|
|
64
50
|
switch (this.dialect) {
|
|
65
51
|
case 'postgres':
|
|
66
|
-
order = [
|
|
52
|
+
order = [this.col(this.aggregateFieldName), 'DESC NULLS LAST'];
|
|
67
53
|
break;
|
|
68
54
|
case 'mssql':
|
|
69
55
|
order = [aggregationFunction, 'DESC'];
|
|
70
56
|
break;
|
|
71
57
|
default:
|
|
72
|
-
order = [
|
|
58
|
+
order = [this.col(this.aggregateFieldName), 'DESC'];
|
|
73
59
|
}
|
|
74
60
|
return order;
|
|
75
61
|
}
|
|
@@ -82,11 +68,11 @@ class AggregationUtils {
|
|
|
82
68
|
group: {},
|
|
83
69
|
};
|
|
84
70
|
aggregationQueryGroup?.forEach(({ field }) => {
|
|
85
|
-
aggregateResult.group[field] = aggregate[this.getGroupFieldName(field)];
|
|
71
|
+
aggregateResult.group[field] = serializer_1.default.serializeValue(aggregate[this.getGroupFieldName(field)]);
|
|
86
72
|
});
|
|
87
73
|
return aggregateResult;
|
|
88
74
|
});
|
|
89
75
|
}
|
|
90
76
|
}
|
|
91
77
|
exports.default = AggregationUtils;
|
|
92
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
78
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWdncmVnYXRpb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdXRpbHMvYWdncmVnYXRpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSx3RUFBZ0c7QUFZaEcsOEZBQW9FO0FBQ3BFLDhEQUFzQztBQUN0QyxnRUFBNEM7QUFFNUMsTUFBcUIsZ0JBQWdCO0lBVW5DLDhEQUE4RDtJQUM5RCxZQUFZLEtBQTZCO1FBSGhDLHVCQUFrQixHQUFHLGVBQWUsQ0FBQztRQUk1QyxJQUFJLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQztRQUNuQixJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLFVBQVUsRUFBYSxDQUFDO1FBQzVELElBQUksQ0FBQyxHQUFHLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDO1FBRXBDLElBQUksQ0FBQyx3QkFBd0IsR0FBRyxJQUFJLG9DQUF3QixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDckYsQ0FBQztJQUVPLGlCQUFpQixDQUFDLFVBQWtCO1FBQzFDLE9BQU8sR0FBRyxVQUFVLGFBQWEsQ0FBQztJQUNwQyxDQUFDO0lBRUQsVUFBVSxDQUFDLEtBQWE7UUFDdEIsSUFBSTtZQUNGLE1BQU0sU0FBUyxHQUFHLElBQUEscUJBQWUsRUFBQyxJQUFJLENBQUMsS0FBSyxFQUFFLEtBQUssRUFBRSxJQUFJLENBQUMsQ0FBQztZQUUzRCxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLGlCQUFpQixFQUFFLENBQUMsZ0JBQWdCLENBQUMsU0FBUyxDQUFDLENBQUM7U0FDN0U7UUFBQyxNQUFNO1lBQ04sTUFBTSxJQUFJLG9DQUFlLENBQ3ZCLG9CQUFvQixLQUFLLFNBQVMsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLG1CQUFtQixDQUNyRSxDQUFDO1NBQ0g7SUFDSCxDQUFDO0lB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
|
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
import { Fn } from 'sequelize/types/utils';
|
|
2
|
-
import {
|
|
2
|
+
import { Sequelize } from 'sequelize';
|
|
3
3
|
import { DateOperation } from '@forestadmin/datasource-toolkit';
|
|
4
4
|
export default class DateAggregationConverter {
|
|
5
|
-
private
|
|
6
|
-
private
|
|
7
|
-
private
|
|
8
|
-
private
|
|
9
|
-
|
|
5
|
+
private dialect;
|
|
6
|
+
private fn;
|
|
7
|
+
private col;
|
|
8
|
+
private literal;
|
|
9
|
+
constructor(sequelize: Sequelize);
|
|
10
|
+
private convertPostgres;
|
|
11
|
+
private convertMssql;
|
|
12
|
+
private convertMysql;
|
|
13
|
+
private convertSqlite;
|
|
14
|
+
convertToDialect(field: string, operation: DateOperation): Fn;
|
|
10
15
|
}
|
|
11
16
|
//# sourceMappingURL=date-aggregation-converter.d.ts.map
|
|
@@ -1,36 +1,41 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const sequelize_1 = require("sequelize");
|
|
4
3
|
class DateAggregationConverter {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
constructor(sequelize) {
|
|
5
|
+
this.dialect = sequelize.getDialect();
|
|
6
|
+
this.fn = sequelize.fn;
|
|
7
|
+
this.col = sequelize.col;
|
|
8
|
+
this.literal = sequelize.literal;
|
|
8
9
|
}
|
|
9
|
-
|
|
10
|
+
convertPostgres(field, operation) {
|
|
11
|
+
const aggregateFunction = this.fn('DATE_TRUNC', operation.toLocaleLowerCase(), this.col(field));
|
|
12
|
+
return this.fn('TO_CHAR', aggregateFunction, 'YYYY-MM-DD');
|
|
13
|
+
}
|
|
14
|
+
convertMssql(field, operation) {
|
|
10
15
|
let dateToConvert;
|
|
11
16
|
switch (operation) {
|
|
12
17
|
case 'Year':
|
|
13
|
-
dateToConvert =
|
|
18
|
+
dateToConvert = this.fn('DATEFROMPARTS', this.fn('DATEPART', this.literal('YEAR'), this.col(field)), '01', '01');
|
|
14
19
|
break;
|
|
15
20
|
case 'Month':
|
|
16
|
-
dateToConvert =
|
|
21
|
+
dateToConvert = this.fn('DATEFROMPARTS', this.fn('DATEPART', this.literal('YEAR'), this.col(field)), this.fn('DATEPART', this.literal('MONTH'), this.col(field)), '01');
|
|
17
22
|
break;
|
|
18
23
|
case 'Week':
|
|
19
|
-
dateToConvert =
|
|
24
|
+
dateToConvert = this.fn('DATEADD', this.literal('DAY'), this.literal(`-DATEPART(dw, ${field})+2`), this.col(field));
|
|
20
25
|
break;
|
|
21
26
|
case 'Day':
|
|
22
|
-
dateToConvert =
|
|
27
|
+
dateToConvert = this.col(field);
|
|
23
28
|
break;
|
|
24
29
|
default:
|
|
25
30
|
throw new Error(`Unknown Date operation: "${operation}"`);
|
|
26
31
|
}
|
|
27
32
|
// eslint-disable-next-line max-len
|
|
28
33
|
// https://docs.microsoft.com/en-us/sql/t-sql/functions/cast-and-convert-transact-sql?redirectedfrom=MSDN&view=sql-server-ver15
|
|
29
|
-
return
|
|
34
|
+
return this.fn('CONVERT', this.literal('varchar(10)'), dateToConvert, 23);
|
|
30
35
|
}
|
|
31
|
-
|
|
36
|
+
convertMysql(field, operation) {
|
|
32
37
|
let format = '%Y-%m-%d';
|
|
33
|
-
let dateToConvert =
|
|
38
|
+
let dateToConvert = this.col(field);
|
|
34
39
|
switch (operation) {
|
|
35
40
|
case 'Year':
|
|
36
41
|
format = '%Y-01-01';
|
|
@@ -39,18 +44,18 @@ class DateAggregationConverter {
|
|
|
39
44
|
format = '%Y-%m-01';
|
|
40
45
|
break;
|
|
41
46
|
case 'Week':
|
|
42
|
-
dateToConvert =
|
|
47
|
+
dateToConvert = this.fn('DATE_SUB', this.col(field), this.literal(`INTERVAL(WEEKDAY(${field})) DAY`));
|
|
43
48
|
break;
|
|
44
49
|
case 'Day':
|
|
45
50
|
break;
|
|
46
51
|
default:
|
|
47
52
|
throw new Error(`Unknown Date operation: "${operation}"`);
|
|
48
53
|
}
|
|
49
|
-
return
|
|
54
|
+
return this.fn('DATE_FORMAT', dateToConvert, format);
|
|
50
55
|
}
|
|
51
|
-
|
|
56
|
+
convertSqlite(field, operation) {
|
|
52
57
|
if (operation === 'Week') {
|
|
53
|
-
return
|
|
58
|
+
return this.fn('DATE', this.col(field), 'weekday 0');
|
|
54
59
|
}
|
|
55
60
|
let format;
|
|
56
61
|
switch (operation) {
|
|
@@ -66,10 +71,10 @@ class DateAggregationConverter {
|
|
|
66
71
|
default:
|
|
67
72
|
throw new Error(`Unknown Date operation: "${operation}"`);
|
|
68
73
|
}
|
|
69
|
-
return
|
|
74
|
+
return this.fn('STRFTIME', format, this.col(field));
|
|
70
75
|
}
|
|
71
|
-
|
|
72
|
-
switch (dialect) {
|
|
76
|
+
convertToDialect(field, operation) {
|
|
77
|
+
switch (this.dialect) {
|
|
73
78
|
case 'postgres':
|
|
74
79
|
return this.convertPostgres(field, operation);
|
|
75
80
|
case 'mssql':
|
|
@@ -80,9 +85,9 @@ class DateAggregationConverter {
|
|
|
80
85
|
case 'sqlite':
|
|
81
86
|
return this.convertSqlite(field, operation);
|
|
82
87
|
default:
|
|
83
|
-
throw new Error(`Unsupported dialect: "${dialect}"`);
|
|
88
|
+
throw new Error(`Unsupported dialect: "${this.dialect}"`);
|
|
84
89
|
}
|
|
85
90
|
}
|
|
86
91
|
}
|
|
87
92
|
exports.default = DateAggregationConverter;
|
|
88
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
93
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0ZS1hZ2dyZWdhdGlvbi1jb252ZXJ0ZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdXRpbHMvZGF0ZS1hZ2dyZWdhdGlvbi1jb252ZXJ0ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFLQSxNQUFxQix3QkFBd0I7SUFNM0MsWUFBWSxTQUFvQjtRQUM5QixJQUFJLENBQUMsT0FBTyxHQUFHLFNBQVMsQ0FBQyxVQUFVLEVBQWEsQ0FBQztRQUNqRCxJQUFJLENBQUMsRUFBRSxHQUFHLFNBQVMsQ0FBQyxFQUFFLENBQUM7UUFDdkIsSUFBSSxDQUFDLEdBQUcsR0FBRyxTQUFTLENBQUMsR0FBRyxDQUFDO1FBQ3pCLElBQUksQ0FBQyxPQUFPLEdBQUcsU0FBUyxDQUFDLE9BQU8sQ0FBQztJQUNuQyxDQUFDO0lBRU8sZUFBZSxDQUFDLEtBQWEsRUFBRSxTQUF3QjtRQUM3RCxNQUFNLGlCQUFpQixHQUFHLElBQUksQ0FBQyxFQUFFLENBQUMsWUFBWSxFQUFFLFNBQVMsQ0FBQyxpQkFBaUIsRUFBRSxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztRQUVoRyxPQUFPLElBQUksQ0FBQyxFQUFFLENBQUMsU0FBUyxFQUFFLGlCQUFpQixFQUFFLFlBQVksQ0FBQyxDQUFDO0lBQzdELENBQUM7SUFFTyxZQUFZLENBQUMsS0FBYSxFQUFFLFNBQXdCO1FBQzFELElBQUksYUFBdUIsQ0FBQztRQUU1QixRQUFRLFNBQVMsRUFBRTtZQUNqQixLQUFLLE1BQU07Z0JBQ1QsYUFBYSxHQUFHLElBQUksQ0FBQyxFQUFFLENBQ3JCLGVBQWUsRUFDZixJQUFJLENBQUMsRUFBRSxDQUFDLFVBQVUsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUMsRUFDMUQsSUFBSSxFQUNKLElBQUksQ0FDTCxDQUFDO2dCQUNGLE1BQU07WUFD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
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const sequelize_1 = require("sequelize");
|
|
4
|
+
const datasource_toolkit_1 = require("@forestadmin/datasource-toolkit");
|
|
5
|
+
async function handleErrors(method, callback) {
|
|
6
|
+
try {
|
|
7
|
+
const result = await callback();
|
|
8
|
+
return result;
|
|
9
|
+
}
|
|
10
|
+
catch (e) {
|
|
11
|
+
if (e instanceof sequelize_1.UniqueConstraintError) {
|
|
12
|
+
const message = 'The query violates a unicity constraint in the database. ' +
|
|
13
|
+
'Please ensure that you are not duplicating information across records.';
|
|
14
|
+
throw new datasource_toolkit_1.ValidationError(message);
|
|
15
|
+
}
|
|
16
|
+
if (e instanceof sequelize_1.ForeignKeyConstraintError) {
|
|
17
|
+
let message = 'The query violates a foreign key constraint in the database. ';
|
|
18
|
+
if (method === 'create' || method === 'update') {
|
|
19
|
+
message += 'Please ensure that you are not linking to a relation which was deleted.';
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
message += 'Please ensure that no records are linked to the one that you wish to delete.';
|
|
23
|
+
}
|
|
24
|
+
throw new datasource_toolkit_1.ValidationError(message);
|
|
25
|
+
}
|
|
26
|
+
throw e;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
exports.default = handleErrors;
|
|
30
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXJyb3ItaGFuZGxlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy91dGlscy9lcnJvci1oYW5kbGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEseUNBQTZFO0FBQzdFLHdFQUFrRTtBQUluRCxLQUFLLFVBQVUsWUFBWSxDQUN4QyxNQUFzQyxFQUN0QyxRQUFxQjtJQUVyQixJQUFJO1FBQ0YsTUFBTSxNQUFNLEdBQUcsTUFBTSxRQUFRLEVBQUUsQ0FBQztRQUVoQyxPQUFPLE1BQU0sQ0FBQztLQUNmO0lBQUMsT0FBTyxDQUFDLEVBQUU7UUFDVixJQUFJLENBQUMsWUFBWSxpQ0FBcUIsRUFBRTtZQUN0QyxNQUFNLE9BQU8sR0FDWCwyREFBMkQ7Z0JBQzNELHdFQUF3RSxDQUFDO1lBRTNFLE1BQU0sSUFBSSxvQ0FBZSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1NBQ3BDO1FBRUQsSUFBSSxDQUFDLFlBQVkscUNBQXlCLEVBQUU7WUFDMUMsSUFBSSxPQUFPLEdBQUcsK0RBQStELENBQUM7WUFFOUUsSUFBSSxNQUFNLEtBQUssUUFBUSxJQUFJLE1BQU0sS0FBSyxRQUFRLEVBQUU7Z0JBQzlDLE9BQU8sSUFBSSx5RUFBeUUsQ0FBQzthQUN0RjtpQkFBTTtnQkFDTCxPQUFPLElBQUksOEVBQThFLENBQUM7YUFDM0Y7WUFFRCxNQUFNLElBQUksb0NBQWUsQ0FBQyxPQUFPLENBQUMsQ0FBQztTQUNwQztRQUVELE1BQU0sQ0FBQyxDQUFDO0tBQ1Q7QUFDSCxDQUFDO0FBL0JELCtCQStCQyJ9
|
|
@@ -22,9 +22,9 @@ class ModelToCollectionSchemaConverter {
|
|
|
22
22
|
foreignCollection: association.target.name,
|
|
23
23
|
throughCollection: association.through.model.name,
|
|
24
24
|
originKey: association.foreignKey,
|
|
25
|
-
originKeyTarget: association.
|
|
25
|
+
originKeyTarget: association.sourceKey,
|
|
26
26
|
foreignKey: association.otherKey,
|
|
27
|
-
foreignKeyTarget: association.
|
|
27
|
+
foreignKeyTarget: association.targetKey,
|
|
28
28
|
type: 'ManyToMany',
|
|
29
29
|
};
|
|
30
30
|
case sequelize_1.HasMany.name:
|
|
@@ -69,6 +69,7 @@ class ModelToCollectionSchemaConverter {
|
|
|
69
69
|
type: 'Column',
|
|
70
70
|
validation: [],
|
|
71
71
|
isReadOnly: attribute.autoIncrement,
|
|
72
|
+
isSortable: true,
|
|
72
73
|
};
|
|
73
74
|
if (attribute.allowNull === false &&
|
|
74
75
|
!column.isReadOnly &&
|
|
@@ -107,6 +108,7 @@ class ModelToCollectionSchemaConverter {
|
|
|
107
108
|
throw new Error('Invalid (null) model.');
|
|
108
109
|
return {
|
|
109
110
|
actions: {},
|
|
111
|
+
countable: true,
|
|
110
112
|
fields: {
|
|
111
113
|
...this.convertAttributes(model.name, model.getAttributes(), logger),
|
|
112
114
|
...this.convertAssociations(model.name, model.associations, logger),
|
|
@@ -117,4 +119,4 @@ class ModelToCollectionSchemaConverter {
|
|
|
117
119
|
}
|
|
118
120
|
}
|
|
119
121
|
exports.default = ModelToCollectionSchemaConverter;
|
|
120
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
122
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9kZWwtdG8tY29sbGVjdGlvbi1zY2hlbWEtY29udmVydGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3V0aWxzL21vZGVsLXRvLWNvbGxlY3Rpb24tc2NoZW1hLWNvbnZlcnRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLHlDQVdtQjtBQVVuQixzRUFBNkM7QUFFN0MsTUFBcUIsZ0NBQWdDO0lBQzNDLE1BQU0sQ0FBQyxrQkFBa0I7SUFDL0IsOERBQThEO0lBQzlELFdBQTBEO1FBRTFELFFBQVEsV0FBVyxDQUFDLGVBQWUsRUFBRTtZQUNuQyxLQUFLLHFCQUFTLENBQUMsSUFBSTtnQkFDakIsT0FBTztvQkFDTCxpQkFBaUIsRUFBRSxXQUFXLENBQUMsTUFBTSxDQUFDLElBQUk7b0JBQzFDLFVBQVUsRUFBRSxXQUFXLENBQUMsVUFBVTtvQkFDbEMsZ0JBQWdCLEVBQUcsV0FBZ0QsQ0FBQyxTQUFTO29CQUM3RSxJQUFJLEVBQUUsV0FBVztpQkFDbEIsQ0FBQztZQUNKLEtBQUsseUJBQWEsQ0FBQyxJQUFJO2dCQUNyQixPQUFPO29CQUNMLGlCQUFpQixFQUFFLFdBQVcsQ0FBQyxNQUFNLENBQUMsSUFBSTtvQkFDMUMsaUJBQWlCLEVBQUcsV0FBNkIsQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLElBQUk7b0JBQ3BFLFNBQVMsRUFBRyxXQUE2QixDQUFDLFVBQVU7b0JBQ3BELGVBQWUsRUFBRyxXQUE2QixDQUFDLFNBQVM7b0JBQ3pELFVBQVUsRUFBRyxXQUE2QixDQUFDLFFBQVE7b0JBQ25ELGdCQUFnQixFQUFHLFdBQTZCLENBQUMsU0FBUztvQkFDMUQsSUFBSSxFQUFFLFlBQVk7aUJBQ25CLENBQUM7WUFDSixLQUFLLG1CQUFPLENBQUMsSUFBSTtnQkFDZixPQUFPO29CQUNMLGlCQUFpQixFQUFFLFdBQVcsQ0FBQyxNQUFNLENBQUMsSUFBSTtvQkFDMUMsU0FBUyxFQUFFLFdBQVcsQ0FBQyxVQUFVO29C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
|
|
@@ -1,12 +1,19 @@
|
|
|
1
1
|
import { ConditionTree, Projection, Sort } from '@forestadmin/datasource-toolkit';
|
|
2
2
|
import { IncludeOptions, ModelDefined, OrderItem, WhereOptions } from 'sequelize';
|
|
3
3
|
export default class QueryConverter {
|
|
4
|
-
private
|
|
5
|
-
private
|
|
6
|
-
|
|
7
|
-
private
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
4
|
+
private model;
|
|
5
|
+
private dialect;
|
|
6
|
+
private col;
|
|
7
|
+
private fn;
|
|
8
|
+
private where;
|
|
9
|
+
constructor(model: ModelDefined<unknown, unknown>);
|
|
10
|
+
private asArray;
|
|
11
|
+
private makeWhereClause;
|
|
12
|
+
getWhereFromConditionTreeToByPassInclude(conditionTree?: ConditionTree): Promise<WhereOptions>;
|
|
13
|
+
getWhereFromConditionTree(conditionTree?: ConditionTree): WhereOptions;
|
|
14
|
+
private computeIncludeFromProjection;
|
|
15
|
+
getIncludeFromProjection(projection: Projection): IncludeOptions[];
|
|
16
|
+
getIncludeWithAttributesFromProjection(projection: Projection): IncludeOptions[];
|
|
17
|
+
getOrderFromSort(sort: Sort): OrderItem[];
|
|
11
18
|
}
|
|
12
19
|
//# sourceMappingURL=query-converter.d.ts.map
|
|
@@ -1,13 +1,25 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const datasource_toolkit_1 = require("@forestadmin/datasource-toolkit");
|
|
3
7
|
const sequelize_1 = require("sequelize");
|
|
8
|
+
const un_ambigous_1 = __importDefault(require("./un-ambigous"));
|
|
4
9
|
class QueryConverter {
|
|
5
|
-
|
|
10
|
+
constructor(model) {
|
|
11
|
+
this.model = model;
|
|
12
|
+
this.dialect = this.model.sequelize.getDialect();
|
|
13
|
+
this.col = this.model.sequelize.col;
|
|
14
|
+
this.fn = this.model.sequelize.fn;
|
|
15
|
+
this.where = this.model.sequelize.where;
|
|
16
|
+
}
|
|
17
|
+
asArray(value) {
|
|
6
18
|
if (!Array.isArray(value))
|
|
7
19
|
return [value];
|
|
8
20
|
return value;
|
|
9
21
|
}
|
|
10
|
-
|
|
22
|
+
makeWhereClause(field, operator,
|
|
11
23
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
12
24
|
value) {
|
|
13
25
|
if (operator === null)
|
|
@@ -15,12 +27,24 @@ class QueryConverter {
|
|
|
15
27
|
switch (operator) {
|
|
16
28
|
case 'Blank':
|
|
17
29
|
return {
|
|
18
|
-
[sequelize_1.Op.or]: [this.makeWhereClause('Missing'
|
|
30
|
+
[sequelize_1.Op.or]: [this.makeWhereClause(field, 'Missing'), { [sequelize_1.Op.eq]: '' }],
|
|
31
|
+
};
|
|
32
|
+
case 'Like':
|
|
33
|
+
if (this.dialect === 'sqlite')
|
|
34
|
+
return this.where(this.col(field), 'GLOB', value.replace(/%/g, '*').replace(/_/g, '?'));
|
|
35
|
+
if (this.dialect === 'mysql' || this.dialect === 'mariadb')
|
|
36
|
+
return this.where(this.fn('BINARY', this.col(field)), 'LIKE', value);
|
|
37
|
+
return { [sequelize_1.Op.like]: value };
|
|
38
|
+
case 'ILike':
|
|
39
|
+
if (this.dialect === 'postgres')
|
|
40
|
+
return { [sequelize_1.Op.iLike]: value };
|
|
41
|
+
if (this.dialect === 'mysql' || this.dialect === 'mariadb' || this.dialect === 'sqlite')
|
|
42
|
+
return { [sequelize_1.Op.like]: value };
|
|
43
|
+
return this.where(this.fn('LOWER', this.col(field)), 'LIKE', value.toLocaleLowerCase());
|
|
44
|
+
case 'NotContains':
|
|
45
|
+
return {
|
|
46
|
+
[sequelize_1.Op.not]: this.makeWhereClause(field, 'Like', `%${value}%`),
|
|
19
47
|
};
|
|
20
|
-
case 'Contains':
|
|
21
|
-
return (0, sequelize_1.where)((0, sequelize_1.fn)('LOWER', (0, sequelize_1.col)(field)), 'LIKE', `%${value.toLocaleLowerCase()}%`);
|
|
22
|
-
case 'EndsWith':
|
|
23
|
-
return (0, sequelize_1.where)((0, sequelize_1.fn)('LOWER', (0, sequelize_1.col)(field)), 'LIKE', `%${value.toLocaleLowerCase()}`);
|
|
24
48
|
case 'Equal':
|
|
25
49
|
return { [sequelize_1.Op.eq]: value };
|
|
26
50
|
case 'GreaterThan':
|
|
@@ -33,23 +57,36 @@ class QueryConverter {
|
|
|
33
57
|
return { [sequelize_1.Op.lt]: value };
|
|
34
58
|
case 'Missing':
|
|
35
59
|
return { [sequelize_1.Op.is]: null };
|
|
36
|
-
case 'NotContains':
|
|
37
|
-
return (0, sequelize_1.where)((0, sequelize_1.fn)('LOWER', (0, sequelize_1.col)(field)), 'NOT LIKE', `%${value.toLocaleLowerCase()}%`);
|
|
38
60
|
case 'NotEqual':
|
|
39
61
|
return { [sequelize_1.Op.ne]: value };
|
|
40
62
|
case 'NotIn':
|
|
41
63
|
return { [sequelize_1.Op.notIn]: this.asArray(value) };
|
|
42
64
|
case 'Present':
|
|
43
65
|
return { [sequelize_1.Op.ne]: null };
|
|
44
|
-
case 'StartsWith':
|
|
45
|
-
return (0, sequelize_1.where)((0, sequelize_1.fn)('LOWER', (0, sequelize_1.col)(field)), 'LIKE', `${value.toLocaleLowerCase()}%`);
|
|
46
66
|
default:
|
|
47
67
|
throw new Error(`Unsupported operator: "${operator}".`);
|
|
48
68
|
}
|
|
49
69
|
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
70
|
+
/*
|
|
71
|
+
* Delete and update sequelize methods does not provide the include options.
|
|
72
|
+
* This method is developed to by pass this problem.
|
|
73
|
+
*/
|
|
74
|
+
async getWhereFromConditionTreeToByPassInclude(conditionTree) {
|
|
75
|
+
const include = conditionTree ? this.getIncludeFromProjection(conditionTree.projection) : [];
|
|
76
|
+
const whereOptions = this.getWhereFromConditionTree(conditionTree);
|
|
77
|
+
if (include.length === 0) {
|
|
78
|
+
return whereOptions;
|
|
79
|
+
}
|
|
80
|
+
const keys = [...this.model.primaryKeyAttributes];
|
|
81
|
+
const records = await this.model.findAll({ attributes: keys, where: whereOptions, include });
|
|
82
|
+
const conditions = records.map(record => {
|
|
83
|
+
const equals = keys.map(pk => new datasource_toolkit_1.ConditionTreeLeaf(pk, 'Equal', record.get(pk)));
|
|
84
|
+
return datasource_toolkit_1.ConditionTreeFactory.intersect(...equals);
|
|
85
|
+
});
|
|
86
|
+
const union = datasource_toolkit_1.ConditionTreeFactory.union(...conditions);
|
|
87
|
+
return this.getWhereFromConditionTree(union);
|
|
88
|
+
}
|
|
89
|
+
getWhereFromConditionTree(conditionTree) {
|
|
53
90
|
if (!conditionTree)
|
|
54
91
|
return {};
|
|
55
92
|
const sequelizeWhereClause = {};
|
|
@@ -62,31 +99,20 @@ class QueryConverter {
|
|
|
62
99
|
if (!Array.isArray(conditions)) {
|
|
63
100
|
throw new Error('Conditions must be an array.');
|
|
64
101
|
}
|
|
65
|
-
sequelizeWhereClause[sequelizeOperator] = conditions.map(condition => this.getWhereFromConditionTree(
|
|
102
|
+
sequelizeWhereClause[sequelizeOperator] = conditions.map(condition => this.getWhereFromConditionTree(condition));
|
|
66
103
|
}
|
|
67
104
|
else if (conditionTree.operator !== undefined) {
|
|
68
105
|
const { field, operator, value } = conditionTree;
|
|
69
106
|
const isRelation = field.includes(':');
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
const paths = field.split(':');
|
|
73
|
-
const fieldName = paths.pop();
|
|
74
|
-
const safeFieldName = paths
|
|
75
|
-
.reduce((acc, path) => acc.associations[path].target, model)
|
|
76
|
-
.getAttributes()[fieldName].field;
|
|
77
|
-
safeField = `${paths.join('.')}.${safeFieldName}`;
|
|
78
|
-
}
|
|
79
|
-
else {
|
|
80
|
-
safeField = model.getAttributes()[field].field;
|
|
81
|
-
}
|
|
82
|
-
sequelizeWhereClause[isRelation ? `$${safeField}$` : safeField] = this.makeWhereClause(operator, safeField, value);
|
|
107
|
+
const safeField = (0, un_ambigous_1.default)(this.model, field);
|
|
108
|
+
sequelizeWhereClause[isRelation ? `$${safeField}$` : safeField] = this.makeWhereClause(safeField, operator, value);
|
|
83
109
|
}
|
|
84
110
|
else {
|
|
85
111
|
throw new Error('Invalid ConditionTree.');
|
|
86
112
|
}
|
|
87
113
|
return sequelizeWhereClause;
|
|
88
114
|
}
|
|
89
|
-
|
|
115
|
+
computeIncludeFromProjection(projection, withAttributes = true) {
|
|
90
116
|
return Object.entries(projection.relations).map(([relationName, relationProjection]) => {
|
|
91
117
|
return {
|
|
92
118
|
association: relationName,
|
|
@@ -95,13 +121,13 @@ class QueryConverter {
|
|
|
95
121
|
};
|
|
96
122
|
});
|
|
97
123
|
}
|
|
98
|
-
|
|
124
|
+
getIncludeFromProjection(projection) {
|
|
99
125
|
return this.computeIncludeFromProjection(projection, false);
|
|
100
126
|
}
|
|
101
|
-
|
|
127
|
+
getIncludeWithAttributesFromProjection(projection) {
|
|
102
128
|
return this.computeIncludeFromProjection(projection);
|
|
103
129
|
}
|
|
104
|
-
|
|
130
|
+
getOrderFromSort(sort) {
|
|
105
131
|
return (sort ?? []).map(({ field, ascending }) => {
|
|
106
132
|
const path = field.split(':');
|
|
107
133
|
return [...path, ascending ? 'ASC' : 'DESC'];
|
|
@@ -109,4 +135,4 @@ class QueryConverter {
|
|
|
109
135
|
}
|
|
110
136
|
}
|
|
111
137
|
exports.default = QueryConverter;
|
|
112
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
138
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicXVlcnktY29udmVydGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3V0aWxzL3F1ZXJ5LWNvbnZlcnRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLHdFQVF5QztBQUN6Qyx5Q0FTbUI7QUFFbkIsZ0VBQTRDO0FBRTVDLE1BQXFCLGNBQWM7SUFPakMsWUFBWSxLQUFxQztRQUMvQyxJQUFJLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQztRQUNuQixJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLFVBQVUsRUFBYSxDQUFDO1FBQzVELElBQUksQ0FBQyxHQUFHLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDO1FBQ3BDLElBQUksQ0FBQyxFQUFFLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDO1FBQ2xDLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDO0lBQzFDLENBQUM7SUFFTyxPQUFPLENBQUMsS0FBYztRQUM1QixJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUM7WUFBRSxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUM7UUFFMUMsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0lBRU8sZUFBZSxDQUNyQixLQUFhLEVBQ2IsUUFBa0I7SUFDbEIsOERBQThEO0lBQzlELEtBQVc7UUFHWCxJQUFJLFFBQVEsS0FBSyxJQUFJO1lBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQywwQkFBMEIsQ0FBQyxDQUFDO1FBRW5FLFFBQVEsUUFBUSxFQUFFO1lBQ2hCLEtBQUssT0FBTztnQkFDVixPQUFPO29CQUNMLENBQUMsY0FBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxLQUFLLEVBQUUsU0FBUyxDQUFD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
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
class Serializer {
|
|
4
|
+
static serialize(record) {
|
|
5
|
+
Object.entries(record).forEach(([name, value]) => {
|
|
6
|
+
if (value instanceof Date)
|
|
7
|
+
record[name] = this.serializeValue(value);
|
|
8
|
+
if (Array.isArray(value))
|
|
9
|
+
this.serializeValue(value); // the change is by references
|
|
10
|
+
if (value instanceof Object)
|
|
11
|
+
return this.serialize(record[name]);
|
|
12
|
+
});
|
|
13
|
+
return record;
|
|
14
|
+
}
|
|
15
|
+
static serializeValue(value) {
|
|
16
|
+
if (value instanceof Date)
|
|
17
|
+
return value.toISOString();
|
|
18
|
+
if (Array.isArray(value)) {
|
|
19
|
+
value.forEach((v, i) => {
|
|
20
|
+
// serialize by reference to improve performances by avoiding the copies
|
|
21
|
+
if (value instanceof Date)
|
|
22
|
+
value[i] = v.toISOString();
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
return value;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
exports.default = Serializer;
|
|
29
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VyaWFsaXplci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy91dGlscy9zZXJpYWxpemVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBRUEsTUFBcUIsVUFBVTtJQUM3QixNQUFNLENBQUMsU0FBUyxDQUFDLE1BQWtCO1FBQ2pDLE1BQU0sQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLEVBQUUsRUFBRTtZQUMvQyxJQUFJLEtBQUssWUFBWSxJQUFJO2dCQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ3JFLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUM7Z0JBQUUsSUFBSSxDQUFDLGNBQWMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLDhCQUE4QjtZQUNwRixJQUFJLEtBQUssWUFBWSxNQUFNO2dCQUFFLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztRQUNuRSxDQUFDLENBQUMsQ0FBQztRQUVILE9BQU8sTUFBTSxDQUFDO0lBQ2hCLENBQUM7SUFFRCxNQUFNLENBQUMsY0FBYyxDQUFDLEtBQWM7UUFDbEMsSUFBSSxLQUFLLFlBQVksSUFBSTtZQUFFLE9BQU8sS0FBSyxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBRXRELElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsRUFBRTtZQUN4QixLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFO2dCQUNyQix3RUFBd0U7Z0JBQ3hFLElBQUksS0FBSyxZQUFZLElBQUk7b0JBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUN4RCxDQUFDLENBQUMsQ0FBQztTQUNKO1FBRUQsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0NBQ0Y7QUF2QkQsNkJBdUJDIn0=
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { AbstractDataType, AbstractDataTypeConstructor } from 'sequelize';
|
|
2
2
|
import { ColumnType, Operator, PrimitiveTypes } from '@forestadmin/datasource-toolkit';
|
|
3
3
|
export default class TypeConverter {
|
|
4
4
|
private static readonly columnTypeToDataType;
|
|
5
5
|
static fromColumnType(columnType: PrimitiveTypes): AbstractDataTypeConstructor;
|
|
6
6
|
private static getColumnTypeFromDataType;
|
|
7
|
-
static fromDataType(dataType:
|
|
7
|
+
static fromDataType(dataType: AbstractDataType): ColumnType;
|
|
8
8
|
private static readonly baseOperators;
|
|
9
9
|
static operatorsForColumnType(columnType: ColumnType): Set<Operator>;
|
|
10
10
|
}
|
|
@@ -10,47 +10,47 @@ class TypeConverter {
|
|
|
10
10
|
return dataType;
|
|
11
11
|
}
|
|
12
12
|
static getColumnTypeFromDataType(dataType) {
|
|
13
|
-
switch (
|
|
14
|
-
case
|
|
13
|
+
switch (dataType.key) {
|
|
14
|
+
case sequelize_1.DataTypes.BOOLEAN.key:
|
|
15
15
|
return 'Boolean';
|
|
16
|
-
case
|
|
17
|
-
case
|
|
16
|
+
case sequelize_1.DataTypes.DATE.key:
|
|
17
|
+
case sequelize_1.DataTypes.NOW.key:
|
|
18
18
|
return 'Date';
|
|
19
|
-
case
|
|
19
|
+
case sequelize_1.DataTypes.DATEONLY.key:
|
|
20
20
|
return 'Dateonly';
|
|
21
|
-
case
|
|
21
|
+
case sequelize_1.DataTypes.ENUM.key:
|
|
22
22
|
return 'Enum';
|
|
23
|
-
case
|
|
24
|
-
case
|
|
23
|
+
case sequelize_1.DataTypes.JSON.key:
|
|
24
|
+
case sequelize_1.DataTypes.JSONB.key:
|
|
25
25
|
return 'Json';
|
|
26
|
-
case
|
|
27
|
-
case
|
|
28
|
-
case
|
|
29
|
-
case
|
|
30
|
-
case
|
|
31
|
-
case
|
|
32
|
-
case
|
|
33
|
-
case
|
|
34
|
-
case
|
|
35
|
-
case
|
|
26
|
+
case sequelize_1.DataTypes.BIGINT.key:
|
|
27
|
+
case sequelize_1.DataTypes.DECIMAL.key:
|
|
28
|
+
case sequelize_1.DataTypes.DOUBLE.key:
|
|
29
|
+
case sequelize_1.DataTypes.FLOAT.key:
|
|
30
|
+
case sequelize_1.DataTypes.INTEGER.key:
|
|
31
|
+
case sequelize_1.DataTypes.MEDIUMINT.key:
|
|
32
|
+
case sequelize_1.DataTypes.NUMBER.key:
|
|
33
|
+
case sequelize_1.DataTypes.REAL.key:
|
|
34
|
+
case sequelize_1.DataTypes.SMALLINT.key:
|
|
35
|
+
case sequelize_1.DataTypes.TINYINT.key:
|
|
36
36
|
return 'Number';
|
|
37
|
-
case
|
|
38
|
-
case
|
|
39
|
-
case
|
|
40
|
-
case
|
|
37
|
+
case sequelize_1.DataTypes.CHAR.key:
|
|
38
|
+
case sequelize_1.DataTypes.CITEXT.key:
|
|
39
|
+
case sequelize_1.DataTypes.STRING.key:
|
|
40
|
+
case sequelize_1.DataTypes.TEXT.key:
|
|
41
41
|
return 'String';
|
|
42
|
-
case
|
|
42
|
+
case sequelize_1.DataTypes.TIME.key:
|
|
43
43
|
return 'Timeonly';
|
|
44
|
-
case
|
|
45
|
-
case
|
|
46
|
-
case
|
|
44
|
+
case sequelize_1.DataTypes.UUID.key:
|
|
45
|
+
case sequelize_1.DataTypes.UUIDV1.key:
|
|
46
|
+
case sequelize_1.DataTypes.UUIDV4.key:
|
|
47
47
|
return 'Uuid';
|
|
48
48
|
default:
|
|
49
49
|
throw new Error(`Unsupported data type: "${dataType}"`);
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
52
|
static fromDataType(dataType) {
|
|
53
|
-
if (dataType
|
|
53
|
+
if (dataType.key === sequelize_1.DataTypes.ARRAY.key) {
|
|
54
54
|
const arrayDataType = dataType;
|
|
55
55
|
return [TypeConverter.fromDataType(arrayDataType.type)];
|
|
56
56
|
}
|
|
@@ -82,15 +82,13 @@ class TypeConverter {
|
|
|
82
82
|
case 'String':
|
|
83
83
|
return new Set([
|
|
84
84
|
...TypeConverter.baseOperators,
|
|
85
|
-
'Contains',
|
|
86
|
-
'EndsWith',
|
|
87
85
|
'In',
|
|
88
86
|
'Like',
|
|
87
|
+
'ILike',
|
|
89
88
|
'LongerThan',
|
|
90
89
|
'NotContains',
|
|
91
90
|
'NotIn',
|
|
92
91
|
'ShorterThan',
|
|
93
|
-
'StartsWith',
|
|
94
92
|
]);
|
|
95
93
|
case 'Date':
|
|
96
94
|
case 'Dateonly':
|
|
@@ -125,4 +123,4 @@ TypeConverter.baseOperators = [
|
|
|
125
123
|
'NotEqual',
|
|
126
124
|
'Present',
|
|
127
125
|
];
|
|
128
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
126
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZS1jb252ZXJ0ZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdXRpbHMvdHlwZS1jb252ZXJ0ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSx5Q0FBb0c7QUFJcEcsTUFBcUIsYUFBYTtJQWtCaEMseURBQXlEO0lBQ2xELE1BQU0sQ0FBQyxjQUFjLENBQUMsVUFBMEI7UUFDckQsTUFBTSxRQUFRLEdBQUcsYUFBYSxDQUFDLG9CQUFvQixDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBRWhFLElBQUksQ0FBQyxRQUFRO1lBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQyw2QkFBNkIsVUFBVSxJQUFJLENBQUMsQ0FBQztRQUU1RSxPQUFPLFFBQVEsQ0FBQztJQUNsQixDQUFDO0lBRU8sTUFBTSxDQUFDLHlCQUF5QixDQUFDLFFBQTBCO1FBQ2pFLFFBQVEsUUFBUSxDQUFDLEdBQUcsRUFBRTtZQUNwQixLQUFLLHFCQUFTLENBQUMsT0FBTyxDQUFDLEdBQUc7Z0JBQ3hCLE9BQU8sU0FBUyxDQUFDO1lBQ25CLEtBQUsscUJBQVMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDO1lBQ3hCLEtBQUsscUJBQVMsQ0FBQyxHQUFHLENBQUMsR0FBRztnQkFDcEIsT0FBTyxNQUFNLENBQUM7WUFDaEIsS0FBSyxxQkFBUyxDQUFDLFFBQVEsQ0FBQyxHQUFHO2dCQUN6QixPQUFPLFVBQVUsQ0FBQztZQUNwQixLQUFLLHFCQUFTLENBQUMsSUFBSSxDQUFDLEdBQUc7Z0JBQ3JCLE9BQU8sTUFBTSxDQUFDO1lBQ2hCLEtBQUsscUJBQVMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDO1lBQ3hCLEtBQUsscUJBQVMsQ0FBQyxLQUFLLENBQUMsR0FBRztnQkFDdEIsT0FBTyxNQUFNLENBQUM7WUFDaEIsS0FBSyxxQkFBUyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUM7WUFDMUIsS0FBSyxxQkFBUyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUM7WUFDM0Is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
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
function unAmbigousField(
|
|
4
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5
|
+
model, field, unAmbigous = false) {
|
|
6
|
+
const isRelation = field.includes(':');
|
|
7
|
+
let safeField;
|
|
8
|
+
if (isRelation) {
|
|
9
|
+
const paths = field.split(':');
|
|
10
|
+
const relationFieldName = paths.pop();
|
|
11
|
+
const fieldName = paths
|
|
12
|
+
.reduce((acc, path) => acc.associations[path].target, model)
|
|
13
|
+
.getAttributes()[relationFieldName].field;
|
|
14
|
+
safeField = `${paths.join('.')}.${fieldName}`;
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
safeField = model.getAttributes()[field].field;
|
|
18
|
+
if (unAmbigous)
|
|
19
|
+
safeField = `${model.name}.${safeField}`;
|
|
20
|
+
}
|
|
21
|
+
return safeField;
|
|
22
|
+
}
|
|
23
|
+
exports.default = unAmbigousField;
|
|
24
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidW4tYW1iaWdvdXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdXRpbHMvdW4tYW1iaWdvdXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFFQSxTQUF3QixlQUFlO0FBQ3JDLDhEQUE4RDtBQUM5RCxLQUE2QixFQUM3QixLQUFhLEVBQ2IsVUFBVSxHQUFHLEtBQUs7SUFFbEIsTUFBTSxVQUFVLEdBQUcsS0FBSyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUV2QyxJQUFJLFNBQWlCLENBQUM7SUFFdEIsSUFBSSxVQUFVLEVBQUU7UUFDZCxNQUFNLEtBQUssR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQy9CLE1BQU0saUJBQWlCLEdBQUcsS0FBSyxDQUFDLEdBQUcsRUFBRSxDQUFDO1FBQ3RDLE1BQU0sU0FBUyxHQUFHLEtBQUs7YUFDcEIsTUFBTSxDQUFDLENBQUMsR0FBRyxFQUFFLElBQUksRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsQ0FBQyxNQUFNLEVBQUUsS0FBSyxDQUFDO2FBQzNELGFBQWEsRUFBRSxDQUFDLGlCQUFpQixDQUFDLENBQUMsS0FBSyxDQUFDO1FBQzVDLFNBQVMsR0FBRyxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksU0FBUyxFQUFFLENBQUM7S0FDL0M7U0FBTTtRQUNMLFNBQVMsR0FBRyxLQUFLLENBQUMsYUFBYSxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUMsS0FBSyxDQUFDO1FBQy9DLElBQUksVUFBVTtZQUFFLFNBQVMsR0FBRyxHQUFHLEtBQUssQ0FBQyxJQUFJLElBQUksU0FBUyxFQUFFLENBQUM7S0FDMUQ7SUFFRCxPQUFPLFNBQVMsQ0FBQztBQUNuQixDQUFDO0FBdkJELGtDQXVCQyJ9
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@forestadmin/datasource-sequelize",
|
|
3
|
-
"version": "1.0.0
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"license": "GPL-3.0",
|
|
6
6
|
"publishConfig": {
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"directory": "packages/datasource-sequelize"
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@forestadmin/datasource-toolkit": "1.0.0
|
|
15
|
+
"@forestadmin/datasource-toolkit": "1.0.0"
|
|
16
16
|
},
|
|
17
17
|
"files": [
|
|
18
18
|
"dist/**/*.js",
|
|
@@ -27,10 +27,9 @@
|
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
29
|
"fishery": "^2.1.0",
|
|
30
|
-
"sequelize": "6.
|
|
31
|
-
"sqlite3": "^5.0.2"
|
|
30
|
+
"sequelize": "6.21.3"
|
|
32
31
|
},
|
|
33
32
|
"peerDependencies": {
|
|
34
|
-
"sequelize": "6.
|
|
33
|
+
"sequelize": ">= 6.12.0 < 7"
|
|
35
34
|
}
|
|
36
35
|
}
|
package/CHANGELOG.md
DELETED
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
# @forestadmin/datasource-sequelize [1.0.0-beta.9](https://github.com/ForestAdmin/agent-nodejs/compare/@forestadmin/datasource-sequelize@1.0.0-beta.8...@forestadmin/datasource-sequelize@1.0.0-beta.9) (2022-04-25)
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
### Bug Fixes
|
|
5
|
-
|
|
6
|
-
* import packages from js ([#260](https://github.com/ForestAdmin/agent-nodejs/issues/260)) ([de00886](https://github.com/ForestAdmin/agent-nodejs/commit/de008862971ea5d3559e5a4c3136b0dd2161d760))
|
|
7
|
-
|
|
8
|
-
# @forestadmin/datasource-sequelize [1.0.0-beta.8](https://github.com/ForestAdmin/agent-nodejs/compare/@forestadmin/datasource-sequelize@1.0.0-beta.7...@forestadmin/datasource-sequelize@1.0.0-beta.8) (2022-04-21)
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
### Features
|
|
12
|
-
|
|
13
|
-
* harmonize datasource creation and pass logger to it ([#257](https://github.com/ForestAdmin/agent-nodejs/issues/257)) ([82cb4ea](https://github.com/ForestAdmin/agent-nodejs/commit/82cb4ea37ac0a9fe83423d917226dfd8fad7d0a6))
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
### Dependencies
|
|
20
|
-
|
|
21
|
-
* **@forestadmin/datasource-toolkit:** upgraded to 1.0.0-beta.6
|
|
22
|
-
|
|
23
|
-
# @forestadmin/datasource-sequelize [1.0.0-beta.7](https://github.com/ForestAdmin/agent-nodejs/compare/@forestadmin/datasource-sequelize@1.0.0-beta.6...@forestadmin/datasource-sequelize@1.0.0-beta.7) (2022-04-20)
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
### Bug Fixes
|
|
27
|
-
|
|
28
|
-
* **datasource sequelize:** add include from sort relation for list ([#243](https://github.com/ForestAdmin/agent-nodejs/issues/243)) ([5a81bc0](https://github.com/ForestAdmin/agent-nodejs/commit/5a81bc04e969442dd38d251be0a48c7bce2dc43e))
|
|
29
|
-
|
|
30
|
-
# @forestadmin/datasource-sequelize [1.0.0-beta.6](https://github.com/ForestAdmin/agent-nodejs/compare/@forestadmin/datasource-sequelize@1.0.0-beta.5...@forestadmin/datasource-sequelize@1.0.0-beta.6) (2022-04-19)
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
### Dependencies
|
|
37
|
-
|
|
38
|
-
* **@forestadmin/datasource-toolkit:** upgraded to 1.0.0-beta.5
|
|
39
|
-
|
|
40
|
-
# @forestadmin/datasource-sequelize [1.0.0-beta.5](https://github.com/ForestAdmin/agent-nodejs/compare/@forestadmin/datasource-sequelize@1.0.0-beta.4...@forestadmin/datasource-sequelize@1.0.0-beta.5) (2022-04-19)
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
### Bug Fixes
|
|
44
|
-
|
|
45
|
-
* **datasource sequelize:** type converter compute correctly type from sequelize DataTypes ([#246](https://github.com/ForestAdmin/agent-nodejs/issues/246)) ([92fc238](https://github.com/ForestAdmin/agent-nodejs/commit/92fc23841c25c502f44fd90c5e68f864ecc6727b))
|
|
46
|
-
|
|
47
|
-
# @forestadmin/datasource-sequelize [1.0.0-beta.4](https://github.com/ForestAdmin/agent-nodejs/compare/@forestadmin/datasource-sequelize@1.0.0-beta.3...@forestadmin/datasource-sequelize@1.0.0-beta.4) (2022-04-15)
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
### Dependencies
|
|
54
|
-
|
|
55
|
-
* **@forestadmin/datasource-toolkit:** upgraded to 1.0.0-beta.4
|
|
56
|
-
|
|
57
|
-
# @forestadmin/datasource-sequelize [1.0.0-beta.3](https://github.com/ForestAdmin/agent-nodejs/compare/@forestadmin/datasource-sequelize@1.0.0-beta.2...@forestadmin/datasource-sequelize@1.0.0-beta.3) (2022-04-15)
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
### Bug Fixes
|
|
61
|
-
|
|
62
|
-
* correct versions in package.json of all datasources ([540d395](https://github.com/ForestAdmin/agent-nodejs/commit/540d395bc5e42bdd7edb3dce5806ade8554f3d7a))
|
|
63
|
-
|
|
64
|
-
# @forestadmin/datasource-sequelize [1.0.0-beta.2](https://github.com/ForestAdmin/agent-nodejs/compare/@forestadmin/datasource-sequelize@1.0.0-beta.1...@forestadmin/datasource-sequelize@1.0.0-beta.2) (2022-04-15)
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
### Dependencies
|
|
71
|
-
|
|
72
|
-
* **@forestadmin/datasource-toolkit:** upgraded to 1.0.0-beta.3
|
|
73
|
-
|
|
74
|
-
# @forestadmin/datasource-sequelize 1.0.0-beta.1 (2022-04-15)
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
### Bug Fixes
|
|
78
|
-
|
|
79
|
-
* **datasource sequelize:** compute where correctly ([#239](https://github.com/ForestAdmin/agent-nodejs/issues/239)) ([ee770ba](https://github.com/ForestAdmin/agent-nodejs/commit/ee770bafe8b6a8ebe542bac3e664a47b4d0c7151))
|
|
80
|
-
* **datasource sequelize:** enable date filter ([#166](https://github.com/ForestAdmin/agent-nodejs/issues/166)) ([5f0e349](https://github.com/ForestAdmin/agent-nodejs/commit/5f0e3494dbb254ef5351e0c85061ce196d8c2f9b))
|
|
81
|
-
* **datasource sequelize:** search like operators is now insensitive ([#175](https://github.com/ForestAdmin/agent-nodejs/issues/175)) ([4660c13](https://github.com/ForestAdmin/agent-nodejs/commit/4660c131e398a151fc2a98c8f7e4e817fd427e63))
|
|
82
|
-
* **datasource,sequelize:** only keep grouped field in order clause for aggregate ([#102](https://github.com/ForestAdmin/agent-nodejs/issues/102)) ([6f0d1dd](https://github.com/ForestAdmin/agent-nodejs/commit/6f0d1dd4df4dc94739c40271afb55aa6928eca1b))
|
|
83
|
-
* **datasource,sequelize:** properly handle array operators ([#100](https://github.com/ForestAdmin/agent-nodejs/issues/100)) ([dd061df](https://github.com/ForestAdmin/agent-nodejs/commit/dd061df90bb35b130cd6e98f8de8e321f1a53964))
|
|
84
|
-
* **datasource:** properly set column FilterOperator values ([#117](https://github.com/ForestAdmin/agent-nodejs/issues/117)) ([92174a5](https://github.com/ForestAdmin/agent-nodejs/commit/92174a5f9016e8e54bed854979b0d7c408f11cae))
|
|
85
|
-
* enable npm, git and github distribution ([bd91825](https://github.com/ForestAdmin/agent-nodejs/commit/bd91825f4d185874a259da28b0f7a6c7f557196d))
|
|
86
|
-
* error when count or list does not match any records ([#223](https://github.com/ForestAdmin/agent-nodejs/issues/223)) ([e51dad6](https://github.com/ForestAdmin/agent-nodejs/commit/e51dad6f9fce502405fbd95300f27f7d25945de5))
|
|
87
|
-
* fix semantic release ([3a2fa73](https://github.com/ForestAdmin/agent-nodejs/commit/3a2fa738af84a50b9563db6ac039c922b77f55cc))
|
|
88
|
-
* handle json type and default value ([#237](https://github.com/ForestAdmin/agent-nodejs/issues/237)) ([1e20364](https://github.com/ForestAdmin/agent-nodejs/commit/1e2036455ce9a5376bbe1102d9bbb05f034962f5))
|
|
89
|
-
* select-all when delete-all action is triggered ([#220](https://github.com/ForestAdmin/agent-nodejs/issues/220)) ([23ef123](https://github.com/ForestAdmin/agent-nodejs/commit/23ef1232d56bc250a3a18257de8ed74bdbdf920b))
|
|
90
|
-
* tests were not compiled ([#7](https://github.com/ForestAdmin/agent-nodejs/issues/7)) ([9f2525d](https://github.com/ForestAdmin/agent-nodejs/commit/9f2525dfe6753471b13296899038df27ca1f28be))
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
### Features
|
|
94
|
-
|
|
95
|
-
* add action routes and decorator ([#149](https://github.com/ForestAdmin/agent-nodejs/issues/149)) ([ebf27ff](https://github.com/ForestAdmin/agent-nodejs/commit/ebf27ffb439f5f2c983fe8873a515fe2802a9a17))
|
|
96
|
-
* bootstrap agent package ([#12](https://github.com/ForestAdmin/agent-nodejs/issues/12)) ([182c858](https://github.com/ForestAdmin/agent-nodejs/commit/182c858b6d912dba37fe821cc6baaad75b80c59d))
|
|
97
|
-
* **condition-tree:** implement user filters and better emulation ([#76](https://github.com/ForestAdmin/agent-nodejs/issues/76)) ([e425704](https://github.com/ForestAdmin/agent-nodejs/commit/e4257046853b2b165f4190daa0d953d7f79ed837))
|
|
98
|
-
* **datasource sequelize:** handle date aggregation ([#133](https://github.com/ForestAdmin/agent-nodejs/issues/133)) ([09158a5](https://github.com/ForestAdmin/agent-nodejs/commit/09158a54da2114276d2c7edc9957ea396f700fa0))
|
|
99
|
-
* **datasource sequelize:** handle enum field type ([#193](https://github.com/ForestAdmin/agent-nodejs/issues/193)) ([04cc0f5](https://github.com/ForestAdmin/agent-nodejs/commit/04cc0f528b10f298b08d78e89e8f553b5e1a08e1))
|
|
100
|
-
* **datasource sequelize:** handle isReadOnly property based on autoIncrement ([#194](https://github.com/ForestAdmin/agent-nodejs/issues/194)) ([28b8e69](https://github.com/ForestAdmin/agent-nodejs/commit/28b8e69b363c125bff5f58a199209bda6bf16557))
|
|
101
|
-
* **datasource,live:** initial version for Live DataSource ([#67](https://github.com/ForestAdmin/agent-nodejs/issues/67)) ([e4ffa52](https://github.com/ForestAdmin/agent-nodejs/commit/e4ffa52c0f2146b73522ed705003018b3d4da758))
|
|
102
|
-
* **datasource,sequelize:** handle array types from Sequelize ([#104](https://github.com/ForestAdmin/agent-nodejs/issues/104)) ([58fc4dd](https://github.com/ForestAdmin/agent-nodejs/commit/58fc4dd661d112ce6462357374cc2380a3059292))
|
|
103
|
-
* **datasource,sequelize:** initial version for Sequelize DataSource ([#63](https://github.com/ForestAdmin/agent-nodejs/issues/63)) ([66ba46e](https://github.com/ForestAdmin/agent-nodejs/commit/66ba46e66b73a2611061125a7e14c88283c3489d))
|
|
104
|
-
* **example,live:** update example package to use Live DataSource ([#69](https://github.com/ForestAdmin/agent-nodejs/issues/69)) ([340d2a0](https://github.com/ForestAdmin/agent-nodejs/commit/340d2a08ea945169dd8c7547a5995bb7dd531fc5))
|
|
105
|
-
* implement relations using any unique key ([#159](https://github.com/ForestAdmin/agent-nodejs/issues/159)) ([b6be495](https://github.com/ForestAdmin/agent-nodejs/commit/b6be495d93ae03a67c6dc9b4ffbb0ae9f4cbc0bc))
|