@forestadmin/datasource-customizer 1.4.3 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/collection-customizer.d.ts +1 -1
- package/dist/decorators/decorators-stack.d.ts +2 -2
- package/dist/decorators/decorators-stack.js +3 -3
- package/dist/decorators/hook/context/update.d.ts +1 -1
- package/dist/decorators/hook/context/update.js +2 -2
- package/dist/decorators/write/create-relations/collection.d.ts +9 -0
- package/dist/decorators/write/create-relations/collection.js +73 -0
- package/dist/decorators/write/datasource.d.ts +10 -0
- package/dist/decorators/write/datasource.js +21 -0
- package/dist/decorators/write/update-relations/collection.d.ts +17 -0
- package/dist/decorators/write/update-relations/collection.js +80 -0
- package/dist/decorators/write/write-replace/collection.d.ts +23 -0
- package/dist/decorators/write/write-replace/collection.js +105 -0
- package/dist/decorators/write/{context.d.ts → write-replace/context.d.ts} +2 -2
- package/dist/decorators/write/write-replace/context.js +15 -0
- package/dist/decorators/write/write-replace/types.d.ts +4 -0
- package/dist/decorators/write/{types.js → write-replace/types.js} +1 -1
- package/dist/index.d.ts +1 -1
- package/package.json +1 -1
- package/dist/decorators/write/collection.d.ts +0 -26
- package/dist/decorators/write/collection.js +0 -214
- package/dist/decorators/write/context.js +0 -15
- package/dist/decorators/write/types.d.ts +0 -4
|
@@ -8,7 +8,7 @@ import { HookHandler, HookPosition, HookType, HooksContext } from './decorators/
|
|
|
8
8
|
import { OperatorDefinition } from './decorators/operators-emulate/types';
|
|
9
9
|
import { SearchDefinition } from './decorators/search/types';
|
|
10
10
|
import { SegmentDefinition } from './decorators/segment/types';
|
|
11
|
-
import { WriteDefinition } from './decorators/write/types';
|
|
11
|
+
import { WriteDefinition } from './decorators/write/write-replace/types';
|
|
12
12
|
import { TCollectionName, TColumnName, TFieldName, TSchema, TSortClause } from './templates';
|
|
13
13
|
import { OneToManyEmbeddedDefinition, Plugin } from './types';
|
|
14
14
|
export default class CollectionCustomizer<S extends TSchema = TSchema, N extends TCollectionName<S> = TCollectionName<S>> {
|
|
@@ -13,7 +13,7 @@ import SearchCollectionDecorator from './search/collection';
|
|
|
13
13
|
import SegmentCollectionDecorator from './segment/collection';
|
|
14
14
|
import SortEmulateCollectionDecorator from './sort-emulate/collection';
|
|
15
15
|
import ValidationCollectionDecorator from './validation/collection';
|
|
16
|
-
import
|
|
16
|
+
import WriteDataSourceDecorator from './write/datasource';
|
|
17
17
|
export default class DecoratorsStack {
|
|
18
18
|
action: DataSourceDecorator<ActionCollectionDecorator>;
|
|
19
19
|
chart: ChartDataSourceDecorator;
|
|
@@ -29,7 +29,7 @@ export default class DecoratorsStack {
|
|
|
29
29
|
segment: DataSourceDecorator<SegmentCollectionDecorator>;
|
|
30
30
|
sortEmulate: DataSourceDecorator<SortEmulateCollectionDecorator>;
|
|
31
31
|
validation: DataSourceDecorator<ValidationCollectionDecorator>;
|
|
32
|
-
write:
|
|
32
|
+
write: WriteDataSourceDecorator;
|
|
33
33
|
hook: DataSourceDecorator<HookCollectionDecorator>;
|
|
34
34
|
dataSource: DataSource;
|
|
35
35
|
private customizations;
|
|
@@ -19,7 +19,7 @@ const collection_11 = __importDefault(require("./search/collection"));
|
|
|
19
19
|
const collection_12 = __importDefault(require("./segment/collection"));
|
|
20
20
|
const collection_13 = __importDefault(require("./sort-emulate/collection"));
|
|
21
21
|
const collection_14 = __importDefault(require("./validation/collection"));
|
|
22
|
-
const
|
|
22
|
+
const datasource_2 = __importDefault(require("./write/datasource"));
|
|
23
23
|
class DecoratorsStack {
|
|
24
24
|
constructor(dataSource) {
|
|
25
25
|
this.customizations = [];
|
|
@@ -47,7 +47,7 @@ class DecoratorsStack {
|
|
|
47
47
|
last = this.action = new datasource_decorator_1.default(last, collection_1.default);
|
|
48
48
|
last = this.schema = new datasource_decorator_1.default(last, collection_10.default);
|
|
49
49
|
last = this.validation = new datasource_decorator_1.default(last, collection_14.default);
|
|
50
|
-
last = this.write = new
|
|
50
|
+
last = this.write = new datasource_2.default(last);
|
|
51
51
|
last = this.hook = new datasource_decorator_1.default(last, collection_4.default);
|
|
52
52
|
// Step 4: Renaming must be either the very first or very last so that naming in customer code
|
|
53
53
|
// is consistent.
|
|
@@ -76,4 +76,4 @@ class DecoratorsStack {
|
|
|
76
76
|
}
|
|
77
77
|
}
|
|
78
78
|
exports.default = DecoratorsStack;
|
|
79
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
79
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVjb3JhdG9ycy1zdGFjay5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9kZWNvcmF0b3JzL2RlY29yYXRvcnMtc3RhY2sudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFFQSxzRUFBNkQ7QUFDN0Qsb0VBQTBEO0FBQzFELHVFQUFnRTtBQUNoRSxrRkFBeUQ7QUFDekQsb0VBQTBEO0FBQzFELG1FQUF3RDtBQUN4RCxnRkFBaUY7QUFDakYsb0ZBQXlGO0FBQ3pGLGdGQUFpRjtBQUNqRix1RUFBZ0U7QUFDaEUsMkVBQXVFO0FBQ3ZFLHNFQUE0RDtBQUM1RCxzRUFBNEQ7QUFDNUQsdUVBQThEO0FBQzlELDRFQUF1RTtBQUN2RSwwRUFBb0U7QUFDcEUsb0VBQTBEO0FBRTFELE1BQXFCLGVBQWU7SUFxQmxDLFlBQVksVUFBc0I7UUFGMUIsbUJBQWMsR0FBNkMsRUFBRSxDQUFDO1FBR3BFLElBQUksSUFBSSxHQUFlLFVBQVUsQ0FBQztRQUVsQyxvQ0FBb0M7UUFDcEMsbUZBQW1GO1FBQ25GLElBQUksR0FBRyxJQUFJLDhCQUFtQixDQUFDLElBQUksRUFBRSxvQkFBd0IsQ0FBQyxDQUFDO1FBQy9ELElBQUksR0FBRyxJQUFJLDhCQUFtQixDQUFDLElBQUksRUFBRSxvQkFBdUMsQ0FBQyxDQUFDO1FBRTlFLDZGQUE2RjtRQUM3RixzRUFBc0U7UUFDdEUsMkZBQTJGO1FBQzNGLElBQUksR0FBRyxJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksOEJBQW1CLENBQUMsSUFBSSxFQUFFLG9CQUEyQixDQUFDLENBQUM7UUFDdkYsSUFBSSxHQUFHLElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSw4QkFBbUIsQ0FBQyxJQUFJLEVBQUUsb0JBQW1DLENBQUMsQ0FBQztRQUNoRyxJQUFJLEdBQUcsSUFBSSw4QkFBbUIsQ0FBQyxJQUFJLEVBQUUsb0JBQXVDLENBQUMsQ0FBQztRQUM5RSxJQUFJLEdBQUcsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJ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
|
|
@@ -6,7 +6,7 @@ export declare class HookBeforeUpdateContext<S extends TSchema = TSchema, N exte
|
|
|
6
6
|
protected _patch: RecordData;
|
|
7
7
|
constructor(collection: Collection, caller: Caller, filter: Filter, patch: RecordData);
|
|
8
8
|
get filter(): Readonly<TFilter<S, N>>;
|
|
9
|
-
get patch():
|
|
9
|
+
get patch(): TRow<S, N>;
|
|
10
10
|
}
|
|
11
11
|
export declare class InternalHookBeforeUpdateContext extends HookBeforeUpdateContext {
|
|
12
12
|
getFilter(): Filter;
|
|
@@ -15,7 +15,7 @@ class HookBeforeUpdateContext extends hook_1.default {
|
|
|
15
15
|
return Object.freeze(this._filter);
|
|
16
16
|
}
|
|
17
17
|
get patch() {
|
|
18
|
-
return
|
|
18
|
+
return this._patch;
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
21
|
exports.HookBeforeUpdateContext = HookBeforeUpdateContext;
|
|
@@ -28,4 +28,4 @@ exports.InternalHookBeforeUpdateContext = InternalHookBeforeUpdateContext;
|
|
|
28
28
|
class HookAfterUpdateContext extends HookBeforeUpdateContext {
|
|
29
29
|
}
|
|
30
30
|
exports.HookAfterUpdateContext = HookAfterUpdateContext;
|
|
31
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
31
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXBkYXRlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2RlY29yYXRvcnMvaG9vay9jb250ZXh0L3VwZGF0ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFJQSxrREFBaUM7QUFFakMsTUFBYSx1QkFHWCxTQUFRLGNBQWlCO0lBSXpCLFlBQVksVUFBc0IsRUFBRSxNQUFjLEVBQUUsTUFBYyxFQUFFLEtBQWlCO1FBQ25GLEtBQUssQ0FBQyxVQUFVLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFFMUIsSUFBSSxDQUFDLE9BQU8sR0FBRyxNQUFNLENBQUM7UUFDdEIsSUFBSSxDQUFDLE1BQU0sR0FBRyxLQUFLLENBQUM7SUFDdEIsQ0FBQztJQUVELElBQUksTUFBTTtRQUNSLE9BQU8sTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBbUMsQ0FBQyxDQUFDO0lBQ2pFLENBQUM7SUFFRCxJQUFJLEtBQUs7UUFDUCxPQUFPLElBQUksQ0FBQyxNQUFNLENBQUM7SUFDckIsQ0FBQztDQUNGO0FBckJELDBEQXFCQztBQUVELE1BQWEsK0JBQWdDLFNBQVEsdUJBQXVCO0lBQzFFLFNBQVM7UUFDUCxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUM7SUFDdEIsQ0FBQztDQUNGO0FBSkQsMEVBSUM7QUFFRCxNQUFhLHNCQUdYLFNBQVEsdUJBQTZCO0NBQUc7QUFIMUMsd0RBRzBDIn0=
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Caller, RecordData } from '@forestadmin/datasource-toolkit';
|
|
2
|
+
import CollectionDecorator from '../../collection-decorator';
|
|
3
|
+
export default class CreateRelationsCollectionDecorator extends CollectionDecorator {
|
|
4
|
+
create(caller: Caller, records: RecordData[]): Promise<RecordData[]>;
|
|
5
|
+
private extractRelations;
|
|
6
|
+
private createManyToOneRelation;
|
|
7
|
+
private createOneToOneRelation;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=collection.d.ts.map
|
|
@@ -0,0 +1,73 @@
|
|
|
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 datasource_toolkit_1 = require("@forestadmin/datasource-toolkit");
|
|
7
|
+
const collection_decorator_1 = __importDefault(require("../../collection-decorator"));
|
|
8
|
+
class CreateRelationsCollectionDecorator extends collection_decorator_1.default {
|
|
9
|
+
async create(caller, records) {
|
|
10
|
+
// Step 1: Remove all relations from records, and store them in a map
|
|
11
|
+
// Note: the extractRelations method modifies the records array in place!
|
|
12
|
+
const recordsByRelation = this.extractRelations(records);
|
|
13
|
+
// Step 2: Create the many-to-one relations, and put the foreign keys in the records
|
|
14
|
+
await Promise.all(Object.entries(recordsByRelation)
|
|
15
|
+
.filter(([key]) => this.schema.fields[key].type === 'ManyToOne')
|
|
16
|
+
.map(([key, entries]) => this.createManyToOneRelation(caller, records, key, entries)));
|
|
17
|
+
// Step 3: Create the records
|
|
18
|
+
const recordsWithPk = await this.childCollection.create(caller, records);
|
|
19
|
+
// Step 4: Create the one-to-one relations
|
|
20
|
+
// Note: the createOneToOneRelation method modifies the recordsWithPk array in place!
|
|
21
|
+
await Promise.all(Object.entries(recordsByRelation)
|
|
22
|
+
.filter(([key]) => this.schema.fields[key].type === 'OneToOne')
|
|
23
|
+
.map(([key, entries]) => this.createOneToOneRelation(caller, recordsWithPk, key, entries)));
|
|
24
|
+
return recordsWithPk;
|
|
25
|
+
}
|
|
26
|
+
extractRelations(records) {
|
|
27
|
+
const recordsByRelation = {};
|
|
28
|
+
for (const [index, record] of records.entries()) {
|
|
29
|
+
for (const [key, subRecord] of Object.entries(record)) {
|
|
30
|
+
if (this.schema.fields[key].type !== 'Column') {
|
|
31
|
+
recordsByRelation[key] ?? (recordsByRelation[key] = []);
|
|
32
|
+
recordsByRelation[key].push({ subRecord, index });
|
|
33
|
+
delete record[key];
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return recordsByRelation;
|
|
38
|
+
}
|
|
39
|
+
async createManyToOneRelation(caller, records, key, entries) {
|
|
40
|
+
const schema = this.schema.fields[key];
|
|
41
|
+
const relation = this.dataSource.getCollection(schema.foreignCollection);
|
|
42
|
+
const creations = entries.filter(({ index }) => !records[index][schema.foreignKey]);
|
|
43
|
+
const updates = entries.filter(({ index }) => records[index][schema.foreignKey]);
|
|
44
|
+
// Create the relations when the fk is not present
|
|
45
|
+
if (creations.length) {
|
|
46
|
+
// Not sure which behavior is better (we'll go with the first option for now):
|
|
47
|
+
// - create a new record for each record in the original create request
|
|
48
|
+
// - use object-hash to create a single record for each unique subRecord
|
|
49
|
+
const subRecords = creations.map(({ subRecord }) => subRecord);
|
|
50
|
+
const relatedRecords = await relation.create(caller, subRecords);
|
|
51
|
+
for (const { index } of creations)
|
|
52
|
+
records[index][schema.foreignKey] = relatedRecords[index][schema.foreignKeyTarget];
|
|
53
|
+
}
|
|
54
|
+
// Update the relations when the fk is present
|
|
55
|
+
await Promise.all(updates.map(async ({ index, subRecord }) => {
|
|
56
|
+
const value = records[index][schema.foreignKey];
|
|
57
|
+
const conditionTree = new datasource_toolkit_1.ConditionTreeLeaf(schema.foreignKeyTarget, 'Equal', value);
|
|
58
|
+
return relation.update(caller, new datasource_toolkit_1.Filter({ conditionTree }), subRecord);
|
|
59
|
+
}));
|
|
60
|
+
}
|
|
61
|
+
async createOneToOneRelation(caller, records, key, entries) {
|
|
62
|
+
const schema = this.schema.fields[key];
|
|
63
|
+
const relation = this.dataSource.getCollection(schema.foreignCollection);
|
|
64
|
+
// Set origin key in the related record
|
|
65
|
+
const subRecords = entries.map(({ index, subRecord }) => ({
|
|
66
|
+
...subRecord,
|
|
67
|
+
[schema.originKey]: records[index][schema.originKeyTarget],
|
|
68
|
+
}));
|
|
69
|
+
await relation.create(caller, subRecords);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
exports.default = CreateRelationsCollectionDecorator;
|
|
73
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29sbGVjdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9kZWNvcmF0b3JzL3dyaXRlL2NyZWF0ZS1yZWxhdGlvbnMvY29sbGVjdGlvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLHdFQU95QztBQUV6QyxzRkFBNkQ7QUFJN0QsTUFBcUIsa0NBQW1DLFNBQVEsOEJBQW1CO0lBQ3hFLEtBQUssQ0FBQyxNQUFNLENBQUMsTUFBYyxFQUFFLE9BQXFCO1FBQ3pELHFFQUFxRTtRQUNyRSx5RUFBeUU7UUFDekUsTUFBTSxpQkFBaUIsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxDQUFDLENBQUM7UUFFekQsb0ZBQW9GO1FBQ3BGLE1BQU0sT0FBTyxDQUFDLEdBQUcsQ0FDZixNQUFNLENBQUMsT0FBTyxDQUFDLGlCQUFpQixDQUFDO2FBQzlCLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksS0FBSyxXQUFXLENBQUM7YUFDL0QsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsT0FBTyxDQUFDLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxNQUFNLEVBQUUsT0FBTyxFQUFFLEdBQUcsRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUN4RixDQUFDO1FBRUYsNkJBQTZCO1FBQzdCLE1BQU0sYUFBYSxHQUFHLE1BQU0sSUFBSSxDQUFDLGVBQWUsQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBRXpFLDBDQUEwQztRQUMxQyxxRkFBcUY7UUFDckYsTUFBTSxPQUFPLENBQUMsR0FBRyxDQUNmLE1BQU0sQ0FBQyxPQUFPLENBQUMsaUJBQWlCLENBQUM7YUFDOUIsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFF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
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { DataSource } from '@forestadmin/datasource-toolkit';
|
|
2
|
+
import DataSourceDecorator from '../datasource-decorator';
|
|
3
|
+
import WriteReplacerCollectionDecorator from './write-replace/collection';
|
|
4
|
+
/**
|
|
5
|
+
* Decorator which allows to change the behavior of the write actions for given fields.
|
|
6
|
+
*/
|
|
7
|
+
export default class WriteDataSourceDecorator extends DataSourceDecorator<WriteReplacerCollectionDecorator> {
|
|
8
|
+
constructor(childDataSource: DataSource);
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=datasource.d.ts.map
|
|
@@ -0,0 +1,21 @@
|
|
|
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 datasource_decorator_1 = __importDefault(require("../datasource-decorator"));
|
|
7
|
+
const collection_1 = __importDefault(require("./create-relations/collection"));
|
|
8
|
+
const collection_2 = __importDefault(require("./update-relations/collection"));
|
|
9
|
+
const collection_3 = __importDefault(require("./write-replace/collection"));
|
|
10
|
+
/**
|
|
11
|
+
* Decorator which allows to change the behavior of the write actions for given fields.
|
|
12
|
+
*/
|
|
13
|
+
class WriteDataSourceDecorator extends datasource_decorator_1.default {
|
|
14
|
+
constructor(childDataSource) {
|
|
15
|
+
const create = new datasource_decorator_1.default(childDataSource, collection_1.default);
|
|
16
|
+
const update = new datasource_decorator_1.default(create, collection_2.default);
|
|
17
|
+
super(update, collection_3.default);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
exports.default = WriteDataSourceDecorator;
|
|
21
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0YXNvdXJjZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9kZWNvcmF0b3JzL3dyaXRlL2RhdGFzb3VyY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFFQSxtRkFBMEQ7QUFDMUQsK0VBQStFO0FBQy9FLCtFQUErRTtBQUMvRSw0RUFBMEU7QUFFMUU7O0dBRUc7QUFDSCxNQUFxQix3QkFBeUIsU0FBUSw4QkFBcUQ7SUFDekcsWUFBWSxlQUEyQjtRQUNyQyxNQUFNLE1BQU0sR0FBRyxJQUFJLDhCQUFtQixDQUFDLGVBQWUsRUFBRSxvQkFBa0MsQ0FBQyxDQUFDO1FBQzVGLE1BQU0sTUFBTSxHQUFHLElBQUksOEJBQW1CLENBQUMsTUFBTSxFQUFFLG9CQUFrQyxDQUFDLENBQUM7UUFDbkYsS0FBSyxDQUFDLE1BQU0sRUFBRSxvQkFBZ0MsQ0FBQyxDQUFDO0lBQ2xELENBQUM7Q0FDRjtBQU5ELDJDQU1DIn0=
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Caller, Filter, RecordData } from '@forestadmin/datasource-toolkit';
|
|
2
|
+
import CollectionDecorator from '../../collection-decorator';
|
|
3
|
+
export default class UpdateRelationCollectionDecorator extends CollectionDecorator {
|
|
4
|
+
update(caller: Caller, filter: Filter, patch: RecordData): Promise<void>;
|
|
5
|
+
/**
|
|
6
|
+
* Build a projection that has enough information to know
|
|
7
|
+
* - which relations need to be created/updated
|
|
8
|
+
* - the values that will be used to build filters to target records
|
|
9
|
+
* - the values that will be used to create/update the relations
|
|
10
|
+
*/
|
|
11
|
+
private buildProjection;
|
|
12
|
+
/**
|
|
13
|
+
* Create or update the relation provided in the key parameter according to the patch.
|
|
14
|
+
*/
|
|
15
|
+
private createOrUpdateRelation;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=collection.d.ts.map
|
|
@@ -0,0 +1,80 @@
|
|
|
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 datasource_toolkit_1 = require("@forestadmin/datasource-toolkit");
|
|
7
|
+
const collection_decorator_1 = __importDefault(require("../../collection-decorator"));
|
|
8
|
+
class UpdateRelationCollectionDecorator extends collection_decorator_1.default {
|
|
9
|
+
async update(caller, filter, patch) {
|
|
10
|
+
// Step 1: Perform the normal update
|
|
11
|
+
if (Object.keys(patch).some(key => this.schema.fields[key].type === 'Column')) {
|
|
12
|
+
const patchWithoutRelations = Object.keys(patch).reduce((memo, key) => {
|
|
13
|
+
return this.schema.fields[key].type === 'Column' ? { ...memo, [key]: patch[key] } : memo;
|
|
14
|
+
}, {});
|
|
15
|
+
await this.childCollection.update(caller, filter, patchWithoutRelations);
|
|
16
|
+
}
|
|
17
|
+
// Step 2: Perform additional updates for relations
|
|
18
|
+
if (Object.keys(patch).some(key => this.schema.fields[key].type !== 'Column')) {
|
|
19
|
+
// Fetch the records that will be updated, to know which relations need to be created/updated
|
|
20
|
+
const projection = this.buildProjection(patch);
|
|
21
|
+
const records = await this.list(caller, filter, projection);
|
|
22
|
+
// Perform the updates for each relation
|
|
23
|
+
await Promise.all(Object.keys(patch)
|
|
24
|
+
.filter(key => this.schema.fields[key].type !== 'Column')
|
|
25
|
+
.map(key => this.createOrUpdateRelation(caller, records, key, patch[key])));
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Build a projection that has enough information to know
|
|
30
|
+
* - which relations need to be created/updated
|
|
31
|
+
* - the values that will be used to build filters to target records
|
|
32
|
+
* - the values that will be used to create/update the relations
|
|
33
|
+
*/
|
|
34
|
+
buildProjection(patch) {
|
|
35
|
+
let projection = new datasource_toolkit_1.Projection().withPks(this);
|
|
36
|
+
for (const key of Object.keys(patch)) {
|
|
37
|
+
const schema = this.schema.fields[key];
|
|
38
|
+
if (schema.type !== 'Column') {
|
|
39
|
+
const relation = this.dataSource.getCollection(schema.foreignCollection);
|
|
40
|
+
projection = projection.union(new datasource_toolkit_1.Projection().withPks(relation).nest(key));
|
|
41
|
+
if (schema.type === 'ManyToOne')
|
|
42
|
+
projection = projection.union(new datasource_toolkit_1.Projection(schema.foreignKeyTarget).nest(key));
|
|
43
|
+
if (schema.type === 'OneToOne')
|
|
44
|
+
projection = projection.union(new datasource_toolkit_1.Projection(schema.originKeyTarget));
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return projection;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Create or update the relation provided in the key parameter according to the patch.
|
|
51
|
+
*/
|
|
52
|
+
async createOrUpdateRelation(caller, records, key, patch) {
|
|
53
|
+
const schema = this.schema.fields[key];
|
|
54
|
+
const relation = this.dataSource.getCollection(schema.foreignCollection);
|
|
55
|
+
const creates = records.filter(r => r[key] === null);
|
|
56
|
+
const updates = records.filter(r => r[key] !== null);
|
|
57
|
+
if (creates.length > 0) {
|
|
58
|
+
if (schema.type === 'ManyToOne') {
|
|
59
|
+
// Create many-to-one relations
|
|
60
|
+
const [subRecord] = await relation.create(caller, [patch]);
|
|
61
|
+
// Set foreign key on the parent records
|
|
62
|
+
const conditionTree = datasource_toolkit_1.ConditionTreeFactory.matchRecords(this.schema, creates);
|
|
63
|
+
const parentPatch = { [schema.foreignKey]: subRecord[schema.foreignKeyTarget] };
|
|
64
|
+
await this.update(caller, new datasource_toolkit_1.Filter({ conditionTree }), parentPatch);
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
// Create the one-to-one relations that don't already exist
|
|
68
|
+
await relation.create(caller, creates.map(record => ({ ...patch, [schema.originKey]: record[schema.originKeyTarget] })));
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
// Update the relations that already exist
|
|
72
|
+
if (updates.length > 0) {
|
|
73
|
+
const subRecords = updates.map(record => record[key]);
|
|
74
|
+
const conditionTree = datasource_toolkit_1.ConditionTreeFactory.matchRecords(relation.schema, subRecords);
|
|
75
|
+
await relation.update(caller, new datasource_toolkit_1.Filter({ conditionTree }), patch);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
exports.default = UpdateRelationCollectionDecorator;
|
|
80
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29sbGVjdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9kZWNvcmF0b3JzL3dyaXRlL3VwZGF0ZS1yZWxhdGlvbnMvY29sbGVjdGlvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLHdFQVF5QztBQUV6QyxzRkFBNkQ7QUFFN0QsTUFBcUIsaUNBQWtDLFNBQVEsOEJBQW1CO0lBQ3ZFLEtBQUssQ0FBQyxNQUFNLENBQUMsTUFBYyxFQUFFLE1BQWMsRUFBRSxLQUFpQjtRQUNyRSxvQ0FBb0M7UUFDcEMsSUFBSSxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksS0FBSyxRQUFRLENBQUMsRUFBRTtZQUM3RSxNQUFNLHFCQUFxQixHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxFQUFFLEdBQUcsRUFBRSxFQUFFO2dCQUNwRSxPQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksS0FBSyxRQUFRLENBQUMsQ0FBQyxDQUFDLEVBQUUsR0FBRyxJQUFJLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxLQUFLLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO1lBQzNGLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztZQUVQLE1BQU0sSUFBSSxDQUFDLGVBQWUsQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFFLE1BQU0sRUFBRSxxQkFBcUIsQ0FBQyxDQUFDO1NBQzFFO1FBRUQsbURBQW1EO1FBQ25ELElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FB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
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Caller, CollectionSchema, Filter, RecordData } from '@forestadmin/datasource-toolkit';
|
|
2
|
+
import CollectionDecorator from '../../collection-decorator';
|
|
3
|
+
import DataSourceDecorator from '../../datasource-decorator';
|
|
4
|
+
import { WriteDefinition } from './types';
|
|
5
|
+
export default class WriteReplacerCollectionDecorator extends CollectionDecorator {
|
|
6
|
+
private handlers;
|
|
7
|
+
readonly dataSource: DataSourceDecorator<WriteReplacerCollectionDecorator>;
|
|
8
|
+
replaceFieldWriting(fieldName: string, definition: WriteDefinition): void;
|
|
9
|
+
protected refineSchema(childSchema: CollectionSchema): CollectionSchema;
|
|
10
|
+
create(caller: Caller, records: RecordData[]): Promise<RecordData[]>;
|
|
11
|
+
update(caller: Caller, filter: Filter, patch: RecordData): Promise<void>;
|
|
12
|
+
/**
|
|
13
|
+
* Takes a patch and recursively applies all rewriting rules to it.
|
|
14
|
+
*/
|
|
15
|
+
private rewritePatch;
|
|
16
|
+
private rewriteKey;
|
|
17
|
+
/**
|
|
18
|
+
* Recursively merge patches into a single one ensuring that there is no conflict.
|
|
19
|
+
*/
|
|
20
|
+
private deepMerge;
|
|
21
|
+
private isObject;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=collection.d.ts.map
|
|
@@ -0,0 +1,105 @@
|
|
|
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 datasource_toolkit_1 = require("@forestadmin/datasource-toolkit");
|
|
7
|
+
const collection_decorator_1 = __importDefault(require("../../collection-decorator"));
|
|
8
|
+
const context_1 = __importDefault(require("./context"));
|
|
9
|
+
class WriteReplacerCollectionDecorator extends collection_decorator_1.default {
|
|
10
|
+
constructor() {
|
|
11
|
+
super(...arguments);
|
|
12
|
+
this.handlers = {};
|
|
13
|
+
}
|
|
14
|
+
replaceFieldWriting(fieldName, definition) {
|
|
15
|
+
if (!Object.keys(this.schema.fields).includes(fieldName)) {
|
|
16
|
+
throw new Error(`The given field "${fieldName}" does not exist on the ${this.name} collection.`);
|
|
17
|
+
}
|
|
18
|
+
this.handlers[fieldName] = definition;
|
|
19
|
+
this.markSchemaAsDirty();
|
|
20
|
+
}
|
|
21
|
+
refineSchema(childSchema) {
|
|
22
|
+
const schema = { ...childSchema, fields: { ...childSchema.fields } };
|
|
23
|
+
for (const [fieldName, handler] of Object.entries(this.handlers)) {
|
|
24
|
+
schema.fields[fieldName] = {
|
|
25
|
+
...schema.fields[fieldName],
|
|
26
|
+
isReadOnly: handler === null,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
return schema;
|
|
30
|
+
}
|
|
31
|
+
async create(caller, records) {
|
|
32
|
+
const promises = records.map(record => this.rewritePatch(caller, 'create', record));
|
|
33
|
+
const newRecords = await Promise.all(promises);
|
|
34
|
+
return this.childCollection.create(caller, newRecords);
|
|
35
|
+
}
|
|
36
|
+
async update(caller, filter, patch) {
|
|
37
|
+
const newPatch = await this.rewritePatch(caller, 'update', patch);
|
|
38
|
+
return this.childCollection.update(caller, filter, newPatch);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Takes a patch and recursively applies all rewriting rules to it.
|
|
42
|
+
*/
|
|
43
|
+
async rewritePatch(caller, action, patch, usedHandlers = []) {
|
|
44
|
+
// We rewrite the patch by applying all handlers on each field.
|
|
45
|
+
const context = new context_1.default(this, caller, action, patch);
|
|
46
|
+
const patches = await Promise.all(Object.keys(patch).map(key => this.rewriteKey(context, key, usedHandlers)));
|
|
47
|
+
// We now have a list of patches (one per field) that we can merge.
|
|
48
|
+
const newPatch = this.deepMerge(...patches);
|
|
49
|
+
// Check that the customer handlers did not introduce invalid data.
|
|
50
|
+
if (Object.keys(newPatch).length > 0)
|
|
51
|
+
datasource_toolkit_1.RecordValidator.validate(this, newPatch);
|
|
52
|
+
return newPatch;
|
|
53
|
+
}
|
|
54
|
+
async rewriteKey(context, key, used) {
|
|
55
|
+
// Guard against infinite recursion.
|
|
56
|
+
if (used.includes(key))
|
|
57
|
+
throw new Error(`Cycle detected: ${used.join(' -> ')}.`);
|
|
58
|
+
const { record, action, caller } = context;
|
|
59
|
+
const schema = this.schema.fields[key];
|
|
60
|
+
// Handle Column fields.
|
|
61
|
+
if (schema?.type === 'Column') {
|
|
62
|
+
// We either call the customer handler or a default one that does nothing.
|
|
63
|
+
const handler = this.handlers[key] ?? (v => ({ [key]: v }));
|
|
64
|
+
const fieldPatch = ((await handler(record[key], context)) ?? {});
|
|
65
|
+
if (fieldPatch && !this.isObject(fieldPatch))
|
|
66
|
+
throw new Error(`The write handler of ${key} should return an object or nothing.`);
|
|
67
|
+
// Isolate change to our own value (which should not recurse) and the rest which should
|
|
68
|
+
// trigger the other handlers.
|
|
69
|
+
const { [key]: value, ...recursionPatch } = fieldPatch;
|
|
70
|
+
const newPatch = await this.rewritePatch(caller, action, recursionPatch, [...used, key]);
|
|
71
|
+
return value !== undefined ? this.deepMerge({ [key]: value }, newPatch) : newPatch;
|
|
72
|
+
}
|
|
73
|
+
// Handle relation fields.
|
|
74
|
+
if (schema?.type === 'ManyToOne' || schema?.type === 'OneToOne') {
|
|
75
|
+
// Delegate relations to the appropriate collection.
|
|
76
|
+
const relation = this.dataSource.getCollection(schema.foreignCollection);
|
|
77
|
+
return { [key]: await relation.rewritePatch(caller, action, record[key]) };
|
|
78
|
+
}
|
|
79
|
+
throw new Error(`Unknown field: "${key}"`);
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Recursively merge patches into a single one ensuring that there is no conflict.
|
|
83
|
+
*/
|
|
84
|
+
deepMerge(...patches) {
|
|
85
|
+
const acc = {};
|
|
86
|
+
for (const patch of patches) {
|
|
87
|
+
for (const [key, value] of Object.entries(patch)) {
|
|
88
|
+
// We could check that this is a relation field but we choose to only check for objects
|
|
89
|
+
// to allow customers to use this for JSON fields.
|
|
90
|
+
if (acc[key] === undefined)
|
|
91
|
+
acc[key] = value;
|
|
92
|
+
else if (this.isObject(value))
|
|
93
|
+
acc[key] = this.deepMerge(acc[key], value);
|
|
94
|
+
else
|
|
95
|
+
throw new Error(`Conflict value on the field "${key}". It received several values.`);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return acc;
|
|
99
|
+
}
|
|
100
|
+
isObject(value) {
|
|
101
|
+
return value && typeof value === 'object' && Object.getPrototypeOf(value) === Object.prototype;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
exports.default = WriteReplacerCollectionDecorator;
|
|
105
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29sbGVjdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9kZWNvcmF0b3JzL3dyaXRlL3dyaXRlLXJlcGxhY2UvY29sbGVjdGlvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLHdFQU95QztBQUV6QyxzRkFBNkQ7QUFFN0Qsd0RBQWtEO0FBR2xELE1BQXFCLGdDQUFpQyxTQUFRLDhCQUFtQjtJQUFqRjs7UUFDVSxhQUFRLEdBQW9DLEVBQUUsQ0FBQztJQTZIekQsQ0FBQztJQTFIQyxtQkFBbUIsQ0FBQyxTQUFpQixFQUFFLFVBQTJCO1FBQ2hFLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxFQUFFO1lBQ3hELE1BQU0sSUFBSSxLQUFLLENBQ2Isb0JBQW9CLFNBQVMsMkJBQTJCLElBQUksQ0FBQyxJQUFJLGNBQWMsQ0FDaEYsQ0FBQztTQUNIO1FBRUQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsR0FBRyxVQUFVLENBQUM7UUFDdEMsSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7SUFDM0IsQ0FBQztJQUVrQixZQUFZLENBQUMsV0FBNkI7UUFDM0QsTUFBTSxNQUFNLEdBQUcsRUFBRSxHQUFHLFdBQVcsRUFBRSxNQUFNLEVBQUUsRUFBRSxHQUFHLFdBQVcsQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDO1FBRXJFLEtBQUssTUFBTSxDQUFDLFNBQVMsRUFBRSxPQUFPLENBQUMsSUFBSSxNQUFNLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRTtZQUNoRSxNQUFNLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxHQUFHO2dCQUN6QixHQUFJLE1BQU0sQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFrQjtnQkFDN0MsVUFBVSxFQUFFLE9BQU8sS0FBSyxJQUFJO2FBQzdC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
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Caller, Collection } from '@forestadmin/datasource-toolkit';
|
|
2
|
-
import CollectionCustomizationContext from '
|
|
3
|
-
import { TCollectionName, TPartialSimpleRow, TSchema } from '
|
|
2
|
+
import CollectionCustomizationContext from '../../../context/collection-context';
|
|
3
|
+
import { TCollectionName, TPartialSimpleRow, TSchema } from '../../../templates';
|
|
4
4
|
export default class WriteCustomizationContext<S extends TSchema = TSchema, N extends TCollectionName<S> = TCollectionName<S>> extends CollectionCustomizationContext<S, N> {
|
|
5
5
|
readonly action: 'update' | 'create';
|
|
6
6
|
readonly record: TPartialSimpleRow<S, N>;
|
|
@@ -0,0 +1,15 @@
|
|
|
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 collection_context_1 = __importDefault(require("../../../context/collection-context"));
|
|
7
|
+
class WriteCustomizationContext extends collection_context_1.default {
|
|
8
|
+
constructor(collection, caller, action, record) {
|
|
9
|
+
super(collection, caller);
|
|
10
|
+
this.action = action;
|
|
11
|
+
this.record = Object.freeze({ ...record });
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
exports.default = WriteCustomizationContext;
|
|
15
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29udGV4dC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9kZWNvcmF0b3JzL3dyaXRlL3dyaXRlLXJlcGxhY2UvY29udGV4dC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUVBLDZGQUFpRjtBQUdqRixNQUFxQix5QkFHbkIsU0FBUSw0QkFBb0M7SUFJNUMsWUFDRSxVQUFzQixFQUN0QixNQUFjLEVBQ2QsTUFBMkIsRUFDM0IsTUFBK0I7UUFFL0IsS0FBSyxDQUFDLFVBQVUsRUFBRSxNQUFNLENBQUMsQ0FBQztRQUUxQixJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztRQUNyQixJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsRUFBRSxHQUFHLE1BQU0sRUFBRSxDQUFDLENBQUM7SUFDN0MsQ0FBQztDQUNGO0FBbEJELDRDQWtCQyJ9
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { TCollectionName, TFieldName, TFieldType, TPartialRow, TSchema } from '../../../templates';
|
|
2
|
+
import WriteCustomizationContext from './context';
|
|
3
|
+
export declare type WriteDefinition<S extends TSchema = TSchema, N extends TCollectionName<S> = TCollectionName<S>, C extends TFieldName<S, N> = TFieldName<S, N>> = null | ((value: TFieldType<S, N, C>, context: WriteCustomizationContext<S, N>) => Promise<TPartialRow<S, N> | void> | TPartialRow<S, N> | void);
|
|
4
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
3
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvZGVjb3JhdG9ycy93cml0ZS93cml0ZS1yZXBsYWNlL3R5cGVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiIifQ==
|
package/dist/index.d.ts
CHANGED
|
@@ -9,7 +9,7 @@ export { OperatorDefinition } from './decorators/operators-emulate/types';
|
|
|
9
9
|
export { RelationDefinition } from './decorators/relation/types';
|
|
10
10
|
export { SearchDefinition } from './decorators/search/types';
|
|
11
11
|
export { SegmentDefinition } from './decorators/segment/types';
|
|
12
|
-
export { WriteDefinition } from './decorators/write/types';
|
|
12
|
+
export { WriteDefinition } from './decorators/write/write-replace/types';
|
|
13
13
|
export * from './decorators/hook/types';
|
|
14
14
|
export { default as CollectionCustomizationContext } from './context/collection-context';
|
|
15
15
|
//# sourceMappingURL=index.d.ts.map
|
package/package.json
CHANGED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { Caller, CollectionSchema, Filter, RecordData } from '@forestadmin/datasource-toolkit';
|
|
2
|
-
import CollectionDecorator from '../collection-decorator';
|
|
3
|
-
import DataSourceDecorator from '../datasource-decorator';
|
|
4
|
-
import { WriteDefinition } from './types';
|
|
5
|
-
export default class WriteDecorator extends CollectionDecorator {
|
|
6
|
-
private replacedDefinitions;
|
|
7
|
-
readonly dataSource: DataSourceDecorator<WriteDecorator>;
|
|
8
|
-
replaceFieldWriting(fieldName: string, definition: WriteDefinition): void;
|
|
9
|
-
protected refineSchema(childSchema: CollectionSchema): CollectionSchema;
|
|
10
|
-
create(caller: Caller, data: RecordData[]): Promise<RecordData[]>;
|
|
11
|
-
update(caller: Caller, filter: Filter, patch: RecordData): Promise<void>;
|
|
12
|
-
private applyDefinitionsAndCreate;
|
|
13
|
-
private applyDefinitionsAndUpdate;
|
|
14
|
-
private createRecord;
|
|
15
|
-
private createOneToOneRelations;
|
|
16
|
-
private createManyToOneRelations;
|
|
17
|
-
private updateAllRelations;
|
|
18
|
-
private getImpactedRecordByUpdate;
|
|
19
|
-
private applyDefinitions;
|
|
20
|
-
private getReplacedDefinitionsColumns;
|
|
21
|
-
private getDefinitionResults;
|
|
22
|
-
private static checkCyclicDependency;
|
|
23
|
-
private getRelationFields;
|
|
24
|
-
private getPatchWithoutRelations;
|
|
25
|
-
}
|
|
26
|
-
//# sourceMappingURL=collection.d.ts.map
|
|
@@ -1,214 +0,0 @@
|
|
|
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 datasource_toolkit_1 = require("@forestadmin/datasource-toolkit");
|
|
7
|
-
const collection_decorator_1 = __importDefault(require("../collection-decorator"));
|
|
8
|
-
const context_1 = __importDefault(require("./context"));
|
|
9
|
-
class WriteDecorator extends collection_decorator_1.default {
|
|
10
|
-
constructor() {
|
|
11
|
-
super(...arguments);
|
|
12
|
-
this.replacedDefinitions = {};
|
|
13
|
-
}
|
|
14
|
-
replaceFieldWriting(fieldName, definition) {
|
|
15
|
-
if (!Object.keys(this.schema.fields).includes(fieldName)) {
|
|
16
|
-
throw new Error(`The given field "${fieldName}" does not exist on the ${this.name} collection.`);
|
|
17
|
-
}
|
|
18
|
-
this.replacedDefinitions[fieldName] = definition;
|
|
19
|
-
this.markSchemaAsDirty();
|
|
20
|
-
}
|
|
21
|
-
refineSchema(childSchema) {
|
|
22
|
-
const schema = { ...childSchema, fields: { ...childSchema.fields } };
|
|
23
|
-
for (const name of Object.keys(this.replacedDefinitions)) {
|
|
24
|
-
schema.fields[name].isReadOnly = false;
|
|
25
|
-
}
|
|
26
|
-
return schema;
|
|
27
|
-
}
|
|
28
|
-
async create(caller, data) {
|
|
29
|
-
return Promise.all(data.map(record => this.applyDefinitionsAndCreate(caller, record)));
|
|
30
|
-
}
|
|
31
|
-
async update(caller, filter, patch) {
|
|
32
|
-
await this.applyDefinitionsAndUpdate(caller, filter, patch);
|
|
33
|
-
}
|
|
34
|
-
async applyDefinitionsAndCreate(caller, record) {
|
|
35
|
-
const patch = await this.applyDefinitions(caller, record, 'create');
|
|
36
|
-
if (this.getRelationFields(patch, ['ManyToOne', 'OneToOne']).length === 0) {
|
|
37
|
-
const result = await this.childCollection.create(caller, [patch]);
|
|
38
|
-
return result[0];
|
|
39
|
-
}
|
|
40
|
-
const manyToOneRecords = await this.createManyToOneRelations(caller, patch);
|
|
41
|
-
const createdRecord = await this.createRecord(caller, patch, manyToOneRecords);
|
|
42
|
-
await this.createOneToOneRelations(caller, patch, createdRecord);
|
|
43
|
-
return createdRecord;
|
|
44
|
-
}
|
|
45
|
-
async applyDefinitionsAndUpdate(caller, filter, patch) {
|
|
46
|
-
const updatedPatch = await this.applyDefinitions(caller, patch, 'update');
|
|
47
|
-
const relations = this.getRelationFields(updatedPatch, ['OneToOne', 'ManyToOne']);
|
|
48
|
-
const idsList = await this.getImpactedRecordByUpdate(caller, relations, filter);
|
|
49
|
-
await Promise.all([
|
|
50
|
-
...this.updateAllRelations(caller, idsList, updatedPatch),
|
|
51
|
-
this.childCollection.update(caller, filter, this.getPatchWithoutRelations(updatedPatch, relations)),
|
|
52
|
-
]);
|
|
53
|
-
}
|
|
54
|
-
async createRecord(caller, patch, manyToOneRecords) {
|
|
55
|
-
const refinedPatch = { ...patch };
|
|
56
|
-
const manyToOneRelations = this.getRelationFields(patch, ['ManyToOne']);
|
|
57
|
-
for (const [record] of manyToOneRecords) {
|
|
58
|
-
const relationName = manyToOneRelations.shift();
|
|
59
|
-
const relationSchema = this.schema.fields[relationName];
|
|
60
|
-
delete refinedPatch[relationName];
|
|
61
|
-
const relation = this.dataSource.getCollection(relationSchema.foreignCollection);
|
|
62
|
-
const [pk] = datasource_toolkit_1.SchemaUtils.getPrimaryKeys(relation.schema);
|
|
63
|
-
refinedPatch[relationSchema.foreignKey] = record[pk];
|
|
64
|
-
}
|
|
65
|
-
for (const relationName of this.getRelationFields(patch, ['OneToOne'])) {
|
|
66
|
-
const relationSchema = this.schema.fields[relationName];
|
|
67
|
-
delete refinedPatch[relationName];
|
|
68
|
-
if (patch[relationSchema.originKey])
|
|
69
|
-
delete refinedPatch[relationSchema.originKey];
|
|
70
|
-
}
|
|
71
|
-
const result = await this.childCollection.create(caller, [refinedPatch]);
|
|
72
|
-
return result[0];
|
|
73
|
-
}
|
|
74
|
-
async createOneToOneRelations(caller, patch, createdRecord) {
|
|
75
|
-
const requests = [];
|
|
76
|
-
for (const oneToOneRelation of this.getRelationFields(patch, ['OneToOne'])) {
|
|
77
|
-
const relationSchema = this.schema.fields[oneToOneRelation];
|
|
78
|
-
const relationRecord = patch[oneToOneRelation];
|
|
79
|
-
const relation = this.dataSource.getCollection(relationSchema.foreignCollection);
|
|
80
|
-
const fk = relationSchema.originKey;
|
|
81
|
-
if (patch[fk]) {
|
|
82
|
-
const conditionTree = new datasource_toolkit_1.ConditionTreeLeaf(fk, 'Equal', patch[fk]);
|
|
83
|
-
const filter = new datasource_toolkit_1.Filter({ conditionTree });
|
|
84
|
-
const update = relation.update(caller, filter, relationRecord);
|
|
85
|
-
requests.push(update);
|
|
86
|
-
}
|
|
87
|
-
else {
|
|
88
|
-
const [pk] = datasource_toolkit_1.SchemaUtils.getPrimaryKeys(this.schema);
|
|
89
|
-
requests.push(relation.create(caller, [{ ...relationRecord, [fk]: createdRecord[pk] }]));
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
await Promise.all(requests);
|
|
93
|
-
}
|
|
94
|
-
createManyToOneRelations(caller, patch) {
|
|
95
|
-
const resultsManyToOne = [];
|
|
96
|
-
for (const relationName of this.getRelationFields(patch, ['ManyToOne'])) {
|
|
97
|
-
const relationSchema = this.schema.fields[relationName];
|
|
98
|
-
const relationRecord = patch[relationName];
|
|
99
|
-
const fk = relationSchema.foreignKey;
|
|
100
|
-
const relation = this.dataSource.getCollection(relationSchema.foreignCollection);
|
|
101
|
-
if (patch[fk]) {
|
|
102
|
-
const [pk] = datasource_toolkit_1.SchemaUtils.getPrimaryKeys(relation.schema);
|
|
103
|
-
const updateWrapper = async () => {
|
|
104
|
-
const conditionTree = new datasource_toolkit_1.ConditionTreeLeaf(pk, 'Equal', patch[fk]);
|
|
105
|
-
await relation.update(caller, new datasource_toolkit_1.Filter({ conditionTree }), relationRecord);
|
|
106
|
-
return [{ [pk]: patch[fk] }];
|
|
107
|
-
};
|
|
108
|
-
resultsManyToOne.push(updateWrapper());
|
|
109
|
-
}
|
|
110
|
-
else {
|
|
111
|
-
resultsManyToOne.push(relation.create(caller, [relationRecord]));
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
return Promise.all(resultsManyToOne);
|
|
115
|
-
}
|
|
116
|
-
updateAllRelations(caller, listIds, patch) {
|
|
117
|
-
const updates = [];
|
|
118
|
-
const relations = this.getRelationFields(patch, ['OneToOne', 'ManyToOne']);
|
|
119
|
-
for (const recordIds of listIds) {
|
|
120
|
-
const relationName = relations.shift();
|
|
121
|
-
const relationSchema = this.schema.fields[relationName];
|
|
122
|
-
const relation = this.dataSource.getCollection(relationSchema.foreignCollection);
|
|
123
|
-
const ids = recordIds.map(field => Object.values(field)[0]);
|
|
124
|
-
let key;
|
|
125
|
-
if (relationSchema.type === 'OneToOne') {
|
|
126
|
-
key = relationSchema.originKey;
|
|
127
|
-
}
|
|
128
|
-
else {
|
|
129
|
-
[key] = datasource_toolkit_1.SchemaUtils.getPrimaryKeys(relation.schema);
|
|
130
|
-
}
|
|
131
|
-
const idsFilter = new datasource_toolkit_1.Filter({ conditionTree: new datasource_toolkit_1.ConditionTreeLeaf(key, 'In', ids) });
|
|
132
|
-
updates.push(relation.update(caller, idsFilter, patch[relationName]));
|
|
133
|
-
}
|
|
134
|
-
return updates;
|
|
135
|
-
}
|
|
136
|
-
async getImpactedRecordByUpdate(caller, relations, filter) {
|
|
137
|
-
const records = [];
|
|
138
|
-
for (const relationName of relations) {
|
|
139
|
-
const relationSchema = this.schema.fields[relationName];
|
|
140
|
-
let projection;
|
|
141
|
-
if (relationSchema.type === 'OneToOne') {
|
|
142
|
-
projection = new datasource_toolkit_1.Projection(...datasource_toolkit_1.SchemaUtils.getPrimaryKeys(this.schema));
|
|
143
|
-
}
|
|
144
|
-
else if (relationSchema.type === 'ManyToOne') {
|
|
145
|
-
projection = new datasource_toolkit_1.Projection(relationSchema.foreignKey);
|
|
146
|
-
}
|
|
147
|
-
records.push(this.list(caller, filter, projection));
|
|
148
|
-
}
|
|
149
|
-
return Promise.all(records);
|
|
150
|
-
}
|
|
151
|
-
async applyDefinitions(caller, patch, action, stackCalls = []) {
|
|
152
|
-
if (Object.keys(patch).length === 0)
|
|
153
|
-
return {};
|
|
154
|
-
const replacedDefinitionsColumns = this.getReplacedDefinitionsColumns(patch);
|
|
155
|
-
WriteDecorator.checkCyclicDependency(replacedDefinitionsColumns, stackCalls);
|
|
156
|
-
const patches = await this.getDefinitionResults(caller, patch, replacedDefinitionsColumns, action);
|
|
157
|
-
const patchToExplore = {};
|
|
158
|
-
const copyPatch = { ...patch };
|
|
159
|
-
patches.forEach(recordData => {
|
|
160
|
-
const setValueColumn = replacedDefinitionsColumns.shift();
|
|
161
|
-
delete copyPatch[setValueColumn];
|
|
162
|
-
if (!recordData)
|
|
163
|
-
return;
|
|
164
|
-
if (recordData.constructor === Object) {
|
|
165
|
-
datasource_toolkit_1.RecordValidator.validate(this, recordData);
|
|
166
|
-
}
|
|
167
|
-
else {
|
|
168
|
-
throw new Error(`The write handler of ${setValueColumn} should return an object or nothing.`);
|
|
169
|
-
}
|
|
170
|
-
for (const [columnName, value] of Object.entries(recordData)) {
|
|
171
|
-
if (copyPatch[columnName]) {
|
|
172
|
-
throw new datasource_toolkit_1.ValidationError(`Conflict value on the field "${columnName}". It receives several values.`);
|
|
173
|
-
}
|
|
174
|
-
if (columnName === setValueColumn) {
|
|
175
|
-
copyPatch[columnName] = value;
|
|
176
|
-
}
|
|
177
|
-
else {
|
|
178
|
-
patchToExplore[columnName] = value;
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
});
|
|
182
|
-
return {
|
|
183
|
-
...copyPatch,
|
|
184
|
-
...(await this.applyDefinitions(caller, patchToExplore, action, stackCalls)),
|
|
185
|
-
};
|
|
186
|
-
}
|
|
187
|
-
getReplacedDefinitionsColumns(patch) {
|
|
188
|
-
const patchKeys = Object.keys(patch);
|
|
189
|
-
return Object.keys(this.replacedDefinitions).filter(name => patchKeys.includes(name));
|
|
190
|
-
}
|
|
191
|
-
async getDefinitionResults(caller, patch, columns, action) {
|
|
192
|
-
return Promise.all(columns.map(column => {
|
|
193
|
-
const definition = this.replacedDefinitions[column];
|
|
194
|
-
const context = new context_1.default(this, caller, action, { ...patch });
|
|
195
|
-
return definition(patch[column], context);
|
|
196
|
-
}));
|
|
197
|
-
}
|
|
198
|
-
static checkCyclicDependency(columns, stackCalls) {
|
|
199
|
-
stackCalls.push(...columns);
|
|
200
|
-
if (stackCalls.length !== [...new Set(stackCalls)].length) {
|
|
201
|
-
throw new datasource_toolkit_1.ValidationError(`There is a cyclic dependency on the "${stackCalls.pop()}" column.`);
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
getRelationFields(patch, types) {
|
|
205
|
-
return Object.keys(patch).filter(field => types.includes(this.schema.fields[field]?.type));
|
|
206
|
-
}
|
|
207
|
-
getPatchWithoutRelations(patch, relations) {
|
|
208
|
-
const copy = { ...patch };
|
|
209
|
-
relations.forEach(relation => delete copy[relation]);
|
|
210
|
-
return copy;
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
exports.default = WriteDecorator;
|
|
214
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29sbGVjdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9kZWNvcmF0b3JzL3dyaXRlL2NvbGxlY3Rpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSx3RUFleUM7QUFFekMsbUZBQTBEO0FBRTFELHdEQUFrRDtBQUdsRCxNQUFxQixjQUFlLFNBQVEsOEJBQW1CO0lBQS9EOztRQUNVLHdCQUFtQixHQUFvQyxFQUFFLENBQUM7SUFtVHBFLENBQUM7SUFoVEMsbUJBQW1CLENBQUMsU0FBaUIsRUFBRSxVQUEyQjtRQUNoRSxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsRUFBRTtZQUN4RCxNQUFNLElBQUksS0FBSyxDQUNiLG9CQUFvQixTQUFTLDJCQUEyQixJQUFJLENBQUMsSUFBSSxjQUFjLENBQ2hGLENBQUM7U0FDSDtRQUVELElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxTQUFTLENBQUMsR0FBRyxVQUFVLENBQUM7UUFDakQsSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7SUFDM0IsQ0FBQztJQUVrQixZQUFZLENBQUMsV0FBNkI7UUFDM0QsTUFBTSxNQUFNLEdBQUcsRUFBRSxHQUFHLFdBQVcsRUFBRSxNQUFNLEVBQUUsRUFBRSxHQUFHLFdBQVcsQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDO1FBRXJFLEtBQUssTUFBTSxJQUFJLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsbUJBQW1CLENBQUMsRUFBRTtZQUN2RCxNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBa0IsQ0FBQyxVQUFVLEdBQUcsS0FBSyxDQUFDO1NBQzFEO1FBRUQsT0FBTyxNQUFNLENBQUM7SUFDaEIsQ0FBQztJQUVRLEtBQUssQ0FBQyxNQUFNLENBQUMsTUFBYyxFQUFFLElBQWtCO1FBQ3RELE9BQU8sT0FB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
|
|
@@ -1,15 +0,0 @@
|
|
|
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 collection_context_1 = __importDefault(require("../../context/collection-context"));
|
|
7
|
-
class WriteCustomizationContext extends collection_context_1.default {
|
|
8
|
-
constructor(collection, caller, action, record) {
|
|
9
|
-
super(collection, caller);
|
|
10
|
-
this.action = action;
|
|
11
|
-
this.record = record;
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
exports.default = WriteCustomizationContext;
|
|
15
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29udGV4dC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9kZWNvcmF0b3JzL3dyaXRlL2NvbnRleHQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFFQSwwRkFBOEU7QUFHOUUsTUFBcUIseUJBR25CLFNBQVEsNEJBQW9DO0lBSTVDLFlBQ0UsVUFBc0IsRUFDdEIsTUFBYyxFQUNkLE1BQTJCLEVBQzNCLE1BQStCO1FBRS9CLEtBQUssQ0FBQyxVQUFVLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFFMUIsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7UUFDckIsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7SUFDdkIsQ0FBQztDQUNGO0FBbEJELDRDQWtCQyJ9
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import { TCollectionName, TFieldName, TFieldType, TPartialRow, TSchema } from '../../templates';
|
|
2
|
-
import WriteCustomizationContext from './context';
|
|
3
|
-
export declare type WriteDefinition<S extends TSchema = TSchema, N extends TCollectionName<S> = TCollectionName<S>, C extends TFieldName<S, N> = TFieldName<S, N>> = (value: TFieldType<S, N, C>, context: WriteCustomizationContext<S, N>) => Promise<TPartialRow<S, N> | void> | TPartialRow<S, N> | void;
|
|
4
|
-
//# sourceMappingURL=types.d.ts.map
|