@forestadmin/agent 1.0.0-beta.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 (109) hide show
  1. package/LICENSE +674 -0
  2. package/README.md +0 -0
  3. package/dist/agent/forestadmin-http-driver.d.ts +34 -0
  4. package/dist/agent/forestadmin-http-driver.js +73 -0
  5. package/dist/agent/routes/access/chart.d.ts +17 -0
  6. package/dist/agent/routes/access/chart.js +125 -0
  7. package/dist/agent/routes/access/count-related.d.ts +9 -0
  8. package/dist/agent/routes/access/count-related.js +24 -0
  9. package/dist/agent/routes/access/count.d.ts +9 -0
  10. package/dist/agent/routes/access/count.js +24 -0
  11. package/dist/agent/routes/access/csv-related.d.ts +9 -0
  12. package/dist/agent/routes/access/csv-related.js +33 -0
  13. package/dist/agent/routes/access/csv.d.ts +9 -0
  14. package/dist/agent/routes/access/csv.js +30 -0
  15. package/dist/agent/routes/access/get.d.ts +9 -0
  16. package/dist/agent/routes/access/get.js +28 -0
  17. package/dist/agent/routes/access/list-related.d.ts +9 -0
  18. package/dist/agent/routes/access/list-related.js +26 -0
  19. package/dist/agent/routes/access/list.d.ts +9 -0
  20. package/dist/agent/routes/access/list.js +23 -0
  21. package/dist/agent/routes/base-route.d.ts +14 -0
  22. package/dist/agent/routes/base-route.js +16 -0
  23. package/dist/agent/routes/collection-route.d.ts +12 -0
  24. package/dist/agent/routes/collection-route.js +20 -0
  25. package/dist/agent/routes/index.d.ts +30 -0
  26. package/dist/agent/routes/index.js +90 -0
  27. package/dist/agent/routes/modification/action.d.ts +17 -0
  28. package/dist/agent/routes/modification/action.js +103 -0
  29. package/dist/agent/routes/modification/associate-related.d.ts +12 -0
  30. package/dist/agent/routes/modification/associate-related.js +49 -0
  31. package/dist/agent/routes/modification/create.d.ts +14 -0
  32. package/dist/agent/routes/modification/create.js +81 -0
  33. package/dist/agent/routes/modification/delete.d.ts +11 -0
  34. package/dist/agent/routes/modification/delete.js +40 -0
  35. package/dist/agent/routes/modification/dissociate-delete-related.d.ts +20 -0
  36. package/dist/agent/routes/modification/dissociate-delete-related.js +88 -0
  37. package/dist/agent/routes/modification/update-relation.d.ts +11 -0
  38. package/dist/agent/routes/modification/update-relation.js +53 -0
  39. package/dist/agent/routes/modification/update.d.ts +9 -0
  40. package/dist/agent/routes/modification/update.js +29 -0
  41. package/dist/agent/routes/relation-route.d.ts +10 -0
  42. package/dist/agent/routes/relation-route.js +18 -0
  43. package/dist/agent/routes/security/authentication.d.ts +17 -0
  44. package/dist/agent/routes/security/authentication.js +86 -0
  45. package/dist/agent/routes/security/ip-whitelist.d.ts +14 -0
  46. package/dist/agent/routes/security/ip-whitelist.js +35 -0
  47. package/dist/agent/routes/security/scope-invalidation.d.ts +11 -0
  48. package/dist/agent/routes/security/scope-invalidation.js +28 -0
  49. package/dist/agent/routes/system/error-handling.d.ts +11 -0
  50. package/dist/agent/routes/system/error-handling.js +56 -0
  51. package/dist/agent/routes/system/healthcheck.d.ts +11 -0
  52. package/dist/agent/routes/system/healthcheck.js +22 -0
  53. package/dist/agent/routes/system/logger.d.ts +10 -0
  54. package/dist/agent/routes/system/logger.js +36 -0
  55. package/dist/agent/services/index.d.ts +10 -0
  56. package/dist/agent/services/index.js +12 -0
  57. package/dist/agent/services/permissions.d.ts +19 -0
  58. package/dist/agent/services/permissions.js +79 -0
  59. package/dist/agent/services/serializer.d.ts +17 -0
  60. package/dist/agent/services/serializer.js +120 -0
  61. package/dist/agent/types.d.ts +23 -0
  62. package/dist/agent/types.js +22 -0
  63. package/dist/agent/utils/body-parser.d.ts +7 -0
  64. package/dist/agent/utils/body-parser.js +18 -0
  65. package/dist/agent/utils/context-filter-factory.d.ts +7 -0
  66. package/dist/agent/utils/context-filter-factory.js +29 -0
  67. package/dist/agent/utils/csv-generator.d.ts +12 -0
  68. package/dist/agent/utils/csv-generator.js +39 -0
  69. package/dist/agent/utils/csv-route-context.d.ts +5 -0
  70. package/dist/agent/utils/csv-route-context.js +14 -0
  71. package/dist/agent/utils/forest-http-api.d.ts +63 -0
  72. package/dist/agent/utils/forest-http-api.js +173 -0
  73. package/dist/agent/utils/forest-schema/action-values.d.ts +34 -0
  74. package/dist/agent/utils/forest-schema/action-values.js +144 -0
  75. package/dist/agent/utils/forest-schema/emitter.d.ts +20 -0
  76. package/dist/agent/utils/forest-schema/emitter.js +70 -0
  77. package/dist/agent/utils/forest-schema/filterable.d.ts +16 -0
  78. package/dist/agent/utils/forest-schema/filterable.js +68 -0
  79. package/dist/agent/utils/forest-schema/generator-actions.d.ts +14 -0
  80. package/dist/agent/utils/forest-schema/generator-actions.js +99 -0
  81. package/dist/agent/utils/forest-schema/generator-collection.d.ts +7 -0
  82. package/dist/agent/utils/forest-schema/generator-collection.js +31 -0
  83. package/dist/agent/utils/forest-schema/generator-fields.d.ts +13 -0
  84. package/dist/agent/utils/forest-schema/generator-fields.js +131 -0
  85. package/dist/agent/utils/forest-schema/generator-segments.d.ts +6 -0
  86. package/dist/agent/utils/forest-schema/generator-segments.js +9 -0
  87. package/dist/agent/utils/forest-schema/types.d.ts +79 -0
  88. package/dist/agent/utils/forest-schema/types.js +16 -0
  89. package/dist/agent/utils/forest-schema/validation.d.ts +10 -0
  90. package/dist/agent/utils/forest-schema/validation.js +26 -0
  91. package/dist/agent/utils/http-driver-options.d.ts +13 -0
  92. package/dist/agent/utils/http-driver-options.js +86 -0
  93. package/dist/agent/utils/id.d.ts +8 -0
  94. package/dist/agent/utils/id.js +43 -0
  95. package/dist/agent/utils/query-string.d.ts +14 -0
  96. package/dist/agent/utils/query-string.js +130 -0
  97. package/dist/builder/agent.d.ts +81 -0
  98. package/dist/builder/agent.js +113 -0
  99. package/dist/builder/collection.d.ts +148 -0
  100. package/dist/builder/collection.js +226 -0
  101. package/dist/builder/types.d.ts +5 -0
  102. package/dist/builder/types.js +3 -0
  103. package/dist/index.d.ts +5 -0
  104. package/dist/index.js +22 -0
  105. package/dist/types.d.ts +22 -0
  106. package/dist/types.js +11 -0
  107. package/dist/utils/csv-generator.d.ts +12 -0
  108. package/dist/utils/csv-generator.js +39 -0
  109. package/package.json +55 -0
