@forestadmin/agent 1.0.0-beta.9 → 1.0.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.
- package/dist/agent.d.ts +76 -0
- package/dist/agent.js +133 -0
- package/dist/framework-mounter.d.ts +43 -0
- package/dist/framework-mounter.js +157 -0
- package/dist/index.d.ts +7 -3
- package/dist/index.js +10 -21
- package/dist/routes/access/api-chart.d.ts +16 -0
- package/dist/routes/access/api-chart.js +47 -0
- package/dist/{agent/routes → routes}/access/chart.d.ts +1 -0
- package/dist/routes/access/chart.js +162 -0
- package/dist/{agent/routes → routes}/access/count-related.d.ts +0 -0
- package/dist/routes/access/count-related.js +31 -0
- package/dist/{agent/routes → routes}/access/count.d.ts +0 -0
- package/dist/routes/access/count.js +31 -0
- package/dist/{agent/routes → routes}/access/csv-related.d.ts +0 -0
- package/dist/routes/access/csv-related.js +33 -0
- package/dist/{agent/routes → routes}/access/csv.d.ts +0 -0
- package/dist/routes/access/csv.js +31 -0
- package/dist/{agent/routes → routes}/access/get.d.ts +0 -0
- package/dist/routes/access/get.js +29 -0
- package/dist/{agent/routes → routes}/access/list-related.d.ts +0 -0
- package/dist/routes/access/list-related.js +25 -0
- package/dist/{agent/routes → routes}/access/list.d.ts +0 -0
- package/dist/routes/access/list.js +22 -0
- package/dist/{agent/routes → routes}/base-route.d.ts +0 -1
- package/dist/routes/base-route.js +13 -0
- package/dist/{agent/routes → routes}/collection-route.d.ts +0 -0
- package/dist/{agent/routes → routes}/collection-route.js +1 -1
- package/dist/{agent/routes → routes}/index.d.ts +0 -0
- package/dist/routes/index.js +108 -0
- package/dist/{agent/routes → routes}/modification/action.d.ts +0 -1
- package/dist/routes/modification/action.js +104 -0
- package/dist/routes/modification/associate-related.d.ts +12 -0
- package/dist/routes/modification/associate-related.js +51 -0
- package/dist/{agent/routes → routes}/modification/create.d.ts +0 -0
- package/dist/routes/modification/create.js +83 -0
- package/dist/{agent/routes → routes}/modification/delete.d.ts +0 -0
- package/dist/routes/modification/delete.js +41 -0
- package/dist/{agent/routes → routes}/modification/dissociate-delete-related.d.ts +0 -0
- package/dist/routes/modification/dissociate-delete-related.js +89 -0
- package/dist/routes/modification/update-field.d.ts +9 -0
- package/dist/routes/modification/update-field.js +39 -0
- package/dist/{agent/routes → routes}/modification/update-relation.d.ts +0 -0
- package/dist/routes/modification/update-relation.js +59 -0
- package/dist/{agent/routes → routes}/modification/update.d.ts +0 -0
- package/dist/routes/modification/update.js +31 -0
- package/dist/{agent/routes → routes}/relation-route.d.ts +0 -0
- package/dist/{agent/routes → routes}/relation-route.js +1 -1
- package/dist/{agent/routes → routes}/security/authentication.d.ts +1 -3
- package/dist/routes/security/authentication.js +74 -0
- package/dist/{agent/routes → routes}/security/ip-whitelist.d.ts +0 -0
- package/dist/{agent/routes → routes}/security/ip-whitelist.js +1 -1
- package/dist/{agent/routes → routes}/security/scope-invalidation.d.ts +0 -0
- package/dist/{agent/routes → routes}/security/scope-invalidation.js +1 -1
- package/dist/{agent/routes → routes}/system/error-handling.d.ts +2 -0
- package/dist/routes/system/error-handling.js +75 -0
- package/dist/{agent/routes → routes}/system/healthcheck.d.ts +0 -0
- package/dist/{agent/routes → routes}/system/healthcheck.js +1 -1
- package/dist/{agent/routes → routes}/system/logger.d.ts +0 -0
- package/dist/{agent/routes → routes}/system/logger.js +2 -2
- package/dist/{agent/services → services}/index.d.ts +0 -0
- package/dist/{agent/services → services}/index.js +2 -2
- package/dist/{agent/services → services}/permissions.d.ts +0 -0
- package/dist/services/permissions.js +85 -0
- package/dist/{agent/services → services}/serializer.d.ts +0 -5
- package/dist/services/serializer.js +120 -0
- package/dist/types.d.ts +28 -3
- package/dist/types.js +21 -1
- package/dist/{agent/utils → utils}/body-parser.d.ts +0 -0
- package/dist/{agent/utils → utils}/body-parser.js +1 -1
- package/dist/utils/condition-tree-parser.d.ts +11 -0
- package/dist/utils/condition-tree-parser.js +53 -0
- package/dist/{agent/utils → utils}/context-filter-factory.d.ts +0 -0
- package/dist/{agent/utils → utils}/context-filter-factory.js +1 -2
- package/dist/{agent/utils → utils}/csv-generator.d.ts +2 -2
- package/dist/utils/csv-generator.js +39 -0
- package/dist/{agent/utils → utils}/csv-route-context.d.ts +0 -0
- package/dist/utils/csv-route-context.js +14 -0
- package/dist/{agent/utils → utils}/forest-http-api.d.ts +5 -3
- package/dist/utils/forest-http-api.js +180 -0
- package/dist/{agent/utils → utils}/forest-schema/action-values.d.ts +2 -2
- package/dist/utils/forest-schema/action-values.js +144 -0
- package/dist/{agent/utils → utils}/forest-schema/emitter.d.ts +2 -2
- package/dist/utils/forest-schema/emitter.js +70 -0
- package/dist/{agent/utils → utils}/forest-schema/filterable.d.ts +0 -0
- package/dist/{agent/utils → utils}/forest-schema/filterable.js +1 -1
- package/dist/{agent/utils → utils}/forest-schema/generator-actions.d.ts +1 -1
- package/dist/utils/forest-schema/generator-actions.js +99 -0
- package/dist/{agent/utils → utils}/forest-schema/generator-collection.d.ts +1 -1
- package/dist/{agent/utils → utils}/forest-schema/generator-collection.js +3 -3
- package/dist/{agent/utils → utils}/forest-schema/generator-fields.d.ts +1 -0
- package/dist/utils/forest-schema/generator-fields.js +160 -0
- package/dist/{agent/utils → utils}/forest-schema/generator-segments.d.ts +0 -0
- package/dist/{agent/utils → utils}/forest-schema/generator-segments.js +1 -1
- package/dist/{agent/utils → utils}/forest-schema/types.d.ts +10 -4
- package/dist/{agent/utils → utils}/forest-schema/types.js +1 -1
- package/dist/{agent/utils → utils}/forest-schema/validation.d.ts +1 -1
- package/dist/utils/forest-schema/validation.js +28 -0
- package/dist/{agent/utils → utils}/id.d.ts +0 -0
- package/dist/utils/id.js +43 -0
- package/dist/{agent/utils/http-driver-options.d.ts → utils/options-validator.d.ts} +4 -5
- package/dist/utils/options-validator.js +92 -0
- package/dist/{agent/utils → utils}/query-string.d.ts +2 -2
- package/dist/utils/query-string.js +134 -0
- package/package.json +14 -3
- package/CHANGELOG.md +0 -465
- package/dist/agent/forestadmin-http-driver.d.ts +0 -34
- package/dist/agent/forestadmin-http-driver.js +0 -72
- package/dist/agent/routes/access/chart.js +0 -147
- package/dist/agent/routes/access/count-related.js +0 -24
- package/dist/agent/routes/access/count.js +0 -24
- package/dist/agent/routes/access/csv-related.js +0 -33
- package/dist/agent/routes/access/csv.js +0 -30
- package/dist/agent/routes/access/get.js +0 -28
- package/dist/agent/routes/access/list-related.js +0 -26
- package/dist/agent/routes/access/list.js +0 -23
- package/dist/agent/routes/base-route.js +0 -16
- package/dist/agent/routes/index.js +0 -90
- package/dist/agent/routes/modification/action.js +0 -103
- package/dist/agent/routes/modification/associate-related.d.ts +0 -12
- package/dist/agent/routes/modification/associate-related.js +0 -49
- package/dist/agent/routes/modification/create.js +0 -81
- package/dist/agent/routes/modification/delete.js +0 -40
- package/dist/agent/routes/modification/dissociate-delete-related.js +0 -88
- package/dist/agent/routes/modification/update-relation.js +0 -53
- package/dist/agent/routes/modification/update.js +0 -29
- package/dist/agent/routes/security/authentication.js +0 -86
- package/dist/agent/routes/system/error-handling.js +0 -56
- package/dist/agent/services/permissions.js +0 -79
- package/dist/agent/services/serializer.js +0 -120
- package/dist/agent/types.d.ts +0 -23
- package/dist/agent/types.js +0 -22
- package/dist/agent/utils/csv-generator.js +0 -39
- package/dist/agent/utils/csv-route-context.js +0 -14
- package/dist/agent/utils/forest-http-api.js +0 -173
- package/dist/agent/utils/forest-schema/action-values.js +0 -144
- package/dist/agent/utils/forest-schema/emitter.js +0 -70
- package/dist/agent/utils/forest-schema/generator-actions.js +0 -99
- package/dist/agent/utils/forest-schema/generator-fields.js +0 -131
- package/dist/agent/utils/forest-schema/validation.js +0 -26
- package/dist/agent/utils/http-driver-options.js +0 -95
- package/dist/agent/utils/id.js +0 -43
- package/dist/agent/utils/query-string.js +0 -130
- package/dist/builder/agent.d.ts +0 -82
- package/dist/builder/agent.js +0 -123
- package/dist/builder/collection.d.ts +0 -148
- package/dist/builder/collection.js +0 -226
- package/dist/builder/types.d.ts +0 -5
- package/dist/builder/types.js +0 -3
package/dist/agent.d.ts
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { ChartDefinition, CollectionCustomizer, DataSourceOptions, TCollectionName, TSchema } from '@forestadmin/datasource-customizer';
|
|
2
|
+
import { DataSourceFactory } from '@forestadmin/datasource-toolkit';
|
|
3
|
+
import { AgentOptions } from './types';
|
|
4
|
+
import FrameworkMounter from './framework-mounter';
|
|
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 Agent<S extends TSchema = TSchema> extends FrameworkMounter {
|
|
16
|
+
private options;
|
|
17
|
+
private customizer;
|
|
18
|
+
/**
|
|
19
|
+
* Create a new Agent Builder.
|
|
20
|
+
* If any options are missing, the default will be applied:
|
|
21
|
+
* ```
|
|
22
|
+
* forestServerUrl: 'https://api.forestadmin.com',
|
|
23
|
+
* logger: (level, data) => console.error(level, data),
|
|
24
|
+
* prefix: 'api/v1',
|
|
25
|
+
* schemaPath: '.forestadmin-schema.json',
|
|
26
|
+
* permissionsCacheDurationInSeconds: 15 * 60,
|
|
27
|
+
* ```
|
|
28
|
+
* @param options options
|
|
29
|
+
* @example
|
|
30
|
+
* new AgentBuilder(options)
|
|
31
|
+
* .addDataSource(new DataSource())
|
|
32
|
+
* .start();
|
|
33
|
+
*/
|
|
34
|
+
constructor(options: AgentOptions);
|
|
35
|
+
/**
|
|
36
|
+
* Start the agent.
|
|
37
|
+
*/
|
|
38
|
+
start(): Promise<void>;
|
|
39
|
+
/**
|
|
40
|
+
* Add a datasource
|
|
41
|
+
* @param factory the datasource to add
|
|
42
|
+
* @param options the options
|
|
43
|
+
*/
|
|
44
|
+
addDataSource(factory: DataSourceFactory, options?: DataSourceOptions): this;
|
|
45
|
+
/**
|
|
46
|
+
* Create a new API chart
|
|
47
|
+
* @param name name of the chart
|
|
48
|
+
* @param definition definition of the chart
|
|
49
|
+
* @example
|
|
50
|
+
* .addChart('numCustomers', {
|
|
51
|
+
* type: 'Value',
|
|
52
|
+
* render: (context, resultBuilder) => {
|
|
53
|
+
* return resultBuilder.value(123);
|
|
54
|
+
* }
|
|
55
|
+
* })
|
|
56
|
+
*/
|
|
57
|
+
addChart(name: string, definition: ChartDefinition<S>): this;
|
|
58
|
+
/**
|
|
59
|
+
* Allow to interact with a decorated collection
|
|
60
|
+
* @param name the name of the collection to manipulate
|
|
61
|
+
* @param handle a function that provide a
|
|
62
|
+
* collection builder on the given collection name
|
|
63
|
+
* @example
|
|
64
|
+
* .customizeCollection('books', books => books.renameField('xx', 'yy'))
|
|
65
|
+
*/
|
|
66
|
+
customizeCollection<N extends TCollectionName<S>>(name: N, handle: (collection: CollectionCustomizer<S, N>) => unknown): this;
|
|
67
|
+
/**
|
|
68
|
+
* Create an http handler which can respond to all queries which are expected from an agent.
|
|
69
|
+
*/
|
|
70
|
+
private getRouter;
|
|
71
|
+
/**
|
|
72
|
+
* Send the apimap to forest admin server
|
|
73
|
+
*/
|
|
74
|
+
private sendSchema;
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=agent.d.ts.map
|
package/dist/agent.js
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
7
|
+
const datasource_customizer_1 = require("@forestadmin/datasource-customizer");
|
|
8
|
+
const router_1 = __importDefault(require("@koa/router"));
|
|
9
|
+
const koa_bodyparser_1 = __importDefault(require("koa-bodyparser"));
|
|
10
|
+
const cors_1 = __importDefault(require("@koa/cors"));
|
|
11
|
+
const forest_http_api_1 = __importDefault(require("./utils/forest-http-api"));
|
|
12
|
+
const framework_mounter_1 = __importDefault(require("./framework-mounter"));
|
|
13
|
+
const options_validator_1 = __importDefault(require("./utils/options-validator"));
|
|
14
|
+
const emitter_1 = __importDefault(require("./utils/forest-schema/emitter"));
|
|
15
|
+
const routes_1 = __importDefault(require("./routes"));
|
|
16
|
+
const services_1 = __importDefault(require("./services"));
|
|
17
|
+
/**
|
|
18
|
+
* Allow to create a new Forest Admin agent from scratch.
|
|
19
|
+
* Builds the application by composing and configuring all the collection decorators.
|
|
20
|
+
*
|
|
21
|
+
* Minimal code to add a datasource
|
|
22
|
+
* @example
|
|
23
|
+
* new AgentBuilder(options)
|
|
24
|
+
* .addDataSource(new SomeDataSource())
|
|
25
|
+
* .start();
|
|
26
|
+
*/
|
|
27
|
+
class Agent extends framework_mounter_1.default {
|
|
28
|
+
/**
|
|
29
|
+
* Create a new Agent Builder.
|
|
30
|
+
* If any options are missing, the default will be applied:
|
|
31
|
+
* ```
|
|
32
|
+
* forestServerUrl: 'https://api.forestadmin.com',
|
|
33
|
+
* logger: (level, data) => console.error(level, data),
|
|
34
|
+
* prefix: 'api/v1',
|
|
35
|
+
* schemaPath: '.forestadmin-schema.json',
|
|
36
|
+
* permissionsCacheDurationInSeconds: 15 * 60,
|
|
37
|
+
* ```
|
|
38
|
+
* @param options options
|
|
39
|
+
* @example
|
|
40
|
+
* new AgentBuilder(options)
|
|
41
|
+
* .addDataSource(new DataSource())
|
|
42
|
+
* .start();
|
|
43
|
+
*/
|
|
44
|
+
constructor(options) {
|
|
45
|
+
const allOptions = options_validator_1.default.validate(options_validator_1.default.withDefaults(options));
|
|
46
|
+
super(allOptions.prefix, allOptions.logger);
|
|
47
|
+
this.options = allOptions;
|
|
48
|
+
this.customizer = new datasource_customizer_1.DataSourceCustomizer();
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Start the agent.
|
|
52
|
+
*/
|
|
53
|
+
async start() {
|
|
54
|
+
const { logger, typingsPath, typingsMaxDepth } = this.options;
|
|
55
|
+
const dataSource = await this.customizer.getDataSource(logger);
|
|
56
|
+
const [router] = await Promise.all([
|
|
57
|
+
this.getRouter(dataSource),
|
|
58
|
+
this.sendSchema(dataSource),
|
|
59
|
+
!this.options.isProduction && typingsPath
|
|
60
|
+
? this.customizer.updateTypesOnFileSystem(typingsPath, typingsMaxDepth)
|
|
61
|
+
: Promise.resolve(),
|
|
62
|
+
]);
|
|
63
|
+
return super.start(router);
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Add a datasource
|
|
67
|
+
* @param factory the datasource to add
|
|
68
|
+
* @param options the options
|
|
69
|
+
*/
|
|
70
|
+
addDataSource(factory, options) {
|
|
71
|
+
this.customizer.addDataSource(factory, options);
|
|
72
|
+
return this;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Create a new API chart
|
|
76
|
+
* @param name name of the chart
|
|
77
|
+
* @param definition definition of the chart
|
|
78
|
+
* @example
|
|
79
|
+
* .addChart('numCustomers', {
|
|
80
|
+
* type: 'Value',
|
|
81
|
+
* render: (context, resultBuilder) => {
|
|
82
|
+
* return resultBuilder.value(123);
|
|
83
|
+
* }
|
|
84
|
+
* })
|
|
85
|
+
*/
|
|
86
|
+
addChart(name, definition) {
|
|
87
|
+
this.customizer.addChart(name, definition);
|
|
88
|
+
return this;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Allow to interact with a decorated collection
|
|
92
|
+
* @param name the name of the collection to manipulate
|
|
93
|
+
* @param handle a function that provide a
|
|
94
|
+
* collection builder on the given collection name
|
|
95
|
+
* @example
|
|
96
|
+
* .customizeCollection('books', books => books.renameField('xx', 'yy'))
|
|
97
|
+
*/
|
|
98
|
+
customizeCollection(name, handle) {
|
|
99
|
+
this.customizer.customizeCollection(name, handle);
|
|
100
|
+
return this;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Create an http handler which can respond to all queries which are expected from an agent.
|
|
104
|
+
*/
|
|
105
|
+
async getRouter(dataSource) {
|
|
106
|
+
// Bootstrap app
|
|
107
|
+
const services = (0, services_1.default)(this.options);
|
|
108
|
+
const routes = (0, routes_1.default)(dataSource, this.options, services);
|
|
109
|
+
await Promise.all(routes.map(route => route.bootstrap()));
|
|
110
|
+
// Build router
|
|
111
|
+
const router = new router_1.default();
|
|
112
|
+
router.all('(.*)', (0, cors_1.default)({ credentials: true, maxAge: 24 * 3600, privateNetworkAccess: true }));
|
|
113
|
+
router.use((0, koa_bodyparser_1.default)({ jsonLimit: '50mb' }));
|
|
114
|
+
routes.forEach(route => route.setupRoutes(router));
|
|
115
|
+
return router;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Send the apimap to forest admin server
|
|
119
|
+
*/
|
|
120
|
+
async sendSchema(dataSource) {
|
|
121
|
+
const schema = await emitter_1.default.getSerializedSchema(this.options, dataSource);
|
|
122
|
+
const schemaIsKnown = await forest_http_api_1.default.hasSchema(this.options, schema.meta.schemaFileHash);
|
|
123
|
+
if (!schemaIsKnown) {
|
|
124
|
+
this.options.logger('Info', 'Schema was updated, sending new version');
|
|
125
|
+
await forest_http_api_1.default.uploadSchema(this.options, schema);
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
this.options.logger('Info', 'Schema was not updated since last run');
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
exports.default = Agent;
|
|
133
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWdlbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvYWdlbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSx1REFBdUQ7QUFDdkQsOEVBTzRDO0FBRTVDLHlEQUFpQztBQUNqQyxvRUFBd0M7QUFDeEMscURBQTZCO0FBRzdCLDhFQUFvRDtBQUNwRCw0RUFBbUQ7QUFDbkQsa0ZBQXlEO0FBQ3pELDRFQUEwRDtBQUMxRCxzREFBa0M7QUFDbEMsMERBQXNDO0FBRXRDOzs7Ozs7Ozs7R0FTRztBQUNILE1BQXFCLEtBQW1DLFNBQVEsMkJBQWdCO0lBSTlFOzs7Ozs7Ozs7Ozs7Ozs7T0FlRztJQUNILFlBQVksT0FBcUI7UUFDL0IsTUFBTSxVQUFVLEdBQUcsMkJBQWdCLENBQUMsUUFBUSxDQUFDLDJCQUFnQixDQUFDLFlBQVksQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO1FBQ3JGLEtBQUssQ0FBQyxVQUFVLENBQUMsTUFBTSxFQUFFLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUU1QyxJQUFJLENBQUMsT0FBTyxHQUFHLFVBQVUsQ0FBQztRQUMxQixJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksNENBQW9CLEVBQUssQ0FBQztJQUNsRCxDQUFDO0lBRUQ7O09BRUc7SUFDTSxLQUFLLENBQUMsS0FBSztRQUNsQixNQUFNLEVBQUUsTUFBTSxFQUFFLFdBQVcsRUFBRSxlQUFlLEVBQUUsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDO1FBRTlELE1BQU0sVUFBVSxHQUFHLE1BQU0sSUFBSSxDQUFDLFVBQVUsQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDL0QsTUFBTSxDQUFDLE1BQU0sQ0FBQyxHQUFHLE1BQU0sT0FBTyxDQUFDLEdBQUcsQ0FBQztZQUNqQyxJQUFJLENBQUMsU0FBUyxDQUFDLFVBQVUsQ0FBQztZQUMxQixJQUFJLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQztZQUMzQixDQUFDLElBQUksQ0FBQyxP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
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/// <reference types="koa__router" />
|
|
2
|
+
import { Logger } from '@forestadmin/datasource-toolkit';
|
|
3
|
+
import Router from '@koa/router';
|
|
4
|
+
export default class FrameworkMounter {
|
|
5
|
+
private onStart;
|
|
6
|
+
private onStop;
|
|
7
|
+
private prefix;
|
|
8
|
+
private logger;
|
|
9
|
+
/** Compute the prefix that the main router should be mounted at in the client's application */
|
|
10
|
+
private get completeMountPrefix();
|
|
11
|
+
constructor(prefix: string, logger: Logger);
|
|
12
|
+
start(router: Router): Promise<void>;
|
|
13
|
+
stop(): Promise<void>;
|
|
14
|
+
/**
|
|
15
|
+
* Expose the agent on a given port and host
|
|
16
|
+
* @param port port that should be used.
|
|
17
|
+
* @param host host that should be used.
|
|
18
|
+
*/
|
|
19
|
+
mountOnStandaloneServer(port?: number, host?: string): this;
|
|
20
|
+
/**
|
|
21
|
+
* Mount the agent on an express app.
|
|
22
|
+
* @param express instance of the express app or router.
|
|
23
|
+
*/
|
|
24
|
+
mountOnExpress(express: any): this;
|
|
25
|
+
/**
|
|
26
|
+
* Mount the agent on a fastify app
|
|
27
|
+
* @param fastify instance of the fastify app, or of a fastify context
|
|
28
|
+
*/
|
|
29
|
+
mountOnFastify(fastify: any): this;
|
|
30
|
+
/**
|
|
31
|
+
* Mount the agent on a koa app
|
|
32
|
+
* @param koa instance of a koa app or a koa Router.
|
|
33
|
+
*/
|
|
34
|
+
mountOnKoa(koa: any): this;
|
|
35
|
+
/**
|
|
36
|
+
* Mount the agent on a NestJS app
|
|
37
|
+
* @param nestJs instance of a NestJS application
|
|
38
|
+
*/
|
|
39
|
+
mountOnNestJs(nestJs: any): this;
|
|
40
|
+
private useCallbackOnFastify;
|
|
41
|
+
private getConnectCallback;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=framework-mounter.d.ts.map
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
|
+
};
|
|
28
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
+
const http_1 = require("http");
|
|
30
|
+
const koa_1 = __importDefault(require("koa"));
|
|
31
|
+
const router_1 = __importDefault(require("@koa/router"));
|
|
32
|
+
const path_1 = __importDefault(require("path"));
|
|
33
|
+
class FrameworkMounter {
|
|
34
|
+
constructor(prefix, logger) {
|
|
35
|
+
this.onStart = [];
|
|
36
|
+
this.onStop = [];
|
|
37
|
+
this.prefix = prefix;
|
|
38
|
+
this.logger = logger;
|
|
39
|
+
}
|
|
40
|
+
/** Compute the prefix that the main router should be mounted at in the client's application */
|
|
41
|
+
get completeMountPrefix() {
|
|
42
|
+
return path_1.default.posix.join('/', this.prefix, 'forest');
|
|
43
|
+
}
|
|
44
|
+
async start(router) {
|
|
45
|
+
for (const task of this.onStart)
|
|
46
|
+
await task(router); // eslint-disable-line no-await-in-loop
|
|
47
|
+
}
|
|
48
|
+
async stop() {
|
|
49
|
+
for (const task of this.onStop)
|
|
50
|
+
await task(); // eslint-disable-line no-await-in-loop
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Expose the agent on a given port and host
|
|
54
|
+
* @param port port that should be used.
|
|
55
|
+
* @param host host that should be used.
|
|
56
|
+
*/
|
|
57
|
+
mountOnStandaloneServer(port = 3351, host = 'localhost') {
|
|
58
|
+
const server = (0, http_1.createServer)(this.getConnectCallback(true));
|
|
59
|
+
server.listen(port, host);
|
|
60
|
+
this.logger('Info', `Successfully mounted on Standalone server (http://${host}:${port})`);
|
|
61
|
+
this.onStop.push(async () => {
|
|
62
|
+
server.close();
|
|
63
|
+
});
|
|
64
|
+
return this;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Mount the agent on an express app.
|
|
68
|
+
* @param express instance of the express app or router.
|
|
69
|
+
*/
|
|
70
|
+
mountOnExpress(express) {
|
|
71
|
+
express.use(this.completeMountPrefix, this.getConnectCallback(false));
|
|
72
|
+
this.logger('Info', `Successfully mounted on Express.js`);
|
|
73
|
+
return this;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Mount the agent on a fastify app
|
|
77
|
+
* @param fastify instance of the fastify app, or of a fastify context
|
|
78
|
+
*/
|
|
79
|
+
mountOnFastify(fastify) {
|
|
80
|
+
const callback = this.getConnectCallback(false);
|
|
81
|
+
this.useCallbackOnFastify(fastify, callback);
|
|
82
|
+
this.logger('Info', `Successfully mounted on Fastify`);
|
|
83
|
+
return this;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Mount the agent on a koa app
|
|
87
|
+
* @param koa instance of a koa app or a koa Router.
|
|
88
|
+
*/
|
|
89
|
+
mountOnKoa(koa) {
|
|
90
|
+
const parentRouter = new router_1.default({ prefix: this.completeMountPrefix });
|
|
91
|
+
koa.use(parentRouter.routes());
|
|
92
|
+
this.logger('Info', `Successfully mounted on Koa`);
|
|
93
|
+
this.onStart.push(async (router) => {
|
|
94
|
+
parentRouter.use(router.routes());
|
|
95
|
+
});
|
|
96
|
+
return this;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Mount the agent on a NestJS app
|
|
100
|
+
* @param nestJs instance of a NestJS application
|
|
101
|
+
*/
|
|
102
|
+
mountOnNestJs(nestJs) {
|
|
103
|
+
const adapter = nestJs.getHttpAdapter();
|
|
104
|
+
const callback = this.getConnectCallback(false);
|
|
105
|
+
if (adapter.constructor.name === 'ExpressAdapter') {
|
|
106
|
+
nestJs.use(this.completeMountPrefix, callback);
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
this.useCallbackOnFastify(nestJs, callback);
|
|
110
|
+
}
|
|
111
|
+
this.logger('Info', `Successfully mounted on NestJS`);
|
|
112
|
+
return this;
|
|
113
|
+
}
|
|
114
|
+
useCallbackOnFastify(fastify, callback) {
|
|
115
|
+
try {
|
|
116
|
+
// 'fastify 2' or 'middie' or 'fastify-express'
|
|
117
|
+
fastify.use(this.completeMountPrefix, callback);
|
|
118
|
+
}
|
|
119
|
+
catch (e) {
|
|
120
|
+
// 'fastify 3'
|
|
121
|
+
if (e.code === 'FST_ERR_MISSING_MIDDLEWARE') {
|
|
122
|
+
fastify
|
|
123
|
+
.register(Promise.resolve().then(() => __importStar(require('@fastify/express'))))
|
|
124
|
+
.then(() => {
|
|
125
|
+
fastify.use(this.completeMountPrefix, callback);
|
|
126
|
+
})
|
|
127
|
+
.catch(err => {
|
|
128
|
+
this.logger('Error', err.message);
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
throw e;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
getConnectCallback(nested) {
|
|
137
|
+
let handler = null;
|
|
138
|
+
this.onStart.push(async (driverRouter) => {
|
|
139
|
+
let router = driverRouter;
|
|
140
|
+
if (nested) {
|
|
141
|
+
router = new router_1.default({ prefix: this.completeMountPrefix }).use(router.routes());
|
|
142
|
+
}
|
|
143
|
+
handler = new koa_1.default().use(router.routes()).callback();
|
|
144
|
+
});
|
|
145
|
+
return (req, res) => {
|
|
146
|
+
if (handler) {
|
|
147
|
+
handler(req, res);
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
151
|
+
res.end(JSON.stringify({ error: 'Agent is not started' }));
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
exports.default = FrameworkMounter;
|
|
157
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZnJhbWV3b3JrLW1vdW50ZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvZnJhbWV3b3JrLW1vdW50ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUVBLCtCQUFvQztBQUNwQyw4Q0FBc0I7QUFDdEIseURBQWlDO0FBQ2pDLGdEQUF3QjtBQUl4QixNQUFxQixnQkFBZ0I7SUFXbkMsWUFBWSxNQUFjLEVBQUUsTUFBYztRQVZsQyxZQUFPLEdBQTBDLEVBQUUsQ0FBQztRQUNwRCxXQUFNLEdBQTRCLEVBQUUsQ0FBQztRQVUzQyxJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztRQUNyQixJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztJQUN2QixDQUFDO0lBUkQsK0ZBQStGO0lBQy9GLElBQVksbUJBQW1CO1FBQzdCLE9BQU8sY0FBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxNQUFNLEVBQUUsUUFBUSxDQUFDLENBQUM7SUFDckQsQ0FBQztJQU9ELEtBQUssQ0FBQyxLQUFLLENBQUMsTUFBYztRQUN4QixLQUFLLE1BQU0sSUFBSSxJQUFJLElBQUksQ0FBQyxPQUFPO1lBQUUsTUFBTSxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyx1Q0FBdUM7SUFDOUYsQ0FBQztJQUVELEtBQUssQ0FBQyxJQUFJO1FBQ1IsS0FBSyxNQUFNLElBQUksSUFBSSxJQUFJLENBQUMsTUFBTTtZQUFFLE1BQU0sSUFBSSxFQUFFLENBQUMsQ0FBQyx1Q0FBdUM7SUFDdkYsQ0FBQztJQUVEOzs7O09BSUc7SUFDSCx1QkFBdUIsQ0FBQyxJQUFJLEdBQUcsSUFBSSxFQUFFLElBQUksR0FBRyxXQUFXO1FBQ3JELE1BQU0sTUFBTSxHQUFHLElBQUEsbUJBQVksRUFBQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztRQUMzRCxN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
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { CollectionCustomizer, TSchema } from '@forestadmin/datasource-customizer';
|
|
2
|
+
import { AgentOptions } from './types';
|
|
3
|
+
import Agent from './agent';
|
|
4
|
+
export declare function createAgent<S extends TSchema = TSchema>(options: AgentOptions): Agent<S>;
|
|
5
|
+
export { Agent };
|
|
6
|
+
export { CollectionCustomizer };
|
|
7
|
+
export { AgentOptions } from './types';
|
|
4
8
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
CHANGED
|
@@ -1,26 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
-
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
-
};
|
|
16
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
17
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
18
4
|
};
|
|
19
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
-
exports.
|
|
21
|
-
|
|
22
|
-
Object.defineProperty(exports, "
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
6
|
+
exports.CollectionCustomizer = exports.Agent = exports.createAgent = void 0;
|
|
7
|
+
const datasource_customizer_1 = require("@forestadmin/datasource-customizer");
|
|
8
|
+
Object.defineProperty(exports, "CollectionCustomizer", { enumerable: true, get: function () { return datasource_customizer_1.CollectionCustomizer; } });
|
|
9
|
+
const agent_1 = __importDefault(require("./agent"));
|
|
10
|
+
exports.Agent = agent_1.default;
|
|
11
|
+
function createAgent(options) {
|
|
12
|
+
return new agent_1.default(options);
|
|
13
|
+
}
|
|
14
|
+
exports.createAgent = createAgent;
|
|
15
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUEsOEVBQW1GO0FBVTFFLHFHQVZBLDRDQUFvQixPQVVBO0FBUDdCLG9EQUE0QjtBQU1uQixnQkFORixlQUFLLENBTUU7QUFKZCxTQUFnQixXQUFXLENBQThCLE9BQXFCO0lBQzVFLE9BQU8sSUFBSSxlQUFLLENBQUksT0FBTyxDQUFDLENBQUM7QUFDL0IsQ0FBQztBQUZELGtDQUVDIn0=
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/// <reference types="koa__router" />
|
|
2
|
+
import { DataSource } from '@forestadmin/datasource-toolkit';
|
|
3
|
+
import Router from '@koa/router';
|
|
4
|
+
import { AgentOptionsWithDefaults, RouteType } from '../../types';
|
|
5
|
+
import { ForestAdminHttpDriverServices } from '../../services';
|
|
6
|
+
import BaseRoute from '../base-route';
|
|
7
|
+
export default class ApiChartRoute extends BaseRoute {
|
|
8
|
+
readonly type = RouteType.PrivateRoute;
|
|
9
|
+
private dataSource;
|
|
10
|
+
private chartName;
|
|
11
|
+
constructor(services: ForestAdminHttpDriverServices, options: AgentOptionsWithDefaults, dataSource: DataSource, chartName: string);
|
|
12
|
+
setupRoutes(router: Router): void;
|
|
13
|
+
private handleApiChart;
|
|
14
|
+
private handleSmartChart;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=api-chart.d.ts.map
|
|
@@ -0,0 +1,47 @@
|
|
|
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 uuid_1 = require("uuid");
|
|
7
|
+
const path_1 = __importDefault(require("path"));
|
|
8
|
+
const types_1 = require("../../types");
|
|
9
|
+
const base_route_1 = __importDefault(require("../base-route"));
|
|
10
|
+
const query_string_1 = __importDefault(require("../../utils/query-string"));
|
|
11
|
+
class ApiChartRoute extends base_route_1.default {
|
|
12
|
+
constructor(services, options, dataSource, chartName) {
|
|
13
|
+
super(services, options);
|
|
14
|
+
this.type = types_1.RouteType.PrivateRoute;
|
|
15
|
+
this.dataSource = dataSource;
|
|
16
|
+
this.chartName = chartName;
|
|
17
|
+
}
|
|
18
|
+
setupRoutes(router) {
|
|
19
|
+
// Mount both GET and POST, respectively for smart and api charts.
|
|
20
|
+
const suffix = `/_charts/${this.chartName}`;
|
|
21
|
+
router.get(suffix, this.handleSmartChart.bind(this));
|
|
22
|
+
router.post(suffix, this.handleApiChart.bind(this));
|
|
23
|
+
// Log the route to help the customer fill the url in the frontend
|
|
24
|
+
if (!this.options.isProduction) {
|
|
25
|
+
const url = path_1.default.posix.join('/', this.options.prefix, 'forest', suffix);
|
|
26
|
+
this.options.logger('Info', `Chart '${this.chartName}' was mounted at '${url}'`);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
async handleApiChart(context) {
|
|
30
|
+
// Api Charts need the data to be formatted in JSON-API
|
|
31
|
+
context.response.body = {
|
|
32
|
+
data: {
|
|
33
|
+
id: (0, uuid_1.v1)(),
|
|
34
|
+
type: 'stats',
|
|
35
|
+
attributes: {
|
|
36
|
+
value: await this.dataSource.renderChart(query_string_1.default.parseCaller(context), this.chartName),
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
async handleSmartChart(context) {
|
|
42
|
+
// Smart charts need the data to be unformatted
|
|
43
|
+
context.response.body = await this.dataSource.renderChart(query_string_1.default.parseCaller(context), this.chartName);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
exports.default = ApiChartRoute;
|
|
47
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBpLWNoYXJ0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL3JvdXRlcy9hY2Nlc3MvYXBpLWNoYXJ0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBRUEsK0JBQW9DO0FBRXBDLGdEQUF3QjtBQUV4Qix1Q0FBa0U7QUFFbEUsK0RBQXNDO0FBQ3RDLDRFQUF5RDtBQUV6RCxNQUFxQixhQUFjLFNBQVEsb0JBQVM7SUFNbEQsWUFDRSxRQUF1QyxFQUN2QyxPQUFpQyxFQUNqQyxVQUFzQixFQUN0QixTQUFpQjtRQUVqQixLQUFLLENBQUMsUUFBUSxFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBWGxCLFNBQUksR0FBRyxpQkFBUyxDQUFDLFlBQVksQ0FBQztRQWFyQyxJQUFJLENBQUMsVUFBVSxHQUFHLFVBQVUsQ0FBQztRQUM3QixJQUFJLENBQUMsU0FBUyxHQUFHLFNBQVMsQ0FBQztJQUM3QixDQUFDO0lBRUQsV0FBVyxDQUFDLE1BQWM7UUFDeEIsa0VBQWtFO1FBQ2xFLE1BQU0sTUFBTSxHQUFHLFlBQVksSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO1FBQzVDLE1BQU0sQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztRQUNyRCxNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO1FBRXBELGtFQUFrRTtRQUNsRSxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLEVBQUU7WUFDOUIsTUFBTSxHQUFHLEdBQUcsY0FBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxFQUFFLFFBQVEsRUFBRSxNQUFNLENBQUMsQ0FBQztZQUN4RSxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxNQUFNLEVBQUUsVUFBVSxJQUFJLENBQUMsU0FBUyxxQkFBcUIsR0FBRyxHQUFHLENBQUMsQ0FBQztTQUNsRjtJQUNILENBQUM7SUFFTyxLQUFLLENBQUMsY0FBYyxDQUFDLE9BQWdCO1FBQzNDLHVEQUF1RDtRQUN2RCxPQUFPLENBQUMsUUFBUSxDQUFDLElBQUksR0FBRztZQUN0QixJQUFJLEVBQUU7Z0JBQ0osRUFBRSxFQUFFLElBQUEsU0FBTSxHQUFFO2dCQUNaLElBQUksRUFBRSxPQUFPO2dCQUNiLFVBQVUsRUFBRTtvQkFDVixLQUFLLEVBQUUsTUFBTSxJQUFJLENBQUMsVUFBVSxDQUFDLFdBQVcsQ0FDdEMsc0JBQWlCLENBQUMsV0FBVyxDQUFDLE9BQU8sQ0FBQyxFQUN0QyxJQUFJLENBQUMsU0FBUyxDQUNmO2lCQUNGO2FBQ0Y7U0FDRixDQUFDO0lBQ0osQ0FBQztJQUVPLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFnQjtRQUM3QywrQ0FBK0M7UUFDL0MsT0FBTyxDQUFDLFFBQVEsQ0FBQyxJQUFJLEdBQUcsTUFBTSxJQUFJLENBQUMsVUFBVSxDQUFDLFdBQVcsQ0FDdkQsc0JBQWlCLENBQUMsV0FBVyxDQUFDLE9BQU8sQ0FBQyxFQUN0QyxJQUFJLENBQUMsU0FBUyxDQUNmLENBQUM7SUFDSixDQUFDO0NBQ0Y7QUF0REQsZ0NBc0RDIn0=
|
|
@@ -6,6 +6,7 @@ export default class Chart extends CollectionRoute {
|
|
|
6
6
|
private static readonly formats;
|
|
7
7
|
setupRoutes(router: Router): void;
|
|
8
8
|
handleChart(context: Context): Promise<void>;
|
|
9
|
+
private makeChart;
|
|
9
10
|
private makeValueChart;
|
|
10
11
|
private makeObjectiveChart;
|
|
11
12
|
private makePieChart;
|