@forestadmin/datasource-customizer 1.0.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. package/LICENSE +674 -0
  2. package/README.md +0 -0
  3. package/dist/collection-customizer.d.ts +263 -0
  4. package/dist/collection-customizer.js +397 -0
  5. package/dist/context/agent-context.d.ts +11 -0
  6. package/dist/context/agent-context.js +20 -0
  7. package/dist/context/collection-context.d.ts +10 -0
  8. package/dist/context/collection-context.js +18 -0
  9. package/dist/context/relaxed-wrappers/collection.d.ts +112 -0
  10. package/dist/context/relaxed-wrappers/collection.js +161 -0
  11. package/dist/context/relaxed-wrappers/datasource.d.ts +15 -0
  12. package/dist/context/relaxed-wrappers/datasource.js +22 -0
  13. package/dist/datasource-customizer.d.ts +53 -0
  14. package/dist/datasource-customizer.js +89 -0
  15. package/dist/decorators/actions/collection.d.ts +18 -0
  16. package/dist/decorators/actions/collection.js +104 -0
  17. package/dist/decorators/actions/context/base.d.ts +28 -0
  18. package/dist/decorators/actions/context/base.js +105 -0
  19. package/dist/decorators/actions/context/single.d.ts +9 -0
  20. package/dist/decorators/actions/context/single.js +22 -0
  21. package/dist/decorators/actions/result-builder.d.ts +53 -0
  22. package/dist/decorators/actions/result-builder.js +81 -0
  23. package/dist/decorators/actions/types/actions.d.ts +18 -0
  24. package/dist/decorators/actions/types/actions.js +3 -0
  25. package/dist/decorators/actions/types/fields.d.ts +32 -0
  26. package/dist/decorators/actions/types/fields.js +3 -0
  27. package/dist/decorators/chart/datasource.d.ts +11 -0
  28. package/dist/decorators/chart/datasource.js +38 -0
  29. package/dist/decorators/chart/result-builder.d.ts +12 -0
  30. package/dist/decorators/chart/result-builder.js +48 -0
  31. package/dist/decorators/chart/types.d.ts +6 -0
  32. package/dist/decorators/chart/types.js +3 -0
  33. package/dist/decorators/collection-decorator.d.ts +21 -0
  34. package/dist/decorators/collection-decorator.js +57 -0
  35. package/dist/decorators/composite-datasource.d.ts +11 -0
  36. package/dist/decorators/composite-datasource.js +38 -0
  37. package/dist/decorators/computed/collection.d.ts +14 -0
  38. package/dist/decorators/computed/collection.js +69 -0
  39. package/dist/decorators/computed/helpers/compute-fields.d.ts +5 -0
  40. package/dist/decorators/computed/helpers/compute-fields.js +36 -0
  41. package/dist/decorators/computed/helpers/rewrite-projection.d.ts +4 -0
  42. package/dist/decorators/computed/helpers/rewrite-projection.js +22 -0
  43. package/dist/decorators/computed/types.d.ts +11 -0
  44. package/dist/decorators/computed/types.js +3 -0
  45. package/dist/decorators/computed/utils/deduplication.d.ts +2 -0
  46. package/dist/decorators/computed/utils/deduplication.js +28 -0
  47. package/dist/decorators/computed/utils/flattener.d.ts +6 -0
  48. package/dist/decorators/computed/utils/flattener.js +35 -0
  49. package/dist/decorators/datasource-decorator.d.ts +15 -0
  50. package/dist/decorators/datasource-decorator.js +27 -0
  51. package/dist/decorators/decorators-stack.d.ts +42 -0
  52. package/dist/decorators/decorators-stack.js +59 -0
  53. package/dist/decorators/empty/collection.d.ts +18 -0
  54. package/dist/decorators/empty/collection.js +85 -0
  55. package/dist/decorators/hook/collection.d.ts +13 -0
  56. package/dist/decorators/hook/collection.js +67 -0
  57. package/dist/decorators/hook/context/aggregate.d.ts +22 -0
  58. package/dist/decorators/hook/context/aggregate.js +46 -0
  59. package/dist/decorators/hook/context/create.d.ts +17 -0
  60. package/dist/decorators/hook/context/create.js +35 -0
  61. package/dist/decorators/hook/context/delete.d.ts +14 -0
  62. package/dist/decorators/hook/context/delete.js +28 -0
  63. package/dist/decorators/hook/context/hook.d.ts +26 -0
  64. package/dist/decorators/hook/context/hook.js +38 -0
  65. package/dist/decorators/hook/context/list.d.ts +20 -0
  66. package/dist/decorators/hook/context/list.js +42 -0
  67. package/dist/decorators/hook/context/update.d.ts +16 -0
  68. package/dist/decorators/hook/context/update.js +31 -0
  69. package/dist/decorators/hook/hook.d.ts +10 -0
  70. package/dist/decorators/hook/hook.js +30 -0
  71. package/dist/decorators/hook/types.d.ts +27 -0
  72. package/dist/decorators/hook/types.js +3 -0
  73. package/dist/decorators/operators-emulate/collection.d.ts +15 -0
  74. package/dist/decorators/operators-emulate/collection.js +99 -0
  75. package/dist/decorators/operators-emulate/types.d.ts +4 -0
  76. package/dist/decorators/operators-emulate/types.js +3 -0
  77. package/dist/decorators/operators-replace/collection.d.ts +10 -0
  78. package/dist/decorators/operators-replace/collection.js +35 -0
  79. package/dist/decorators/publication/collection.d.ts +14 -0
  80. package/dist/decorators/publication/collection.js +63 -0
  81. package/dist/decorators/relation/collection.d.ts +23 -0
  82. package/dist/decorators/relation/collection.js +190 -0
  83. package/dist/decorators/relation/types.d.ts +5 -0
  84. package/dist/decorators/relation/types.js +3 -0
  85. package/dist/decorators/rename-collection/collection.d.ts +15 -0
  86. package/dist/decorators/rename-collection/collection.js +50 -0
  87. package/dist/decorators/rename-collection/datasource.d.ts +11 -0
  88. package/dist/decorators/rename-collection/datasource.js +33 -0
  89. package/dist/decorators/rename-field/collection.d.ts +33 -0
  90. package/dist/decorators/rename-field/collection.js +149 -0
  91. package/dist/decorators/schema/collection.d.ts +13 -0
  92. package/dist/decorators/schema/collection.js +26 -0
  93. package/dist/decorators/search/collection.d.ts +14 -0
  94. package/dist/decorators/search/collection.js +105 -0
  95. package/dist/decorators/search/types.d.ts +4 -0
  96. package/dist/decorators/search/types.js +3 -0
  97. package/dist/decorators/segment/collection.d.ts +10 -0
  98. package/dist/decorators/segment/collection.js +43 -0
  99. package/dist/decorators/segment/types.d.ts +4 -0
  100. package/dist/decorators/segment/types.js +3 -0
  101. package/dist/decorators/sort-emulate/collection.d.ts +15 -0
  102. package/dist/decorators/sort-emulate/collection.js +97 -0
  103. package/dist/decorators/validation/collection.d.ts +20 -0
  104. package/dist/decorators/validation/collection.js +109 -0
  105. package/dist/decorators/write/collection.d.ts +26 -0
  106. package/dist/decorators/write/collection.js +214 -0
  107. package/dist/decorators/write/context.d.ts +9 -0
  108. package/dist/decorators/write/context.js +15 -0
  109. package/dist/decorators/write/types.d.ts +4 -0
  110. package/dist/decorators/write/types.js +3 -0
  111. package/dist/index.d.ts +14 -0
  112. package/dist/index.js +27 -0
  113. package/dist/templates.d.ts +65 -0
  114. package/dist/templates.js +3 -0
  115. package/dist/types.d.ts +18 -0
  116. package/dist/types.js +3 -0
  117. package/dist/typing-generator.d.ts +19 -0
  118. package/dist/typing-generator.js +123 -0
  119. package/package.json +37 -0
