@forestadmin/agent-bff 1.16.0 → 1.18.0
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/README.md +15 -1
- package/dist/action/action-form-mapper.d.ts +2 -1
- package/dist/action/action-form-mapper.js +1 -1
- package/dist/action/agent-action-client.d.ts +2 -1
- package/dist/action/agent-action-client.js +1 -1
- package/dist/cli-core.d.ts +3 -0
- package/dist/cli-core.js +52 -10
- package/dist/cli-dispatch.d.ts +8 -2
- package/dist/cli-dispatch.js +90 -9
- package/dist/data/data-routes-middleware.js +3 -12
- package/dist/data/pack-id.d.ts +1 -0
- package/dist/data/pack-id.js +4 -3
- package/dist/openapi/collect-unfolding.d.ts +23 -0
- package/dist/openapi/collect-unfolding.js +144 -0
- package/dist/openapi/component-pool.d.ts +18 -0
- package/dist/openapi/component-pool.js +28 -0
- package/dist/openapi/field-schemas.d.ts +9 -0
- package/dist/openapi/field-schemas.js +43 -0
- package/dist/openapi/names.d.ts +16 -0
- package/dist/openapi/names.js +28 -0
- package/dist/openapi/openapi-document.d.ts +2 -1
- package/dist/openapi/openapi-document.js +112 -66
- package/dist/openapi/openapi-routes.d.ts +4 -1
- package/dist/openapi/openapi-routes.js +46 -9
- package/dist/openapi/schemas.d.ts +14 -1
- package/dist/openapi/schemas.js +11 -10
- package/dist/openapi/unfolded-document.d.ts +28 -0
- package/dist/openapi/unfolded-document.js +52 -0
- package/dist/openapi/unfolded-paths.d.ts +20 -0
- package/dist/openapi/unfolded-paths.js +408 -0
- package/dist/openapi/unfolding.d.ts +66 -0
- package/dist/openapi/unfolding.js +17 -0
- package/dist/read-model/agent-capabilities-fetcher.d.ts +8 -3
- package/dist/read-model/agent-capabilities-fetcher.js +15 -7
- package/dist/read-model/capabilities-cache.d.ts +11 -1
- package/dist/read-model/capabilities-cache.js +1 -1
- package/dist/read-model/read-model.d.ts +14 -0
- package/dist/read-model/read-model.js +36 -2
- package/dist/validation/operator-normalizer.d.ts +6 -0
- package/dist/validation/operator-normalizer.js +11 -1
- package/package.json +4 -4
|
@@ -14,6 +14,10 @@ export type PrimaryKeyField = {
|
|
|
14
14
|
name: string;
|
|
15
15
|
type: string;
|
|
16
16
|
};
|
|
17
|
+
export type ListableRelation = {
|
|
18
|
+
name: string;
|
|
19
|
+
foreignCollection: string;
|
|
20
|
+
};
|
|
17
21
|
/**
|
|
18
22
|
* The agent read-model derived from a schema. Names are collection-scoped: relations and actions
|
|
19
23
|
* are keyed by `(collection, name)` so the same relation/action name on two collections stays
|
|
@@ -23,6 +27,7 @@ export type PrimaryKeyField = {
|
|
|
23
27
|
export default class ReadModel {
|
|
24
28
|
private readonly collections;
|
|
25
29
|
private readonly relations;
|
|
30
|
+
private readonly listableRelations;
|
|
26
31
|
private readonly actionEndpoints;
|
|
27
32
|
private readonly primaryKeys;
|
|
28
33
|
constructor(collections: ForestSchemaCollection[]);
|
|
@@ -30,7 +35,16 @@ export default class ReadModel {
|
|
|
30
35
|
private buildActionEndpoints;
|
|
31
36
|
private buildPrimaryKeys;
|
|
32
37
|
isCollectionAllowed(collection: string): boolean;
|
|
38
|
+
/** A fresh copy per call, so a consumer cannot mutate the shared cached read-model. */
|
|
33
39
|
getAllowedCollections(): string[];
|
|
40
|
+
/**
|
|
41
|
+
* The to-many, non-polymorphic relations of a collection — the only ones with a list/count route.
|
|
42
|
+
* The foreign collection is NOT checked against the allow-list here: the data routes must keep
|
|
43
|
+
* telling a non-listable relation (404 unknown_relation) from a listable one pointing at a hidden
|
|
44
|
+
* collection (404 unknown_collection), so that filter belongs to each caller.
|
|
45
|
+
*/
|
|
46
|
+
getListableRelations(collection: string): ListableRelation[];
|
|
47
|
+
getListableRelationTarget(collection: string, relation: string): string | undefined;
|
|
34
48
|
isRelationAllowed(collection: string, relation: string): boolean;
|
|
35
49
|
getRelationTarget(collection: string, relation: string): RelationTarget | undefined;
|
|
36
50
|
isActionAllowed(collection: string, action: string): boolean;
|
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
// Only to-many relations expose list/count on the agent; to-one relations get update-relation only.
|
|
4
|
+
// A polymorphic relation carrying multiple targets is always the to-one (PolymorphicManyToOne) side.
|
|
5
|
+
// The data routes and the OpenAPI unfolding both resolve listability here, so a relation can never be
|
|
6
|
+
// documented as listable while the runtime 404s it, or the reverse.
|
|
7
|
+
function toListableTarget(target) {
|
|
8
|
+
if (!('target' in target))
|
|
9
|
+
return null;
|
|
10
|
+
if (target.type !== 'HasMany' && target.type !== 'BelongsToMany')
|
|
11
|
+
return null;
|
|
12
|
+
return target.target;
|
|
13
|
+
}
|
|
3
14
|
function toRelationTarget(field) {
|
|
4
15
|
if (!field.relationship)
|
|
5
16
|
return null;
|
|
@@ -31,6 +42,7 @@ class ReadModel {
|
|
|
31
42
|
constructor(collections) {
|
|
32
43
|
this.collections = new Set();
|
|
33
44
|
this.relations = new Map();
|
|
45
|
+
this.listableRelations = new Map();
|
|
34
46
|
// Null-prototype so an action/collection named like an Object.prototype member
|
|
35
47
|
// (`toString`, `constructor`, `__proto__`, …) can't falsely pass the allow-list.
|
|
36
48
|
this.actionEndpoints = Object.create(null);
|
|
@@ -48,12 +60,18 @@ class ReadModel {
|
|
|
48
60
|
}
|
|
49
61
|
buildRelations(collection) {
|
|
50
62
|
const relations = new Map();
|
|
63
|
+
const listable = new Map();
|
|
51
64
|
for (const field of collection.fields ?? []) {
|
|
52
65
|
const target = toRelationTarget(field);
|
|
53
|
-
if (target)
|
|
66
|
+
if (target) {
|
|
54
67
|
relations.set(field.field, target);
|
|
68
|
+
const foreignCollection = toListableTarget(target);
|
|
69
|
+
if (foreignCollection)
|
|
70
|
+
listable.set(field.field, foreignCollection);
|
|
71
|
+
}
|
|
55
72
|
}
|
|
56
73
|
this.relations.set(collection.name, relations);
|
|
74
|
+
this.listableRelations.set(collection.name, listable);
|
|
57
75
|
}
|
|
58
76
|
buildActionEndpoints(collection) {
|
|
59
77
|
const actions = collection.actions ?? [];
|
|
@@ -85,9 +103,25 @@ class ReadModel {
|
|
|
85
103
|
isCollectionAllowed(collection) {
|
|
86
104
|
return this.collections.has(collection);
|
|
87
105
|
}
|
|
106
|
+
/** A fresh copy per call, so a consumer cannot mutate the shared cached read-model. */
|
|
88
107
|
getAllowedCollections() {
|
|
89
108
|
return [...this.collections];
|
|
90
109
|
}
|
|
110
|
+
/**
|
|
111
|
+
* The to-many, non-polymorphic relations of a collection — the only ones with a list/count route.
|
|
112
|
+
* The foreign collection is NOT checked against the allow-list here: the data routes must keep
|
|
113
|
+
* telling a non-listable relation (404 unknown_relation) from a listable one pointing at a hidden
|
|
114
|
+
* collection (404 unknown_collection), so that filter belongs to each caller.
|
|
115
|
+
*/
|
|
116
|
+
getListableRelations(collection) {
|
|
117
|
+
const listable = this.listableRelations.get(collection);
|
|
118
|
+
if (!listable)
|
|
119
|
+
return [];
|
|
120
|
+
return [...listable].map(([name, foreignCollection]) => ({ name, foreignCollection }));
|
|
121
|
+
}
|
|
122
|
+
getListableRelationTarget(collection, relation) {
|
|
123
|
+
return this.listableRelations.get(collection)?.get(relation);
|
|
124
|
+
}
|
|
91
125
|
isRelationAllowed(collection, relation) {
|
|
92
126
|
return this.relations.get(collection)?.has(relation) ?? false;
|
|
93
127
|
}
|
|
@@ -105,4 +139,4 @@ class ReadModel {
|
|
|
105
139
|
}
|
|
106
140
|
}
|
|
107
141
|
exports.default = ReadModel;
|
|
108
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
142
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVhZC1tb2RlbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9yZWFkLW1vZGVsL3JlYWQtbW9kZWwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFhQSxvR0FBb0c7QUFDcEcscUdBQXFHO0FBQ3JHLHNHQUFzRztBQUN0RyxvRUFBb0U7QUFDcEUsU0FBUyxnQkFBZ0IsQ0FBQyxNQUFzQjtJQUM5QyxJQUFJLENBQUMsQ0FBQyxRQUFRLElBQUksTUFBTSxDQUFDO1FBQUUsT0FBTyxJQUFJLENBQUM7SUFDdkMsSUFBSSxNQUFNLENBQUMsSUFBSSxLQUFLLFNBQVMsSUFBSSxNQUFNLENBQUMsSUFBSSxLQUFLLGVBQWU7UUFBRSxPQUFPLElBQUksQ0FBQztJQUU5RSxPQUFPLE1BQU0sQ0FBQyxNQUFNLENBQUM7QUFDdkIsQ0FBQztBQUVELFNBQVMsZ0JBQWdCLENBQUMsS0FBd0I7SUFDaEQsSUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZO1FBQUUsT0FBTyxJQUFJLENBQUM7SUFFckMsTUFBTSxJQUFJLEdBQUcsS0FBSyxDQUFDLFlBQVksQ0FBQztJQUVoQyxJQUFJLEtBQUssQ0FBQywyQkFBMkIsSUFBSSxLQUFLLENBQUMsMkJBQTJCLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO1FBQ3RGLE9BQU8sRUFBRSxJQUFJLEVBQUUsV0FBVyxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsQ0FBQyxHQUFHLEtBQUssQ0FBQywyQkFBMkIsQ0FBQyxFQUFFLENBQUM7SUFDdEYsQ0FBQztJQUVELElBQUksS0FBSyxDQUFDLFNBQVMsRUFBRSxDQUFDO1FBQ3BCLDBGQUEwRjtRQUMxRix5RkFBeUY7UUFDekYsT0FBTyxFQUFFLElBQUksRUFBRSxXQUFXLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxLQUFLLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFD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
|
|
@@ -11,4 +11,10 @@ export declare function toSnakeCaseOperator(operator: string): string;
|
|
|
11
11
|
* only happens when the agent runs a newer operator set than this package (a version skew).
|
|
12
12
|
*/
|
|
13
13
|
export declare function normalizeOperator(snakeCaseOperator: string): Operator | undefined;
|
|
14
|
+
/**
|
|
15
|
+
* Deduplicates and reorders an operator set to the `allOperators` order. The agent serializes a
|
|
16
|
+
* field's operators from a set, so their order is not contractual: putting them in a canonical order
|
|
17
|
+
* is what lets two fields sharing an operator set be recognized as sharing it.
|
|
18
|
+
*/
|
|
19
|
+
export declare function toCanonicalOperatorSet(operators: Operator[]): Operator[];
|
|
14
20
|
//# sourceMappingURL=operator-normalizer.d.ts.map
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.toSnakeCaseOperator = toSnakeCaseOperator;
|
|
4
4
|
exports.normalizeOperator = normalizeOperator;
|
|
5
|
+
exports.toCanonicalOperatorSet = toCanonicalOperatorSet;
|
|
5
6
|
const datasource_toolkit_1 = require("@forestadmin/datasource-toolkit");
|
|
6
7
|
/**
|
|
7
8
|
* Mirrors the agent's capabilities serialization (`packages/agent/src/routes/capabilities.ts`),
|
|
@@ -23,4 +24,13 @@ const SNAKE_TO_PASCAL = new Map(datasource_toolkit_1.allOperators.map(operator =
|
|
|
23
24
|
function normalizeOperator(snakeCaseOperator) {
|
|
24
25
|
return SNAKE_TO_PASCAL.get(snakeCaseOperator);
|
|
25
26
|
}
|
|
26
|
-
|
|
27
|
+
const CANONICAL_ORDER = new Map(datasource_toolkit_1.allOperators.map((operator, index) => [operator, index]));
|
|
28
|
+
/**
|
|
29
|
+
* Deduplicates and reorders an operator set to the `allOperators` order. The agent serializes a
|
|
30
|
+
* field's operators from a set, so their order is not contractual: putting them in a canonical order
|
|
31
|
+
* is what lets two fields sharing an operator set be recognized as sharing it.
|
|
32
|
+
*/
|
|
33
|
+
function toCanonicalOperatorSet(operators) {
|
|
34
|
+
return [...new Set(operators)].sort((left, right) => CANONICAL_ORDER.get(left) - CANONICAL_ORDER.get(right));
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3BlcmF0b3Itbm9ybWFsaXplci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy92YWxpZGF0aW9uL29wZXJhdG9yLW5vcm1hbGl6ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFTQSxrREFLQztBQVdELDhDQUVDO0FBV0Qsd0RBSUM7QUF4Q0Qsd0VBQStEO0FBRS9EOzs7O0dBSUc7QUFDSCxTQUFnQixtQkFBbUIsQ0FBQyxRQUFnQjtJQUNsRCxPQUFPLFFBQVE7U0FDWixLQUFLLENBQUMsY0FBYyxDQUFDO1NBQ3JCLElBQUksQ0FBQyxHQUFHLENBQUM7U0FDVCxXQUFXLEVBQUUsQ0FBQztBQUNuQixDQUFDO0FBRUQsTUFBTSxlQUFlLEdBQUcsSUFBSSxHQUFHLENBQzdCLGlDQUFZLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsQ0FBQyxtQkFBbUIsQ0FBQyxRQUFRLENBQUMsRUFBRSxRQUFRLENBQUMsQ0FBQyxDQUN4RSxDQUFDO0FBRUY7Ozs7R0FJRztBQUNILFNBQWdCLGlCQUFpQixDQUFDLGlCQUF5QjtJQUN6RCxPQUFPLGVBQWUsQ0FBQyxHQUFHLENBQUMsaUJBQWlCLENBQUMsQ0FBQztBQUNoRCxDQUFDO0FBRUQsTUFBTSxlQUFlLEdBQUcsSUFBSSxHQUFHLENBQzdCLGlDQUFZLENBQUMsR0FBRyxDQUFDLENBQUMsUUFBUSxFQUFFLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQyxRQUFRLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FDekQsQ0FBQztBQUVGOzs7O0dBSUc7QUFDSCxTQUFnQixzQkFBc0IsQ0FBQyxTQUFxQjtJQUMxRCxPQUFPLENBQUMsR0FBRyxJQUFJLEdBQUcsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FDakMsQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLEVBQUUsQ0FBRSxlQUFlLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBWSxHQUFJLGVBQWUsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFZLENBQ2hHLENBQUM7QUFDSixDQUFDIn0=
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@forestadmin/agent-bff",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.18.0",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"bin": {
|
|
6
6
|
"forest-bff": "dist/cli.js"
|
|
@@ -32,9 +32,9 @@
|
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
34
|
"@asteasolutions/zod-to-openapi": "8.5.0",
|
|
35
|
-
"@forestadmin/agent-client": "1.
|
|
36
|
-
"@forestadmin/datasource-toolkit": "1.
|
|
37
|
-
"@forestadmin/forestadmin-client": "1.42.
|
|
35
|
+
"@forestadmin/agent-client": "1.14.0",
|
|
36
|
+
"@forestadmin/datasource-toolkit": "1.55.0",
|
|
37
|
+
"@forestadmin/forestadmin-client": "1.42.1",
|
|
38
38
|
"@koa/bodyparser": "^6.1.0",
|
|
39
39
|
"jsonwebtoken": "^9.0.3",
|
|
40
40
|
"koa": "^3.0.1",
|