@forestadmin/agent 1.0.0-beta.25 → 1.0.0-beta.28

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,32 @@
1
+ # @forestadmin/agent [1.0.0-beta.28](https://github.com/ForestAdmin/agent-nodejs/compare/@forestadmin/agent@1.0.0-beta.27...@forestadmin/agent@1.0.0-beta.28) (2022-05-18)
2
+
3
+
4
+ ### Features
5
+
6
+ * compatibility with Express.js, Koa, Fastify & NestJS ([#300](https://github.com/ForestAdmin/agent-nodejs/issues/300)) ([904639e](https://github.com/ForestAdmin/agent-nodejs/commit/904639ec66f4116b3c5557d83ec43656e55ccbbc))
7
+
8
+ # @forestadmin/agent [1.0.0-beta.27](https://github.com/ForestAdmin/agent-nodejs/compare/@forestadmin/agent@1.0.0-beta.26...@forestadmin/agent@1.0.0-beta.27) (2022-05-17)
9
+
10
+
11
+ ### Features
12
+
13
+ * add support for standalone mode ([#304](https://github.com/ForestAdmin/agent-nodejs/issues/304)) ([c2bca75](https://github.com/ForestAdmin/agent-nodejs/commit/c2bca75a882c1591ad7560583ba0c56fb8020e12))
14
+
15
+ # @forestadmin/agent [1.0.0-beta.26](https://github.com/ForestAdmin/agent-nodejs/compare/@forestadmin/agent@1.0.0-beta.25...@forestadmin/agent@1.0.0-beta.26) (2022-05-16)
16
+
17
+
18
+ ### Features
19
+
20
+ * autocomplete on field names ([#263](https://github.com/ForestAdmin/agent-nodejs/issues/263)) ([e2025d5](https://github.com/ForestAdmin/agent-nodejs/commit/e2025d57d930edf6d326bd0c6d7fffcd4aad728d))
21
+
22
+
23
+
24
+
25
+
26
+ ### Dependencies
27
+
28
+ * **@forestadmin/datasource-toolkit:** upgraded to 1.0.0-beta.16
29
+
1
30
  # @forestadmin/agent [1.0.0-beta.25](https://github.com/ForestAdmin/agent-nodejs/compare/@forestadmin/agent@1.0.0-beta.24...@forestadmin/agent@1.0.0-beta.25) (2022-05-16)
2
31
 
3
32
 
@@ -1,34 +1,12 @@
1
- /// <reference types="node" />
1
+ /// <reference types="koa__router" />
2
2
  import { DataSource } from '@forestadmin/datasource-toolkit';
3
- import { IncomingMessage, ServerResponse } from 'http';
4
- import { AgentOptions } from '../types';
3
+ import Router from '@koa/router';
5
4
  import { AgentOptionsWithDefaults } from './types';
6
- import BaseRoute from './routes/base-route';
7
- import { ForestAdminHttpDriverServices } from './services';
8
- /** Native Node.js callback that can be passed to an HTTP Server */
9
- export declare type HttpCallback = (req: IncomingMessage, res: ServerResponse) => void;
10
5
  export default class ForestAdminHttpDriver {
11
6
  readonly dataSource: DataSource;
12
7
  readonly options: AgentOptionsWithDefaults;
13
- readonly services: ForestAdminHttpDriverServices;
14
- routes: BaseRoute[];
15
- private readonly app;
16
- private status;
17
- /**
18
- * Native request handler.
19
- * Can be used directly with express.js or the Node.js http module.
20
- * Other frameworks will require adapters.
21
- */
22
- get handler(): HttpCallback;
23
- constructor(dataSource: DataSource, options: AgentOptions);
24
- /**
25
- * Builds the underlying application from the datasource.
26
- * This method can only be called once.
27
- */
28
- start(): Promise<void>;
29
- /**
30
- * Tear down all routes (close open sockets, ...)
31
- */
32
- stop(): Promise<void>;
8
+ constructor(dataSource: DataSource, options: AgentOptionsWithDefaults);
9
+ getRouter(): Promise<Router>;
10
+ sendSchema(): Promise<void>;
33
11
  }
34
12
  //# sourceMappingURL=forestadmin-http-driver.d.ts.map
@@ -3,81 +3,41 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- const koa_1 = __importDefault(require("koa"));
7
6
  const router_1 = __importDefault(require("@koa/router"));
8
7
  const koa_bodyparser_1 = __importDefault(require("koa-bodyparser"));
9
8
  const cors_1 = __importDefault(require("@koa/cors"));
10
- const path_1 = __importDefault(require("path"));
11
9
  const forest_http_api_1 = __importDefault(require("./utils/forest-http-api"));
12
- const http_driver_options_1 = __importDefault(require("./utils/http-driver-options"));
13
10
  const emitter_1 = __importDefault(require("./utils/forest-schema/emitter"));
14
11
  const routes_1 = __importDefault(require("./routes"));
15
12
  const services_1 = __importDefault(require("./services"));
16
13
  class ForestAdminHttpDriver {
17
14
  constructor(dataSource, options) {
18
- this.routes = [];
19
- this.app = new koa_1.default();
20
- this.status = 'waiting';
21
15
  this.dataSource = dataSource;
22
- this.options = http_driver_options_1.default.withDefaults(options);
23
- this.services = (0, services_1.default)(this.options);
24
- http_driver_options_1.default.validate(this.options);
16
+ this.options = options;
25
17
  }
26
- /**
27
- * Native request handler.
28
- * Can be used directly with express.js or the Node.js http module.
29
- * Other frameworks will require adapters.
30
- */
31
- get handler() {
32
- return this.app.callback();
18
+ async getRouter() {
19
+ // Bootstrap app
20
+ const services = (0, services_1.default)(this.options);
21
+ const routes = (0, routes_1.default)(this.dataSource, this.options, services);
22
+ await Promise.all(routes.map(route => route.bootstrap()));
23
+ // Build router
24
+ const router = new router_1.default();
25
+ router.all('(.*)', (0, cors_1.default)({ credentials: true, maxAge: 24 * 3600, privateNetworkAccess: true }));
26
+ router.use((0, koa_bodyparser_1.default)({ jsonLimit: '50mb' }));
27
+ routes.forEach(route => route.setupRoutes(router));
28
+ return router;
33
29
  }
34
- /**
35
- * Builds the underlying application from the datasource.
36
- * This method can only be called once.
37
- */
38
- async start() {
39
- if (this.status !== 'waiting') {
40
- throw new Error('Agent cannot be restarted.');
30
+ async sendSchema() {
31
+ const schema = await emitter_1.default.getSerializedSchema(this.options, this.dataSource);
32
+ const schemaIsKnown = await forest_http_api_1.default.hasSchema(this.options, schema.meta.schemaFileHash);
33
+ if (!schemaIsKnown) {
34
+ this.options.logger('Info', 'Schema was updated, sending new version');
35
+ await forest_http_api_1.default.uploadSchema(this.options, schema);
41
36
  }
42
- try {
43
- this.status = 'running';
44
- // Build http application
45
- const router = new router_1.default({ prefix: path_1.default.join('/', this.options.prefix) });
46
- this.routes = (0, routes_1.default)(this.dataSource, this.options, this.services);
47
- this.routes.forEach(route => route.setupRoutes(router));
48
- await Promise.all(this.routes.map(route => route.bootstrap()));
49
- this.app
50
- .use((0, cors_1.default)({ credentials: true, maxAge: 24 * 3600, privateNetworkAccess: true }))
51
- .use((0, koa_bodyparser_1.default)({ jsonLimit: '50mb' }))
52
- .use(router.routes());
53
- // Send schema to forestadmin-server (if relevant).
54
- const schema = await emitter_1.default.getSerializedSchema(this.options, this.dataSource);
55
- const schemaIsKnown = await forest_http_api_1.default.hasSchema(this.options, schema.meta.schemaFileHash);
56
- if (!schemaIsKnown) {
57
- this.options.logger('Info', 'Schema was updated, sending new version');
58
- await forest_http_api_1.default.uploadSchema(this.options, schema);
59
- }
60
- else {
61
- this.options.logger('Info', 'Schema was not updated since last run');
62
- }
63
- this.options.logger('Info', 'Started');
37
+ else {
38
+ this.options.logger('Info', 'Schema was not updated since last run');
64
39
  }
65
- catch (e) {
66
- this.options.logger('Error', e.message);
67
- this.status = 'done';
68
- throw e;
69
- }
70
- }
71
- /**
72
- * Tear down all routes (close open sockets, ...)
73
- */
74
- async stop() {
75
- if (this.status !== 'running') {
76
- throw new Error('Agent is not running.');
77
- }
78
- this.status = 'done';
79
- await Promise.all(this.routes.map(route => route.tearDown()));
80
40
  }
81
41
  }
82
42
  exports.default = ForestAdminHttpDriver;
83
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm9yZXN0YWRtaW4taHR0cC1kcml2ZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYWdlbnQvZm9yZXN0YWRtaW4taHR0cC1kcml2ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFFQSw4Q0FBc0I7QUFDdEIseURBQWlDO0FBQ2pDLG9FQUF3QztBQUN4QyxxREFBNkI7QUFDN0IsZ0RBQXdCO0FBS3hCLDhFQUFvRDtBQUNwRCxzRkFBdUQ7QUFDdkQsNEVBQTBEO0FBQzFELHNEQUFrQztBQUNsQywwREFBeUU7QUFLekUsTUFBcUIscUJBQXFCO0lBa0J4QyxZQUFZLFVBQXNCLEVBQUUsT0FBcUI7UUFkbEQsV0FBTSxHQUFnQixFQUFFLENBQUM7UUFFZixRQUFHLEdBQUcsSUFBSSxhQUFHLEVBQUUsQ0FBQztRQUN6QixXQUFNLEdBQW1DLFNBQVMsQ0FBQztRQVl6RCxJQUFJLENBQUMsVUFBVSxHQUFHLFVBQVUsQ0FBQztRQUM3QixJQUFJLENBQUMsT0FBTyxHQUFHLDZCQUFZLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ2xELElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBQSxrQkFBWSxFQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUUzQyw2QkFBWSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDdEMsQ0FBQztJQWZEOzs7O09BSUc7SUFDSCxJQUFJLE9BQU87UUFDVCxPQUFPLElBQUksQ0FBQyxHQUFHLENBQUMsUUFBUSxFQUFFLENBQUM7SUFDN0IsQ0FBQztJQVVEOzs7T0FHRztJQUNILEtBQUssQ0FBQyxLQUFLO1FBQ1QsSUFBSSxJQUFJLENBQUMsTUFBTSxLQUFLLFNBQVMsRUFBRTtZQUM3QixNQUFNLElBQUksS0FBSyxDQUFDLDRCQUE0QixDQUFDLENBQUM7U0FDL0M7UUFFRCxJQUFJO1lBQ0YsSUFBSSxDQUFDLE1BQU0sR0FBRyxTQUFTLENBQUM7WUFFeEIs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
43
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm9yZXN0YWRtaW4taHR0cC1kcml2ZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYWdlbnQvZm9yZXN0YWRtaW4taHR0cC1kcml2ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFDQSx5REFBaUM7QUFDakMsb0VBQXdDO0FBQ3hDLHFEQUE2QjtBQUc3Qiw4RUFBb0Q7QUFDcEQsNEVBQTBEO0FBQzFELHNEQUFrQztBQUNsQywwREFBc0M7QUFFdEMsTUFBcUIscUJBQXFCO0lBSXhDLFlBQVksVUFBc0IsRUFBRSxPQUFpQztRQUNuRSxJQUFJLENBQUMsVUFBVSxHQUFHLFVBQVUsQ0FBQztRQUM3QixJQUFJLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQztJQUN6QixDQUFDO0lBRUQsS0FBSyxDQUFDLFNBQVM7UUFDYixnQkFBZ0I7UUFDaEIsTUFBTSxRQUFRLEdBQUcsSUFBQSxrQkFBWSxFQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUM1QyxNQUFNLE1BQU0sR0FBRyxJQUFBLGdCQUFVLEVBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRSxJQUFJLENBQUMsT0FBTyxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBQ25FLE1BQU0sT0FBTyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUUxRCxlQUFlO1FBQ2YsTUFBTSxNQUFNLEdBQUcsSUFBSSxnQkFBTSxFQUFFLENBQUM7UUFDNUIsTUFBTSxDQUFDLEdBQUcsQ0FBQyxNQUFNLEVBQUUsSUFBQSxjQUFJLEVBQUMsRUFBRSxXQUFXLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxFQUFFLEdBQUcsSUFBSSxFQUFFLG9CQUFvQixFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQztRQUMvRixNQUFNLENBQUMsR0FBRyxDQUFDLElBQUEsd0JBQVUsRUFBQyxFQUFFLFNBQVMsRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDOUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztRQUVuRCxPQUFPLE1BQU0sQ0FBQztJQUNoQixDQUFDO0lBRUQsS0FBSyxDQUFDLFVBQVU7UUFDZCxNQUFNLE1BQU0sR0FBRyxNQUFNLGlCQUFhLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDdEYsTUFBTSxhQUFhLEdBQUcsTUFBTSx5QkFBYSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLENBQUM7UUFFOUYsSUFBSSxDQUFDLGFBQWEsRUFBRTtZQUNsQixJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxNQUFNLEVBQUUseUNBQXlDLENBQUMsQ0FBQztZQUN2RSxNQUFNLHlCQUFhLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsTUFBTSxDQUFDLENBQUM7U0FDeEQ7YUFBTTtZQUNMLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSx1Q0FBdUMsQ0FBQyxDQUFDO1NBQ3RFO0lBQ0gsQ0FBQztDQUNGO0FBbkNELHdDQW1DQyJ9
@@ -8,7 +8,6 @@ export default abstract class BaseRoute {
8
8
  abstract get type(): RouteType;
9
9
  constructor(services: ForestAdminHttpDriverServices, options: AgentOptionsWithDefaults);
10
10
  bootstrap(): Promise<void>;
11
- tearDown(): Promise<void>;
12
11
  abstract setupRoutes(router: Router): void;
13
12
  }
14
13
  //# sourceMappingURL=base-route.d.ts.map
@@ -8,9 +8,6 @@ class BaseRoute {
8
8
  async bootstrap() {
9
9
  // Do nothing by default
10
10
  }
11
- async tearDown() {
12
- // Do nothing by default
13
- }
14
11
  }
15
12
  exports.default = BaseRoute;
16
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFzZS1yb3V0ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9hZ2VudC9yb3V0ZXMvYmFzZS1yb3V0ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUtBLE1BQThCLFNBQVM7SUFNckMsWUFBWSxRQUF1QyxFQUFFLE9BQWlDO1FBQ3BGLElBQUksQ0FBQyxRQUFRLEdBQUcsUUFBUSxDQUFDO1FBQ3pCLElBQUksQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDO0lBQ3pCLENBQUM7SUFFRCxLQUFLLENBQUMsU0FBUztRQUNiLHdCQUF3QjtJQUMxQixDQUFDO0lBRUQsS0FBSyxDQUFDLFFBQVE7UUFDWix3QkFBd0I7SUFDMUIsQ0FBQztDQUdGO0FBcEJELDRCQW9CQyJ9
13
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFzZS1yb3V0ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9hZ2VudC9yb3V0ZXMvYmFzZS1yb3V0ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUtBLE1BQThCLFNBQVM7SUFNckMsWUFBWSxRQUF1QyxFQUFFLE9BQWlDO1FBQ3BGLElBQUksQ0FBQyxRQUFRLEdBQUcsUUFBUSxDQUFDO1FBQ3pCLElBQUksQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDO0lBQ3pCLENBQUM7SUFFRCxLQUFLLENBQUMsU0FBUztRQUNiLHdCQUF3QjtJQUMxQixDQUFDO0NBR0Y7QUFoQkQsNEJBZ0JDIn0=
@@ -1,7 +1,6 @@
1
- import { ChartDefinition, DataSourceFactory } from '@forestadmin/datasource-toolkit';
1
+ import { ChartDefinition, DataSourceFactory, TCollectionName, TSchema } from '@forestadmin/datasource-toolkit';
2
2
  import { AgentOptions } from '../types';
3
3
  import CollectionBuilder from './collection';
4
- import { HttpCallback } from '../agent/forestadmin-http-driver';
5
4
  /**
6
5
  * Allow to create a new Forest Admin agent from scratch.
7
6
  * Builds the application by composing and configuring all the collection decorators.
@@ -12,19 +11,13 @@ import { HttpCallback } from '../agent/forestadmin-http-driver';
12
11
  * .addDataSource(new SomeDataSource())
13
12
  * .start();
14
13
  */
15
- export default class AgentBuilder {
16
- private readonly forestAdminHttpDriver;
14
+ export default class AgentBuilder<S extends TSchema = TSchema> {
17
15
  private readonly compositeDataSource;
18
16
  private readonly stack;
19
- private tasks;
20
- /**
21
- * Native nodejs HttpCallback object
22
- * @example
23
- * import http from 'http';
24
- * ...
25
- * const server = http.createServer(agent.httpCallback);
26
- */
27
- get httpCallback(): HttpCallback;
17
+ private readonly options;
18
+ private customizations;
19
+ private mounts;
20
+ private termination;
28
21
  /**
29
22
  * Create a new Agent Builder.
30
23
  * If any options are missing, the default will be applied:
@@ -60,7 +53,7 @@ export default class AgentBuilder {
60
53
  * }
61
54
  * })
62
55
  */
63
- addChart(name: string, definition: ChartDefinition): this;
56
+ addChart(name: string, definition: ChartDefinition<S>): this;
64
57
  /**
65
58
  * Allow to interact with a decorated collection
66
59
  * @param name the name of the collection to manipulate
@@ -69,14 +62,39 @@ export default class AgentBuilder {
69
62
  * @example
70
63
  * .customizeCollection('books', books => books.renameField('xx', 'yy'))
71
64
  */
72
- customizeCollection(name: string, handle: (collection: CollectionBuilder) => unknown): this;
65
+ customizeCollection<N extends TCollectionName<S>>(name: N, handle: (collection: CollectionBuilder<S, N>) => unknown): this;
73
66
  /**
74
- * Start the agent.
67
+ * Expose the agent on a given port and host
68
+ * @param port port that should be used.
69
+ * @param host host that should be used.
75
70
  */
76
- start(): Promise<void>;
71
+ mountOnStandaloneServer(port?: number, host?: string): this;
72
+ /**
73
+ * Mount the agent on an express app.
74
+ * @param express instance of the express app or router.
75
+ */
76
+ mountOnExpress(express: any): this;
77
77
  /**
78
- * Stop the agent gracefully.
78
+ * Mount the agent on a fastify app
79
+ * @param fastify instance of the fastify app, or of a fastify context
79
80
  */
81
+ mountOnFastify(fastify: any): this;
82
+ /**
83
+ * Mount the agent on a koa app
84
+ * @param koa instance of a koa app or a koa Router.
85
+ */
86
+ mountOnKoa(koa: any): this;
87
+ /**
88
+ * Mount the agent on a NestJS app
89
+ * @param nestJs instance of a NestJS application
90
+ */
91
+ mountOnNestJs(nestJs: any): this;
92
+ /**
93
+ * Start the agent.
94
+ */
95
+ start(): Promise<void>;
80
96
  stop(): Promise<void>;
97
+ private useCallbackOnFastify;
98
+ private getConnectCallback;
81
99
  }
82
100
  //# sourceMappingURL=agent.d.ts.map
@@ -4,9 +4,16 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const datasource_toolkit_1 = require("@forestadmin/datasource-toolkit");
7
+ const promises_1 = require("fs/promises");
8
+ const koa_1 = __importDefault(require("koa"));
9
+ const router_1 = __importDefault(require("@koa/router"));
10
+ const express_1 = __importDefault(require("@fastify/express"));
11
+ const http_1 = __importDefault(require("http"));
7
12
  const collection_1 = __importDefault(require("./collection"));
8
13
  const decorators_stack_1 = __importDefault(require("./decorators-stack"));
9
14
  const forestadmin_http_driver_1 = __importDefault(require("../agent/forestadmin-http-driver"));
15
+ const options_validator_1 = __importDefault(require("./utils/options-validator"));
16
+ const typing_generator_1 = __importDefault(require("./utils/typing-generator"));
10
17
  /**
11
18
  * Allow to create a new Forest Admin agent from scratch.
12
19
  * Builds the application by composing and configuring all the collection decorators.
@@ -36,28 +43,20 @@ class AgentBuilder {
36
43
  * .start();
37
44
  */
38
45
  constructor(options) {
39
- this.tasks = [];
46
+ this.customizations = [];
47
+ this.mounts = [];
48
+ this.termination = [];
49
+ this.options = options_validator_1.default.withDefaults(options);
40
50
  this.compositeDataSource = new datasource_toolkit_1.BaseDataSource();
41
51
  this.stack = new decorators_stack_1.default(this.compositeDataSource);
42
- this.forestAdminHttpDriver = new forestadmin_http_driver_1.default(this.stack.dataSource, options);
43
- }
44
- /**
45
- * Native nodejs HttpCallback object
46
- * @example
47
- * import http from 'http';
48
- * ...
49
- * const server = http.createServer(agent.httpCallback);
50
- */
51
- get httpCallback() {
52
- return this.forestAdminHttpDriver.handler;
53
52
  }
54
53
  /**
55
54
  * Add a datasource
56
55
  * @param factory the datasource to add
57
56
  */
58
57
  addDataSource(factory) {
59
- this.tasks.push(async () => {
60
- const datasource = await factory(this.forestAdminHttpDriver.options.logger);
58
+ this.customizations.push(async () => {
59
+ const datasource = await factory(this.options.logger);
61
60
  datasource.collections.forEach(collection => {
62
61
  this.compositeDataSource.addCollection(collection);
63
62
  });
@@ -77,7 +76,7 @@ class AgentBuilder {
77
76
  * })
78
77
  */
79
78
  addChart(name, definition) {
80
- this.tasks.push(async () => {
79
+ this.customizations.push(async () => {
81
80
  this.stack.chart.addChart(name, definition);
82
81
  });
83
82
  return this;
@@ -91,7 +90,7 @@ class AgentBuilder {
91
90
  * .customizeCollection('books', books => books.renameField('xx', 'yy'))
92
91
  */
93
92
  customizeCollection(name, handle) {
94
- this.tasks.push(async () => {
93
+ this.customizations.push(async () => {
95
94
  if (this.stack.dataSource.getCollection(name)) {
96
95
  handle(new collection_1.default(this.stack, name));
97
96
  }
@@ -99,21 +98,137 @@ class AgentBuilder {
99
98
  return this;
100
99
  }
101
100
  /**
102
- * Start the agent.
101
+ * Expose the agent on a given port and host
102
+ * @param port port that should be used.
103
+ * @param host host that should be used.
103
104
  */
104
- async start() {
105
- for (const task of this.tasks) {
106
- // eslint-disable-next-line no-await-in-loop
107
- await task();
105
+ mountOnStandaloneServer(port = 3351, host = 'localhost') {
106
+ const server = http_1.default.createServer(this.getConnectCallback(true));
107
+ server.listen(port, host);
108
+ this.options.logger('Info', `Successfully mounted on Standalone server (http://${host}:${port})`);
109
+ this.termination.push(async () => {
110
+ server.close();
111
+ });
112
+ return this;
113
+ }
114
+ /**
115
+ * Mount the agent on an express app.
116
+ * @param express instance of the express app or router.
117
+ */
118
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
119
+ mountOnExpress(express) {
120
+ express.use('/forest', this.getConnectCallback(false));
121
+ this.options.logger('Info', `Successfully mounted on Express.js`);
122
+ return this;
123
+ }
124
+ /**
125
+ * Mount the agent on a fastify app
126
+ * @param fastify instance of the fastify app, or of a fastify context
127
+ */
128
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
129
+ mountOnFastify(fastify) {
130
+ const callback = this.getConnectCallback(false);
131
+ this.useCallbackOnFastify(fastify, callback);
132
+ this.options.logger('Info', `Successfully mounted on Fastify`);
133
+ return this;
134
+ }
135
+ /**
136
+ * Mount the agent on a koa app
137
+ * @param koa instance of a koa app or a koa Router.
138
+ */
139
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
140
+ mountOnKoa(koa) {
141
+ const parentRouter = new router_1.default({ prefix: '/forest' });
142
+ koa.use(parentRouter.routes());
143
+ this.options.logger('Info', `Successfully mounted on Koa`);
144
+ this.mounts.push(async (router) => {
145
+ parentRouter.use(router.routes());
146
+ });
147
+ return this;
148
+ }
149
+ /**
150
+ * Mount the agent on a NestJS app
151
+ * @param nestJs instance of a NestJS application
152
+ */
153
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
154
+ mountOnNestJs(nestJs) {
155
+ const adapter = nestJs.getHttpAdapter();
156
+ const callback = this.getConnectCallback(false);
157
+ if (adapter.constructor.name === 'ExpressAdapter') {
158
+ nestJs.use('/forest', callback);
159
+ }
160
+ else {
161
+ this.useCallbackOnFastify(nestJs, callback);
108
162
  }
109
- await this.forestAdminHttpDriver.start();
163
+ this.options.logger('Info', `Successfully mounted on NestJS`);
164
+ return this;
110
165
  }
111
166
  /**
112
- * Stop the agent gracefully.
167
+ * Start the agent.
113
168
  */
169
+ async start() {
170
+ // Customize agent
171
+ for (const task of this.customizations)
172
+ await task(); // eslint-disable-line no-await-in-loop
173
+ // Check that options are valid
174
+ const options = options_validator_1.default.validate(this.options);
175
+ // Write typings file
176
+ if (!options.isProduction && options.typingsPath) {
177
+ const types = typing_generator_1.default.generateTypes(this.stack.action, options.typingsMaxDepth);
178
+ await (0, promises_1.writeFile)(options.typingsPath, types, { encoding: 'utf-8' });
179
+ }
180
+ const httpDriver = new forestadmin_http_driver_1.default(this.stack.dataSource, options);
181
+ await httpDriver.sendSchema();
182
+ const router = await httpDriver.getRouter();
183
+ for (const task of this.mounts)
184
+ await task(router); // eslint-disable-line no-await-in-loop
185
+ }
114
186
  async stop() {
115
- return this.forestAdminHttpDriver.stop();
187
+ for (const task of this.termination)
188
+ await task(); // eslint-disable-line no-await-in-loop
189
+ }
190
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
191
+ useCallbackOnFastify(fastify, callback) {
192
+ try {
193
+ // 'fastify 2' or 'middie' or 'fastify-express'
194
+ fastify.use('/forest', callback);
195
+ }
196
+ catch (e) {
197
+ // 'fastify 3'
198
+ if (e.code === 'FST_ERR_MISSING_MIDDLEWARE') {
199
+ fastify
200
+ .register(express_1.default)
201
+ .then(() => {
202
+ fastify.use('/forest', callback);
203
+ })
204
+ .catch(err => {
205
+ this.options.logger('Error', err.message);
206
+ });
207
+ }
208
+ else {
209
+ throw e;
210
+ }
211
+ }
212
+ }
213
+ getConnectCallback(nested) {
214
+ let handler = null;
215
+ this.mounts.push(async (driverRouter) => {
216
+ let router = driverRouter;
217
+ if (nested) {
218
+ router = new router_1.default({ prefix: '/forest' }).use(router.routes());
219
+ }
220
+ handler = new koa_1.default().use(router.routes()).callback();
221
+ });
222
+ return (req, res) => {
223
+ if (handler) {
224
+ handler(req, res);
225
+ }
226
+ else {
227
+ res.writeHead(200, { 'Content-Type': 'application/json' });
228
+ res.end(JSON.stringify({ error: 'Agent is not started' }));
229
+ }
230
+ };
116
231
  }
117
232
  }
118
233
  exports.default = AgentBuilder;
119
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWdlbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYnVpbGRlci9hZ2VudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLHdFQUt5QztBQUd6Qyw4REFBNkM7QUFDN0MsMEVBQWlEO0FBQ2pELCtGQUF1RjtBQUV2Rjs7Ozs7Ozs7O0dBU0c7QUFDSCxNQUFxQixZQUFZO0lBaUIvQjs7Ozs7Ozs7Ozs7Ozs7OztPQWdCRztJQUNILFlBQVksT0FBcUI7UUE5QnpCLFVBQUssR0FBNEIsRUFBRSxDQUFDO1FBK0IxQyxJQUFJLENBQUMsbUJBQW1CLEdBQUcsSUFBSSxtQ0FBYyxFQUFjLENBQUM7UUFDNUQsSUFBSSxDQUFDLEtBQUssR0FBRyxJQUFJLDBCQUFlLENBQUMsSUFBSSxDQUFDLG1CQUFtQixDQUFDLENBQUM7UUFFM0QsSUFBSSxDQUFDLHFCQUFxQixHQUFHLElBQUksaUNBQXFCLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDekYsQ0FBQztJQWpDRDs7Ozs7O09BTUc7SUFDSCxJQUFJLFlBQVk7UUFDZCxPQUFPLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxPQUFPLENBQUM7SUFDNUMsQ0FBQztJQTBCRDs7O09BR0c7SUFDSCxhQUFhLENBQUMsT0FBMEI7UUFDdEMsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsS0FBSyxJQUFJLEVBQUU7WUFDekIsTUFBTSxVQUFVLEdBQUcsTUFBTSxPQUFPLENBQUMsSUFBSSxDQUFDLHFCQUFxQixDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUM1RSxVQUFVLENBQUMsV0FBVyxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsRUFBRTtnQkFDMUMsSUFBSSxDQUFDLG1CQUFtQixDQUFDLGFBQWEsQ0FBQyxVQUFVLENBQUMsQ0FBQztZQUNyRCxDQUFDLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO1FBRUgsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQ7Ozs7Ozs7Ozs7O09BV0c7SUFDSCxRQUFRLENBQUMsSUFBWSxFQUFFLFVBQTJCO1FBQ2hELElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEtBQUssSUFBSSxFQUFFO1lBQ3pCLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxJQUFJLEVBQUUsVUFBVSxDQUFDLENBQUM7UUFDOUMsQ0FBQyxDQUFDLENBQUM7UUFFSCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRDs7Ozs7OztPQU9HO0lBQ0gsbUJBQW1CLENBQUMsSUFBWSxFQUFFLE1BQWtEO1FBQ2xGLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEtBQUssSUFBSSxFQUFFO1lBQ3pCLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxFQUFFO2dCQUM3QyxNQUFNLENBQUMsSUFBSSxvQkFBaUIsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUM7YUFDakQ7UUFDSCxDQUFDLENBQUMsQ0FBQztRQUVILE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVEOztPQUVHO0lBQ0gsS0FBSyxDQUFDLEtBQUs7UUFDVCxLQUFLLE1BQU0sSUFBSSxJQUFJLElBQUksQ0FBQyxLQUFLLEVBQUU7WUFDN0IsNENBQTRDO1lBQzVDLE1BQU0sSUFBSSxFQUFFLENBQUM7U0FDZDtRQUVELE1BQU0sSUFBSSxDQUFDLHFCQUFxQixDQUFDLEtBQUssRUFBRSxDQUFDO0lBQzNDLENBQUM7SUFFRDs7T0FFRztJQUNILEtBQUssQ0FBQyxJQUFJO1FBQ1IsT0FBTyxJQUFJLENBQUMscUJBQXFCLENBQUMsSUFBSSxFQUFFLENBQUM7SUFDM0MsQ0FBQztDQUNGO0FBaEhELCtCQWdIQyJ9
234
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWdlbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYnVpbGRlci9hZ2VudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLHdFQU95QztBQUN6QywwQ0FBd0M7QUFDeEMsOENBQXNCO0FBQ3RCLHlEQUFpQztBQUNqQywrREFBOEM7QUFDOUMsZ0RBQXdCO0FBSXhCLDhEQUE2QztBQUM3QywwRUFBaUQ7QUFDakQsK0ZBQXFFO0FBQ3JFLGtGQUF5RDtBQUN6RCxnRkFBdUQ7QUFFdkQ7Ozs7Ozs7OztHQVNHO0FBQ0gsTUFBcUIsWUFBWTtJQVEvQjs7Ozs7Ozs7Ozs7Ozs7OztPQWdCRztJQUNILFlBQVksT0FBcUI7UUFyQnpCLG1CQUFjLEdBQTRCLEVBQUUsQ0FBQztRQUM3QyxXQUFNLEdBQTBDLEVBQUUsQ0FBQztRQUNuRCxnQkFBVyxHQUE0QixFQUFFLENBQUM7UUFvQmhELElBQUksQ0FBQyxPQUFPLEdBQUcsMkJBQWdCLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ3RELElBQUksQ0FBQyxtQkFBbUIsR0FBRyxJQUFJLG1DQUFjLEVBQWMsQ0FBQztRQUM1RCxJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksMEJBQWUsQ0FBQyxJQUFJLENBQUMsbUJBQW1CLENBQUMsQ0FBQztJQUM3RCxDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsYUFBYSxDQUFDLE9BQTBCO1FBQ3RDLElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLEtBQUssSUFBSSxFQUFFO1lBQ2xDLE1BQU0sVUFBVSxHQUFHLE1BQU0sT0FBTyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDdEQsVUFBVSxDQUFDLFdBQVcsQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLEVBQUU7Z0JBQzFDLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxhQUFhLENBQUMsVUFBVSxDQUFDLENBQUM7WUFDckQsQ0FBQyxDQUFDLENBQUM7UUFDTCxD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
@@ -1,7 +1,7 @@
1
- import { ActionDefinition, Operator, OperatorDefinition, PlainSortClause, SegmentDefinition, WriteDefinition } from '@forestadmin/datasource-toolkit';
1
+ import { ActionDefinition, Operator, OperatorDefinition, PlainSortClause, SegmentDefinition, TCollectionName, TColumnName, TFieldName, TSchema, WriteDefinition } from '@forestadmin/datasource-toolkit';
2
2
  import { FieldDefinition } from './types';
3
3
  import DecoratorsStack from './decorators-stack';
4
- export default class CollectionBuilder {
4
+ export default class CollectionBuilder<S extends TSchema = TSchema, N extends TCollectionName<S> = TCollectionName<S>> {
5
5
  private readonly name;
6
6
  private readonly stack;
7
7
  constructor(stack: DecoratorsStack, name: string);
@@ -14,7 +14,7 @@ export default class CollectionBuilder {
14
14
  * .importField('authorName', { path: 'author:fullName' })
15
15
  */
16
16
  importField(name: string, options: {
17
- path: string;
17
+ path: TFieldName<S, N>;
18
18
  beforeRelations?: boolean;
19
19
  }): this;
20
20
  /**
@@ -24,14 +24,14 @@ export default class CollectionBuilder {
24
24
  * @example
25
25
  * .renameField('theCurrentNameOfTheField', 'theNewNameOfTheField');
26
26
  */
27
- renameField(oldName: string, newName: string): this;
27
+ renameField(oldName: TColumnName<S, N>, newName: string): this;
28
28
  /**
29
29
  * Remove field by setting its visibility to false.
30
30
  * @param names the fields to remove
31
31
  * @example
32
32
  * .removeField('aFieldToRemove', 'anOtherFieldToRemove');
33
33
  */
34
- removeField(...names: string[]): this;
34
+ removeField(...names: TColumnName<S, N>[]): this;
35
35
  /**
36
36
  * Add a new action on the collection.
37
37
  * @param name the name of the action
@@ -44,7 +44,7 @@ export default class CollectionBuilder {
44
44
  * },
45
45
  * })
46
46
  */
47
- addAction(name: string, definition: ActionDefinition): this;
47
+ addAction(name: string, definition: ActionDefinition<S, N>): this;
48
48
  /**
49
49
  * Add a new field on the collection.
50
50
  * @param name the name of the field
@@ -56,7 +56,7 @@ export default class CollectionBuilder {
56
56
  * getValues: (records) => records.map(record => `${record.lastName} ${record.firstName}`),
57
57
  * });
58
58
  */
59
- addField(name: string, definition: FieldDefinition): this;
59
+ addField(name: string, definition: FieldDefinition<S, N>): this;
60
60
  /**
61
61
  * Add a many to one relation to the collection
62
62
  * @param name name of the new relation
@@ -65,9 +65,9 @@ export default class CollectionBuilder {
65
65
  * @example
66
66
  * books.addManyToOne('myAuthor', 'persons', { foreignKey: 'author_id' })
67
67
  */
68
- addManyToOne(name: string, foreignCollection: string, options: {
69
- foreignKey: string;
70
- foreignKeyTarget?: string;
68
+ addManyToOne<T extends TCollectionName<S>>(name: string, foreignCollection: T, options: {
69
+ foreignKey: TColumnName<S, N>;
70
+ foreignKeyTarget?: TColumnName<S, T>;
71
71
  }): this;
72
72
  /**
73
73
  * Add a one to many relation to the collection
@@ -77,9 +77,9 @@ export default class CollectionBuilder {
77
77
  * @example
78
78
  * persons.addOneToMany('writtenBooks', 'books', { originKey: 'author_id' })
79
79
  */
80
- addOneToMany(name: string, foreignCollection: string, options: {
81
- originKey: string;
82
- originKeyTarget?: string;
80
+ addOneToMany<T extends TCollectionName<S>>(name: string, foreignCollection: T, options: {
81
+ originKey: TColumnName<S, T>;
82
+ originKeyTarget?: TColumnName<S, N>;
83
83
  }): this;
84
84
  /**
85
85
  * Add a one to one relation to the collection
@@ -89,9 +89,9 @@ export default class CollectionBuilder {
89
89
  * @example
90
90
  * persons.addOneToOne('bestFriend', 'persons', { originKey: 'best_friend_id' })
91
91
  */
92
- addOneToOne(name: string, foreignCollection: string, options: {
93
- originKey: string;
94
- originKeyTarget?: string;
92
+ addOneToOne<T extends TCollectionName<S>>(name: string, foreignCollection: T, options: {
93
+ originKey: TColumnName<S, T>;
94
+ originKeyTarget?: TColumnName<S, N>;
95
95
  }): this;
96
96
  /**
97
97
  * Add a many to many relation to the collection
@@ -105,11 +105,11 @@ export default class CollectionBuilder {
105
105
  * foreignKey: 'rental_id'
106
106
  * })
107
107
  */
108
- addManyToMany(name: string, foreignCollection: string, throughCollection: string, options: {
109
- originKey: string;
110
- foreignKey: string;
111
- originKeyTarget?: string;
112
- foreignKeyTarget?: string;
108
+ addManyToMany<Foreign extends TCollectionName<S>, Through extends TCollectionName<S>>(name: string, foreignCollection: Foreign, throughCollection: Through, options: {
109
+ originKey: TColumnName<S, Through>;
110
+ foreignKey: TColumnName<S, Through>;
111
+ originKeyTarget?: TColumnName<S, N>;
112
+ foreignKeyTarget?: TColumnName<S, Foreign>;
113
113
  }): this;
114
114
  /**
115
115
  * Add a new segment on the collection.
@@ -119,10 +119,10 @@ export default class CollectionBuilder {
119
119
  * @example
120
120
  * .addSegment(
121
121
  * 'Wrote more than 2 books',
122
- * new ConditionTreeLeaf('booksCount', 'GreaterThan', 2),
122
+ * {field: 'booksCount', operator: 'GreaterThan', value: 2}
123
123
  * );
124
124
  */
125
- addSegment(name: string, definition: SegmentDefinition): this;
125
+ addSegment(name: string, definition: SegmentDefinition<S, N>): this;
126
126
  /**
127
127
  * Enable sorting on a specific field using emulation.
128
128
  * As for all the emulation method, the field sorting will be done in-memory.
@@ -130,7 +130,7 @@ export default class CollectionBuilder {
130
130
  * @example
131
131
  * .emulateFieldSorting('fullName');
132
132
  */
133
- emulateFieldSorting(name: string): this;
133
+ emulateFieldSorting(name: TColumnName<S, N>): this;
134
134
  /**
135
135
  * Replace an implementation for the sorting.
136
136
  * The field sorting will be done by the datasource.
@@ -145,7 +145,7 @@ export default class CollectionBuilder {
145
145
  * ]
146
146
  * )
147
147
  */
148
- replaceFieldSorting(name: string, equivalentSort: PlainSortClause[]): this;
148
+ replaceFieldSorting(name: TColumnName<S, N>, equivalentSort: PlainSortClause<S, N>[]): this;
149
149
  /**
150
150
  * Enable filtering on a specific field using emulation.
151
151
  * As for all the emulation method, the field filtering will be done in-memory.
@@ -153,7 +153,7 @@ export default class CollectionBuilder {
153
153
  * @example
154
154
  * .emulateFieldFiltering('aField');
155
155
  */
156
- emulateFieldFiltering(name: string): this;
156
+ emulateFieldFiltering(name: TColumnName<S, N>): this;
157
157
  /**
158
158
  * Enable filtering on a specific field with a specific operator using emulation.
159
159
  * As for all the emulation method, the field filtering will be done in-memory.
@@ -162,7 +162,7 @@ export default class CollectionBuilder {
162
162
  * @example
163
163
  * .emulateFieldOperator('aField', 'In');
164
164
  */
165
- emulateFieldOperator(name: string, operator: Operator): this;
165
+ emulateFieldOperator(name: TColumnName<S, N>, operator: Operator): this;
166
166
  /**
167
167
  * Replace an implementation for a specific operator on a specific field.
168
168
  * The operator replacement will be done by the datasource.
@@ -174,7 +174,7 @@ export default class CollectionBuilder {
174
174
  * new ConditionTreeLeaf('booksCount', 'Equal', value),
175
175
  * ));
176
176
  */
177
- replaceFieldOperator(name: string, operator: Operator, replacer: OperatorDefinition): this;
177
+ replaceFieldOperator<C extends TColumnName<S, N>>(name: C, operator: Operator, replacer: OperatorDefinition<S, N, C>): this;
178
178
  /**
179
179
  * Replace the write behavior of a field.
180
180
  * @param name the name of the field
@@ -185,7 +185,7 @@ export default class CollectionBuilder {
185
185
  * return { firstName, lastName };
186
186
  * });
187
187
  */
188
- replaceFieldWriting(name: string, definition: WriteDefinition): this;
188
+ replaceFieldWriting<C extends TColumnName<S, N>>(name: C, definition: WriteDefinition<S, N, C>): this;
189
189
  /**
190
190
  * Add a relation between two collections.
191
191
  * @param name name of the new relation
@@ -30,11 +30,13 @@ class CollectionBuilder {
30
30
  enumValues: schema.enumValues,
31
31
  });
32
32
  for (const operator of schema.filterOperators) {
33
- const handler = (value) => ({ field: options.path, operator, value });
33
+ const handler = value => ({ field: options.path, operator, value });
34
34
  this.replaceFieldOperator(name, operator, handler);
35
35
  }
36
36
  if (schema.isSortable) {
37
- this.replaceFieldSorting(name, [{ field: options.path, ascending: true }]);
37
+ this.replaceFieldSorting(name, [
38
+ { field: options.path, ascending: true },
39
+ ]);
38
40
  }
39
41
  return this;
40
42
  }
@@ -74,7 +76,10 @@ class CollectionBuilder {
74
76
  * })
75
77
  */
76
78
  addAction(name, definition) {
77
- this.stack.action.getCollection(this.name).addAction(name, definition);
79
+ this.stack.action
80
+ .getCollection(this.name)
81
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
82
+ .addAction(name, definition);
78
83
  return this;
79
84
  }
80
85
  /**
@@ -179,7 +184,7 @@ class CollectionBuilder {
179
184
  * @example
180
185
  * .addSegment(
181
186
  * 'Wrote more than 2 books',
182
- * new ConditionTreeLeaf('booksCount', 'GreaterThan', 2),
187
+ * {field: 'booksCount', operator: 'GreaterThan', value: 2}
183
188
  * );
184
189
  */
185
190
  addSegment(name, definition) {
@@ -212,7 +217,9 @@ class CollectionBuilder {
212
217
  * )
213
218
  */
214
219
  replaceFieldSorting(name, equivalentSort) {
215
- this.stack.sortEmulate.getCollection(this.name).replaceFieldSorting(name, equivalentSort);
220
+ this.stack.sortEmulate
221
+ .getCollection(this.name)
222
+ .replaceFieldSorting(name, equivalentSort);
216
223
  return this;
217
224
  }
218
225
  /**
@@ -296,4 +303,4 @@ class CollectionBuilder {
296
303
  }
297
304
  }
298
305
  exports.default = CollectionBuilder;
299
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29sbGVjdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9idWlsZGVyL2NvbGxlY3Rpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSx3RUFXeUM7QUFHekMseUZBQThFO0FBRTlFLE1BQXFCLGlCQUFpQjtJQUlwQyxZQUFZLEtBQXNCLEVBQUUsSUFBWTtRQUM5QyxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztRQUNqQixJQUFJLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQztJQUNyQixDQUFDO0lBRUQ7Ozs7Ozs7T0FPRztJQUNILFdBQVcsQ0FBQyxJQUFZLEVBQUUsT0FBb0Q7UUFDNUUsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNwRSxNQUFNLE1BQU0sR0FBRyxvQ0FBZSxDQUFDLGNBQWMsQ0FBQyxVQUFVLEVBQUUsT0FBTyxDQUFDLElBQUksQ0FBaUIsQ0FBQztRQUV4RixJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksRUFBRTtZQUNsQixlQUFlLEVBQUUsT0FBTyxDQUFDLGVBQWU7WUFDeEMsVUFBVSxFQUFFLE1BQU0sQ0FBQyxVQUFVO1lBQzdCLFlBQVksRUFBRSxNQUFNLENBQUMsWUFBWTtZQUNqQyxZQUFZLEVBQUUsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDO1lBQzVCLFNBQVMsRUFBRSxPQUFPLENBQUMsRUFBRSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxnQ0FBVyxDQUFDLGFBQWEsQ0FBQyxDQUFDLEVBQUUsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ2xGLFVBQVUsRUFBRSxNQUFNLENBQUMsVUFBVTtTQUM5QixDQUFDLENBQUM7UUFFSCxLQUFLLE1BQU0sUUFBUSxJQUFJLE1BQU0sQ0FBQyxlQUFlLEVBQUU7WUFDN0MsTUFBTSxPQUFP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
306
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29sbGVjdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9idWlsZGVyL2NvbGxlY3Rpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSx3RUFleUM7QUFHekMseUZBQThFO0FBRTlFLE1BQXFCLGlCQUFpQjtJQU9wQyxZQUFZLEtBQXNCLEVBQUUsSUFBWTtRQUM5QyxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztRQUNqQixJQUFJLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQztJQUNyQixDQUFDO0lBRUQ7Ozs7Ozs7T0FPRztJQUNILFdBQVcsQ0FBQyxJQUFZLEVBQUUsT0FBOEQ7UUFDdEYsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNwRSxNQUFNLE1BQU0sR0FBRyxvQ0FBZSxDQUFDLGNBQWMsQ0FBQyxVQUFVLEVBQUUsT0FBTyxDQUFDLElBQUksQ0FBaUIsQ0FBQztRQUV4RixJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksRUFBRTtZQUNsQixlQUFlLEVBQUUsT0FBTyxDQUFDLGVBQWU7WUFDeEMsVUFBVSxFQUFFLE1BQU0sQ0FBQyxVQUFVO1lBQzdCLFlBQVksRUFBRSxNQUFNLENBQUMsWUFBWTtZQUNqQyxZQUFZLEVBQUUsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDO1lBQzVCLFNBQVMsRUFBRSxPQUFPLENBQUMsRUFBRSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxnQ0FBVyxDQUFDLGFBQWEsQ0FBQyxDQUFDLEVBQUUsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ2xGLFVBQVUsRUFBRSxNQUFNLENBQUMsVUFBVTtTQUM5QixDQUFDLENBQUM7UUFFSCxLQUFLLE1BQU0sUUFBUSxJQUFJLE1BQU0sQ0FBQyxlQUFlLEVBQUU7WUFDN0MsTUFBTSxPQUFPLEdBQUcsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsS0FBSyxFQUFFLE9BQU8sQ0FBQyxJQUFJLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7WUFDcEUsSUFBSSxDQUFDLG9CQUFvQixDQUN2QixJQUF3QixFQUN4QixRQUFRLEVBQ1IsT0FBbUMsQ0FDcEMsQ0FBQztTQUNIO1FBRUQsSUFBSSxNQUFNLENBQUMsVUFBVSxFQUFFO1lBQ3JCLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxJQUF3QixFQUFFO2dCQUNqRCxFQUFFLEtBQUssRUFBRSxPQUFPLENBQUMsSUFBSSxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUU7YUFDekMsQ0FBQyxDQUFDO1NBQ0o7UUFFRCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSCxXQUFXLENBQUMsT0FBMEIsRUFBRSxPQUFlO1FBQ3JELElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsV0FBVyxDQUFDLE9BQU8sRUFBRSxPQUFPLENBQUMsQ0FBQztRQUV6RSxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNILFdBQVcsQ0FBQyxHQUFHLEtBQTBCO1FBQ3ZDLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDbkUsS0FBSyxNQUFNLElBQUksSUFBSSxLQUFLO1lBQUUsVUFBVSxDQUFDLHFCQUFxQixDQUFDLElBQUksRUFBRSxLQUFLLENBQUMsQ0FBQztRQUV4RSxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRDs7Ozs7Ozs7Ozs7T0FXRztJQUNILFNBQVMsQ0FBQyxJQUFZLEVBQUUsVUFBa0M7UUFDeEQsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNO2FBQ2QsYUFBYSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7WUFDekIsOERBQThEO2FBQzdELFNBQVMsQ0FBQyxJQUFJLEVBQUUsVUFBd0MsQ0FBQyxDQUFDO1FBRTdELE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVEOzs7Ozs7Ozs7O09BVUc7SUFDSCxRQUFRLENBQUMsSUFBWSxFQUFFLFVBQWlDO1FBQ3RELE1BQU0sRUFBRSxlQUFlLEVBQUUsR0FBRyxrQkFBa0IsRUFBRSxHQUFHLFVBQVUsQ0FBQztRQUM5RCxNQUFNLFVBQVUsR0FBRyxVQUFVLENBQUMsZUFBZTtZQUMzQyxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxhQUFhLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7WUFDbkQsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFckQsVUFBVSxDQUFDLGdCQUFnQixDQUFDLElBQUksRUFBRSxrQkFBa0IsQ0FBQyxDQUFDO1FBRXRELE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVEOzs7Ozs7O09BT0c7SUFDSCxZQUFZLENBQ1YsSUFBWSxFQUNaLGlCQUFvQixFQUNwQixPQUFnRjtRQUVoRixJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksRUFBRTtZQUNyQixJQUFJLEVBQUUsV0FBVztZQUNqQixpQkFBaUI7WUFDakIsVUFBVSxFQUFFLE9BQU8sQ0FBQyxVQUFVO1lBQzlCLGdCQUFnQixFQUFFLE9BQU8sQ0FBQyxnQkFBZ0I7U0FDM0MsQ0FBQyxDQUFDO1FBRUgsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQ7Ozs7Ozs7T0FPRztJQUNILFlBQVksQ0FDVixJQUFZLEVBQ1osaUJBQW9CLEVBQ3BCLE9BQThFO1FBRTlFLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxFQUFFO1lBQ3JCLElBQUksRUFBRSxXQUFXO1lBQ2pCLGlCQUFpQjtZQUNqQixTQUFTLEVBQUUsT0FBTyxDQUFDLFNBQVM7WUFDNUIsZUFBZSxFQUFFLE9BQU8sQ0FBQyxlQUFlO1NBQ3pDLENBQUMsQ0FBQztRQUVILE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVEOzs7Ozs7O09BT0c7SUFDSCxXQUFXLENBQ1QsSUFBWSxFQUNaLGlCQUFvQixFQUNwQixPQUE4RTtRQUU5RSxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksRUFBRTtZQUNyQixJQUFJLEVBQUUsVUFBVTtZQUNoQixpQkFBaUI7WUFDakIsU0FBUyxFQUFFLE9BQU8sQ0FBQyxTQUFTO1lBQzVCLGVBQWUsRUFBRSxPQUFPLENBQUMsZUFBZTtTQUN6QyxDQUFDLENBQUM7UUFFSCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRDs7Ozs7Ozs7Ozs7T0FXRztJQUNILGFBQWEsQ0FDWCxJQUFZLEVBQ1osaUJBQTBCLEVBQzFCLGlCQUEwQixFQUMxQixPQUtDO1FBRUQsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLEVBQUU7WUFDckIsSUFBSSxFQUFFLFlBQVk7WUFDbEIsaUJBQWlCO1lBQ2pCLGlCQUFpQjtZQUNqQixTQUFTLEVBQUUsT0FBTyxDQUFDLFNBQVM7WUFDNUIsZUFBZSxFQUFFLE9BQU8sQ0FBQyxlQUFlO1lBQ3hDLFVBQVUsRUFBRSxPQUFPLENBQUMsVUFBVTtZQUM5QixnQkFBZ0IsRUFBRSxPQUFPLENBQUMsZ0JBQWdCO1NBQzNDLENBQUMsQ0FBQztRQUVILE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVEOzs7Ozs7Ozs7O09BVUc7SUFDSCxVQUFVLENBQUMsSUFBWSxFQUFFLFVBQW1DO1FBQzFELElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsVUFBVSxDQUFDLElBQUksRUFBRSxVQUErQixDQUFDLENBQUM7UUFFOUYsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0gsbUJBQW1CLENBQUMsSUFBdUI7UUFDekMsSUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUUxRSxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRDs7Ozs7Ozs7Ozs7OztPQWFHO0lBQ0gsbUJBQW1CLENBQUMsSUFBdUIsRUFBRSxjQUF1QztRQUNsRixJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVc7YUFDbkIsYUFBYSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7YUFDeEIsbUJBQW1CLENBQUMsSUFBSSxFQUFFLGNBQW1DLENBQUMsQ0FBQztRQUVsRSxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSCxxQkFBcUIsQ0FBQyxJQUF1QjtRQUMzQyxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLGFBQWEsQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3JFLE1BQU0sS0FBSyxHQUFHLFVBQVUsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBaUIsQ0FBQztRQUU3RCxLQUFLLE1BQU0sUUFBUSxJQUFJLG9CQUF1QixDQUFDLG9CQUFvQixDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsRUFBRTtZQUNyRixJQUFJLENBQUMsS0FBSyxDQUFDLGVBQWUsRUFBRSxHQUFHLENBQUMsUUFBUSxDQUFDLEVBQUU7Z0JBQ3pDLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxJQUFJLEVBQUUsUUFBUSxDQUFDLENBQUM7YUFDM0M7U0FDRjtRQUVELE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVEOzs7Ozs7O09BT0c7SUFDSCxvQkFBb0IsQ0FBQyxJQUF1QixFQUFFLFFBQWtCO1FBQzlELE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsY0FBYyxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUM7WUFDdkYsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsY0FBYyxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO1lBQ3BELENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLGFBQWEsQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBRXRELFVBQVUsQ0FBQyxvQkFBb0IsQ0FBQyxJQUFJLEVBQUUsUUFBUSxDQUFDLENBQUM7UUFFaEQsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQ7Ozs7Ozs7Ozs7T0FVRztJQUNILG9CQUFvQixDQUNsQixJQUFPLEVBQ1AsUUFBa0IsRUFDbEIsUUFBcUM7UUFFckMsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxjQUFjLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQztZQUN2RixDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxjQUFjLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7WUFDcEQsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsYUFBYSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFdEQsVUFBVSxDQUFDLG9CQUFvQixDQUFDLElBQUksRUFBRSxRQUFRLEVBQUUsUUFBOEIsQ0FBQyxDQUFDO1FBRWhGLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVEOzs7Ozs7Ozs7T0FTRztJQUNILG1CQUFtQixDQUNqQixJQUFPLEVBQ1AsVUFBb0M7UUFFcEMsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLEVBQUUsVUFBVSxDQUFDLENBQUM7UUFFaEYsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQ7Ozs7Ozs7Ozs7T0FVRztJQUNLLFdBQVcsQ0FBQyxJQUFZLEVBQUUsVUFBOEI7UUFDOUQsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxXQUFXLENBQUMsSUFBSSxFQUFFLFVBQVUsQ0FBQyxDQUFDO1FBRTNFLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztDQUNGO0FBdlhELG9DQXVYQyJ9
@@ -1,5 +1,8 @@
1
- import { ComputedDefinition } from '@forestadmin/datasource-toolkit';
2
- export declare type FieldDefinition = ComputedDefinition & {
1
+ /// <reference types="node" />
2
+ import { ComputedDefinition, TCollectionName, TSchema } from '@forestadmin/datasource-toolkit';
3
+ import { IncomingMessage, ServerResponse } from 'http';
4
+ export declare type FieldDefinition<S extends TSchema = TSchema, N extends TCollectionName<S> = TCollectionName<S>> = ComputedDefinition<S, N> & {
3
5
  beforeRelations?: boolean;
4
6
  };
7
+ export declare type HttpCallback = (req: IncomingMessage, res: ServerResponse) => void;
5
8
  //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1,13 @@
1
+ import { AgentOptions } from '../../types';
2
+ import { AgentOptionsWithDefaults } from '../../agent/types';
3
+ export default class OptionsValidator {
4
+ private static loggerPrefix;
5
+ static withDefaults(options: AgentOptions): AgentOptions;
6
+ static validate(options: AgentOptions): AgentOptionsWithDefaults;
7
+ private static checkForestServerOptions;
8
+ private static checkAuthOptions;
9
+ private static checkOtherOptions;
10
+ private static isExistingPath;
11
+ private static isUrl;
12
+ }
13
+ //# sourceMappingURL=options-validator.d.ts.map
@@ -0,0 +1,103 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const fs_1 = require("fs");
4
+ const path_1 = require("path");
5
+ class OptionsValidator {
6
+ static withDefaults(options) {
7
+ const copyOptions = { ...options };
8
+ const defaultLogger = (level, data) => {
9
+ const loggerLevel = options.loggerLevel ?? 'Info';
10
+ const levels = Object.keys(this.loggerPrefix);
11
+ if (levels.indexOf(level) >= levels.indexOf(loggerLevel)) {
12
+ console.error(OptionsValidator.loggerPrefix[level], data);
13
+ }
14
+ };
15
+ copyOptions.logger = copyOptions.logger || defaultLogger;
16
+ copyOptions.schemaPath = copyOptions.schemaPath || '.forestadmin-schema.json';
17
+ copyOptions.forestServerUrl = copyOptions.forestServerUrl || 'https://api.forestadmin.com';
18
+ copyOptions.typingsMaxDepth = copyOptions.typingsMaxDepth ?? 5;
19
+ const parsed = new URL(options.agentUrl);
20
+ copyOptions.prefix ?? (copyOptions.prefix = (0, path_1.join)('/', parsed.pathname, 'forest'));
21
+ return {
22
+ clientId: null,
23
+ loggerLevel: 'Info',
24
+ prefix: '/forest',
25
+ permissionsCacheDurationInSeconds: 15 * 60,
26
+ ...copyOptions,
27
+ };
28
+ }
29
+ static validate(options) {
30
+ OptionsValidator.checkForestServerOptions(options);
31
+ OptionsValidator.checkAuthOptions(options);
32
+ OptionsValidator.checkOtherOptions(options);
33
+ return options;
34
+ }
35
+ static checkForestServerOptions(options) {
36
+ if (typeof options.envSecret !== 'string' || !/^[0-9a-f]{64}$/.test(options.envSecret)) {
37
+ throw new Error('options.envSecret is invalid. You can retrieve its value from ' +
38
+ 'https://www.forestadmin.com');
39
+ }
40
+ if (!OptionsValidator.isUrl(options.forestServerUrl)) {
41
+ throw new Error('options.forestServerUrl is invalid. It should contain an URL ' +
42
+ '(i.e. "https://api.forestadmin.com")');
43
+ }
44
+ if (!OptionsValidator.isExistingPath(options.schemaPath)) {
45
+ throw new Error('options.schemaPath is invalid. It should contain a relative filepath ' +
46
+ 'where the schema should be loaded/updated (i.e. "./.forestadmin-schema.json")');
47
+ }
48
+ if (options.typingsPath && !OptionsValidator.isExistingPath(options.typingsPath)) {
49
+ throw new Error('options.typingsPath is invalid. It should contain a relative filepath ' +
50
+ 'where the schema should be loaded/updated (i.e. "./src/typings.ts")');
51
+ }
52
+ }
53
+ static checkAuthOptions(options) {
54
+ if (!OptionsValidator.isUrl(options.agentUrl)) {
55
+ throw new Error('options.agentUrl is invalid. It should contain an url where your agent is reachable ' +
56
+ '(i.e. "https://api-forestadmin.mycompany.com")');
57
+ }
58
+ if (typeof options.authSecret !== 'string') {
59
+ throw new Error('options.authSecret is invalid. Any long random string should work ' +
60
+ '(i.e. "OfpssLrbgF3P4vHJTTpb"');
61
+ }
62
+ if (options.clientId === null) {
63
+ options.logger?.('Warn', 'options.clientId was not provided. Using Node.js cluster mode, ' +
64
+ 'or multiple instances of the agent will break authentication');
65
+ }
66
+ else if (typeof options.clientId !== 'string') {
67
+ throw new Error('options.clientId is invalid.');
68
+ }
69
+ }
70
+ static checkOtherOptions(options) {
71
+ if (typeof options.prefix !== 'string' || !/[-/a-z+]/.test(options.prefix)) {
72
+ throw new Error('options.prefix is invalid. It should contain the prefix on which ' +
73
+ 'forest admin routes should be mounted (i.e. "/forest")');
74
+ }
75
+ }
76
+ static isExistingPath(string) {
77
+ if (typeof string !== 'string') {
78
+ return false;
79
+ }
80
+ const parsed = (0, path_1.parse)(string);
81
+ return parsed.dir.length ? (0, fs_1.existsSync)(parsed.dir) : true;
82
+ }
83
+ static isUrl(string) {
84
+ if (typeof string !== 'string') {
85
+ return false;
86
+ }
87
+ try {
88
+ const url = new URL(string);
89
+ return url.protocol === 'http:' || url.protocol === 'https:';
90
+ }
91
+ catch (_) {
92
+ return false;
93
+ }
94
+ }
95
+ }
96
+ exports.default = OptionsValidator;
97
+ OptionsValidator.loggerPrefix = {
98
+ Debug: '\x1b[34mdebug:\x1b[0m',
99
+ Info: '\x1b[32minfo:\x1b[0m',
100
+ Warn: '\x1b[33mwarning:\x1b[0m',
101
+ Error: '\x1b[31merror:\x1b[0m',
102
+ };
103
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3B0aW9ucy12YWxpZGF0b3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvYnVpbGRlci91dGlscy9vcHRpb25zLXZhbGlkYXRvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLDJCQUFnQztBQUNoQywrQkFBNEQ7QUFLNUQsTUFBcUIsZ0JBQWdCO0lBUW5DLE1BQU0sQ0FBQyxZQUFZLENBQUMsT0FBcUI7UUFDdkMsTUFBTSxXQUFXLEdBQUcsRUFBRSxHQUFHLE9BQU8sRUFBRSxDQUFDO1FBRW5DLE1BQU0sYUFBYSxHQUFHLENBQUMsS0FBSyxFQUFFLElBQUksRUFBRSxFQUFFO1lBQ3BDLE1BQU0sV0FBVyxHQUFHLE9BQU8sQ0FBQyxXQUFXLElBQUksTUFBTSxDQUFDO1lBQ2xELE1BQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO1lBRTlDLElBQUksTUFBTSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsSUFBSSxNQUFNLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQyxFQUFFO2dCQUN4RCxPQUFPLENBQUMsS0FBSyxDQUFDLGdCQUFnQixDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQzthQUMzRDtRQUNILENBQUMsQ0FBQztRQUVGLFdBQVcsQ0FBQyxNQUFNLEdBQUcsV0FBVyxDQUFDLE1BQU0sSUFBSSxhQUFhLENBQUM7UUFDekQsV0FBVyxDQUFDLFVBQVUsR0FBRyxXQUFXLENBQUMsVUFBVSxJQUFJLDBCQUEwQixDQUFDO1FBQzlFLFdBQVcsQ0FBQyxlQUFlLEdBQUcsV0FBVyxDQUFDLGVBQWUsSUFBSSw2QkFBNkIsQ0FBQztRQUMzRixXQUFXLENBQUMsZUFBZSxHQUFHLFdBQVcsQ0FBQyxlQUFlLElBQUksQ0FBQyxDQUFDO1FBRS9ELE1BQU0sTUFBTSxHQUFHLElBQUksR0FBRyxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMs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
@@ -0,0 +1,10 @@
1
+ import { DataSource } from '@forestadmin/datasource-toolkit';
2
+ export default class TypingGenerator {
3
+ static generateTypes(dataSource: DataSource, maxDepth: number): string;
4
+ private static getRow;
5
+ private static getRelations;
6
+ private static getFlatRelations;
7
+ private static getFieldsRec;
8
+ private static getType;
9
+ }
10
+ //# sourceMappingURL=typing-generator.d.ts.map
@@ -0,0 +1,98 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const datasource_toolkit_1 = require("@forestadmin/datasource-toolkit");
4
+ class TypingGenerator {
5
+ static generateTypes(dataSource, maxDepth) {
6
+ const collections = [...dataSource.collections].sort((a, b) => a.name.localeCompare(b.name));
7
+ return [
8
+ `/* eslint-disable */`,
9
+ 'export type Schema = {',
10
+ ...collections.map(collection => [
11
+ ` ${collection.name}: {`,
12
+ this.getRow(collection),
13
+ this.getRelations(collection),
14
+ this.getFlatRelations(collection, maxDepth),
15
+ ' };',
16
+ ].join(`\n`)),
17
+ '};\n',
18
+ ].join('\n');
19
+ }
20
+ static getRow(collection) {
21
+ const content = Object.entries(collection.schema.fields).reduce((memo, [name, field]) => {
22
+ return field.type === 'Column' ? [...memo, ` ${name}: ${this.getType(field)};`] : memo;
23
+ }, []);
24
+ return ` plain: {\n${content.join('\n')}\n };`;
25
+ }
26
+ static getRelations(collection) {
27
+ const content = Object.entries(collection.schema.fields).reduce((memo, [name, field]) => {
28
+ if (field.type === 'ManyToOne' || field.type === 'OneToOne') {
29
+ const relation = field.foreignCollection;
30
+ return [
31
+ ...memo,
32
+ ` ${name}: Schema['${relation}']['plain'] & Schema['${relation}']['nested'];`,
33
+ ];
34
+ }
35
+ return memo;
36
+ }, []);
37
+ return content.length ? ` nested: {\n${content.join('\n')}\n };` : ` nested: {};`;
38
+ }
39
+ static getFlatRelations(collection, maxDepth) {
40
+ const fields = this.getFieldsRec(collection, maxDepth, []);
41
+ return fields.length
42
+ ? ` flat: {\n ${fields.join('\n ')}\n };`
43
+ : ` flat: {};`;
44
+ }
45
+ static getFieldsRec(collection, maxDepth, traversed) {
46
+ const columns = traversed.length > 0
47
+ ? Object.entries(collection.schema.fields)
48
+ .filter(([, schema]) => schema.type === 'Column')
49
+ .map(([name, schema]) => `'${name}': ${this.getType(schema)};`)
50
+ : [];
51
+ const relations = Object.entries(collection.schema.fields).reduce((memo, [name, schema]) => {
52
+ if (schema.type !== 'ManyToOne' && schema.type !== 'OneToOne')
53
+ return memo;
54
+ const subCollection = collection.dataSource.getCollection(schema.foreignCollection);
55
+ const inverse = datasource_toolkit_1.CollectionUtils.getInverseRelation(collection, name);
56
+ // Do not expand inverse relations, as those create useless cycles
57
+ const expand = traversed.length < maxDepth &&
58
+ !traversed.find(({ c, r }) => c === subCollection && r === inverse);
59
+ if (!expand)
60
+ return memo;
61
+ // Manually expand the field type (cycles are not allowed in template literal types)
62
+ return [
63
+ ...memo,
64
+ ...this.getFieldsRec(subCollection, maxDepth, [
65
+ ...traversed,
66
+ { c: collection, r: name },
67
+ ]).map(f => `'${name}:${f.slice(1)}`),
68
+ ];
69
+ }, []);
70
+ return [...columns, ...relations];
71
+ }
72
+ static getType(field) {
73
+ if (Array.isArray(field.columnType)) {
74
+ return `Array<${this.getType({ columnType: field.columnType[0] })}>`;
75
+ }
76
+ if (field.columnType === 'Enum') {
77
+ return field.enumValues.map(v => `'${v.replace(/'/g, "\\'")}'`).join(' | ');
78
+ }
79
+ if (typeof field.columnType === 'string') {
80
+ return {
81
+ Boolean: 'boolean',
82
+ Date: 'string',
83
+ Dateonly: 'string',
84
+ Json: 'any',
85
+ Number: 'number',
86
+ Point: '[number, number]',
87
+ String: 'string',
88
+ Timeonly: 'string',
89
+ Uuid: 'string',
90
+ }[field.columnType];
91
+ }
92
+ return `{${Object.entries(field.columnType)
93
+ .map(([key, subType]) => `${key}: ${this.getType({ columnType: subType })}`)
94
+ .join('; ')}}`;
95
+ }
96
+ }
97
+ exports.default = TypingGenerator;
98
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwaW5nLWdlbmVyYXRvci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9idWlsZGVyL3V0aWxzL3R5cGluZy1nZW5lcmF0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSx3RUFNeUM7QUFFekMsTUFBcUIsZUFBZTtJQUNsQyxNQUFNLENBQUMsYUFBYSxDQUFDLFVBQXNCLEVBQUUsUUFBZ0I7UUFDM0QsTUFBTSxXQUFXLEdBQUcsQ0FBQyxHQUFHLFVBQVUsQ0FBQyxXQUFXLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztRQUU3RixPQUFPO1lBQ0wsc0JBQXNCO1lBQ3RCLHdCQUF3QjtZQUN4QixHQUFHLFdBQVcsQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FDOUI7Z0JBQ0UsS0FBSyxVQUFVLENBQUMsSUFBSSxLQUFLO2dCQUN6QixJQUFJLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQztnQkFDdkIsSUFBSSxDQUFDLFlBQVksQ0FBQyxVQUFVLENBQUM7Z0JBQzdCLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxVQUFVLEVBQUUsUUFBUSxDQUFDO2dCQUMzQyxNQUFNO2FBQ1AsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQ2I7WUFDRCxNQUFNO1NBQ1AsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDZixDQUFDO0lBRU8sTUFBTSxDQUFDLE1BQU0sQ0FBQyxVQUFzQjtRQUMxQyxNQUFNLE9BQU8sR0FBRyxNQUFNLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxFQUFFLEVBQUU7WUFDdEYsT0FBTyxLQUFLLENBQUMsSUFBSSxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksRUFBRSxTQUFTLElBQUksS0FBSyxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO1FBQzlGLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUVQLE9BQU8saUJBQWlCLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQztJQUN2RCxDQUFDO0lBRU8sTUFBTSxDQUFDLFlBQVksQ0FBQyxVQUFzQjtRQUNoRCxNQUFNLE9BQU8sR0FBRyxNQUFNLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxFQUFFLEVBQUU7WUFDdEYsSUFBSSxLQUFLLENBQUMsSUFBSSxLQUFLLFdBQVcsSUFBSSxLQUFLLENBQUMsSUFBSSxLQUFLLFVBQVUsRUFBRTtnQkFDM0QsTUFBTSxRQUFRLEdBQUcsS0FBSyxDQUFDLGlCQUFpQixDQUFDO2dCQUV6QyxPQUFPO29CQUNMLEdBQUcsSUFBSTtvQkFDUCxTQUFTLElBQUksYUFBYSxRQUFRLHlCQUF5QixRQUFRLGVBQWU7aUJBQ25GLENBQUM7YUFDSDtZQUVELE9BQU8sSUFBSSxDQUFDO1FBQ2QsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBRVAsT0FBTyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxrQkFBa0IsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxpQkFBaUIsQ0FBQztJQUM3RixDQUFDO0lBRU8sTUFBTSxDQUFDLGdCQUFnQixDQUFDLFVBQXNCLEVBQUUsUUFBZ0I7UUFDdEUsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxVQUFVLEVBQUUsUUFBUSxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBRTNELE9BQU8sTUFBTSxDQUFDLE1BQU07WUFDbEIsQ0FBQyxDQUFDLHNCQUFzQixNQUFNLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxVQUFVO1lBQ3pELENBQUMsQ0FBQyxlQUFlLENBQUM7SUFDdEIsQ0FBQztJQUVPLE1BQU0sQ0FBQyxZQUFZLENBQ3pCLFVBQXNCLEVBQ3RCLFFBQWdCLEVBQ2hCLFNBQXlDO1FBRXpDLE1BQU0sT0FBTyxHQUNYLFNBQVMsQ0FBQyxNQUFNLEdBQUcsQ0FBQztZQUNsQixDQUFDLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQztpQkFDckMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxFQUFFLEVBQUUsQ0FBQyxNQUFNLENBQUMsSUFBSSxLQUFLLFFBQVEsQ0FBQztpQkFDaEQsR0FBRyxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLEVBQUUsRUFBRSxDQUFDLElBQUksSUFBSSxNQUFNLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBc0IsQ0FBQyxHQUFHLENBQUM7WUFDbkYsQ0FBQyxDQUFDLEVBQUUsQ0FBQztRQUVULE1BQU0sU0FBUyxHQUFHLE1BQU0sQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLEVBQUUsRUFBRTtZQUN6RixJQUFJLE1BQU0sQ0FBQyxJQUFJLEtBQUssV0FBVyxJQUFJLE1BQU0sQ0FBQyxJQUFJLEtBQUssVUFBVTtnQkFBRSxPQUFPLElBQUksQ0FBQztZQUUzRSxNQUFNLGFBQWEsR0FBRyxVQUFVLENBQUMsVUFBVSxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsaUJBQWlCLENBQUMsQ0FBQztZQUNwRixNQUFNLE9BQU8sR0FBRyxvQ0FBZSxDQUFDLGtCQUFrQixDQUFDLFVBQVUsRUFBRSxJQUFJLENBQUMsQ0FBQztZQUVyRSxrRUFBa0U7WUFDbEUsTUFBTSxNQUFNLEdBQ1YsU0FBUyxDQUFDLE1BQU0sR0FBRyxRQUFRO2dCQUMzQixDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQyxLQUFLLGFBQWEsSUFBSSxDQUFDLEtBQUssT0FBTyxDQUFDLENBQUM7WUFDdEUsSUFBSSxDQUFDLE1BQU07Z0JBQUUsT0FBTyxJQUFJLENBQUM7WUFFekIsb0ZBQW9GO1lBQ3BGLE9BQU87Z0JBQ0wsR0FBRyxJQUFJO2dCQUNQLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxhQUFhLEVBQUUsUUFBUSxFQUFFO29CQUM1QyxHQUFHLFNBQVM7b0JBQ1osRUFBRSxDQUFDLEVBQUUsVUFBVSxFQUFFLENBQUMsRUFBRSxJQUFJLEVBQUU7aUJBQzNCLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxJQUFJLElBQUksSUFBSSxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7YUFDdEMsQ0FBQztRQUNKLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUVQLE9BQU8sQ0FBQyxHQUFHLE9BQU8sRUFBRSxHQUFHLFNBQVMsQ0FBQyxDQUFDO0lBQ3BDLENBQUM7SUFFTyxNQUFNLENBQUMsT0FBTyxDQUFDLEtBQXdEO1FBQzdFLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLEVBQUU7WUFDbkMsT0FBTyxTQUFTLElBQUksQ0FBQyxPQUFPLENBQUMsRUFBRSxVQUFVLEVBQUUsS0FBSyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQztTQUN0RTtRQUVELElBQUksS0FBSyxDQUFDLFVBQVUsS0FBSyxNQUFNLEVBQUU7WUFDL0IsT0FBTyxLQUFLLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztTQUM3RTtRQUVELElBQUksT0FBTyxLQUFLLENBQUMsVUFBVSxLQUFLLFFBQVEsRUFBRTtZQUN4QyxPQUFPO2dCQUNMLE9BQU8sRUFBRSxTQUFTO2dCQUNsQixJQUFJLEVBQUUsUUFBUTtnQkFDZCxRQUFRLEVBQUUsUUFBUTtnQkFDbEIsSUFBSSxFQUFFLEtBQUs7Z0JBQ1gsTUFBTSxFQUFFLFFBQVE7Z0JBQ2hCLEtBQUssRUFBRSxrQkFBa0I7Z0JBQ3pCLE1BQU0sRUFBRSxRQUFRO2dCQUNoQixRQUFRLEVBQUUsUUFBUTtnQkFDbEIsSUFBSSxFQUFFLFFBQVE7YUFDZixDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsQ0FBQztTQUNyQjtRQUVELE9BQU8sSUFBSSxNQUFNLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUM7YUFDeEMsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsT0FBTyxDQUFDLEVBQUUsRUFBRSxDQUFDLEdBQUcsR0FBRyxLQUFLLElBQUksQ0FBQyxPQUFPLENBQUMsRUFBRSxVQUFVLEVBQUUsT0FBTyxFQUFFLENBQUMsRUFBRSxDQUFDO2FBQzNFLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDO0lBQ25CLENBQUM7Q0FDRjtBQXJIRCxrQ0FxSEMifQ==
package/dist/index.d.ts CHANGED
@@ -1,7 +1,8 @@
1
+ import { TSchema } from '@forestadmin/datasource-toolkit';
1
2
  import { AgentOptions } from './types';
2
3
  import Agent from './builder/agent';
3
4
  export { default as Collection } from './builder/collection';
4
5
  export { Agent };
5
6
  export * from './types';
6
- export declare function createAgent(agentoptions: AgentOptions): Agent;
7
+ export declare function createAgent<S extends TSchema = TSchema>(options: AgentOptions): Agent<S>;
7
8
  //# sourceMappingURL=index.d.ts.map
package/dist/index.js CHANGED
@@ -23,8 +23,8 @@ exports.Agent = agent_1.default;
23
23
  var collection_1 = require("./builder/collection");
24
24
  Object.defineProperty(exports, "Collection", { enumerable: true, get: function () { return __importDefault(collection_1).default; } });
25
25
  __exportStar(require("./types"), exports);
26
- function createAgent(agentoptions) {
27
- return new agent_1.default(agentoptions);
26
+ function createAgent(options) {
27
+ return new agent_1.default(options);
28
28
  }
29
29
  exports.createAgent = createAgent;
30
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFDQSw0REFBb0M7QUFHM0IsZ0JBSEYsZUFBSyxDQUdFO0FBRGQsbURBQTZEO0FBQXBELHlIQUFBLE9BQU8sT0FBYztBQUU5QiwwQ0FBd0I7QUFFeEIsU0FBZ0IsV0FBVyxDQUFDLFlBQTBCO0lBQ3BELE9BQU8sSUFBSSxlQUFLLENBQUMsWUFBWSxDQUFDLENBQUM7QUFDakMsQ0FBQztBQUZELGtDQUVDIn0=
30
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFHQSw0REFBb0M7QUFHM0IsZ0JBSEYsZUFBSyxDQUdFO0FBRGQsbURBQTZEO0FBQXBELHlIQUFBLE9BQU8sT0FBYztBQUU5QiwwQ0FBd0I7QUFFeEIsU0FBZ0IsV0FBVyxDQUE4QixPQUFxQjtJQUM1RSxPQUFPLElBQUksZUFBSyxDQUFJLE9BQU8sQ0FBQyxDQUFDO0FBQy9CLENBQUM7QUFGRCxrQ0FFQyJ9
package/dist/types.d.ts CHANGED
@@ -11,6 +11,8 @@ export declare type AgentOptions = {
11
11
  prefix?: string;
12
12
  isProduction: boolean;
13
13
  schemaPath?: string;
14
+ typingsPath?: string;
15
+ typingsMaxDepth?: number;
14
16
  permissionsCacheDurationInSeconds?: number;
15
17
  };
16
18
  //# sourceMappingURL=types.d.ts.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@forestadmin/agent",
3
- "version": "1.0.0-beta.25",
3
+ "version": "1.0.0-beta.28",
4
4
  "main": "dist/index.js",
5
5
  "license": "GPL-3.0",
6
6
  "publishConfig": {
@@ -13,7 +13,8 @@
13
13
  },
14
14
  "dependencies": {
15
15
  "@fast-csv/format": "^4.3.5",
16
- "@forestadmin/datasource-toolkit": "1.0.0-beta.15",
16
+ "@fastify/express": "^1.1.0",
17
+ "@forestadmin/datasource-toolkit": "1.0.0-beta.16",
17
18
  "@koa/cors": "^3.3.0",
18
19
  "@koa/router": "^10.1.1",
19
20
  "forest-ip-utils": "^1.0.1",
@@ -50,6 +51,15 @@
50
51
  "@types/koa__cors": "^3.1.1",
51
52
  "@types/koa__router": "^8.0.11",
52
53
  "@types/superagent": "^4.1.15",
53
- "fishery": "^2.1.0"
54
+ "fishery": "^2.1.0",
55
+ "@nestjs/common": "^8.4.5",
56
+ "@nestjs/core": "^8.4.5",
57
+ "@nestjs/platform-express": "^8.4.5",
58
+ "@nestjs/platform-fastify": "^8.4.5",
59
+ "express": "^4.18.1",
60
+ "fastify": "^3.29.0",
61
+ "fastify2": "npm:fastify@^2.15.3",
62
+ "reflect-metadata": "^0.1.13",
63
+ "rxjs": "^7.5.5"
54
64
  }
55
65
  }
@@ -1,13 +0,0 @@
1
- import { AgentOptions } from '../../types';
2
- import { AgentOptionsWithDefaults } from '../types';
3
- export default class OptionsUtils {
4
- private static loggerPrefix;
5
- static withDefaults(options: AgentOptions): AgentOptionsWithDefaults;
6
- static validate(options: AgentOptionsWithDefaults): void;
7
- private static checkForestServerOptions;
8
- private static checkAuthOptions;
9
- private static checkOtherOptions;
10
- private static isExistingPath;
11
- private static isUrl;
12
- }
13
- //# sourceMappingURL=http-driver-options.d.ts.map
@@ -1,95 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const fs_1 = require("fs");
4
- const path_1 = require("path");
5
- class OptionsUtils {
6
- static withDefaults(options) {
7
- const copyOptions = { ...options };
8
- const defaultLogger = (level, data) => {
9
- const loggerLevel = options.loggerLevel ?? 'Info';
10
- const levels = Object.keys(this.loggerPrefix);
11
- if (levels.indexOf(level) >= levels.indexOf(loggerLevel)) {
12
- console.error(OptionsUtils.loggerPrefix[level], data);
13
- }
14
- };
15
- copyOptions.logger = copyOptions.logger || defaultLogger;
16
- copyOptions.schemaPath = copyOptions.schemaPath || '.forestadmin-schema.json';
17
- copyOptions.forestServerUrl = copyOptions.forestServerUrl || 'https://api.forestadmin.com';
18
- return Object.freeze({
19
- clientId: null,
20
- loggerLevel: 'Info',
21
- prefix: '/forest',
22
- permissionsCacheDurationInSeconds: 15 * 60,
23
- ...copyOptions,
24
- });
25
- }
26
- static validate(options) {
27
- OptionsUtils.checkForestServerOptions(options);
28
- OptionsUtils.checkAuthOptions(options);
29
- OptionsUtils.checkOtherOptions(options);
30
- }
31
- static checkForestServerOptions(options) {
32
- if (typeof options.envSecret !== 'string' || !/^[0-9a-f]{64}$/.test(options.envSecret)) {
33
- throw new Error('options.envSecret is invalid. You can retrieve its value from ' +
34
- 'https://www.forestadmin.com');
35
- }
36
- if (!OptionsUtils.isUrl(options.forestServerUrl)) {
37
- throw new Error('options.forestServerUrl is invalid. It should contain an URL ' +
38
- '(i.e. "https://api.forestadmin.com")');
39
- }
40
- if (!OptionsUtils.isExistingPath(options.schemaPath)) {
41
- throw new Error('options.schemaPath is invalid. It should contain a relative filepath ' +
42
- 'where the schema should be loaded/updated (i.e. "./.forestadmin-schema.json")');
43
- }
44
- }
45
- static checkAuthOptions(options) {
46
- if (!OptionsUtils.isUrl(options.agentUrl)) {
47
- throw new Error('options.agentUrl is invalid. It should contain an url where your agent is reachable ' +
48
- '(i.e. "https://api-forestadmin.mycompany.com")');
49
- }
50
- if (typeof options.authSecret !== 'string') {
51
- throw new Error('options.authSecret is invalid. Any long random string should work ' +
52
- '(i.e. "OfpssLrbgF3P4vHJTTpb"');
53
- }
54
- if (options.clientId === null) {
55
- options.logger?.('Warn', 'options.clientId was not provided. Using Node.js cluster mode, ' +
56
- 'or multiple instances of the agent will break authentication');
57
- }
58
- else if (typeof options.clientId !== 'string') {
59
- throw new Error('options.clientId is invalid.');
60
- }
61
- }
62
- static checkOtherOptions(options) {
63
- if (typeof options.prefix !== 'string' || !/[-/a-z+]/.test(options.prefix)) {
64
- throw new Error('options.prefix is invalid. It should contain the prefix on which ' +
65
- 'forest admin routes should be mounted (i.e. "/forest")');
66
- }
67
- }
68
- static isExistingPath(string) {
69
- if (typeof string !== 'string') {
70
- return false;
71
- }
72
- const parsed = (0, path_1.parse)(string);
73
- return parsed.dir.length ? (0, fs_1.existsSync)(parsed.dir) : true;
74
- }
75
- static isUrl(string) {
76
- if (typeof string !== 'string') {
77
- return false;
78
- }
79
- try {
80
- const url = new URL(string);
81
- return url.protocol === 'http:' || url.protocol === 'https:';
82
- }
83
- catch (_) {
84
- return false;
85
- }
86
- }
87
- }
88
- exports.default = OptionsUtils;
89
- OptionsUtils.loggerPrefix = {
90
- Debug: '\x1b[34mdebug:\x1b[0m',
91
- Info: '\x1b[32minfo:\x1b[0m',
92
- Warn: '\x1b[33mwarning:\x1b[0m',
93
- Error: '\x1b[31merror:\x1b[0m',
94
- };
95
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaHR0cC1kcml2ZXItb3B0aW9ucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9hZ2VudC91dGlscy9odHRwLWRyaXZlci1vcHRpb25zLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsMkJBQWdDO0FBQ2hDLCtCQUEwQztBQUsxQyxNQUFxQixZQUFZO0lBUS9CLE1BQU0sQ0FBQyxZQUFZLENBQUMsT0FBcUI7UUFDdkMsTUFBTSxXQUFXLEdBQUcsRUFBRSxHQUFHLE9BQU8sRUFBRSxDQUFDO1FBRW5DLE1BQU0sYUFBYSxHQUFHLENBQUMsS0FBSyxFQUFFLElBQUksRUFBRSxFQUFFO1lBQ3BDLE1BQU0sV0FBVyxHQUFHLE9BQU8sQ0FBQyxXQUFXLElBQUksTUFBTSxDQUFDO1lBQ2xELE1BQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO1lBRTlDLElBQUksTUFBTSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsSUFBSSxNQUFNLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQyxFQUFFO2dCQUN4RCxPQUFPLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUM7YUFDdkQ7UUFDSCxDQUFDLENBQUM7UUFFRixXQUFXLENBQUMsTUFBTSxHQUFHLFdBQVcsQ0FBQyxNQUFNLElBQUksYUFBYSxDQUFDO1FBQ3pELFdBQVcsQ0FBQyxVQUFVLEdBQUcsV0FBVyxDQUFDLFVBQVUsSUFBSSwwQkFBMEIsQ0FBQztRQUM5RSxXQUFXLENBQUMsZUFBZSxHQUFHLFdBQVcsQ0FBQyxlQUFlLElBQUksNkJBQTZCLENBQUM7UUFFM0YsT0FBaUMsTUFBTSxDQUFDLE1BQU0sQ0FBQztZQUM3QyxRQUFRLEVBQUUsSUFBSTtZQUNkLFdBQVcsRUFBRSxNQUFNO1lBQ25CLE1BQU0sRUFBRSxTQUFTO1lBQ2pCLGlDQUFpQyxFQUFFLEVB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