@forestadmin/agent 1.0.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +674 -0
- package/README.md +0 -0
- 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 +8 -0
- package/dist/index.js +15 -0
- package/dist/routes/access/api-chart.d.ts +16 -0
- package/dist/routes/access/api-chart.js +47 -0
- package/dist/routes/access/chart.d.ts +18 -0
- package/dist/routes/access/chart.js +162 -0
- package/dist/routes/access/count-related.d.ts +9 -0
- package/dist/routes/access/count-related.js +31 -0
- package/dist/routes/access/count.d.ts +9 -0
- package/dist/routes/access/count.js +31 -0
- package/dist/routes/access/csv-related.d.ts +9 -0
- package/dist/routes/access/csv-related.js +33 -0
- package/dist/routes/access/csv.d.ts +9 -0
- package/dist/routes/access/csv.js +31 -0
- package/dist/routes/access/get.d.ts +9 -0
- package/dist/routes/access/get.js +29 -0
- package/dist/routes/access/list-related.d.ts +9 -0
- package/dist/routes/access/list-related.js +25 -0
- package/dist/routes/access/list.d.ts +9 -0
- package/dist/routes/access/list.js +22 -0
- package/dist/routes/base-route.d.ts +13 -0
- package/dist/routes/base-route.js +13 -0
- package/dist/routes/collection-route.d.ts +12 -0
- package/dist/routes/collection-route.js +20 -0
- package/dist/routes/index.d.ts +30 -0
- package/dist/routes/index.js +108 -0
- package/dist/routes/modification/action.d.ts +16 -0
- 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/routes/modification/create.d.ts +14 -0
- package/dist/routes/modification/create.js +83 -0
- package/dist/routes/modification/delete.d.ts +11 -0
- package/dist/routes/modification/delete.js +41 -0
- package/dist/routes/modification/dissociate-delete-related.d.ts +20 -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/routes/modification/update-relation.d.ts +11 -0
- package/dist/routes/modification/update-relation.js +59 -0
- package/dist/routes/modification/update.d.ts +9 -0
- package/dist/routes/modification/update.js +31 -0
- package/dist/routes/relation-route.d.ts +10 -0
- package/dist/routes/relation-route.js +18 -0
- package/dist/routes/security/authentication.d.ts +15 -0
- package/dist/routes/security/authentication.js +74 -0
- package/dist/routes/security/ip-whitelist.d.ts +14 -0
- package/dist/routes/security/ip-whitelist.js +35 -0
- package/dist/routes/security/scope-invalidation.d.ts +11 -0
- package/dist/routes/security/scope-invalidation.js +28 -0
- package/dist/routes/system/error-handling.d.ts +13 -0
- package/dist/routes/system/error-handling.js +75 -0
- package/dist/routes/system/healthcheck.d.ts +11 -0
- package/dist/routes/system/healthcheck.js +22 -0
- package/dist/routes/system/logger.d.ts +10 -0
- package/dist/routes/system/logger.js +35 -0
- package/dist/services/authorization/authorization.d.ts +15 -0
- package/dist/services/authorization/authorization.js +45 -0
- package/dist/services/authorization/index.d.ts +5 -0
- package/dist/services/authorization/index.js +16 -0
- package/dist/services/authorization/internal/action-permission.d.ts +16 -0
- package/dist/services/authorization/internal/action-permission.js +68 -0
- package/dist/services/authorization/internal/generate-action-identifier.d.ts +4 -0
- package/dist/services/authorization/internal/generate-action-identifier.js +12 -0
- package/dist/services/authorization/internal/generate-actions-from-permissions.d.ts +8 -0
- package/dist/services/authorization/internal/generate-actions-from-permissions.js +87 -0
- package/dist/services/authorization/internal/types.d.ts +61 -0
- package/dist/services/authorization/internal/types.js +26 -0
- package/dist/services/index.d.ts +12 -0
- package/dist/services/index.js +16 -0
- package/dist/services/permissions.d.ts +19 -0
- package/dist/services/permissions.js +85 -0
- package/dist/services/serializer.d.ts +12 -0
- package/dist/services/serializer.js +120 -0
- package/dist/types.d.ts +41 -0
- package/dist/types.js +23 -0
- package/dist/utils/body-parser.d.ts +7 -0
- package/dist/utils/body-parser.js +18 -0
- package/dist/utils/condition-tree-parser.d.ts +11 -0
- package/dist/utils/condition-tree-parser.js +53 -0
- package/dist/utils/context-filter-factory.d.ts +7 -0
- package/dist/utils/context-filter-factory.js +28 -0
- package/dist/utils/csv-generator.d.ts +12 -0
- package/dist/utils/csv-generator.js +39 -0
- package/dist/utils/csv-route-context.d.ts +5 -0
- package/dist/utils/csv-route-context.js +14 -0
- package/dist/utils/forest-http-api.d.ts +68 -0
- package/dist/utils/forest-http-api.js +202 -0
- package/dist/utils/forest-schema/action-values.d.ts +34 -0
- package/dist/utils/forest-schema/action-values.js +144 -0
- package/dist/utils/forest-schema/emitter.d.ts +20 -0
- package/dist/utils/forest-schema/emitter.js +70 -0
- package/dist/utils/forest-schema/filterable.d.ts +16 -0
- package/dist/utils/forest-schema/filterable.js +68 -0
- package/dist/utils/forest-schema/generator-actions.d.ts +14 -0
- package/dist/utils/forest-schema/generator-actions.js +99 -0
- package/dist/utils/forest-schema/generator-collection.d.ts +7 -0
- package/dist/utils/forest-schema/generator-collection.js +36 -0
- package/dist/utils/forest-schema/generator-fields.d.ts +14 -0
- package/dist/utils/forest-schema/generator-fields.js +160 -0
- package/dist/utils/forest-schema/generator-segments.d.ts +6 -0
- package/dist/utils/forest-schema/generator-segments.js +9 -0
- package/dist/utils/forest-schema/types.d.ts +85 -0
- package/dist/utils/forest-schema/types.js +16 -0
- package/dist/utils/forest-schema/validation.d.ts +10 -0
- package/dist/utils/forest-schema/validation.js +28 -0
- package/dist/utils/id.d.ts +8 -0
- package/dist/utils/id.js +43 -0
- package/dist/utils/options-validator.d.ts +12 -0
- package/dist/utils/options-validator.js +92 -0
- package/dist/utils/query-string.d.ts +14 -0
- package/dist/utils/query-string.js +134 -0
- package/package.json +66 -0
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const datasource_toolkit_1 = require("@forestadmin/datasource-toolkit");
|
|
7
|
+
const json_api_serializer_1 = __importDefault(require("json-api-serializer"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
const id_1 = __importDefault(require("../utils/id"));
|
|
10
|
+
class Serializer {
|
|
11
|
+
constructor() {
|
|
12
|
+
// No need to keep references to serializers for outdated schemas => weakmap.
|
|
13
|
+
this.serializers = new WeakMap();
|
|
14
|
+
}
|
|
15
|
+
serialize(collection, data) {
|
|
16
|
+
const result = this.getSerializer(collection).serialize(collection.name, data);
|
|
17
|
+
this.stripUndefinedsInPlace(result);
|
|
18
|
+
return result;
|
|
19
|
+
}
|
|
20
|
+
deserialize(collection, body) {
|
|
21
|
+
return this.getSerializer(collection).deserialize(collection.name, body);
|
|
22
|
+
}
|
|
23
|
+
serializeWithSearchMetadata(collection, data, searchValue) {
|
|
24
|
+
const results = this.serialize(collection, data);
|
|
25
|
+
if (searchValue && searchValue.trim().length > 0) {
|
|
26
|
+
const resultsData = results.data;
|
|
27
|
+
const decorators = resultsData.reduce((decorator, record) => {
|
|
28
|
+
const search = Object.keys(record.attributes).filter(attribute => {
|
|
29
|
+
const value = record.attributes[attribute];
|
|
30
|
+
return value && value.toString().toLowerCase().includes(searchValue.toLowerCase());
|
|
31
|
+
});
|
|
32
|
+
if (search.length === 0) {
|
|
33
|
+
return decorator;
|
|
34
|
+
}
|
|
35
|
+
return { ...decorator, [Object.keys(decorator).length]: { id: record.id, search } };
|
|
36
|
+
}, {});
|
|
37
|
+
if (Object.values(decorators).length === 0) {
|
|
38
|
+
return results;
|
|
39
|
+
}
|
|
40
|
+
results.meta = { decorators };
|
|
41
|
+
}
|
|
42
|
+
return results;
|
|
43
|
+
}
|
|
44
|
+
getSerializer(collection) {
|
|
45
|
+
if (this.serializers.has(collection.schema)) {
|
|
46
|
+
return this.serializers.get(collection.schema);
|
|
47
|
+
}
|
|
48
|
+
const serializer = new json_api_serializer_1.default();
|
|
49
|
+
for (const sibling of collection.dataSource.collections) {
|
|
50
|
+
this.registerCollection(sibling, serializer);
|
|
51
|
+
this.serializers.set(sibling.schema, serializer);
|
|
52
|
+
}
|
|
53
|
+
return serializer;
|
|
54
|
+
}
|
|
55
|
+
registerCollection(collection, serializer) {
|
|
56
|
+
serializer.register(collection.name, {
|
|
57
|
+
id: 'forestId',
|
|
58
|
+
relationships: this.buildRelationshipsConfiguration(collection),
|
|
59
|
+
beforeSerialize: (data) => {
|
|
60
|
+
const copy = { ...data };
|
|
61
|
+
copy.forestId = id_1.default.packId(collection.schema, data);
|
|
62
|
+
return copy;
|
|
63
|
+
},
|
|
64
|
+
afterDeserialize: (data) => {
|
|
65
|
+
const copy = { ...data };
|
|
66
|
+
if (data.forestId) {
|
|
67
|
+
const parts = id_1.default.unpackId(collection.schema, data.forestId);
|
|
68
|
+
const primaryKeys = datasource_toolkit_1.SchemaUtils.getPrimaryKeys(collection.schema);
|
|
69
|
+
primaryKeys.forEach((field, index) => {
|
|
70
|
+
copy[field] = parts[index];
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
delete copy.forestId;
|
|
74
|
+
return copy;
|
|
75
|
+
},
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
buildRelationshipsConfiguration(collection) {
|
|
79
|
+
const relationships = {};
|
|
80
|
+
const urlPrefix = path_1.default.posix.join('/forest', collection.name);
|
|
81
|
+
for (const [name, field] of Object.entries(collection.schema.fields)) {
|
|
82
|
+
if (field.type === 'ManyToOne' || field.type === 'OneToOne') {
|
|
83
|
+
relationships[name] = {
|
|
84
|
+
type: field.foreignCollection,
|
|
85
|
+
deserialize: (data) => {
|
|
86
|
+
const foreignCollection = collection.dataSource.getCollection(field.foreignCollection);
|
|
87
|
+
return id_1.default.unpackId(foreignCollection.schema, data.id);
|
|
88
|
+
},
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
if (field.type === 'ManyToMany' || field.type === 'OneToMany') {
|
|
92
|
+
relationships[name] = {
|
|
93
|
+
type: field.foreignCollection,
|
|
94
|
+
links: (data) => ({
|
|
95
|
+
related: {
|
|
96
|
+
href: `${urlPrefix}/${data.forestId}/relationships/${name}`,
|
|
97
|
+
},
|
|
98
|
+
}),
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return relationships;
|
|
103
|
+
}
|
|
104
|
+
stripUndefinedsInPlace(record) {
|
|
105
|
+
if (record === null || typeof record !== 'object') {
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
const indexable = record;
|
|
109
|
+
for (const key of Object.keys(indexable)) {
|
|
110
|
+
if (indexable[key] === undefined) {
|
|
111
|
+
delete indexable[key];
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
this.stripUndefinedsInPlace(indexable[key]);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
exports.default = Serializer;
|
|
120
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VyaWFsaXplci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zZXJ2aWNlcy9zZXJpYWxpemVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsd0VBS3lDO0FBQ3pDLDhFQUFvRDtBQUNwRCxnREFBd0I7QUFFeEIscURBQWtDO0FBSWxDLE1BQXFCLFVBQVU7SUFBL0I7UUFDRSw2RUFBNkU7UUFDNUQsZ0JBQVcsR0FBaUQsSUFBSSxPQUFPLEVBQUUsQ0FBQztJQXlJN0YsQ0FBQztJQXZJQyxTQUFTLENBQUMsVUFBc0IsRUFBRSxJQUErQjtRQUMvRCxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLFVBQVUsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxVQUFVLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQy9FLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUVwQyxPQUFPLE1BQU0sQ0FBQztJQUNoQixDQUFDO0lBRUQsV0FBVyxDQUFDLFVBQXNCLEVBQUUsSUFBYTtRQUMvQyxPQUFPLElBQUksQ0FBQyxhQUFhLENBQUMsVUFBVSxDQUFDLENBQUMsV0FBVyxDQUFDLFVBQVUsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFDM0UsQ0FBQztJQUVELDJCQUEyQixDQUN6QixVQUFzQixFQUN0QixJQUFrQixFQUNsQixXQUFtQjtRQUVuQixNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLFVBQVUsRUFBRSxJQUFJLENBQWUsQ0FBQztRQUUvRCxJQUFJLFdBQVcsSUFBSSxXQUFXLENBQUMsSUFBSSxFQUFFLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRTtZQUNoRCxNQUFNLFdBQVcsR0FBRyxPQUFPLENBQUMsSUFBb0IsQ0FBQztZQUNqRCxNQUFNLFVBQVUsR0FBRyxXQUFXLENBQUMsTUFBTSxDQUFDLENBQUMsU0FBUyxFQUFFLE1BQWtCLEVBQUUsRUFBRTtn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
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { CompositeId, Logger, LoggerLevel } from '@forestadmin/datasource-toolkit';
|
|
3
|
+
import { IncomingMessage, ServerResponse } from 'http';
|
|
4
|
+
/** Options to configure behavior of an agent's forestadmin driver */
|
|
5
|
+
export declare type AgentOptions = {
|
|
6
|
+
authSecret: string;
|
|
7
|
+
envSecret: string;
|
|
8
|
+
customizeErrorMessage?: ((error: Error) => string | null) | null;
|
|
9
|
+
forestServerUrl?: string;
|
|
10
|
+
logger?: Logger;
|
|
11
|
+
loggerLevel?: LoggerLevel;
|
|
12
|
+
prefix?: string;
|
|
13
|
+
isProduction: boolean;
|
|
14
|
+
schemaPath?: string;
|
|
15
|
+
typingsPath?: string | null;
|
|
16
|
+
typingsMaxDepth?: number;
|
|
17
|
+
permissionsCacheDurationInSeconds?: number;
|
|
18
|
+
};
|
|
19
|
+
export declare type AgentOptionsWithDefaults = Readonly<Required<AgentOptions>>;
|
|
20
|
+
export declare type HttpCallback = (req: IncomingMessage, res: ServerResponse) => void;
|
|
21
|
+
export declare enum HttpCode {
|
|
22
|
+
BadRequest = 400,
|
|
23
|
+
Forbidden = 403,
|
|
24
|
+
InternalServerError = 500,
|
|
25
|
+
NoContent = 204,
|
|
26
|
+
NotFound = 404,
|
|
27
|
+
Ok = 200,
|
|
28
|
+
Unprocessable = 422
|
|
29
|
+
}
|
|
30
|
+
export declare enum RouteType {
|
|
31
|
+
LoggerHandler = 0,
|
|
32
|
+
ErrorHandler = 1,
|
|
33
|
+
PublicRoute = 2,
|
|
34
|
+
Authentication = 3,
|
|
35
|
+
PrivateRoute = 4
|
|
36
|
+
}
|
|
37
|
+
export declare type SelectionIds = {
|
|
38
|
+
areExcluded: boolean;
|
|
39
|
+
ids: CompositeId[];
|
|
40
|
+
};
|
|
41
|
+
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RouteType = exports.HttpCode = void 0;
|
|
4
|
+
var HttpCode;
|
|
5
|
+
(function (HttpCode) {
|
|
6
|
+
HttpCode[HttpCode["BadRequest"] = 400] = "BadRequest";
|
|
7
|
+
HttpCode[HttpCode["Forbidden"] = 403] = "Forbidden";
|
|
8
|
+
HttpCode[HttpCode["InternalServerError"] = 500] = "InternalServerError";
|
|
9
|
+
HttpCode[HttpCode["NoContent"] = 204] = "NoContent";
|
|
10
|
+
HttpCode[HttpCode["NotFound"] = 404] = "NotFound";
|
|
11
|
+
HttpCode[HttpCode["Ok"] = 200] = "Ok";
|
|
12
|
+
HttpCode[HttpCode["Unprocessable"] = 422] = "Unprocessable";
|
|
13
|
+
})(HttpCode = exports.HttpCode || (exports.HttpCode = {}));
|
|
14
|
+
var RouteType;
|
|
15
|
+
(function (RouteType) {
|
|
16
|
+
// Changing the values of this enum changes the order in which routes are loaded into koa-router.
|
|
17
|
+
RouteType[RouteType["LoggerHandler"] = 0] = "LoggerHandler";
|
|
18
|
+
RouteType[RouteType["ErrorHandler"] = 1] = "ErrorHandler";
|
|
19
|
+
RouteType[RouteType["PublicRoute"] = 2] = "PublicRoute";
|
|
20
|
+
RouteType[RouteType["Authentication"] = 3] = "Authentication";
|
|
21
|
+
RouteType[RouteType["PrivateRoute"] = 4] = "PrivateRoute";
|
|
22
|
+
})(RouteType = exports.RouteType || (exports.RouteType = {}));
|
|
23
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvdHlwZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBc0JBLElBQVksUUFRWDtBQVJELFdBQVksUUFBUTtJQUNsQixxREFBZ0IsQ0FBQTtJQUNoQixtREFBZSxDQUFBO0lBQ2YsdUVBQXlCLENBQUE7SUFDekIsbURBQWUsQ0FBQTtJQUNmLGlEQUFjLENBQUE7SUFDZCxxQ0FBUSxDQUFBO0lBQ1IsMkRBQW1CLENBQUE7QUFDckIsQ0FBQyxFQVJXLFFBQVEsR0FBUixnQkFBUSxLQUFSLGdCQUFRLFFBUW5CO0FBRUQsSUFBWSxTQU9YO0FBUEQsV0FBWSxTQUFTO0lBQ25CLGlHQUFpRztJQUNqRywyREFBaUIsQ0FBQTtJQUNqQix5REFBZ0IsQ0FBQTtJQUNoQix1REFBZSxDQUFBO0lBQ2YsNkRBQWtCLENBQUE7SUFDbEIseURBQWdCLENBQUE7QUFDbEIsQ0FBQyxFQVBXLFNBQVMsR0FBVCxpQkFBUyxLQUFULGlCQUFTLFFBT3BCIn0=
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { CollectionSchema } from '@forestadmin/datasource-toolkit';
|
|
2
|
+
import { Context } from 'koa';
|
|
3
|
+
import { SelectionIds } from '../types';
|
|
4
|
+
export default class BodyParser {
|
|
5
|
+
static parseSelectionIds(schema: CollectionSchema, context: Context): SelectionIds;
|
|
6
|
+
}
|
|
7
|
+
//# sourceMappingURL=body-parser.d.ts.map
|
|
@@ -0,0 +1,18 @@
|
|
|
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 id_1 = __importDefault(require("./id"));
|
|
7
|
+
class BodyParser {
|
|
8
|
+
static parseSelectionIds(schema, context) {
|
|
9
|
+
const data = context.request.body?.data;
|
|
10
|
+
const attributes = data?.attributes;
|
|
11
|
+
const areExcluded = Boolean(attributes?.all_records);
|
|
12
|
+
let ids = attributes?.ids || (Array.isArray(data) && data.map(r => r.id)) || undefined;
|
|
13
|
+
ids = id_1.default.unpackIds(schema, areExcluded ? attributes?.all_records_ids_excluded : ids);
|
|
14
|
+
return { areExcluded, ids };
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
exports.default = BodyParser;
|
|
18
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYm9keS1wYXJzZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdXRpbHMvYm9keS1wYXJzZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFHQSw4Q0FBMkI7QUFFM0IsTUFBcUIsVUFBVTtJQUM3QixNQUFNLENBQUMsaUJBQWlCLENBQUMsTUFBd0IsRUFBRSxPQUFnQjtRQUNqRSxNQUFNLElBQUksR0FBRyxPQUFPLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxJQUFJLENBQUM7UUFDeEMsTUFBTSxVQUFVLEdBQUcsSUFBSSxFQUFFLFVBQVUsQ0FBQztRQUNwQyxNQUFNLFdBQVcsR0FBRyxPQUFPLENBQUMsVUFBVSxFQUFFLFdBQVcsQ0FBQyxDQUFDO1FBQ3JELElBQUksR0FBRyxHQUFHLFVBQVUsRUFBRSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsSUFBSSxTQUFTLENBQUM7UUFDdkYsR0FBRyxHQUFHLFlBQU8sQ0FBQyxTQUFTLENBQUMsTUFBTSxFQUFFLFdBQVcsQ0FBQyxDQUFDLENBQUMsVUFBVSxFQUFFLHdCQUF3QixDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUUxRixPQUFPLEVBQUUsV0FBVyxFQUFFLEdBQUcsRUFBRSxDQUFDO0lBQzlCLENBQUM7Q0FDRjtBQVZELDZCQVVDIn0=
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Collection, ConditionTree } from '@forestadmin/datasource-toolkit';
|
|
2
|
+
export default class ConditionTreeParser {
|
|
3
|
+
static fromPlainObject(collection: Collection, json: unknown): ConditionTree;
|
|
4
|
+
/** Handle 'In' where the frontend unexpectedly sends strings */
|
|
5
|
+
private static parseValue;
|
|
6
|
+
/** Convert snake_case to PascalCase */
|
|
7
|
+
private static toPascalCase;
|
|
8
|
+
private static isLeaf;
|
|
9
|
+
private static isBranch;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=condition-tree-parser.d.ts.map
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const datasource_toolkit_1 = require("@forestadmin/datasource-toolkit");
|
|
4
|
+
class ConditionTreeParser {
|
|
5
|
+
static fromPlainObject(collection, json) {
|
|
6
|
+
if (ConditionTreeParser.isLeaf(json)) {
|
|
7
|
+
const operator = ConditionTreeParser.toPascalCase(json.operator);
|
|
8
|
+
const value = ConditionTreeParser.parseValue(collection, { ...json, operator });
|
|
9
|
+
return new datasource_toolkit_1.ConditionTreeLeaf(json.field, operator, value);
|
|
10
|
+
}
|
|
11
|
+
if (ConditionTreeParser.isBranch(json)) {
|
|
12
|
+
const aggregator = ConditionTreeParser.toPascalCase(json.aggregator);
|
|
13
|
+
const conditions = json.conditions.map(subTree => ConditionTreeParser.fromPlainObject(collection, subTree));
|
|
14
|
+
return conditions.length !== 1
|
|
15
|
+
? new datasource_toolkit_1.ConditionTreeBranch(aggregator, conditions)
|
|
16
|
+
: conditions[0];
|
|
17
|
+
}
|
|
18
|
+
throw new Error('Failed to instantiate condition tree from json');
|
|
19
|
+
}
|
|
20
|
+
/** Handle 'In' where the frontend unexpectedly sends strings */
|
|
21
|
+
static parseValue(collection, leaf) {
|
|
22
|
+
const schema = datasource_toolkit_1.CollectionUtils.getFieldSchema(collection, leaf.field);
|
|
23
|
+
if (leaf.operator === 'In' && typeof leaf.value === 'string') {
|
|
24
|
+
if (schema.columnType === 'Boolean') {
|
|
25
|
+
return leaf.value
|
|
26
|
+
.split(',')
|
|
27
|
+
.map(bool => !['false', '0', 'no'].includes(bool.toLowerCase().trim()));
|
|
28
|
+
}
|
|
29
|
+
if (schema.columnType === 'Number') {
|
|
30
|
+
return leaf.value
|
|
31
|
+
.split(',')
|
|
32
|
+
.map(string => Number(string.trim()))
|
|
33
|
+
.filter(number => !Number.isNaN(number) && Number.isFinite(number));
|
|
34
|
+
}
|
|
35
|
+
return leaf.value.split(',').map(v => v.trim());
|
|
36
|
+
}
|
|
37
|
+
return leaf.value;
|
|
38
|
+
}
|
|
39
|
+
/** Convert snake_case to PascalCase */
|
|
40
|
+
static toPascalCase(value) {
|
|
41
|
+
const pascalCased = value.slice(0, 1).toUpperCase() +
|
|
42
|
+
value.slice(1).replace(/_[a-z]/g, match => match.slice(1).toUpperCase());
|
|
43
|
+
return pascalCased;
|
|
44
|
+
}
|
|
45
|
+
static isLeaf(raw) {
|
|
46
|
+
return typeof raw === 'object' && 'field' in raw && 'operator' in raw;
|
|
47
|
+
}
|
|
48
|
+
static isBranch(raw) {
|
|
49
|
+
return typeof raw === 'object' && 'aggregator' in raw && 'conditions' in raw;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
exports.default = ConditionTreeParser;
|
|
53
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uZGl0aW9uLXRyZWUtcGFyc2VyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3V0aWxzL2NvbmRpdGlvbi10cmVlLXBhcnNlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLHdFQVN5QztBQUV6QyxNQUFxQixtQkFBbUI7SUFDdEMsTUFBTSxDQUFDLGVBQWUsQ0FBQyxVQUFzQixFQUFFLElBQWE7UUFDMUQsSUFBSSxtQkFBbUIsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEVBQUU7WUFDcEMsTUFBTSxRQUFRLEdBQUcsbUJBQW1CLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUNqRSxNQUFNLEtBQUssR0FBRyxtQkFBbUIsQ0FBQyxVQUFVLENBQUMsVUFBVSxFQUFFLEVBQUUsR0FBRyxJQUFJLEVBQUUsUUFBUSxFQUFFLENBQUMsQ0FBQztZQUVoRixPQUFPLElBQUksc0NBQWlCLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxRQUFRLEVBQUUsS0FBSyxDQUFDLENBQUM7U0FDM0Q7UUFFRCxJQUFJLG1CQUFtQixDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsRUFBRTtZQUN0QyxNQUFNLFVBQVUsR0FBRyxtQkFBbUIsQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBZSxDQUFDO1lBQ25GLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQy9DLG1CQUFtQixDQUFDLGVBQWUsQ0FBQyxVQUFVLEVBQUUsT0FBTyxDQUFDLENBQ3pELENBQUM7WUFFRixPQUFPLFVBQVUsQ0FBQyxNQUFNLEtBQUssQ0FBQztnQkFDNUIsQ0FBQyxDQUFDLElBQUksd0NBQW1CLENBQUMsVUFBVSxFQUFFLFVBQVUsQ0FBQztnQkFDakQsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQztTQUNuQjtRQUVELE1BQU0sSUFBSSxLQUFLLENBQUMsZ0RBQWdELENBQUMsQ0FBQztJQUNwRSxDQUFDO0lBRUQsZ0VBQWdFO0lBQ3hELE1BQU0sQ0FBQyxVQUFVLENBQ3ZCLFVBQXNCLEVBQ3RCLElBQXlEO1FBRXpELE1BQU0sTUFBTSxHQUFHLG9DQUFlLENBQUMsY0FBYyxDQUFDLFVBQVUsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFpQixDQUFDO1FBRXRGLElBQUksSUFBSSxDQUFDLFFBQVEsS0FBSyxJQUFJLElBQUksT0FBTyxJQUFJLENBQUMsS0FBSyxLQUFLLFFBQVEsRUFBRTtZQUM1RCxJQUFJLE1BQU0sQ0FBQyxVQUFVLEtBQUssU0FBUyxFQUFFO2dCQUNuQyxPQUFPLElBQUksQ0FBQyxLQUFLO3FCQUNkLEtBQUssQ0FBQyxHQUFHLENBQUM7cUJBQ1YsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLE9BQU8sRUFBRSxHQUFHLEVBQUUsSUFBSSxDQUFDLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUM7YUFDM0U7WUFFRCxJQUFJLE1BQU0sQ0FBQyxVQUFVLEtBQUssUUFBUSxFQUFFO2dCQUNsQyxPQUFPLElBQUksQ0FBQyxLQUFLO3FCQUNkLEtBQUssQ0FBQyxHQUFHLENBQUM7cUJBQ1YsR0FBRyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO3FCQUNwQyxNQUFNLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLElBQUksTUFBTSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO2FBQ3ZFO1lBRUQsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQztTQUNqRDtRQUVELE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQztJQUNwQixDQUFDO0lBRUQsdUNBQXVDO0lBQy9CLE1BQU0sQ0FBQyxZQUFZLENBQUMsS0FBYTtRQUN2QyxNQUFNLFdBQVcsR0FDZixLQUFLLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxXQUFXLEVBQUU7WUFDL0IsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsU0FBUyxFQUFFLEtBQUssQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDO1FBRTNFLE9BQU8sV0FBdUIsQ0FBQztJQUNqQyxDQUFDO0lBRU8sTUFBTSxDQUFDLE1BQU0sQ0FBQyxHQUFZO1FBQ2hDLE9BQU8sT0FBTyxHQUFHLEtBQUssUUFBUSxJQUFJLE9BQU8sSUFBSSxHQUFHLElBQUksVUFBVSxJQUFJLEdBQUcsQ0FBQztJQUN4RSxDQUFDO0lBRU8sTUFBTSxDQUFDLFFBQVEsQ0FBQyxHQUFZO1FBQ2xDLE9BQU8sT0FBTyxHQUFHLEtBQUssUUFBUSxJQUFJLFlBQVksSUFBSSxHQUFHLElBQUksWUFBWSxJQUFJLEdBQUcsQ0FBQztJQUMvRSxDQUFDO0NBQ0Y7QUFsRUQsc0NBa0VDIn0=
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Collection, ConditionTree, Filter, PaginatedFilter } from '@forestadmin/datasource-toolkit';
|
|
2
|
+
import { Context } from 'koa';
|
|
3
|
+
export default class ContextFilterFactory {
|
|
4
|
+
static buildPaginated(collection: Collection, context: Context, scope: ConditionTree, partialFilter?: Partial<PaginatedFilter>): PaginatedFilter;
|
|
5
|
+
static build(collection: Collection, context: Context, scope: ConditionTree, partialFilter?: Partial<Filter>): PaginatedFilter;
|
|
6
|
+
}
|
|
7
|
+
//# sourceMappingURL=context-filter-factory.d.ts.map
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const datasource_toolkit_1 = require("@forestadmin/datasource-toolkit");
|
|
7
|
+
const query_string_1 = __importDefault(require("./query-string"));
|
|
8
|
+
class ContextFilterFactory {
|
|
9
|
+
static buildPaginated(collection, context, scope, partialFilter) {
|
|
10
|
+
return new datasource_toolkit_1.PaginatedFilter({
|
|
11
|
+
sort: query_string_1.default.parseSort(collection, context),
|
|
12
|
+
page: query_string_1.default.parsePagination(context),
|
|
13
|
+
...ContextFilterFactory.build(collection, context, scope),
|
|
14
|
+
...partialFilter,
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
static build(collection, context, scope, partialFilter) {
|
|
18
|
+
return new datasource_toolkit_1.Filter({
|
|
19
|
+
search: query_string_1.default.parseSearch(collection, context),
|
|
20
|
+
segment: query_string_1.default.parseSegment(collection, context),
|
|
21
|
+
searchExtended: query_string_1.default.parseSearchExtended(context),
|
|
22
|
+
conditionTree: datasource_toolkit_1.ConditionTreeFactory.intersect(query_string_1.default.parseConditionTree(collection, context), scope),
|
|
23
|
+
...partialFilter,
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
exports.default = ContextFilterFactory;
|
|
28
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29udGV4dC1maWx0ZXItZmFjdG9yeS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy91dGlscy9jb250ZXh0LWZpbHRlci1mYWN0b3J5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsd0VBTXlDO0FBRXpDLGtFQUErQztBQUUvQyxNQUFxQixvQkFBb0I7SUFDdkMsTUFBTSxDQUFDLGNBQWMsQ0FDbkIsVUFBc0IsRUFDdEIsT0FBZ0IsRUFDaEIsS0FBb0IsRUFDcEIsYUFBd0M7UUFFeEMsT0FBTyxJQUFJLG9DQUFlLENBQUM7WUFDekIsSUFBSSxFQUFFLHNCQUFpQixDQUFDLFNBQVMsQ0FBQyxVQUFVLEVBQUUsT0FBTyxDQUFDO1lBQ3RELElBQUksRUFBRSxzQkFBaUIsQ0FBQyxlQUFlLENBQUMsT0FBTyxDQUFDO1lBQ2hELEdBQUcsb0JBQW9CLENBQUMsS0FBSyxDQUFDLFVBQVUsRUFBRSxPQUFPLEVBQUUsS0FBSyxDQUFDO1lBQ3pELEdBQUcsYUFBYTtTQUNqQixDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQsTUFBTSxDQUFDLEtBQUssQ0FDVixVQUFzQixFQUN0QixPQUFnQixFQUNoQixLQUFvQixFQUNwQixhQUErQjtRQUUvQixPQUFPLElBQUksMkJBQU0sQ0FBQztZQUNoQixNQUFNLEVBQUUsc0JBQWlCLENBQUMsV0FBVyxDQUFDLFVBQVUsRUFBRSxPQUFPLENBQUM7WUFDMUQsT0FBTyxFQUFFLHNCQUFpQixDQUFDLFlBQVksQ0FBQyxVQUFVLEVBQUUsT0FBTyxDQUFDO1lBQzVELGNBQWMsRUFBRSxzQkFBaUIsQ0FBQyxtQkFBbUIsQ0FBQyxPQUFPLENBQUM7WUFDOUQsYUFBYSxFQUFFLHlDQUFvQixDQUFDLFNBQVMsQ0FDM0Msc0JBQWlCLENBQUMsa0JBQWtCLENBQUMsVUFBVSxFQUFFLE9BQU8sQ0FBQyxFQUN6RCxLQUFLLENBQ047WUFDRCxHQUFHLGFBQWE7U0FDakIsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztDQUNGO0FBaENELHVDQWdDQyJ9
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Caller, Collection, PaginatedFilter, Projection } from '@forestadmin/datasource-toolkit';
|
|
2
|
+
export declare const CHUNK_SIZE = 1000;
|
|
3
|
+
export default class CsvGenerator {
|
|
4
|
+
/**
|
|
5
|
+
* Use an async generator to ensure that
|
|
6
|
+
* - backpressure is properly applied without needing to extend Readable (for slow clients)
|
|
7
|
+
* - we stop making queries to the database if the client closes the connection.
|
|
8
|
+
*/
|
|
9
|
+
static generate(caller: Caller, projection: Projection, header: string, filter: PaginatedFilter, collection: Collection, list: Collection['list']): AsyncGenerator<string>;
|
|
10
|
+
private static convert;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=csv-generator.d.ts.map
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CHUNK_SIZE = void 0;
|
|
4
|
+
const datasource_toolkit_1 = require("@forestadmin/datasource-toolkit");
|
|
5
|
+
const format_1 = require("@fast-csv/format");
|
|
6
|
+
exports.CHUNK_SIZE = 1000;
|
|
7
|
+
class CsvGenerator {
|
|
8
|
+
/**
|
|
9
|
+
* Use an async generator to ensure that
|
|
10
|
+
* - backpressure is properly applied without needing to extend Readable (for slow clients)
|
|
11
|
+
* - we stop making queries to the database if the client closes the connection.
|
|
12
|
+
*/
|
|
13
|
+
static async *generate(caller, projection, header, filter, collection, list) {
|
|
14
|
+
yield (0, format_1.writeToString)([header.split(',')], { headers: true, includeEndRowDelimiter: true });
|
|
15
|
+
const limit = filter.page?.limit;
|
|
16
|
+
let skip = filter.page?.skip || 0;
|
|
17
|
+
let areAllRecordsFetched = false;
|
|
18
|
+
const copiedFilter = { ...filter };
|
|
19
|
+
while (!areAllRecordsFetched) {
|
|
20
|
+
let currentPageSize = exports.CHUNK_SIZE;
|
|
21
|
+
if (limit < skip)
|
|
22
|
+
currentPageSize = skip - limit;
|
|
23
|
+
copiedFilter.page = new datasource_toolkit_1.Page(skip, currentPageSize);
|
|
24
|
+
if (!copiedFilter.sort || copiedFilter.sort.length === 0) {
|
|
25
|
+
copiedFilter.sort = datasource_toolkit_1.SortFactory.byPrimaryKeys(collection);
|
|
26
|
+
}
|
|
27
|
+
// eslint-disable-next-line no-await-in-loop
|
|
28
|
+
const records = await list(caller, new datasource_toolkit_1.PaginatedFilter(copiedFilter), projection);
|
|
29
|
+
yield CsvGenerator.convert(records, projection);
|
|
30
|
+
areAllRecordsFetched = records.length < exports.CHUNK_SIZE;
|
|
31
|
+
skip += currentPageSize;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
static convert(records, projection) {
|
|
35
|
+
return (0, format_1.writeToString)(records.map(record => projection.map(field => datasource_toolkit_1.RecordUtils.getFieldValue(record, field))));
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
exports.default = CsvGenerator;
|
|
39
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3N2LWdlbmVyYXRvci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy91dGlscy9jc3YtZ2VuZXJhdG9yLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLHdFQVN5QztBQUN6Qyw2Q0FBaUQ7QUFFcEMsUUFBQSxVQUFVLEdBQUcsSUFBSSxDQUFDO0FBRS9CLE1BQXFCLFlBQVk7SUFDL0I7Ozs7T0FJRztJQUNILE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxRQUFRLENBQ3BCLE1BQWMsRUFDZCxVQUFzQixFQUN0QixNQUFjLEVBQ2QsTUFBdUIsRUFDdkIsVUFBc0IsRUFDdEIsSUFBd0I7UUFFeEIsTUFBTSxJQUFBLHNCQUFhLEVBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLHNCQUFzQixFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7UUFFMUYsTUFBTSxLQUFLLEdBQUcsTUFBTSxDQUFDLElBQUksRUFBRSxLQUFLLENBQUM7UUFDakMsSUFBSSxJQUFJLEdBQUcsTUFBTSxDQUFDLElBQUksRUFBRSxJQUFJLElBQUksQ0FBQyxDQUFDO1FBRWxDLElBQUksb0JBQW9CLEdBQUcsS0FBSyxDQUFDO1FBQ2pDLE1BQU0sWUFBWSxHQUFHLEVBQUUsR0FBRyxNQUFNLEVBQUUsQ0FBQztRQUVuQyxPQUFPLENBQUMsb0JBQW9CLEVBQUU7WUFDNUIsSUFBSSxlQUFlLEdBQUcsa0JBQVUsQ0FBQztZQUNqQyxJQUFJLEtBQUssR0FBRyxJQUFJO2dCQUFFLGVBQWUsR0FBRyxJQUFJLEdBQUcsS0FBSyxDQUFDO1lBRWpELFlBQVksQ0FBQyxJQUFJLEdBQUcsSUFBSSx5QkFBSSxDQUFDLElBQUksRUFBRSxlQUFlLENBQUMsQ0FBQztZQUVwRCxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksSUFBSSxZQUFZLENBQUMsSUFBSSxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUU7Z0JBQ3hELFlBQVksQ0FBQyxJQUFJLEdBQUcsZ0NBQVcsQ0FBQyxhQUFhLENBQUMsVUFBVSxDQUFDLENBQUM7YUFDM0Q7WUFFRCw0Q0FBNEM7WUFDNUMsTUFBTSxPQUFPLEdBQUcsTUFBTSxJQUFJLENBQUMsTUFBTSxFQUFFLElBQUksb0NBQWUsQ0FBQyxZQUFZLENBQUMsRUFBRSxVQUFVLENBQUMsQ0FBQztZQUVsRixNQUFNLFlBQVksQ0FBQyxPQUFPLENBQUMsT0FBTyxFQUFFLFVBQVUsQ0FBQyxDQUFDO1lBRWhELG9CQUFvQixHQUFHLE9BQU8sQ0FBQyxNQUFNLEdBQUcsa0JBQVUsQ0FBQztZQUNuRCxJQUFJLElBQUksZUFBZSxDQUFDO1NBQ3pCO0lBQ0gsQ0FBQztJQUVPLE1BQU0sQ0FBQyxPQUFPLENBQUMsT0FBcUIsRUFBRSxVQUFzQjtRQUNsRSxPQUFPLElBQUEsc0JBQWEsRUFDbEIsT0FBTyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxnQ0FBVyxDQUFDLGFBQWEsQ0FBQyxNQUFNLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUN6RixDQUFDO0lBQ0osQ0FBQztDQUNGO0FBL0NELCtCQStDQyJ9
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
class CsvRouteContext {
|
|
4
|
+
static buildResponse(context) {
|
|
5
|
+
const { filename } = context.request.query;
|
|
6
|
+
context.response.type = 'text/csv; charset=utf-8';
|
|
7
|
+
context.response.attachment(`attachment; filename=${filename}`);
|
|
8
|
+
context.response.lastModified = new Date();
|
|
9
|
+
context.response.set({ 'X-Accel-Buffering': 'no' });
|
|
10
|
+
context.response.set({ 'Cache-Control': 'no-cache' });
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
exports.default = CsvRouteContext;
|
|
14
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3N2LXJvdXRlLWNvbnRleHQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdXRpbHMvY3N2LXJvdXRlLWNvbnRleHQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFFQSxNQUFxQixlQUFlO0lBQ2xDLE1BQU0sQ0FBQyxhQUFhLENBQUMsT0FBZ0I7UUFDbkMsTUFBTSxFQUFFLFFBQVEsRUFBRSxHQUFHLE9BQU8sQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDO1FBRTNDLE9BQU8sQ0FBQyxRQUFRLENBQUMsSUFBSSxHQUFHLHlCQUF5QixDQUFDO1FBQ2xELE9BQU8sQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLHdCQUF3QixRQUFRLEVBQUUsQ0FBQyxDQUFDO1FBQ2hFLE9BQU8sQ0FBQyxRQUFRLENBQUMsWUFBWSxHQUFHLElBQUksSUFBSSxFQUFFLENBQUM7UUFDM0MsT0FBTyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsRUFBRSxtQkFBbUIsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBQ3BELE9BQU8sQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLEVBQUUsZUFBZSxFQUFFLFVBQVUsRUFBRSxDQUFDLENBQUM7SUFDeEQsQ0FBQztDQUNGO0FBVkQsa0NBVUMifQ==
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { IssuerMetadata } from 'openid-client';
|
|
2
|
+
import { JSONAPIDocument } from 'json-api-serializer';
|
|
3
|
+
import { PlainConditionTree } from '@forestadmin/datasource-toolkit';
|
|
4
|
+
import { AgentOptions } from '../types';
|
|
5
|
+
import { EnvironmentPermissionsV4, UserPermissionV4 } from '../services/authorization';
|
|
6
|
+
export declare type IpWhitelistConfiguration = {
|
|
7
|
+
isFeatureEnabled: boolean;
|
|
8
|
+
ipRules: Array<{
|
|
9
|
+
type: number;
|
|
10
|
+
ipMinimum?: string;
|
|
11
|
+
ipMaximum?: string;
|
|
12
|
+
ip?: string;
|
|
13
|
+
range?: string;
|
|
14
|
+
}>;
|
|
15
|
+
};
|
|
16
|
+
export declare type UserInfo = {
|
|
17
|
+
id: number;
|
|
18
|
+
email: string;
|
|
19
|
+
firstName: string;
|
|
20
|
+
lastName: string;
|
|
21
|
+
team: string;
|
|
22
|
+
renderingId: number;
|
|
23
|
+
role: string;
|
|
24
|
+
tags: {
|
|
25
|
+
[key: string]: string;
|
|
26
|
+
};
|
|
27
|
+
permissionLevel: string;
|
|
28
|
+
};
|
|
29
|
+
export declare type RenderingPermissions = {
|
|
30
|
+
actions: Set<string>;
|
|
31
|
+
actionsByUser: {
|
|
32
|
+
[actionName: string]: Set<number>;
|
|
33
|
+
};
|
|
34
|
+
scopes: {
|
|
35
|
+
[collectionName: string]: {
|
|
36
|
+
conditionTree: PlainConditionTree;
|
|
37
|
+
dynamicScopeValues: {
|
|
38
|
+
[userId: number]: {
|
|
39
|
+
[replacementKey: string]: unknown;
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
};
|
|
45
|
+
declare type HttpOptions = Pick<AgentOptions, 'envSecret' | 'forestServerUrl' | 'isProduction'>;
|
|
46
|
+
export default class ForestHttpApi {
|
|
47
|
+
static getIpWhitelistConfiguration(options: HttpOptions): Promise<IpWhitelistConfiguration>;
|
|
48
|
+
static getOpenIdIssuerMetadata(options: HttpOptions): Promise<IssuerMetadata>;
|
|
49
|
+
static getUserInformation(options: HttpOptions, renderingId: number, accessToken: string): Promise<UserInfo>;
|
|
50
|
+
static hasSchema(options: HttpOptions, hash: string): Promise<boolean>;
|
|
51
|
+
static uploadSchema(options: HttpOptions, apimap: JSONAPIDocument): Promise<void>;
|
|
52
|
+
static getPermissions(options: HttpOptions, renderingId: number): Promise<RenderingPermissions>;
|
|
53
|
+
static getEnvironmentPermissions(options: HttpOptions): Promise<EnvironmentPermissionsV4>;
|
|
54
|
+
static getUsers(options: HttpOptions): Promise<UserPermissionV4[]>;
|
|
55
|
+
/** Helper to format permissions into something easy to validate against */
|
|
56
|
+
private static decodeChartPermissions;
|
|
57
|
+
/**
|
|
58
|
+
* Helper to format permissions into something easy to validate against
|
|
59
|
+
* Note that the format the server is sending varies depending on if we're using a remote or
|
|
60
|
+
* local environment.
|
|
61
|
+
*/
|
|
62
|
+
private static decodeActionPermissions;
|
|
63
|
+
/** Helper to format permissions into something easy to validate against */
|
|
64
|
+
private static decodeScopePermissions;
|
|
65
|
+
private static handleResponseError;
|
|
66
|
+
}
|
|
67
|
+
export {};
|
|
68
|
+
//# sourceMappingURL=forest-http-api.d.ts.map
|