@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,28 @@
1
+ import { Caller, Collection, CompositeId, RecordData } from '@forestadmin/datasource-toolkit';
2
+ import { TCollectionName, TFieldName, TFilter, TRow, TSchema } from '../../../templates';
3
+ import CollectionCustomizationContext from '../../../context/collection-context';
4
+ export default class ActionContext<S extends TSchema = TSchema, N extends TCollectionName<S> = TCollectionName<S>> extends CollectionCustomizationContext<S, N> {
5
+ readonly formValues: any;
6
+ readonly filter: TFilter<S, N>;
7
+ private queries;
8
+ private projection;
9
+ constructor(collection: Collection, caller: Caller, formValue: RecordData, filter: TFilter<S, N>, used?: Set<string>);
10
+ /**
11
+ * Get all the records selected by an action
12
+ * @param fields An array of fields needed in the response
13
+ * @example
14
+ * .getRecords(['id', 'isActive', 'name']);
15
+ */
16
+ getRecords(fields: TFieldName<S, N>[]): Promise<TRow<S, N>[]>;
17
+ /**
18
+ * Get all the records ids selected by an action
19
+ */
20
+ getRecordIds(): Promise<Array<string | number>>;
21
+ /**
22
+ * Get all the records ids (when the collection uses composite keys)
23
+ */
24
+ getCompositeRecordIds(): Promise<CompositeId[]>;
25
+ private runQuery;
26
+ private reset;
27
+ }
28
+ //# sourceMappingURL=base.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
+ /* eslint-disable max-classes-per-file */
7
+ const datasource_toolkit_1 = require("@forestadmin/datasource-toolkit");
8
+ const collection_context_1 = __importDefault(require("../../../context/collection-context"));
9
+ class Deferred {
10
+ constructor() {
11
+ this.promise = new Promise((resolve, reject) => {
12
+ this.reject = reject;
13
+ this.resolve = resolve;
14
+ });
15
+ }
16
+ }
17
+ class ActionContext extends collection_context_1.default {
18
+ constructor(collection, caller, formValue, filter, used) {
19
+ super(collection, caller);
20
+ this.formValues = formValue;
21
+ this.filter = filter;
22
+ this.reset();
23
+ // Spy on which formValues are accessed to set-up change hooks
24
+ if (used) {
25
+ this.formValues = new Proxy(this.formValues, {
26
+ get: (target, prop, receiver) => {
27
+ if (typeof prop === 'string')
28
+ used.add(prop);
29
+ return Reflect.get(target, prop, receiver);
30
+ },
31
+ set: () => {
32
+ throw new Error('formValues is readonly');
33
+ },
34
+ });
35
+ }
36
+ }
37
+ /**
38
+ * Get all the records selected by an action
39
+ * @param fields An array of fields needed in the response
40
+ * @example
41
+ * .getRecords(['id', 'isActive', 'name']);
42
+ */
43
+ async getRecords(fields) {
44
+ // This function just queues the request into this.queries, so that we can merge all calls
45
+ // to getRecords() into a single one.
46
+ // The call to setTimeout which resolve the promises will trigger only once all handlers in
47
+ // the customer's form have been called as Promises are queued before calls to setTimeout
48
+ // in Node.js event loop
49
+ // @see https://dev.to/khaosdoctor/node-js-under-the-hood-3-deep-dive-into-the-event-loop-135d\
50
+ // #microtasks-and-macrotasks
51
+ // Ordering of micro/macro tasks in Node.js event loop
52
+ //
53
+ // @see https://github.com/graphql/dataloader
54
+ // A library from facebook from which this pattern is inspired.
55
+ datasource_toolkit_1.ProjectionValidator.validate(this.realCollection, fields);
56
+ const deferred = new Deferred();
57
+ const projection = new datasource_toolkit_1.Projection(...fields);
58
+ if (this.queries.length === 0)
59
+ setTimeout(() => this.runQuery());
60
+ this.queries.push({ projection, deferred });
61
+ this.projection = this.projection.union(projection);
62
+ return deferred.promise;
63
+ }
64
+ /**
65
+ * Get all the records ids selected by an action
66
+ */
67
+ async getRecordIds() {
68
+ const compositeIds = await this.getCompositeRecordIds();
69
+ return compositeIds.map(id => id[0]);
70
+ }
71
+ /**
72
+ * Get all the records ids (when the collection uses composite keys)
73
+ */
74
+ async getCompositeRecordIds() {
75
+ const projection = new datasource_toolkit_1.Projection().withPks(this.realCollection);
76
+ const records = await this.getRecords(projection);
77
+ return records.map(r => datasource_toolkit_1.RecordUtils.getPrimaryKey(this.realCollection.schema, r));
78
+ }
79
+ async runQuery() {
80
+ const { queries, projection } = this;
81
+ this.reset();
82
+ try {
83
+ // Run a single query which contains all fields / relations which were requested by
84
+ // the different calls made to getRecords
85
+ const records = await this.collection.list(this.filter, projection);
86
+ // Resolve each on of the promises only with the requested fields.
87
+ for (const query of queries)
88
+ query.deferred.resolve(query.projection.apply(records));
89
+ }
90
+ catch (e) {
91
+ // Rejecting each promises at next tick
92
+ // This ensures that we don't let any promise hanging forever if the customer throws in
93
+ // the rejection handler.
94
+ for (const query of queries) {
95
+ process.nextTick(() => query.deferred.reject(e));
96
+ }
97
+ }
98
+ }
99
+ reset() {
100
+ this.queries = [];
101
+ this.projection = new datasource_toolkit_1.Projection();
102
+ }
103
+ }
104
+ exports.default = ActionContext;
105
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFzZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9kZWNvcmF0b3JzL2FjdGlvbnMvY29udGV4dC9iYXNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEseUNBQXlDO0FBQ3pDLHdFQVF5QztBQUd6Qyw2RkFBaUY7QUFFakYsTUFBTSxRQUFRO0lBS1o7UUFDRSxJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksT0FBTyxDQUFDLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxFQUFFO1lBQzdDLElBQUksQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDO1lBQ3JCLElBQUksQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDO1FBQ3pCLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztDQUNGO0FBRUQsTUFBcUIsYUFHbkIsU0FBUSw0QkFBb0M7SUFPNUMsWUFDRSxVQUFzQixFQUN0QixNQUFjLEVBQ2QsU0FBcUIsRUFDckIsTUFBcUIsRUFDckIsSUFBa0I7UUFFbEIsS0FBSyxDQUFDLFVBQVUsRUFBRSxNQUFNLENBQUMsQ0FBQztRQUMxQixJQUFJLENBQUMsVUFBVSxHQUFHLFNBQVMsQ0FBQztRQUM1QixJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztRQUNyQixJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7UUFFYiw4REFBOEQ7UUFDOUQsSUFBSSxJQUFJLEVBQUU7WUFDUixJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksS0FBSyxDQUFDLElBQUksQ0FBQyxVQUFVLEVBQUU7Z0JBQzNDLEdBQUcsRUFBRSxDQUFDLE1BQU0sRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLEVBQUU7b0JBQzlCLElBQUksT0FBTyxJQUFJLEtBQUssUUFBUTt3QkFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO29CQUU3QyxPQUFPLE9BQU8sQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFLElBQUksRUFBRSxRQUFRLENBQUMsQ0FB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
@@ -0,0 +1,9 @@
1
+ import { CompositeId } from '@forestadmin/datasource-toolkit';
2
+ import { TCollectionName, TFieldName, TRow, TSchema } from '../../../templates';
3
+ import ActionContext from './base';
4
+ export default class ActionContextSingle<S extends TSchema = TSchema, N extends TCollectionName<S> = TCollectionName<S>> extends ActionContext<S, N> {
5
+ getRecordId(): Promise<string | number>;
6
+ getCompositeRecordId(): Promise<CompositeId>;
7
+ getRecord(fields: TFieldName<S, N>[]): Promise<TRow<S, N>>;
8
+ }
9
+ //# sourceMappingURL=single.d.ts.map
@@ -0,0 +1,22 @@
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 base_1 = __importDefault(require("./base"));
7
+ class ActionContextSingle extends base_1.default {
8
+ async getRecordId() {
9
+ const compositeId = await this.getCompositeRecordId();
10
+ return compositeId[0];
11
+ }
12
+ async getCompositeRecordId() {
13
+ const ids = await this.getCompositeRecordIds();
14
+ return ids[0];
15
+ }
16
+ async getRecord(fields) {
17
+ const records = await this.getRecords(fields);
18
+ return records[0];
19
+ }
20
+ }
21
+ exports.default = ActionContextSingle;
22
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2luZ2xlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2RlY29yYXRvcnMvYWN0aW9ucy9jb250ZXh0L3NpbmdsZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUVBLGtEQUFtQztBQUVuQyxNQUFxQixtQkFHbkIsU0FBUSxjQUFtQjtJQUMzQixLQUFLLENBQUMsV0FBVztRQUNmLE1BQU0sV0FBVyxHQUFHLE1BQU0sSUFBSSxDQUFDLG9CQUFvQixFQUFFLENBQUM7UUFFdEQsT0FBTyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDeEIsQ0FBQztJQUVELEtBQUssQ0FBQyxvQkFBb0I7UUFDeEIsTUFBTSxHQUFHLEdBQUcsTUFBTSxJQUFJLENBQUMscUJBQXFCLEVBQUUsQ0FBQztRQUUvQyxPQUFPLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNoQixDQUFDO0lBRUQsS0FBSyxDQUFDLFNBQVMsQ0FBQyxNQUEwQjtRQUN4QyxNQUFNLE9BQU8sR0FBRyxNQUFNLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUM7UUFFOUMsT0FBTyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDcEIsQ0FBQztDQUNGO0FBckJELHNDQXFCQyJ9
@@ -0,0 +1,53 @@
1
+ /// <reference types="node" />
2
+ import { ActionResult } from '@forestadmin/datasource-toolkit';
3
+ import { Readable } from 'stream';
4
+ export default class ResultBuilder {
5
+ /**
6
+ * Returns a success response from the action
7
+ * @param message the success message to return
8
+ * @param options available options to return
9
+ * @example
10
+ * .success('Success', { html: '<blinkee>Success!</blinkee>' });
11
+ */
12
+ success(message?: string, options?: {
13
+ html?: string;
14
+ invalidated?: string[];
15
+ }): ActionResult;
16
+ /**
17
+ * Returns an error response from the action
18
+ * @param message the error message to return
19
+ * @param options available options to return
20
+ * @example
21
+ * .error('Failed to refund the customer!', { html: '<strong>Error!</strong>' });
22
+ */
23
+ error(message?: string, options?: {
24
+ html: string;
25
+ }): ActionResult;
26
+ /**
27
+ * Returns a webhook that the UI will trigger
28
+ * @param url the url of the webhook
29
+ * @param method the HTTP method of the webhook
30
+ * @param headers an object representing the list of headers to send with the webhook
31
+ * @param body an object representing the body of the HTTP request
32
+ * @example
33
+ * .webhook('http://my-company-name', 'POST', {}, { adminToken: 'my-admin-token' });
34
+ */
35
+ webhook(url: string, method?: 'GET' | 'POST', headers?: Record<string, string>, body?: unknown): ActionResult;
36
+ /**
37
+ * Returns a file that will be downloaded
38
+ * @param streamOrBufferOrString the actual file to download
39
+ * @param name the name of the file
40
+ * @param mimeType the mime type of the file
41
+ * @example
42
+ * .file('This is my file content', 'download.txt', 'text/plain');
43
+ */
44
+ file(streamOrBufferOrString: Readable | Uint8Array | string, name?: string, mimeType?: string): ActionResult;
45
+ /**
46
+ * Returns to the UI that a redirection is needed
47
+ * @param path the path to redirect to
48
+ * @example
49
+ * .redirectTo('https://www.google.com');
50
+ */
51
+ redirectTo(path: string): ActionResult;
52
+ }
53
+ //# sourceMappingURL=result-builder.d.ts.map
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const stream_1 = require("stream");
4
+ class ResultBuilder {
5
+ /**
6
+ * Returns a success response from the action
7
+ * @param message the success message to return
8
+ * @param options available options to return
9
+ * @example
10
+ * .success('Success', { html: '<blinkee>Success!</blinkee>' });
11
+ */
12
+ success(message, options) {
13
+ return {
14
+ type: 'Success',
15
+ message: message ?? 'Success',
16
+ invalidated: new Set(options?.invalidated ?? []),
17
+ html: options?.html,
18
+ };
19
+ }
20
+ /**
21
+ * Returns an error response from the action
22
+ * @param message the error message to return
23
+ * @param options available options to return
24
+ * @example
25
+ * .error('Failed to refund the customer!', { html: '<strong>Error!</strong>' });
26
+ */
27
+ error(message, options) {
28
+ return {
29
+ type: 'Error',
30
+ message: message ?? 'Error',
31
+ html: options?.html,
32
+ };
33
+ }
34
+ /**
35
+ * Returns a webhook that the UI will trigger
36
+ * @param url the url of the webhook
37
+ * @param method the HTTP method of the webhook
38
+ * @param headers an object representing the list of headers to send with the webhook
39
+ * @param body an object representing the body of the HTTP request
40
+ * @example
41
+ * .webhook('http://my-company-name', 'POST', {}, { adminToken: 'my-admin-token' });
42
+ */
43
+ webhook(url, method = 'POST', headers = {}, body = {}) {
44
+ return {
45
+ type: 'Webhook',
46
+ url,
47
+ method,
48
+ headers,
49
+ body,
50
+ };
51
+ }
52
+ /**
53
+ * Returns a file that will be downloaded
54
+ * @param streamOrBufferOrString the actual file to download
55
+ * @param name the name of the file
56
+ * @param mimeType the mime type of the file
57
+ * @example
58
+ * .file('This is my file content', 'download.txt', 'text/plain');
59
+ */
60
+ file(streamOrBufferOrString, name = 'file', mimeType = 'application/octet-stream') {
61
+ return {
62
+ type: 'File',
63
+ name,
64
+ mimeType,
65
+ stream: streamOrBufferOrString instanceof stream_1.Readable
66
+ ? streamOrBufferOrString
67
+ : stream_1.Readable.from([streamOrBufferOrString]),
68
+ };
69
+ }
70
+ /**
71
+ * Returns to the UI that a redirection is needed
72
+ * @param path the path to redirect to
73
+ * @example
74
+ * .redirectTo('https://www.google.com');
75
+ */
76
+ redirectTo(path) {
77
+ return { type: 'Redirect', path };
78
+ }
79
+ }
80
+ exports.default = ResultBuilder;
81
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVzdWx0LWJ1aWxkZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvZGVjb3JhdG9ycy9hY3Rpb25zL3Jlc3VsdC1idWlsZGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQ0EsbUNBQWtDO0FBRWxDLE1BQXFCLGFBQWE7SUFDaEM7Ozs7OztPQU1HO0lBQ0gsT0FBTyxDQUFDLE9BQWdCLEVBQUUsT0FBbUQ7UUFDM0UsT0FBTztZQUNMLElBQUksRUFBRSxTQUFTO1lBQ2YsT0FBTyxFQUFFLE9BQU8sSUFBSSxTQUFTO1lBQzdCLFdBQVcsRUFBRSxJQUFJLEdBQUcsQ0FBQyxPQUFPLEVBQUUsV0FBVyxJQUFJLEVBQUUsQ0FBQztZQUNoRCxJQUFJLEVBQUUsT0FBTyxFQUFFLElBQUk7U0FDcEIsQ0FBQztJQUNKLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSCxLQUFLLENBQUMsT0FBZ0IsRUFBRSxPQUEwQjtRQUNoRCxPQUFPO1lBQ0wsSUFBSSxFQUFFLE9BQU87WUFDYixPQUFPLEVBQUUsT0FBTyxJQUFJLE9BQU87WUFDM0IsSUFBSSxFQUFFLE9BQU8sRUFBRSxJQUFJO1NBQ3BCLENBQUM7SUFDSixDQUFDO0lBRUQ7Ozs7Ozs7O09BUUc7SUFDSCxPQUFPLENBQ0wsR0FBVyxFQUNYLFNBQXlCLE1BQU0sRUFDL0IsVUFBa0MsRUFBRSxFQUNwQyxPQUFnQixFQUFFO1FBRWxCLE9BQU87WUFDTCxJQUFJLEVBQUUsU0FBUztZQUNmLEdBQUc7WUFDSCxNQUFNO1lBQ04sT0FBTztZQUNQLElBQUk7U0FDTCxDQUFDO0lBQ0osQ0FBQztJQUVEOzs7Ozs7O09BT0c7SUFDSCxJQUFJLENBQ0Ysc0JBQXNELEVBQ3RELElBQUksR0FBRyxNQUFNLEVBQ2IsUUFBUSxHQUFHLDBCQUEwQjtRQUVyQyxPQUFPO1lBQ0wsSUFBSSxFQUFFLE1BQU07WUFDWixJQUFJO1lBQ0osUUFBUTtZQUNSLE1BQU0sRUFDSixzQkFBc0IsWUFBWSxpQkFBUTtnQkFDeEMsQ0FBQyxDQUFDLHNCQUFzQjtnQkFDeEIsQ0FBQyxDQUFDLGlCQUFRLENBQUMsSUFBSSxDQUFDLENBQUMsc0JBQXNCLENBQUMsQ0FBQztTQUM5QyxDQUFDO0lBQ0osQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0gsVUFBVSxDQUFDLElBQVk7UUFDckIsT0FBTyxFQUFFLElBQUksRUFBRSxVQUFVLEVBQUUsSUFBSSxFQUFFLENBQUM7SUFDcEMsQ0FBQztDQUNGO0FBekZELGdDQXlGQyJ9
@@ -0,0 +1,18 @@
1
+ import { ActionResult, ActionScope } from '@forestadmin/datasource-toolkit';
2
+ import { DynamicField } from './fields';
3
+ import { TCollectionName, TSchema } from '../../../templates';
4
+ import ActionContext from '../context/base';
5
+ import ActionContextSingle from '../context/single';
6
+ import ResultBuilder from '../result-builder';
7
+ interface BaseAction<S extends TSchema, N extends TCollectionName<S>, Scope extends ActionScope, Context extends ActionContext<S, N>> {
8
+ generateFile?: boolean;
9
+ scope: Scope;
10
+ form?: DynamicField<Context>[];
11
+ execute(context: Context, resultBuilder: ResultBuilder): void | ActionResult | Promise<void> | Promise<ActionResult>;
12
+ }
13
+ export declare type ActionGlobal<S extends TSchema = TSchema, N extends TCollectionName<S> = TCollectionName<S>> = BaseAction<S, N, 'Global', ActionContext<S, N>>;
14
+ export declare type ActionBulk<S extends TSchema = TSchema, N extends TCollectionName<S> = TCollectionName<S>> = BaseAction<S, N, 'Bulk', ActionContext<S, N>>;
15
+ export declare type ActionSingle<S extends TSchema = TSchema, N extends TCollectionName<S> = TCollectionName<S>> = BaseAction<S, N, 'Single', ActionContextSingle<S, N>>;
16
+ export declare type ActionDefinition<S extends TSchema = TSchema, N extends TCollectionName<S> = TCollectionName<S>> = ActionSingle<S, N> | ActionBulk<S, N> | ActionGlobal<S, N>;
17
+ export {};
18
+ //# sourceMappingURL=actions.d.ts.map
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWN0aW9ucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9kZWNvcmF0b3JzL2FjdGlvbnMvdHlwZXMvYWN0aW9ucy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiIn0=
@@ -0,0 +1,32 @@
1
+ import { CompositeId, Json } from '@forestadmin/datasource-toolkit';
2
+ export declare type ValueOrHandler<Context = unknown, Result = unknown> = ((context: Context) => Promise<Result>) | ((context: Context) => Result) | Promise<Result> | Result;
3
+ interface BaseDynamicField<Type, Context, Result> {
4
+ type: Type;
5
+ label: string;
6
+ description?: string;
7
+ isRequired?: ValueOrHandler<Context, boolean>;
8
+ isReadOnly?: ValueOrHandler<Context, boolean>;
9
+ if?: ((context: Context) => Promise<unknown>) | ((context: Context) => unknown);
10
+ value?: ValueOrHandler<Context, Result>;
11
+ defaultValue?: ValueOrHandler<Context, Result>;
12
+ }
13
+ interface CollectionDynamicField<Context> extends BaseDynamicField<'Collection', Context, CompositeId> {
14
+ collectionName: ValueOrHandler<Context, string>;
15
+ }
16
+ interface EnumDynamicField<Context> extends BaseDynamicField<'Enum', Context, string> {
17
+ enumValues: ValueOrHandler<Context, string[]>;
18
+ }
19
+ interface EnumListDynamicField<Context> extends BaseDynamicField<'EnumList', Context, string[]> {
20
+ enumValues: ValueOrHandler<Context, string[]>;
21
+ }
22
+ declare type BooleanDynamicField<Context> = BaseDynamicField<'Boolean', Context, boolean>;
23
+ declare type FileDynamicField<Context> = BaseDynamicField<'File', Context, File>;
24
+ declare type FileListDynamicField<Context> = BaseDynamicField<'FileList', Context, File[]>;
25
+ declare type JsonDynamicField<Context> = BaseDynamicField<'Json', Context, Json>;
26
+ declare type NumberDynamicField<Context> = BaseDynamicField<'Number', Context, number>;
27
+ declare type NumberListDynamicField<Context> = BaseDynamicField<'NumberList', Context, number[]>;
28
+ declare type StringDynamicField<Context> = BaseDynamicField<'Date' | 'Dateonly' | 'String', Context, string>;
29
+ declare type StringListDynamicField<Context> = BaseDynamicField<'StringList', Context, string[]>;
30
+ export declare type DynamicField<Context = unknown> = BooleanDynamicField<Context> | CollectionDynamicField<Context> | EnumDynamicField<Context> | EnumListDynamicField<Context> | FileDynamicField<Context> | FileListDynamicField<Context> | JsonDynamicField<Context> | NumberDynamicField<Context> | NumberListDynamicField<Context> | StringDynamicField<Context> | StringListDynamicField<Context>;
31
+ export {};
32
+ //# sourceMappingURL=fields.d.ts.map
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmllbGRzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2RlY29yYXRvcnMvYWN0aW9ucy90eXBlcy9maWVsZHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiJ9
@@ -0,0 +1,11 @@
1
+ import { Caller, Chart, DataSource, DataSourceSchema } from '@forestadmin/datasource-toolkit';
2
+ import { ChartDefinition } from './types';
3
+ import DataSourceDecorator from '../datasource-decorator';
4
+ export default class ChartDataSourceDecorator extends DataSourceDecorator {
5
+ private charts;
6
+ get schema(): DataSourceSchema;
7
+ constructor(childDataSource: DataSource);
8
+ addChart(name: string, definition: ChartDefinition): void;
9
+ renderChart(caller: Caller, name: string): Promise<Chart>;
10
+ }
11
+ //# sourceMappingURL=datasource.d.ts.map
@@ -0,0 +1,38 @@
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 agent_context_1 = __importDefault(require("../../context/agent-context"));
7
+ const collection_decorator_1 = __importDefault(require("../collection-decorator"));
8
+ const datasource_decorator_1 = __importDefault(require("../datasource-decorator"));
9
+ const result_builder_1 = __importDefault(require("./result-builder"));
10
+ class ChartDataSourceDecorator extends datasource_decorator_1.default {
11
+ constructor(childDataSource) {
12
+ super(childDataSource, collection_decorator_1.default);
13
+ this.charts = {};
14
+ }
15
+ get schema() {
16
+ const myCharts = Object.keys(this.charts);
17
+ const otherCharts = this.childDataSource.schema.charts;
18
+ const duplicate = myCharts.find(name => otherCharts.includes(name));
19
+ if (duplicate)
20
+ throw new Error(`Chart '${duplicate}' is defined twice.`);
21
+ return { ...this.childDataSource.schema, charts: [...myCharts, ...otherCharts] };
22
+ }
23
+ addChart(name, definition) {
24
+ if (this.schema.charts.includes(name)) {
25
+ throw new Error(`Chart '${name}' already exists.`);
26
+ }
27
+ this.charts[name] = definition;
28
+ }
29
+ async renderChart(caller, name) {
30
+ const chartDefinition = this.charts[name];
31
+ if (chartDefinition) {
32
+ return chartDefinition(new agent_context_1.default(this, caller), new result_builder_1.default());
33
+ }
34
+ return super.renderChart(caller, name);
35
+ }
36
+ }
37
+ exports.default = ChartDataSourceDecorator;
38
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0YXNvdXJjZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9kZWNvcmF0b3JzL2NoYXJ0L2RhdGFzb3VyY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFHQSxnRkFBb0U7QUFDcEUsbUZBQTBEO0FBQzFELG1GQUEwRDtBQUMxRCxzRUFBNkM7QUFFN0MsTUFBcUIsd0JBQXlCLFNBQVEsOEJBQW1CO0lBYXZFLFlBQVksZUFBMkI7UUFDckMsS0FBSyxDQUFDLGVBQWUsRUFBRSw4QkFBbUIsQ0FBQyxDQUFDO1FBYnRDLFdBQU0sR0FBb0MsRUFBRSxDQUFDO0lBY3JELENBQUM7SUFaRCxJQUFhLE1BQU07UUFDakIsTUFBTSxRQUFRLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDMUMsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDO1FBRXZELE1BQU0sU0FBUyxHQUFHLFFBQVEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxXQUFXLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7UUFDcEUsSUFBSSxTQUFTO1lBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQyxVQUFVLFNBQVMscUJBQXFCLENBQUMsQ0FBQztRQUV6RSxPQUFPLEVBQUUsR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLE1BQU0sRUFBRSxNQUFNLEVBQUUsQ0FBQyxHQUFHLFFBQVEsRUFBRSxHQUFHLFdBQVcsQ0FBQyxFQUFFLENBQUM7SUFDbkYsQ0FBQztJQU1ELFFBQVEsQ0FBQyxJQUFZLEVBQUUsVUFBMkI7UUFDaEQsSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEVBQUU7WUFDckMsTUFBTSxJQUFJLEtBQUssQ0FBQyxVQUFVLElBQUksbUJBQW1CLENBQUMsQ0FBQztTQUNwRDtRQUVELElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsVUFBVSxDQUFDO0lBQ2pDLENBQUM7SUFFUSxLQUFLLENBQUMsV0FBVyxDQUFDLE1BQWMsRUFBRSxJQUFZO1FBQ3JELE1BQU0sZUFBZSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFMUMsSUFBSSxlQUFlLEVBQUU7WUFDbkIsT0FBTyxlQUFlLENBQUMsSUFBSSx1QkFBeUIsQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLEVBQUUsSUFBSSx3QkFBYSxFQUFFLENBQUMsQ0FBQztTQUMxRjtRQUVELE9BQU8sS0FBSyxDQUFDLFdBQVcsQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFDekMsQ0FBQztDQUNGO0FBbENELDJDQWtDQyJ9
@@ -0,0 +1,12 @@
1
+ import { DateOperation, DistributionChart, LeaderboardChart, ObjectiveChart, PercentageChart, SmartChart, TimeBasedChart, ValueChart } from '@forestadmin/datasource-toolkit';
2
+ export default class ResultBuilder {
3
+ private static readonly formats;
4
+ value(value: number, previousValue?: number): ValueChart;
5
+ distribution(obj: Record<string, number>): DistributionChart;
6
+ timeBased(timeRange: DateOperation, values: Record<string, number>): TimeBasedChart;
7
+ percentage(value: number): PercentageChart;
8
+ objective(value: number, objective: number): ObjectiveChart;
9
+ leaderboard(obj: Record<string, number>): LeaderboardChart;
10
+ smart(data: unknown): SmartChart;
11
+ }
12
+ //# sourceMappingURL=result-builder.d.ts.map
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const luxon_1 = require("luxon");
4
+ class ResultBuilder {
5
+ value(value, previousValue) {
6
+ return { countCurrent: value, countPrevious: previousValue };
7
+ }
8
+ distribution(obj) {
9
+ return Object.entries(obj).map(([key, value]) => ({ key, value }));
10
+ }
11
+ timeBased(timeRange, values) {
12
+ const format = ResultBuilder.formats[timeRange];
13
+ const formatted = {};
14
+ for (const [date, value] of Object.entries(values)) {
15
+ const label = luxon_1.DateTime.fromISO(date).toFormat(format);
16
+ formatted[label] = (formatted[label] ?? 0) + value;
17
+ }
18
+ const dataPoints = [];
19
+ const dates = Object.keys(values).sort((dateA, dateB) => dateA.localeCompare(dateB));
20
+ const first = luxon_1.DateTime.fromISO(dates[0]).startOf(timeRange.toLowerCase());
21
+ const last = luxon_1.DateTime.fromISO(dates[dates.length - 1]);
22
+ for (let current = first; current <= last; current = current.plus({ [timeRange]: 1 })) {
23
+ const label = current.toFormat(format);
24
+ dataPoints.push({ label, values: { value: formatted[label] ?? 0 } });
25
+ }
26
+ return dataPoints;
27
+ }
28
+ percentage(value) {
29
+ return value;
30
+ }
31
+ objective(value, objective) {
32
+ return { value, objective };
33
+ }
34
+ leaderboard(obj) {
35
+ return this.distribution(obj).sort((a, b) => b.value - a.value);
36
+ }
37
+ smart(data) {
38
+ return data;
39
+ }
40
+ }
41
+ exports.default = ResultBuilder;
42
+ ResultBuilder.formats = {
43
+ Day: 'dd/MM/yyyy',
44
+ Week: "'W'W-kkkk",
45
+ Month: 'MMM yy',
46
+ Year: 'yyyy',
47
+ };
48
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVzdWx0LWJ1aWxkZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvZGVjb3JhdG9ycy9jaGFydC9yZXN1bHQtYnVpbGRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQVVBLGlDQUErQztBQUUvQyxNQUFxQixhQUFhO0lBUWhDLEtBQUssQ0FBQyxLQUFhLEVBQUUsYUFBc0I7UUFDekMsT0FBTyxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQUUsYUFBYSxFQUFFLGFBQWEsRUFBRSxDQUFDO0lBQy9ELENBQUM7SUFFRCxZQUFZLENBQUMsR0FBMkI7UUFDdEMsT0FBTyxNQUFNLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsR0FBRyxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQztJQUNyRSxDQUFDO0lBRUQsU0FBUyxDQUFDLFNBQXdCLEVBQUUsTUFBOEI7UUFDaEUsTUFBTSxNQUFNLEdBQUcsYUFBYSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUNoRCxNQUFNLFNBQVMsR0FBRyxFQUFFLENBQUM7UUFFckIsS0FBSyxNQUFNLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxJQUFJLE1BQU0sQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLEVBQUU7WUFDbEQsTUFBTSxLQUFLLEdBQUcsZ0JBQVEsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ3RELFNBQVMsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUM7U0FDcEQ7UUFFRCxNQUFNLFVBQVUsR0FBRyxFQUFFLENBQUM7UUFDdEIsTUFBTSxLQUFLLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxLQUFLLEVBQUUsS0FBSyxFQUFFLEVBQUUsQ0FBQyxLQUFLLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7UUFDckYsTUFBTSxLQUFLLEdBQUcsZ0JBQVEsQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxXQUFXLEVBQWtCLENBQUMsQ0FBQztRQUMxRixNQUFNLElBQUksR0FBRyxnQkFBUSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBRXZELEtBQUssSUFBSSxPQUFPLEdBQUcsS0FBSyxFQUFFLE9BQU8sSUFBSSxJQUFJLEVBQUUsT0FBTyxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUU7WUFDckYsTUFBTSxLQUFLLEdBQUcsT0FBTyxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUN2QyxVQUFVLENBQUMsSUFBSSxDQUFDLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxFQUFFLEtBQUssRUFBRSxTQUFTLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1NBQ3RFO1FBRUQsT0FBTyxVQUFVLENBQUM7SUFDcEIsQ0FBQztJQUVELFVBQVUsQ0FBQyxLQUFhO1FBQ3RCLE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztJQUVELFNBQVMsQ0FBQyxLQUFhLEVBQUUsU0FBaUI7UUFDeEMsT0FBTyxFQUFFLEtBQUssRUFBRSxTQUFTLEVBQUUsQ0FBQztJQUM5QixDQUFDO0lBRUQsV0FBVyxDQUFDLEdBQTJCO1FBQ3JDLE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNsRSxDQUFDO0lBRUQsS0FBSyxDQUFDLElBQWE7UUFDakIsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDOztBQXBESCxnQ0FxREM7QUFwRHlCLHFCQUFPLEdBQWtDO0lBQy9ELEdBQUcsRUFBRSxZQUFZO0lBQ2pCLElBQUksRUFBRSxXQUFXO0lBQ2pCLEtBQUssRUFBRSxRQUFRO0lBQ2YsSUFBSSxFQUFFLE1BQU07Q0FDYixDQUFDIn0=
@@ -0,0 +1,6 @@
1
+ import { Chart } from '@forestadmin/datasource-toolkit';
2
+ import { TSchema } from '../../templates';
3
+ import AgentCustomizationContext from '../../context/agent-context';
4
+ import ResultBuilder from './result-builder';
5
+ export declare type ChartDefinition<S extends TSchema = TSchema> = (context: AgentCustomizationContext<S>, resultBuilder: ResultBuilder) => Promise<Chart> | Chart;
6
+ //# 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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvZGVjb3JhdG9ycy9jaGFydC90eXBlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiIn0=
@@ -0,0 +1,21 @@
1
+ import { ActionField, ActionResult, AggregateResult, Aggregation, Caller, Collection, CollectionSchema, DataSource, Filter, PaginatedFilter, Projection, RecordData } from '@forestadmin/datasource-toolkit';
2
+ export default class CollectionDecorator implements Collection {
3
+ readonly dataSource: DataSource;
4
+ protected childCollection: Collection;
5
+ private lastSchema;
6
+ private lastSubSchema;
7
+ get schema(): CollectionSchema;
8
+ get name(): string;
9
+ constructor(childCollection: Collection, dataSource: DataSource);
10
+ execute(caller: Caller, name: string, data: RecordData, filter?: Filter): Promise<ActionResult>;
11
+ getForm(caller: Caller, name: string, data?: RecordData, filter?: Filter): Promise<ActionField[]>;
12
+ create(caller: Caller, data: RecordData[]): Promise<RecordData[]>;
13
+ list(caller: Caller, filter: PaginatedFilter, projection: Projection): Promise<RecordData[]>;
14
+ update(caller: Caller, filter: Filter, patch: RecordData): Promise<void>;
15
+ delete(caller: Caller, filter: Filter): Promise<void>;
16
+ aggregate(caller: Caller, filter: Filter, aggregation: Aggregation, limit?: number): Promise<AggregateResult[]>;
17
+ protected markSchemaAsDirty(): void;
18
+ protected refineFilter(caller: Caller, filter?: PaginatedFilter): Promise<PaginatedFilter>;
19
+ protected refineSchema(subSchema: CollectionSchema): CollectionSchema;
20
+ }
21
+ //# sourceMappingURL=collection-decorator.d.ts.map
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ class CollectionDecorator {
4
+ constructor(childCollection, dataSource) {
5
+ this.childCollection = childCollection;
6
+ this.dataSource = dataSource;
7
+ }
8
+ get schema() {
9
+ const subSchema = this.childCollection.schema;
10
+ if (!this.lastSchema || this.lastSubSchema !== subSchema) {
11
+ this.lastSchema = this.refineSchema(subSchema);
12
+ this.lastSubSchema = subSchema;
13
+ }
14
+ return this.lastSchema;
15
+ }
16
+ get name() {
17
+ return this.childCollection.name;
18
+ }
19
+ async execute(caller, name, data, filter) {
20
+ const refinedFilter = await this.refineFilter(caller, filter);
21
+ return this.childCollection.execute(caller, name, data, refinedFilter);
22
+ }
23
+ async getForm(caller, name, data, filter) {
24
+ const refinedFilter = await this.refineFilter(caller, filter);
25
+ return this.childCollection.getForm(caller, name, data, refinedFilter);
26
+ }
27
+ async create(caller, data) {
28
+ return this.childCollection.create(caller, data);
29
+ }
30
+ async list(caller, filter, projection) {
31
+ const refinedFilter = await this.refineFilter(caller, filter);
32
+ return this.childCollection.list(caller, refinedFilter, projection);
33
+ }
34
+ async update(caller, filter, patch) {
35
+ const refinedFilter = await this.refineFilter(caller, filter);
36
+ return this.childCollection.update(caller, refinedFilter, patch);
37
+ }
38
+ async delete(caller, filter) {
39
+ const refinedFilter = await this.refineFilter(caller, filter);
40
+ return this.childCollection.delete(caller, refinedFilter);
41
+ }
42
+ async aggregate(caller, filter, aggregation, limit) {
43
+ const refinedFilter = await this.refineFilter(caller, filter);
44
+ return this.childCollection.aggregate(caller, refinedFilter, aggregation, limit);
45
+ }
46
+ markSchemaAsDirty() {
47
+ this.lastSchema = null;
48
+ }
49
+ async refineFilter(caller, filter) {
50
+ return filter;
51
+ }
52
+ refineSchema(subSchema) {
53
+ return subSchema;
54
+ }
55
+ }
56
+ exports.default = CollectionDecorator;
57
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29sbGVjdGlvbi1kZWNvcmF0b3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvZGVjb3JhdG9ycy9jb2xsZWN0aW9uLWRlY29yYXRvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQWVBLE1BQXFCLG1CQUFtQjtJQXNCdEMsWUFBWSxlQUEyQixFQUFFLFVBQXNCO1FBQzdELElBQUksQ0FBQyxlQUFlLEdBQUcsZUFBZSxDQUFDO1FBQ3ZDLElBQUksQ0FBQyxVQUFVLEdBQUcsVUFBVSxDQUFDO0lBQy9CLENBQUM7SUFsQkQsSUFBSSxNQUFNO1FBQ1IsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxNQUFNLENBQUM7UUFFOUMsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLElBQUksSUFBSSxDQUFDLGFBQWEsS0FBSyxTQUFTLEVBQUU7WUFDeEQsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBQy9DLElBQUksQ0FBQyxhQUFhLEdBQUcsU0FBUyxDQUFDO1NBQ2hDO1FBRUQsT0FBTyxJQUFJLENBQUMsVUFBVSxDQUFDO0lBQ3pCLENBQUM7SUFFRCxJQUFJLElBQUk7UUFDTixPQUFPLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDO0lBQ25DLENBQUM7SUFPRCxLQUFLLENBQUMsT0FBTyxDQUNYLE1BQWMsRUFDZCxJQUFZLEVBQ1osSUFBZ0IsRUFDaEIsTUFBZTtRQUVmLE1BQU0sYUFBYSxHQUFHLE1BQU0sSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFFOUQsT0FBTyxJQUFJLENBQUMsZUFBZSxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxhQUFhLENBQUMsQ0FBQztJQUN6RSxDQUFDO0lBRUQsS0FBSyxDQUFDLE9BQU8sQ0FDWCxNQUFjLEVBQ2QsSUFBWSxFQUNaLElBQWlCLEVBQ2pCLE1BQWU7UUFFZixNQUFNLGFBQWEsR0FBRyxNQUFNLElBQUksQ0FBQyxZQUFZLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBRTlELE9BQU8sSUFBSSxDQUFDLGVBQWUsQ0FBQyxPQUFPLENBQUMsTUFBTSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsYUFBYSxDQUFDLENBQUM7SUFDekUsQ0FBQztJQUVELEtBQUssQ0FBQyxNQUFNLENBQUMsTUFBYyxFQUFFLElBQWtCO1FBQzdDLE9BQU8sSUFBSSxDQUFDLGVBQWUsQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxDQUFDO0lBQ25ELENBQUM7SUFFRCxLQUFLLENBQUMsSUFBSSxDQUNSLE1BQWMsRUFDZCxNQUF1QixFQUN2QixVQUFzQjtRQUV0QixNQUFNLGFBQWEsR0FBRyxNQUFNLElBQUksQ0FBQyxZQUFZLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBRTlELE9BQU8sSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLGFBQWEsRUFBRSxVQUFVLENBQUMsQ0FBQztJQUN0RSxDQUFDO0lBRUQsS0FBSyxDQUFDLE1BQU0sQ0FBQyxNQUFjLEVBQUUsTUFBYyxFQUFFLEtBQWlCO1FBQzVELE1BQU0sYUFBYSxHQUFHLE1BQU0sSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFFOUQsT0FBTyxJQUFJLENBQUMsZUFBZSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEVBQUUsYUFBYSxFQUFFLEtBQUssQ0FBQyxDQUFDO0lBQ25FLENBQUM7SUFFRCxLQUFLLENBQUMsTUFBTSxDQUFDLE1BQWMsRUFBRSxNQUFjO1FBQ3pDLE1BQU0sYUFBYSxHQUFHLE1BQU0sSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFFOUQsT0FBTyxJQUFJLENBQUMsZUFBZSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEVBQUUsYUFBYSxDQUFDLENBQUM7SUFDNUQsQ0FBQztJQUVELEtBQUssQ0FBQyxTQUFTLENBQ2IsTUFBYyxFQUNkLE1BQWMsRUFDZCxXQUF3QixFQUN4QixLQUFjO1FBRWQsTUFBTSxhQUFhLEdBQUcsTUFBTSxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQztRQUU5RCxPQUFPLElBQUksQ0FBQyxlQUFlLENBQUMsU0FBUyxDQUFDLE1BQU0sRUFBRSxhQUFhLEVBQUUsV0FBVyxFQUFFLEtBQUssQ0FBQyxDQUFDO0lBQ25GLENBQUM7SUFFUyxpQkFBaUI7UUFDekIsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUM7SUFDekIsQ0FBQztJQUVTLEtBQUssQ0FBQyxZQUFZLENBQUMsTUFBYyxFQUFFLE1BQXdCO1FBQ25FLE9BQU8sTUFBTSxDQUFDO0lBQ2hCLENBQUM7SUFFUyxZQUFZLENBQUMsU0FBMkI7UUFDaEQsT0FBTyxTQUFTLENBQUM7SUFDbkIsQ0FBQztDQUNGO0FBakdELHNDQWlHQyJ9
@@ -0,0 +1,11 @@
1
+ import { BaseDataSource, Caller, Chart, Collection, DataSource, DataSourceSchema } from '@forestadmin/datasource-toolkit';
2
+ export default class CompositeDatasource<T extends Collection = Collection> extends BaseDataSource<T> {
3
+ private readonly datasourceChartMapping;
4
+ constructor();
5
+ addDataSource(dataSource: DataSource): CompositeDatasource;
6
+ get schema(): DataSourceSchema;
7
+ renderChart(caller: Caller, name: string): Promise<Chart>;
8
+ private addCollections;
9
+ private addCharts;
10
+ }
11
+ //# sourceMappingURL=composite-datasource.d.ts.map