@@ -0,0 +1,149 @@
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_decorator_1 = __importDefault(require("../collection-decorator"));
7
+ /**
8
+ * This decorator renames fields.
9
+ *
10
+ * It works on one side, by rewriting all references to fields in aggregations, filters, projections
11
+ * and on the other, by rewriting records and aggregation results which are returned by the
12
+ * subCollection.
13
+ */
14
+ class RenameFieldCollectionDecorator extends collection_decorator_1.default {
15
+ constructor() {
16
+ super(...arguments);
17
+ this.fromChildCollection = {};
18
+ this.toChildCollection = {};
19
+ }
20
+ /** Rename a field from the collection */
21
+ renameField(currentName, newName) {
22
+ if (!this.schema.fields[currentName]) {
23
+ throw new Error(`No such field '${currentName}'`);
24
+ }
25
+ let initialName = currentName;
26
+ // Revert previous renaming (avoids conflicts and need to recurse on this.toSubCollection).
27
+ if (this.toChildCollection[currentName]) {
28
+ const childName = this.toChildCollection[currentName];
29
+ delete this.toChildCollection[currentName];
30
+ delete this.fromChildCollection[childName];
31
+ initialName = childName;
32
+ this.markAllSchemaAsDirty();
33
+ }
34
+ // Do not update arrays if renaming is a no-op (ie: customer is cancelling a previous rename).
35
+ if (initialName !== newName) {
36
+ this.fromChildCollection[initialName] = newName;
37
+ this.toChildCollection[newName] = initialName;
38
+ this.markAllSchemaAsDirty();
39
+ }
40
+ }
41
+ refineSchema(childSchema) {
42
+ const fields = {};
43
+ for (const [oldName, oldSchema] of Object.entries(childSchema.fields)) {
44
+ const schema = { ...oldSchema };
45
+ if (schema.type === 'ManyToOne') {
46
+ schema.foreignKey = this.fromChildCollection[schema.foreignKey] ?? schema.foreignKey;
47
+ }
48
+ else if (schema.type === 'OneToMany' || schema.type === 'OneToOne') {
49
+ const relation = this.dataSource.getCollection(schema.foreignCollection);
50
+ schema.originKey = relation.fromChildCollection[schema.originKey] ?? schema.originKey;
51
+ }
52
+ else if (schema.type === 'ManyToMany') {
53
+ const through = this.dataSource.getCollection(schema.throughCollection);
54
+ schema.foreignKey = through.fromChildCollection[schema.foreignKey] ?? schema.foreignKey;
55
+ schema.originKey = through.fromChildCollection[schema.originKey] ?? schema.originKey;
56
+ }
57
+ fields[this.fromChildCollection[oldName] ?? oldName] = schema;
58
+ }
59
+ return { ...childSchema, fields };
60
+ }
61
+ async refineFilter(caller, filter) {
62
+ return filter?.override({
63
+ conditionTree: filter.conditionTree?.replaceFields(field => this.pathToChildCollection(field)),
64
+ sort: filter.sort?.replaceClauses(clause => ({
65
+ field: this.pathToChildCollection(clause.field),
66
+ ascending: clause.ascending,
67
+ })),
68
+ });
69
+ }
70
+ async create(caller, records) {
71
+ const newRecords = await super.create(caller, records.map(record => this.recordToChildCollection(record)));
72
+ return newRecords.map(record => this.recordFromChildCollection(record));
73
+ }
74
+ async list(caller, filter, projection) {
75
+ const childProjection = projection.replace(field => this.pathToChildCollection(field));
76
+ const records = await super.list(caller, filter, childProjection);
77
+ return records.map(record => this.recordFromChildCollection(record));
78
+ }
79
+ async update(caller, filter, patch) {
80
+ return super.update(caller, filter, this.recordToChildCollection(patch));
81
+ }
82
+ async aggregate(caller, filter, aggregation, limit) {
83
+ const rows = await super.aggregate(caller, filter, aggregation.replaceFields(f => this.pathToChildCollection(f)), limit);
84
+ return rows.map(row => ({
85
+ value: row.value,
86
+ group: Object.entries(row.group).reduce((memo, [path, value]) => ({ ...memo, [this.pathFromChildCollection(path)]: value }), {}),
87
+ }));
88
+ }
89
+ markAllSchemaAsDirty() {
90
+ for (const collection of this.dataSource.collections) {
91
+ collection.markSchemaAsDirty();
92
+ }
93
+ }
94
+ /** Convert field path from child collection to this collection */
95
+ pathFromChildCollection(childPath) {
96
+ if (childPath.includes(':')) {
97
+ const dotIndex = childPath.indexOf(':');
98
+ const childField = childPath.substring(0, dotIndex);
99
+ const thisField = this.fromChildCollection[childField] ?? childField;
100
+ const schema = this.schema.fields[thisField];
101
+ const relation = this.dataSource.getCollection(schema.foreignCollection);
102
+ return `${thisField}:${relation.pathFromChildCollection(childPath.substring(dotIndex + 1))}`;
103
+ }
104
+ return this.fromChildCollection[childPath] ?? childPath;
105
+ }
106
+ /** Convert field path from this collection to child collection */
107
+ pathToChildCollection(thisPath) {
108
+ if (thisPath.includes(':')) {
109
+ const dotIndex = thisPath.indexOf(':');
110
+ const thisField = thisPath.substring(0, dotIndex);
111
+ const schema = this.schema.fields[thisField];
112
+ const relation = this.dataSource.getCollection(schema.foreignCollection);
113
+ const childField = this.toChildCollection[thisField] ?? thisField;
114
+ return `${childField}:${relation.pathToChildCollection(thisPath.substring(dotIndex + 1))}`;
115
+ }
116
+ return this.toChildCollection[thisPath] ?? thisPath;
117
+ }
118
+ /** Convert record from this collection to the child collection */
119
+ recordToChildCollection(thisRecord) {
120
+ const childRecord = {};
121
+ for (const [thisField, value] of Object.entries(thisRecord)) {
122
+ childRecord[this.toChildCollection[thisField] ?? thisField] = value;
123
+ }
124
+ return childRecord;
125
+ }
126
+ /** Convert record from the child collection to this collection */
127
+ recordFromChildCollection(childRecord) {
128
+ const { schema } = this;
129
+ const thisRecord = {};
130
+ for (const [childField, value] of Object.entries(childRecord)) {
131
+ const thisField = this.fromChildCollection[childField] ?? childField;
132
+ const fieldSchema = schema.fields[thisField];
133
+ // Perform the mapping, recurse for relations.
134
+ if (fieldSchema.type === 'Column') {
135
+ thisRecord[thisField] = value;
136
+ }
137
+ else if (value === null) {
138
+ thisRecord[thisField] = value;
139
+ }
140
+ else {
141
+ const relation = this.dataSource.getCollection(fieldSchema.foreignCollection);
142
+ thisRecord[thisField] = relation.recordFromChildCollection(value);
143
+ }
144
+ }
145
+ return thisRecord;
146
+ }
147
+ }
148
+ exports.default = RenameFieldCollectionDecorator;
149
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29sbGVjdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9kZWNvcmF0b3JzL3JlbmFtZS1maWVsZC9jb2xsZWN0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBWUEsbUZBQTBEO0FBRzFEOzs7Ozs7R0FNRztBQUNILE1BQXFCLDhCQUErQixTQUFRLDhCQUFtQjtJQUEvRTs7UUFHbUIsd0JBQW1CLEdBQWtDLEVBQUUsQ0FBQztRQUN4RCxzQkFBaUIsR0FBbUMsRUFBRSxDQUFDO0lBb0wxRSxDQUFDO0lBbExDLHlDQUF5QztJQUN6QyxXQUFXLENBQUMsV0FBbUIsRUFBRSxPQUFlO1FBQzlDLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxXQUFXLENBQUMsRUFBRTtZQUNwQyxNQUFNLElBQUksS0FBSyxDQUFDLGtCQUFrQixXQUFXLEdBQUcsQ0FBQyxDQUFDO1NBQ25EO1FBRUQsSUFBSSxXQUFXLEdBQUcsV0FBVyxDQUFDO1FBRTlCLDJGQUEyRjtRQUMzRixJQUFJLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxXQUFXLENBQUMsRUFBRTtZQUN2QyxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsaUJBQWlCLENBQUMsV0FBVyxDQUFDLENBQUM7WUFDdEQsT0FBTyxJQUFJLENBQUMsaUJBQWlCLENBQUMsV0FBVyxDQUFDLENBQUM7WUFDM0MsT0FBTyxJQUFJLENBQUMsbUJBQW1CLENBQUMsU0FBUyxDQUFDLENBQUM7WUFDM0MsV0FBVyxHQUFHLFNBQVMsQ0FBQztZQUN4QixJQUFJLENBQUMsb0JBQW9CLEVBQUUsQ0FBQztTQUM3QjtRQUVELDhGQUE4RjtRQUM5RixJQUFJLFdBQVcsS0FBSyxPQUFPLEVBQUU7WUFDM0IsSUFBSSxDQUFDLG1CQUFtQixDQUFDLFdBQVcsQ0FBQyxHQUFHLE9BQU8sQ0FBQztZQUNoRCxJQUFJLENBQUMsaUJBQWlCLENBQUMsT0FBTyxDQUFDLEdBQUcsV0FBVyxD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
@@ -0,0 +1,13 @@
1
+ import { CollectionSchema } from '@forestadmin/datasource-toolkit';
2
+ import CollectionDecorator from '../collection-decorator';
3
+ /**
4
+ * This decorator allows to override parts of the collections schema.
5
+ * It can be used to toggle off collection level capabilities for performance
6
+ * (for now, list-view counts and the search bar)
7
+ */
8
+ export default class SchemaCollectionDecorator extends CollectionDecorator {
9
+ private schemaOverride;
10
+ overrideSchema(value: Partial<CollectionSchema>): void;
11
+ protected refineSchema(subSchema: CollectionSchema): CollectionSchema;
12
+ }
13
+ //# sourceMappingURL=collection.d.ts.map
@@ -0,0 +1,26 @@
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_decorator_1 = __importDefault(require("../collection-decorator"));
7
+ /**
8
+ * This decorator allows to override parts of the collections schema.
9
+ * It can be used to toggle off collection level capabilities for performance
10
+ * (for now, list-view counts and the search bar)
11
+ */
12
+ class SchemaCollectionDecorator extends collection_decorator_1.default {
13
+ constructor() {
14
+ super(...arguments);
15
+ this.schemaOverride = {};
16
+ }
17
+ overrideSchema(value) {
18
+ Object.assign(this.schemaOverride, value);
19
+ this.markSchemaAsDirty();
20
+ }
21
+ refineSchema(subSchema) {
22
+ return { ...subSchema, ...this.schemaOverride };
23
+ }
24
+ }
25
+ exports.default = SchemaCollectionDecorator;
26
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29sbGVjdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9kZWNvcmF0b3JzL3NjaGVtYS9jb2xsZWN0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQ0EsbUZBQTBEO0FBRTFEOzs7O0dBSUc7QUFDSCxNQUFxQix5QkFBMEIsU0FBUSw4QkFBbUI7SUFBMUU7O1FBQ1UsbUJBQWMsR0FBOEIsRUFBRSxDQUFDO0lBVXpELENBQUM7SUFSQyxjQUFjLENBQUMsS0FBZ0M7UUFDN0MsTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsY0FBYyxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQzFDLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO0lBQzNCLENBQUM7SUFFa0IsWUFBWSxDQUFDLFNBQTJCO1FBQ3pELE9BQU8sRUFBRSxHQUFHLFNBQVMsRUFBRSxHQUFHLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztJQUNsRCxDQUFDO0NBQ0Y7QUFYRCw0Q0FXQyJ9
@@ -0,0 +1,14 @@
1
+ import { Caller, CollectionSchema, PaginatedFilter } from '@forestadmin/datasource-toolkit';
2
+ import { SearchDefinition } from './types';
3
+ import CollectionDecorator from '../collection-decorator';
4
+ export default class SearchCollectionDecorator extends CollectionDecorator {
5
+ replacer: SearchDefinition;
6
+ replaceSearch(replacer: SearchDefinition): void;
7
+ refineSchema(subSchema: CollectionSchema): CollectionSchema;
8
+ refineFilter(caller: Caller, filter?: PaginatedFilter): Promise<PaginatedFilter>;
9
+ private defaultReplacer;
10
+ private static buildCondition;
11
+ private static getFields;
12
+ private static lenientFind;
13
+ }
14
+ //# 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 uuid_1 = require("uuid");
8
+ const collection_context_1 = __importDefault(require("../../context/collection-context"));
9
+ const collection_decorator_1 = __importDefault(require("../collection-decorator"));
10
+ class SearchCollectionDecorator extends collection_decorator_1.default {
11
+ constructor() {
12
+ super(...arguments);
13
+ this.replacer = null;
14
+ }
15
+ replaceSearch(replacer) {
16
+ this.replacer = replacer;
17
+ }
18
+ refineSchema(subSchema) {
19
+ return { ...subSchema, searchable: true };
20
+ }
21
+ async refineFilter(caller, filter) {
22
+ // Search string is not significant
23
+ if (!filter?.search?.trim().length) {
24
+ return filter.override({ search: null });
25
+ }
26
+ // Implement search ourselves
27
+ if (this.replacer || !this.childCollection.schema.searchable) {
28
+ const ctx = new collection_context_1.default(this, caller);
29
+ let tree = this.defaultReplacer(filter.search, filter.searchExtended);
30
+ if (this.replacer) {
31
+ const plainTree = await this.replacer(filter.search, filter.searchExtended, ctx);
32
+ tree = datasource_toolkit_1.ConditionTreeFactory.fromPlainObject(plainTree);
33
+ }
34
+ // Note that if no fields are searchable with the provided searchString, the conditions
35
+ // array might be empty, which will create a condition returning zero records
36
+ // (this is the desired behavior).
37
+ return filter.override({
38
+ conditionTree: datasource_toolkit_1.ConditionTreeFactory.intersect(filter.conditionTree, tree),
39
+ search: null,
40
+ });
41
+ }
42
+ // Let subcollection deal with the search
43
+ return filter;
44
+ }
45
+ defaultReplacer(search, extended) {
46
+ const searchableFields = SearchCollectionDecorator.getFields(this.childCollection, extended);
47
+ const conditions = searchableFields
48
+ .map(([field, schema]) => SearchCollectionDecorator.buildCondition(field, schema, search))
49
+ .filter(Boolean);
50
+ return datasource_toolkit_1.ConditionTreeFactory.union(...conditions);
51
+ }
52
+ static buildCondition(field, schema, searchString) {
53
+ const { columnType, enumValues, filterOperators } = schema;
54
+ const isNumber = Number(searchString).toString() === searchString;
55
+ const isUuid = (0, uuid_1.validate)(searchString);
56
+ if (columnType === 'Number' && isNumber && filterOperators?.has('Equal')) {
57
+ return new datasource_toolkit_1.ConditionTreeLeaf(field, 'Equal', Number(searchString));
58
+ }
59
+ if (columnType === 'Enum' && filterOperators?.has('Equal')) {
60
+ const searchValue = SearchCollectionDecorator.lenientFind(enumValues, searchString);
61
+ if (searchValue)
62
+ return new datasource_toolkit_1.ConditionTreeLeaf(field, 'Equal', searchValue);
63
+ }
64
+ if (columnType === 'String') {
65
+ const isCaseSensitive = searchString.toLocaleLowerCase() !== searchString.toLocaleUpperCase();
66
+ const supportsIContains = filterOperators?.has('IContains');
67
+ const supportsContains = filterOperators?.has('Contains');
68
+ const supportsEqual = filterOperators?.has('Equal');
69
+ // Perf: don't use case-insensitive operator when the search string is indifferent to case
70
+ let operator;
71
+ if (supportsIContains && (isCaseSensitive || !supportsContains))
72
+ operator = 'IContains';
73
+ else if (supportsContains)
74
+ operator = 'Contains';
75
+ else if (supportsEqual)
76
+ operator = 'Equal';
77
+ if (operator)
78
+ return new datasource_toolkit_1.ConditionTreeLeaf(field, operator, searchString);
79
+ }
80
+ if (columnType === 'Uuid' && isUuid && filterOperators?.has('Equal')) {
81
+ return new datasource_toolkit_1.ConditionTreeLeaf(field, 'Equal', searchString);
82
+ }
83
+ return null;
84
+ }
85
+ static getFields(collection, extended) {
86
+ const fields = [];
87
+ for (const [name, field] of Object.entries(collection.schema.fields)) {
88
+ if (field.type === 'Column')
89
+ fields.push([name, field]);
90
+ if (extended && (field.type === 'ManyToOne' || field.type === 'OneToOne')) {
91
+ const related = collection.dataSource.getCollection(field.foreignCollection);
92
+ for (const [subName, subField] of Object.entries(related.schema.fields))
93
+ if (subField.type === 'Column')
94
+ fields.push([`${name}:${subName}`, subField]);
95
+ }
96
+ }
97
+ return fields;
98
+ }
99
+ static lenientFind(haystack, needle) {
100
+ return (haystack?.find(v => v === needle.trim()) ??
101
+ haystack?.find(v => v.toLocaleLowerCase() === needle.toLocaleLowerCase().trim()));
102
+ }
103
+ }
104
+ exports.default = SearchCollectionDecorator;
105
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29sbGVjdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9kZWNvcmF0b3JzL3NlYXJjaC9jb2xsZWN0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsd0VBVXlDO0FBQ3pDLCtCQUFnRDtBQUdoRCwwRkFBOEU7QUFDOUUsbUZBQTBEO0FBRTFELE1BQXFCLHlCQUEwQixTQUFRLDhCQUFtQjtJQUExRTs7UUFDRSxhQUFRLEdBQXFCLElBQUksQ0FBQztJQW1IcEMsQ0FBQztJQWpIQyxhQUFhLENBQUMsUUFBMEI7UUFDdEMsSUFBSSxDQUFDLFFBQVEsR0FBRyxRQUFRLENBQUM7SUFDM0IsQ0FBQztJQUVlLFlBQVksQ0FBQyxTQUEyQjtRQUN0RCxPQUFPLEVBQUUsR0FBRyxTQUFTLEVBQUUsVUFBVSxFQUFFLElBQUksRUFBRSxDQUFDO0lBQzVDLENBQUM7SUFFZSxLQUFLLENBQUMsWUFBWSxDQUNoQyxNQUFjLEVBQ2QsTUFBd0I7UUFFeEIsbUNBQW1DO1FBQ25DLElBQUksQ0FBQyxNQUFNLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxDQUFDLE1BQU0sRUFBRTtZQUNsQyxPQUFPLE1BQU0sQ0FBQyxRQUFRLENBQUMsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztTQUMxQztRQUVELDZCQUE2QjtRQUM3QixJQUFJLElBQUksQ0FBQyxRQUFRLElBQUksQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLE1BQU0sQ0FBQyxVQUFVLEVBQUU7WUFDNUQsTUFBTSxHQUFHLEdBQUcsSUFBSSw0QkFBOEIsQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLENBQUM7WUFDN0QsSUFBSSxJQUFJLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxjQUFjLENBQUMsQ0FBQztZQUV0RSxJQUFJLElBQUksQ0FBQyxRQUFRLEVBQUU7Z0JBQ2pCLE1BQU0sU0FBUyxHQUFH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
@@ -0,0 +1,4 @@
1
+ import { TCollectionName, TConditionTree, TSchema } from '../../templates';
2
+ import CollectionCustomizationContext from '../../context/collection-context';
3
+ export declare type SearchDefinition<S extends TSchema = TSchema, N extends TCollectionName<S> = TCollectionName<S>> = (value: string, extended: boolean, context: CollectionCustomizationContext<S, N>) => Promise<TConditionTree<S, N>> | TConditionTree<S, N>;
4
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvZGVjb3JhdG9ycy9zZWFyY2gvdHlwZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiJ9
@@ -0,0 +1,10 @@
1
+ import { Caller, CollectionSchema, PaginatedFilter } from '@forestadmin/datasource-toolkit';
2
+ import { SegmentDefinition } from './types';
3
+ import CollectionDecorator from '../collection-decorator';
4
+ export default class SegmentCollectionDecorator extends CollectionDecorator {
5
+ private segments;
6
+ addSegment(segmentName: string, definition: SegmentDefinition): void;
7
+ protected refineSchema(subSchema: CollectionSchema): CollectionSchema;
8
+ refineFilter(caller: Caller, filter?: PaginatedFilter): Promise<PaginatedFilter>;
9
+ }
10
+ //# sourceMappingURL=collection.d.ts.map
@@ -0,0 +1,43 @@
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_context_1 = __importDefault(require("../../context/collection-context"));
8
+ const collection_decorator_1 = __importDefault(require("../collection-decorator"));
9
+ class SegmentCollectionDecorator extends collection_decorator_1.default {
10
+ constructor() {
11
+ super(...arguments);
12
+ this.segments = {};
13
+ }
14
+ addSegment(segmentName, definition) {
15
+ this.segments[segmentName] = definition;
16
+ this.markSchemaAsDirty();
17
+ }
18
+ refineSchema(subSchema) {
19
+ return {
20
+ ...subSchema,
21
+ segments: [...subSchema.segments, ...Object.keys(this.segments)],
22
+ };
23
+ }
24
+ async refineFilter(caller, filter) {
25
+ if (!filter) {
26
+ return null;
27
+ }
28
+ let { conditionTree, segment } = filter;
29
+ if (segment && this.segments[segment]) {
30
+ const definition = this.segments[segment];
31
+ const result = typeof definition === 'function'
32
+ ? await definition(new collection_context_1.default(this, caller))
33
+ : await definition;
34
+ const conditionTreeSegment = result instanceof datasource_toolkit_1.ConditionTree ? result : datasource_toolkit_1.ConditionTreeFactory.fromPlainObject(result);
35
+ datasource_toolkit_1.ConditionTreeValidator.validate(conditionTreeSegment, this);
36
+ conditionTree = datasource_toolkit_1.ConditionTreeFactory.intersect(conditionTree, conditionTreeSegment);
37
+ segment = null;
38
+ }
39
+ return filter.override({ conditionTree, segment });
40
+ }
41
+ }
42
+ exports.default = SegmentCollectionDecorator;
43
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29sbGVjdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9kZWNvcmF0b3JzL3NlZ21lbnQvY29sbGVjdGlvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLHdFQU95QztBQUV6QywwRkFBOEU7QUFDOUUsbUZBQTBEO0FBRTFELE1BQXFCLDBCQUEyQixTQUFRLDhCQUFtQjtJQUEzRTs7UUFDVSxhQUFRLEdBQTBDLEVBQUUsQ0FBQztJQTBDL0QsQ0FBQztJQXhDQyxVQUFVLENBQUMsV0FBbUIsRUFBRSxVQUE2QjtRQUMzRCxJQUFJLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxHQUFHLFVBQVUsQ0FBQztRQUN4QyxJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztJQUMzQixDQUFDO0lBRWtCLFlBQVksQ0FBQyxTQUEyQjtRQUN6RCxPQUFPO1lBQ0wsR0FBRyxTQUFTO1lBQ1osUUFBUSxFQUFFLENBQUMsR0FBRyxTQUFTLENBQUMsUUFBUSxFQUFFLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7U0FDakUsQ0FBQztJQUNKLENBQUM7SUFFZSxLQUFLLENBQUMsWUFBWSxDQUNoQyxNQUFjLEVBQ2QsTUFBd0I7UUFFeEIsSUFBSSxDQUFDLE1BQU0sRUFBRTtZQUNYLE9BQU8sSUFBSSxDQUFDO1NBQ2I7UUFFRCxJQUFJLEVBQUUsYUFBYSxFQUFFLE9BQU8sRUFBRSxHQUFHLE1BQU0sQ0FBQztRQUV4QyxJQUFJLE9BQU8sSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxFQUFFO1lBQ3JDLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDMUMsTUFBTSxNQUFNLEdBQ1YsT0FBTyxVQUFVLEtBQUssVUFBVTtnQkFDOUIsQ0FBQyxDQUFDLE1BQU0sVUFBVSxDQUFDLElBQUksNEJBQThCLENBQUMsSUFBSSxFQUFFLE1BQU0sQ0FBQyxDQUFDO2dCQUNwRSxDQUFDLENBQUMsTUFBTSxVQUFVLENBQUM7WUFFdkIsTUFBTSxvQkFBb0IsR0FDeEIsTUFBTSxZQUFZLGtDQUFhLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMseUNBQW9CLENBQUMsZUFBZSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBRTFGLDJDQUFzQixDQUFDLFFBQVEsQ0FBQyxvQkFBb0IsRUFBRSxJQUFJLENBQUMsQ0FBQztZQUU1RCxhQUFhLEdBQUcseUNBQW9CLENBQUMsU0FBUyxDQUFDLGFBQWEsRUFBRSxvQkFBb0IsQ0FBQyxDQUFDO1lBQ3BGLE9BQU8sR0FBRyxJQUFJLENBQUM7U0FDaEI7UUFFRCxPQUFPLE1BQU0sQ0FBQyxRQUFRLENBQUMsRUFBRSxhQUFhLEVBQUUsT0FBTyxFQUFFLENBQUMsQ0FBQztJQUNyRCxDQUFDO0NBQ0Y7QUEzQ0QsNkNBMkNDIn0=
@@ -0,0 +1,4 @@
1
+ import { TCollectionName, TConditionTree, TSchema } from '../../templates';
2
+ import CollectionCustomizationContext from '../../context/collection-context';
3
+ export declare type SegmentDefinition<S extends TSchema = TSchema, N extends TCollectionName<S> = TCollectionName<S>> = ((context: CollectionCustomizationContext<S, N>) => Promise<TConditionTree<S, N>> | TConditionTree<S, N>) | TConditionTree<S, N>;
4
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvZGVjb3JhdG9ycy9zZWdtZW50L3R5cGVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiIifQ==
@@ -0,0 +1,15 @@
1
+ import { Caller, CollectionSchema, PaginatedFilter, PlainSortClause, Projection, RecordData } from '@forestadmin/datasource-toolkit';
2
+ import CollectionDecorator from '../collection-decorator';
3
+ import DataSourceDecorator from '../datasource-decorator';
4
+ export default class SortEmulate extends CollectionDecorator {
5
+ readonly dataSource: DataSourceDecorator<SortEmulate>;
6
+ private readonly sorts;
7
+ emulateFieldSorting(name: string): void;
8
+ replaceFieldSorting(name: string, equivalentSort: PlainSortClause[]): void;
9
+ list(caller: Caller, filter: PaginatedFilter, projection: Projection): Promise<RecordData[]>;
10
+ protected refineSchema(childSchema: CollectionSchema): CollectionSchema;
11
+ private sortRecords;
12
+ private rewritePlainSortClause;
13
+ private isEmulated;
14
+ }
15
+ //# sourceMappingURL=collection.d.ts.map
@@ -0,0 +1,97 @@
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 SortEmulate extends collection_decorator_1.default {
9
+ constructor() {
10
+ super(...arguments);
11
+ this.sorts = new Map();
12
+ }
13
+ emulateFieldSorting(name) {
14
+ this.replaceFieldSorting(name, null);
15
+ }
16
+ replaceFieldSorting(name, equivalentSort) {
17
+ datasource_toolkit_1.FieldValidator.validate(this, name);
18
+ const field = this.childCollection.schema.fields[name];
19
+ if (!field)
20
+ throw new Error('Cannot replace sort on relation');
21
+ this.sorts.set(name, equivalentSort ? new datasource_toolkit_1.Sort(...equivalentSort) : null);
22
+ this.markSchemaAsDirty();
23
+ }
24
+ async list(caller, filter, projection) {
25
+ const childFilter = filter.override({
26
+ sort: filter.sort?.replaceClauses(clause => this.rewritePlainSortClause(clause)),
27
+ });
28
+ if (!childFilter.sort?.some(({ field }) => this.isEmulated(field))) {
29
+ return this.childCollection.list(caller, childFilter, projection);
30
+ }
31
+ // Fetch the whole collection, but only with the fields we need to sort
32
+ let referenceRecords;
33
+ referenceRecords = await this.childCollection.list(caller, childFilter.override({ sort: null, page: null }), childFilter.sort.projection.withPks(this));
34
+ referenceRecords = childFilter.sort.apply(referenceRecords);
35
+ if (childFilter.page)
36
+ referenceRecords = childFilter.page.apply(referenceRecords);
37
+ // We now have the information we need to sort by the field
38
+ const newFilter = new datasource_toolkit_1.Filter({
39
+ conditionTree: datasource_toolkit_1.ConditionTreeFactory.matchRecords(this.schema, referenceRecords),
40
+ });
41
+ let records;
42
+ records = await this.childCollection.list(caller, newFilter, projection.withPks(this));
43
+ records = this.sortRecords(referenceRecords, records);
44
+ records = projection.apply(records);
45
+ return records;
46
+ }
47
+ refineSchema(childSchema) {
48
+ const fields = {};
49
+ for (const [name, schema] of Object.entries(childSchema.fields)) {
50
+ fields[name] =
51
+ this.sorts.has(name) && schema.type === 'Column' ? { ...schema, isSortable: true } : schema;
52
+ }
53
+ return { ...childSchema, fields };
54
+ }
55
+ sortRecords(referenceRecords, records) {
56
+ const positionById = {};
57
+ const sorted = new Array(records.length);
58
+ for (const [index, record] of referenceRecords.entries()) {
59
+ positionById[datasource_toolkit_1.RecordUtils.getPrimaryKey(this.schema, record).join('|')] = index;
60
+ }
61
+ for (const record of records) {
62
+ const id = datasource_toolkit_1.RecordUtils.getPrimaryKey(this.schema, record).join('|');
63
+ sorted[positionById[id]] = record;
64
+ }
65
+ return sorted;
66
+ }
67
+ rewritePlainSortClause(clause) {
68
+ // Order by is targeting a field on another collection => recurse.
69
+ if (clause.field.includes(':')) {
70
+ const [prefix] = clause.field.split(':');
71
+ const schema = this.schema.fields[prefix];
72
+ const association = this.dataSource.getCollection(schema.foreignCollection);
73
+ return new datasource_toolkit_1.Sort(clause)
74
+ .unnest()
75
+ .replaceClauses(subClause => association.rewritePlainSortClause(subClause))
76
+ .nest(prefix);
77
+ }
78
+ // Field that we own: recursively replace using equivalent sort
79
+ let equivalentSort = this.sorts.get(clause.field);
80
+ if (equivalentSort) {
81
+ if (!clause.ascending)
82
+ equivalentSort = equivalentSort.inverse();
83
+ return equivalentSort.replaceClauses(subClause => this.rewritePlainSortClause(subClause));
84
+ }
85
+ return new datasource_toolkit_1.Sort(clause);
86
+ }
87
+ isEmulated(path) {
88
+ const index = path.indexOf(':');
89
+ if (index === -1)
90
+ return this.sorts.has(path);
91
+ const { foreignCollection } = this.schema.fields[path.substring(0, index)];
92
+ const association = this.dataSource.getCollection(foreignCollection);
93
+ return association.isEmulated(path.substring(index + 1));
94
+ }
95
+ }
96
+ exports.default = SortEmulate;
97
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29sbGVjdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9kZWNvcmF0b3JzL3NvcnQtZW11bGF0ZS9jb2xsZWN0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsd0VBZXlDO0FBRXpDLG1GQUEwRDtBQUcxRCxNQUFxQixXQUFZLFNBQVEsOEJBQW1CO0lBQTVEOztRQUVtQixVQUFLLEdBQXNCLElBQUksR0FBRyxFQUFFLENBQUM7SUFpSHhELENBQUM7SUEvR0MsbUJBQW1CLENBQUMsSUFBWTtRQUM5QixJQUFJLENBQUMsbUJBQW1CLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDO0lBQ3ZDLENBQUM7SUFFRCxtQkFBbUIsQ0FBQyxJQUFZLEVBQUUsY0FBaUM7UUFDakUsbUNBQWMsQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDO1FBRXBDLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQWlCLENBQUM7UUFDdkUsSUFBSSxDQUFDLEtBQUs7WUFBRSxNQUFNLElBQUksS0FBSyxDQUFDLGlDQUFpQyxDQUFDLENBQUM7UUFFL0QsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLGNBQWMsQ0FBQyxDQUFDLENBQUMsSUFBSSx5QkFBSSxDQUFDLEdBQUcsY0FBYyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQzFFLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO0lBQzNCLENBQUM7SUFFUSxLQUFLLENBQUMsSUFBSSxDQUNqQixNQUFjLEVBQ2QsTUFBdUIsRUFDdkIsVUFBc0I7UUFFdEIsTUFBTSxXQUFXLEdBQUcsTUFBTSxDQUFDLFFBQVEsQ0FBQztZQUNsQyxJQUFJLEVBQUUsTUFBTSxDQUFDLElBQUksRUFBRSxjQUFjLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxJ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
@@ -0,0 +1,20 @@
1
+ import { Caller, CollectionSchema, ColumnSchema, Filter, RecordData } from '@forestadmin/datasource-toolkit';
2
+ import CollectionDecorator from '../collection-decorator';
3
+ declare type ValidationRule = ColumnSchema['validation'][number];
4
+ export default class ValidationDecorator extends CollectionDecorator {
5
+ private validation;
6
+ addValidation(name: string, validation: ValidationRule): void;
7
+ create(caller: Caller, data: RecordData[]): Promise<RecordData[]>;
8
+ update(caller: Caller, filter: Filter, patch: RecordData): Promise<void>;
9
+ protected refineSchema(subSchema: CollectionSchema): CollectionSchema;
10
+ private validate;
11
+ /**
12
+ * Deduplicate rules which the frontend understand
13
+ * We ignore other rules as duplications are not an issue within the agent
14
+ */
15
+ private static deduplicate;
16
+ private static min;
17
+ private static max;
18
+ }
19
+ export {};
20
+ //# sourceMappingURL=collection.d.ts.map