@@ -0,0 +1,130 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const datasource_toolkit_1 = require("@forestadmin/datasource-toolkit");
4
+ const DEFAULT_ITEMS_PER_PAGE = 15;
5
+ const DEFAULT_PAGE_TO_SKIP = 1;
6
+ class QueryStringParser {
7
+ static parseConditionTree(collection, context) {
8
+ try {
9
+ const filters = context.request.body?.data?.attributes?.all_records_subset_query?.filters ??
10
+ context.request.body?.filters ??
11
+ context.request.query?.filters;
12
+ if (!filters)
13
+ return null;
14
+ const json = JSON.parse(filters.toString());
15
+ const conditionTree = datasource_toolkit_1.ConditionTreeFactory.fromPlainObject(json);
16
+ datasource_toolkit_1.ConditionTreeValidator.validate(conditionTree, collection);
17
+ return conditionTree;
18
+ }
19
+ catch (e) {
20
+ throw new datasource_toolkit_1.ValidationError(`Invalid filters (${e.message})`);
21
+ }
22
+ }
23
+ static parseProjection(collection, context) {
24
+ try {
25
+ const fields = context.request.query[`fields[${collection.name}]`];
26
+ if (fields === '' || fields === undefined) {
27
+ return datasource_toolkit_1.ProjectionFactory.all(collection);
28
+ }
29
+ const rootFields = fields.toString().split(',');
30
+ const explicitRequest = rootFields.map(field => {
31
+ const schema = collection.schema.fields[field];
32
+ return schema.type === 'Column'
33
+ ? field
34
+ : `${field}:${context.request.query[`fields[${field}]`]}`;
35
+ });
36
+ datasource_toolkit_1.ProjectionValidator.validate(collection, explicitRequest);
37
+ return new datasource_toolkit_1.Projection(...explicitRequest);
38
+ }
39
+ catch (e) {
40
+ throw new datasource_toolkit_1.ValidationError(`Invalid projection`);
41
+ }
42
+ }
43
+ static parseProjectionWithPks(collection, context) {
44
+ const projection = QueryStringParser.parseProjection(collection, context);
45
+ // Primary keys are not explicitly listed in the projections that the frontend
46
+ // is sending, but are still required for the frontend to work.
47
+ return projection.withPks(collection);
48
+ }
49
+ static parseSearch(collection, context) {
50
+ const search = context.request.body?.data?.attributes?.all_records_subset_query?.search?.toString() ??
51
+ context.request.query.search?.toString();
52
+ if (search && !collection.schema.searchable) {
53
+ throw new datasource_toolkit_1.ValidationError(`Collection is not searchable`);
54
+ }
55
+ return search ?? null;
56
+ }
57
+ static parseSearchExtended(context) {
58
+ const { request } = context;
59
+ const extended = request.body?.data?.attributes?.all_records_subset_query?.searchExtended?.toString() ??
60
+ request.query.searchExtended?.toString();
61
+ return !!extended && extended !== '0' && extended !== 'false';
62
+ }
63
+ static parseSegment(collection, context) {
64
+ const segment = context.request.body?.data?.attributes?.all_records_subset_query?.segment?.toString() ??
65
+ context.request.query.segment?.toString();
66
+ if (!segment) {
67
+ return null;
68
+ }
69
+ if (!collection.schema.segments.includes(segment)) {
70
+ throw new datasource_toolkit_1.ValidationError(`Invalid segment: "${segment}"`);
71
+ }
72
+ return segment;
73
+ }
74
+ static parseTimezone(context) {
75
+ const timezone = context.request.query.timezone?.toString();
76
+ if (!timezone) {
77
+ throw new datasource_toolkit_1.ValidationError('Missing timezone');
78
+ }
79
+ // This is a method to validate a timezone using node only
80
+ // @see https://stackoverflow.com/questions/44115681
81
+ if (!Intl || !Intl.DateTimeFormat().resolvedOptions().timeZone) {
82
+ throw new Error('Time zones are not available in this environment');
83
+ }
84
+ try {
85
+ Intl.DateTimeFormat('en-US', { timeZone: timezone });
86
+ }
87
+ catch {
88
+ throw new datasource_toolkit_1.ValidationError(`Invalid timezone: "${timezone}"`);
89
+ }
90
+ return timezone;
91
+ }
92
+ static parsePagination(context) {
93
+ const queryItemsPerPage = (context.request.body?.data?.attributes?.all_records_subset_query?.['page[size]'] ??
94
+ context.request.query['page[size]'] ??
95
+ DEFAULT_ITEMS_PER_PAGE).toString();
96
+ const queryPageToSkip = (context.request.body?.data?.attributes?.all_records_subset_query?.['page[number]'] ??
97
+ context.request.query['page[number]'] ??
98
+ DEFAULT_PAGE_TO_SKIP).toString();
99
+ const itemsPerPage = Number.parseInt(queryItemsPerPage, 10);
100
+ let pageToSkip = Number.parseInt(queryPageToSkip, 10);
101
+ if (Number.isNaN(itemsPerPage) ||
102
+ Number.isNaN(pageToSkip) ||
103
+ itemsPerPage <= 0 ||
104
+ pageToSkip <= 0) {
105
+ throw new datasource_toolkit_1.ValidationError(`Invalid pagination [limit: ${itemsPerPage}, skip: ${pageToSkip}]`);
106
+ }
107
+ pageToSkip = Math.max(pageToSkip - 1, 0);
108
+ pageToSkip *= itemsPerPage;
109
+ return new datasource_toolkit_1.Page(pageToSkip, itemsPerPage);
110
+ }
111
+ static parseSort(collection, context) {
112
+ const sortString = context.request.body?.data?.attributes?.all_records_subset_query?.sort?.toString() ??
113
+ context.request.query.sort?.toString();
114
+ try {
115
+ if (!sortString)
116
+ return datasource_toolkit_1.SortFactory.byPrimaryKeys(collection);
117
+ const sort = new datasource_toolkit_1.Sort({
118
+ field: sortString.replace(/^-/, '').replace('.', ':'),
119
+ ascending: !sortString.startsWith('-'),
120
+ });
121
+ datasource_toolkit_1.SortValidator.validate(collection, sort);
122
+ return sort;
123
+ }
124
+ catch {
125
+ throw new datasource_toolkit_1.ValidationError(`Invalid sort: ${sortString}`);
126
+ }
127
+ }
128
+ }
129
+ exports.default = QueryStringParser;
130
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicXVlcnktc3RyaW5nLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2FnZW50L3V0aWxzL3F1ZXJ5LXN0cmluZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLHdFQWF5QztBQUd6QyxNQUFNLHNCQUFzQixHQUFHLEVBQUUsQ0FBQztBQUNsQyxNQUFNLG9CQUFvQixHQUFHLENBQUMsQ0FBQztBQUUvQixNQUFxQixpQkFBaUI7SUFDcEMsTUFBTSxDQUFDLGtCQUFrQixDQUFDLFVBQXNCLEVBQUUsT0FBZ0I7UUFDaEUsSUFBSTtZQUNGLE1BQU0sT0FBTyxHQUNYLE9BQU8sQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxVQUFVLEVBQUUsd0JBQXdCLEVBQUUsT0FBTztnQkFDekUsT0FBTyxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsT0FBTztnQkFDN0IsT0FBTyxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsT0FBTyxDQUFDO1lBRWpDLElBQUksQ0FBQyxPQUFPO2dCQUFFLE9BQU8sSUFBSSxDQUFDO1lBRTFCLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUM7WUFDNUMsTUFBTSxhQUFhLEdBQUcseUNBQW9CLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ2pFLDJDQUFzQixDQUFDLFFBQVEsQ0FBQyxhQUFhLEVBQUUsVUFBVSxDQUFDLENBQUM7WUFFM0QsT0FBTyxhQUFhLENBQUM7U0FDdEI7UUFBQyxPQUFPLENBQUMsRUFBRTtZQUNWLE1BQU0sSUFBSSxvQ0FBZSxDQUFDLG9CQUFvQixDQUFDLENBQUMsT0FBTyxHQUFHLENBQUMsQ0FBQztTQUM3RDtJQUNILENBQUM7SUFFRCxNQUFNLENBQUMsZUFBZSxDQUFDLFVBQXNCLEVBQUUsT0FBZ0I7UUFDN0QsSUFBSTtZQUNGLE1BQU0sTUFBTSxHQUFHLE9BQU8sQ0FBQyxPQUFP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
@@ -0,0 +1,81 @@
1
+ import { ActionCollectionDecorator, BaseDataSource, Collection, ComputedCollectionDecorator, DataSource, DataSourceDecorator, OperatorsEmulateCollectionDecorator, OperatorsReplaceCollectionDecorator, PublicationCollectionDecorator, RelationCollectionDecorator, RenameCollectionDecorator, SearchCollectionDecorator, SegmentCollectionDecorator, SortEmulateCollectionDecorator, WriteCollectionDecorator } from '@forestadmin/datasource-toolkit';
2
+ import { AgentOptions } from '../types';
3
+ import CollectionBuilder from './collection';
4
+ import ForestAdminHttpDriver, { HttpCallback } from '../agent/forestadmin-http-driver';
5
+ /**
6
+ * Allow to create a new Forest Admin agent from scratch.
7
+ * Builds the application by composing and configuring all the collection decorators.
8
+ *
9
+ * Minimal code to add a datasource
10
+ * @example
11
+ * new AgentBuilder(options)
12
+ * .addDatasource(new SomeDatasource())
13
+ * .start();
14
+ */
15
+ export default class AgentBuilder {
16
+ forestAdminHttpDriver: ForestAdminHttpDriver;
17
+ compositeDatasource: BaseDataSource<Collection>;
18
+ action: DataSourceDecorator<ActionCollectionDecorator>;
19
+ earlyComputed: DataSourceDecorator<ComputedCollectionDecorator>;
20
+ earlyOpEmulate: DataSourceDecorator<OperatorsEmulateCollectionDecorator>;
21
+ earlyOpReplace: DataSourceDecorator<OperatorsReplaceCollectionDecorator>;
22
+ relation: DataSourceDecorator<RelationCollectionDecorator>;
23
+ lateComputed: DataSourceDecorator<ComputedCollectionDecorator>;
24
+ lateOpEmulate: DataSourceDecorator<OperatorsEmulateCollectionDecorator>;
25
+ lateOpReplace: DataSourceDecorator<OperatorsReplaceCollectionDecorator>;
26
+ publication: DataSourceDecorator<PublicationCollectionDecorator>;
27
+ rename: DataSourceDecorator<RenameCollectionDecorator>;
28
+ search: DataSourceDecorator<SearchCollectionDecorator>;
29
+ segment: DataSourceDecorator<SegmentCollectionDecorator>;
30
+ sortEmulate: DataSourceDecorator<SortEmulateCollectionDecorator>;
31
+ write: DataSourceDecorator<WriteCollectionDecorator>;
32
+ /**
33
+ * Native nodejs HttpCallback object
34
+ * @example
35
+ * import http from 'http';
36
+ * ...
37
+ * const server = http.createServer(agent.httpCallback);
38
+ */
39
+ get httpCallback(): HttpCallback;
40
+ /**
41
+ * Create a new Agent Builder.
42
+ * If any options are missing, the default will be applied:
43
+ * ```
44
+ * clientId: null,
45
+ * forestServerUrl: 'https://api.forestadmin.com',
46
+ * logger: (level, data) => console.error(OptionsUtils.loggerPrefix[level], data),
47
+ * prefix: '/forest',
48
+ * schemaPath: '.forestadmin-schema.json',
49
+ * permissionsCacheDurationInSeconds: 15 * 60,
50
+ * ```
51
+ * @param {AgentOptions} options options
52
+ * @example
53
+ * new AgentBuilder(options)
54
+ * .addDatasource(new Datasource())
55
+ * .start();
56
+ */
57
+ constructor(options: AgentOptions);
58
+ /**
59
+ * Add a datasource
60
+ * @param {DataSource} datasource the datasource to add
61
+ */
62
+ addDatasource(datasource: DataSource): this;
63
+ /**
64
+ * Allow to interact with a decorated collection
65
+ * @param {string} name the name of the collection to manipulate
66
+ * @param {(collection: CollectionBuilder) => unknown} handle a function that provide a
67
+ * collection builder on the given collection name
68
+ * @example
69
+ * .customizeCollection('books', books => books.renameField('xx', 'yy'))
70
+ */
71
+ customizeCollection(name: string, handle: (collection: CollectionBuilder) => unknown): this;
72
+ /**
73
+ * Start the agent.
74
+ */
75
+ start(): Promise<void>;
76
+ /**
77
+ * Stop the agent gracefully.
78
+ */
79
+ stop(): Promise<void>;
80
+ }
81
+ //# sourceMappingURL=agent.d.ts.map
@@ -0,0 +1,113 @@
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_1 = __importDefault(require("./collection"));
8
+ const forestadmin_http_driver_1 = __importDefault(require("../agent/forestadmin-http-driver"));
9
+ /**
10
+ * Allow to create a new Forest Admin agent from scratch.
11
+ * Builds the application by composing and configuring all the collection decorators.
12
+ *
13
+ * Minimal code to add a datasource
14
+ * @example
15
+ * new AgentBuilder(options)
16
+ * .addDatasource(new SomeDatasource())
17
+ * .start();
18
+ */
19
+ class AgentBuilder {
20
+ /**
21
+ * Create a new Agent Builder.
22
+ * If any options are missing, the default will be applied:
23
+ * ```
24
+ * clientId: null,
25
+ * forestServerUrl: 'https://api.forestadmin.com',
26
+ * logger: (level, data) => console.error(OptionsUtils.loggerPrefix[level], data),
27
+ * prefix: '/forest',
28
+ * schemaPath: '.forestadmin-schema.json',
29
+ * permissionsCacheDurationInSeconds: 15 * 60,
30
+ * ```
31
+ * @param {AgentOptions} options options
32
+ * @example
33
+ * new AgentBuilder(options)
34
+ * .addDatasource(new Datasource())
35
+ * .start();
36
+ */
37
+ constructor(options) {
38
+ let last;
39
+ /* eslint-disable no-multi-assign */
40
+ last = this.compositeDatasource = new datasource_toolkit_1.BaseDataSource();
41
+ // Step 1: Computed-Relation-Computed sandwich (needed because some emulated relations depend
42
+ // on computed fields, and some computed fields depend on relation...)
43
+ // Note that replacement goes before emulation, as replacements may use emulated operators.
44
+ last = this.earlyComputed = new datasource_toolkit_1.DataSourceDecorator(last, datasource_toolkit_1.ComputedCollectionDecorator);
45
+ last = this.earlyOpEmulate = new datasource_toolkit_1.DataSourceDecorator(last, datasource_toolkit_1.OperatorsEmulateCollectionDecorator);
46
+ last = this.earlyOpReplace = new datasource_toolkit_1.DataSourceDecorator(last, datasource_toolkit_1.OperatorsReplaceCollectionDecorator);
47
+ last = this.relation = new datasource_toolkit_1.DataSourceDecorator(last, datasource_toolkit_1.RelationCollectionDecorator);
48
+ last = this.lateComputed = new datasource_toolkit_1.DataSourceDecorator(last, datasource_toolkit_1.ComputedCollectionDecorator);
49
+ last = this.lateOpEmulate = new datasource_toolkit_1.DataSourceDecorator(last, datasource_toolkit_1.OperatorsEmulateCollectionDecorator);
50
+ last = this.lateOpReplace = new datasource_toolkit_1.DataSourceDecorator(last, datasource_toolkit_1.OperatorsReplaceCollectionDecorator);
51
+ // Step 2: Those five need access to all fields. They can be loaded in any order.
52
+ last = this.publication = new datasource_toolkit_1.DataSourceDecorator(last, datasource_toolkit_1.PublicationCollectionDecorator);
53
+ last = this.search = new datasource_toolkit_1.DataSourceDecorator(last, datasource_toolkit_1.SearchCollectionDecorator);
54
+ last = this.segment = new datasource_toolkit_1.DataSourceDecorator(last, datasource_toolkit_1.SegmentCollectionDecorator);
55
+ last = this.sortEmulate = new datasource_toolkit_1.DataSourceDecorator(last, datasource_toolkit_1.SortEmulateCollectionDecorator);
56
+ last = this.write = new datasource_toolkit_1.DataSourceDecorator(last, datasource_toolkit_1.WriteCollectionDecorator);
57
+ // Step 3: Access to all fields AND emulated capabilities
58
+ last = this.action = new datasource_toolkit_1.DataSourceDecorator(last, datasource_toolkit_1.ActionCollectionDecorator);
59
+ // Step 4: Renaming must be either the very first or very last so that naming in customer code
60
+ // is consistent.
61
+ last = this.rename = new datasource_toolkit_1.DataSourceDecorator(last, datasource_toolkit_1.RenameCollectionDecorator);
62
+ /* eslint-enable no-multi-assign */
63
+ this.forestAdminHttpDriver = new forestadmin_http_driver_1.default(last, options);
64
+ }
65
+ /**
66
+ * Native nodejs HttpCallback object
67
+ * @example
68
+ * import http from 'http';
69
+ * ...
70
+ * const server = http.createServer(agent.httpCallback);
71
+ */
72
+ get httpCallback() {
73
+ return this.forestAdminHttpDriver.handler;
74
+ }
75
+ /**
76
+ * Add a datasource
77
+ * @param {DataSource} datasource the datasource to add
78
+ */
79
+ addDatasource(datasource) {
80
+ datasource.collections.forEach(collection => {
81
+ this.compositeDatasource.addCollection(collection);
82
+ });
83
+ return this;
84
+ }
85
+ /**
86
+ * Allow to interact with a decorated collection
87
+ * @param {string} name the name of the collection to manipulate
88
+ * @param {(collection: CollectionBuilder) => unknown} handle a function that provide a
89
+ * collection builder on the given collection name
90
+ * @example
91
+ * .customizeCollection('books', books => books.renameField('xx', 'yy'))
92
+ */
93
+ customizeCollection(name, handle) {
94
+ if (this.publication.getCollection(name)) {
95
+ handle(new collection_1.default(this, name));
96
+ }
97
+ return this;
98
+ }
99
+ /**
100
+ * Start the agent.
101
+ */
102
+ async start() {
103
+ return this.forestAdminHttpDriver.start();
104
+ }
105
+ /**
106
+ * Stop the agent gracefully.
107
+ */
108
+ async stop() {
109
+ return this.forestAdminHttpDriver.stop();
110
+ }
111
+ }
112
+ exports.default = AgentBuilder;
113
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWdlbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYnVpbGRlci9hZ2VudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLHdFQWdCeUM7QUFHekMsOERBQTZDO0FBQzdDLCtGQUF1RjtBQUV2Rjs7Ozs7Ozs7O0dBU0c7QUFDSCxNQUFxQixZQUFZO0lBa0MvQjs7Ozs7Ozs7Ozs7Ozs7OztPQWdCRztJQUNILFlBQVksT0FBcUI7UUFDL0IsSUFBSSxJQUFnQixDQUFDO1FBRXJCLG9DQUFvQztRQUNwQyxJQUFJLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixHQUFHLElBQUksbUNBQWMsRUFBYyxDQUFDO1FBRW5FLDZGQUE2RjtRQUM3RixzRUFBc0U7UUFDdEUsMkZBQTJGO1FBQzNGLElBQUksR0FBRyxJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksd0NBQW1CLENBQUMsSUFBSSxFQUFFLGdEQUEyQixDQUFDLENBQUM7UUFDdkYsSUFBSSxHQUFHLElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSx3Q0FBbUIsQ0FBQyxJQUFJLEVBQUUsd0RBQW1DLENBQUMsQ0FBQztRQUNoRyxJQUFJLEdBQUcsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLHdDQUFtQixDQUFDLElBQUksRUFBRSx3REFBbUMsQ0FBQyxDQUFDO1FBQ2hHLElBQUksR0FBRyxJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksd0NBQW1CLENBQUMsSUFBSSxFQUFFLGdEQUEyQixDQUFDLENBQUM7UUFDbEYsSUFBSSxHQUFHLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSx3Q0FBbUIsQ0FBQyxJQUFJLEVBQUUsZ0RBQTJCLENBQUMsQ0FBQztRQUN0RixJQUFJLEdBQUcsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLHdDQUFtQixDQUFDLElBQUksRUFBRSx3REFBbUMsQ0FBQyxDQUFDO1FBQy9GLElBQUksR0FBRyxJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksd0NBQW1CLENBQUMsSUFBSSxFQUFFLHdEQUFtQyxDQUFDLENBQUM7UUFFL0YsaUZBQWlGO1FBQ2pGLElBQUksR0FBRyxJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksd0NBQW1CLENBQUMsSUFBSSxFQUFFLG1EQUE4QixDQUFDLENBQUM7UUFDeEYsSUFBSSxHQUFHLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSx3Q0FBbUIsQ0FBQyxJQUFJLEVBQUUsOENBQXlCLENBQUMsQ0FBQztRQUM5RSxJQUFJLEdBQUcsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLHdDQUFtQixDQUFDLElBQUksRUFBRSwrQ0FBMEIsQ0FBQyxDQUFDO1FBQ2hGLElBQUksR0FBRyxJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksd0NBQW1CLENBQUMsSUFBSSxFQUFFLG1EQUE4QixDQUFDLENBQUM7UUFDeEYsSUFBSSxHQUFHLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSx3Q0FBbUIsQ0FBQyxJQUFJLEVBQUUsNkNBQXdCLENBQUMsQ0FBQztRQUU1RSx5REFBeUQ7UUFDekQsSUFBSSxHQUFHLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSx3Q0FBbUIsQ0FBQyxJQUFJLEVBQUUsOENBQXlCLENBQUMsQ0FBQztRQUU5RSw4RkFBOEY7UUFDOUYsaUJBQWlCO1FBQ2pCLElBQUksR0FBRyxJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksd0NBQW1CLENBQUMsSUFBSSxFQUFFLDhDQUF5QixDQUFDLENBQUM7UUFFOUUsbUNBQW1DO1FBRW5DLElBQUksQ0FBQyxxQkFBcUIsR0FBRyxJQUFJLGlDQUFxQixDQUFDLElBQUksRUFBRSxPQUFPLENBQUMsQ0FBQztJQUN4RSxDQUFDO0lBOUREOzs7Ozs7T0FNRztJQUNILElBQUksWUFBWTtRQUNkLE9BQU8sSUFBSSxDQUFDLHFCQUFxQixDQUFDLE9BQU8sQ0FBQztJQUM1QyxDQUFDO0lBdUREOzs7T0FHRztJQUNILGFBQWEsQ0FBQyxVQUFzQjtRQUNsQyxVQUFVLENBQUMsV0FBVyxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsRUFBRTtZQUMxQyxJQUFJLENBQUMsbUJBQW1CLENBQUMsYUFBYSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ3JELENBQUMsQ0FBQyxDQUFDO1FBRUgsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQ7Ozs7Ozs7T0FPRztJQUNILG1CQUFtQixDQUFDLElBQVksRUFBRSxNQUFrRDtRQUNsRixJQUFJLElBQUksQ0FBQyxXQUFXLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxFQUFFO1lBQ3hDLE1BQU0sQ0FBQyxJQUFJLG9CQUFpQixDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDO1NBQzNDO1FBRUQsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQ7O09BRUc7SUFDSCxLQUFLLENBQUMsS0FBSztRQUNULE9BQU8sSUFBSSxDQUFDLHFCQUFxQixDQUFDLEtBQUssRUFBRSxDQUFDO0lBQzVDLENBQUM7SUFFRDs7T0FFRztJQUNILEtBQUssQ0FBQyxJQUFJO1FBQ1IsT0FBTyxJQUFJLENBQUMscUJBQXFCLENBQUMsSUFBSSxFQUFFLENBQUM7SUFDM0MsQ0FBQztDQUNGO0FBaElELCtCQWdJQyJ9
@@ -0,0 +1,148 @@
1
+ import { ActionDefinition, Operator, OperatorReplacer, PartialRelationSchema, PlainSortClause, SegmentDefinition, WriteDefinition } from '@forestadmin/datasource-toolkit';
2
+ import { FieldDefinition } from './types';
3
+ import AgentBuilder from './agent';
4
+ export default class CollectionBuilder {
5
+ private agentBuilder;
6
+ private readonly name;
7
+ constructor(agentBuilder: AgentBuilder, name: string);
8
+ /**
9
+ * Import a field from a many to one or one to one relation.
10
+ *
11
+ * @param name the name of the field that will be created on the collection
12
+ * @param options options to import the field
13
+ * @example
14
+ * .importField('authorName', { path: 'author:fullName' })
15
+ */
16
+ importField(name: string, options: {
17
+ path: string;
18
+ beforeRelations?: boolean;
19
+ }): this;
20
+ /**
21
+ * Allow to rename a field of a given collection.
22
+ * @param {string} oldName the current name of the field in a given collection
23
+ * @param {string} newName the new name of the field
24
+ * @example
25
+ * .renameField('theCurrentNameOfTheField', 'theNewNameOfTheField');
26
+ */
27
+ renameField(oldName: string, newName: string): this;
28
+ /**
29
+ * Remove field by setting its visibility to false.
30
+ * @param {...string[]} names the fields to remove
31
+ * @example
32
+ * .removeField('aFieldToRemove', 'anOtherFieldToRemove');
33
+ */
34
+ removeField(...names: string[]): this;
35
+ /**
36
+ * Add a new action on the collection.
37
+ * @param {string} name the name of the action
38
+ * @param {ActionDefinition} definition the definition of the action
39
+ * @example
40
+ * .addAction('is live', {
41
+ * scope: 'Single',
42
+ * execute: async (context, responseBuilder) => {
43
+ * return responseBuilder.success(`Is live!`);
44
+ * },
45
+ * })
46
+ */
47
+ addAction(name: string, definition: ActionDefinition): this;
48
+ /**
49
+ * Add a new field on the collection.
50
+ * @param {string} name the name of the field
51
+ * @param {FieldDefinition} definition The definition of the field
52
+ * @example
53
+ * .addField('fullName', {
54
+ * columnType: 'String',
55
+ * dependencies: ['firstName', 'lastName'],
56
+ * getValues: (records) => records.map(record => `${record.lastName} ${record.firstName}`),
57
+ * });
58
+ */
59
+ addField(name: string, definition: FieldDefinition): this;
60
+ /**
61
+ * Add a relation between two collections.
62
+ * @param name name of the new relation
63
+ * @param definition definition of the new relation
64
+ * @example
65
+ * .addRelation('author', {
66
+ * type: 'ManyToOne',
67
+ * foreignCollection: 'persons',
68
+ * foreignKey: 'authorId'
69
+ * });
70
+ */
71
+ addRelation(name: string, definition: PartialRelationSchema): this;
72
+ /**
73
+ * Add a new segment on the collection.
74
+ * @param {string} name the name of the segment
75
+ * @param {SegmentDefinition} definition a function used to generate a condition tree
76
+ * or a condition tree
77
+ * @example
78
+ * .addSegment(
79
+ * 'Wrote more than 2 books',
80
+ * new ConditionTreeLeaf('booksCount', 'GreaterThan', 2),
81
+ * );
82
+ */
83
+ addSegment(name: string, definition: SegmentDefinition): this;
84
+ /**
85
+ * Enable sorting on a specific field using emulation.
86
+ * As for all the emulation method, the field sorting will be done in-memory.
87
+ * @param {string} name the name of the field to enable emulation on
88
+ * @example
89
+ * .emulateFieldSorting('fullName');
90
+ */
91
+ emulateFieldSorting(name: string): this;
92
+ /**
93
+ * Replace an implementation for the sorting.
94
+ * The field sorting will be done by the datasource.
95
+ * @param {string} name the name of the field to enable sort
96
+ * @param {SortClause[]} equivalentSort the sort equivalent
97
+ * @example
98
+ * .replaceFieldSorting(
99
+ * 'fullName',
100
+ * [
101
+ * { field: 'firstName', ascending: true },
102
+ * { field: 'lastName', ascending: true },
103
+ * ]
104
+ * )
105
+ */
106
+ replaceFieldSorting(name: string, equivalentSort: PlainSortClause[]): this;
107
+ /**
108
+ * Enable filtering on a specific field using emulation.
109
+ * As for all the emulation method, the field filtering will be done in-memory.
110
+ * @param name the name of the field to enable emulation on
111
+ * @example
112
+ * .emulateFieldFiltering('aField');
113
+ */
114
+ emulateFieldFiltering(name: string): this;
115
+ /**
116
+ * Enable filtering on a specific field with a specific operator using emulation.
117
+ * As for all the emulation method, the field filtering will be done in-memory.
118
+ * @param {string} name the name of the field to enable emulation on
119
+ * @param {Operator} operator the operator to emulate
120
+ * @example
121
+ * .emulateFieldOperator('aField', 'In');
122
+ */
123
+ emulateFieldOperator(name: string, operator: Operator): this;
124
+ /**
125
+ * Replace an implementation for a specific operator on a specific field.
126
+ * The operator replacement will be done by the datasource.
127
+ * @param {string} name the name of the field to filter on
128
+ * @param {Operator} operator the operator to replace
129
+ * @param {OperatorReplacer} replacer the proposed implementation
130
+ * @example
131
+ * .replaceFieldOperator('booksCount', 'Equal', ({ value }) => new ConditionTreeNot(
132
+ * new ConditionTreeLeaf('booksCount', 'Equal', value),
133
+ * ));
134
+ */
135
+ replaceFieldOperator(name: string, operator: Operator, replacer: OperatorReplacer): this;
136
+ /**
137
+ * Replace the write behavior of a field.
138
+ * @param {string} name the name of the field
139
+ * @param {WriteDefinition} definition the function or a value to represent the write behavior
140
+ * @example
141
+ * .replaceFieldWriting('fullName', ({ patch: fullName }) => {
142
+ * const [firstName, lastName] = fullName.split(' ');
143
+ * return { firstName, lastName };
144
+ * });
145
+ */
146
+ replaceFieldWriting(name: string, definition: WriteDefinition): this;
147
+ }
148
+ //# sourceMappingURL=collection.d.ts.map