@forestadmin/agent-bff 1.30.0 → 1.30.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/dist/action/action-routes-middleware.js +8 -1
  2. package/dist/context/build-context.d.ts +1 -0
  3. package/dist/context/build-context.js +18 -4
  4. package/dist/data/agent-query.js +23 -3
  5. package/dist/data/data-routes-middleware.js +7 -2
  6. package/dist/data/pack-id.d.ts +6 -1
  7. package/dist/data/pack-id.js +96 -3
  8. package/dist/data/response-mappers.js +2 -2
  9. package/dist/http/agent-error-mapper.js +42 -27
  10. package/dist/openapi/collect-unfolding.js +23 -9
  11. package/dist/openapi/schemas.d.ts +1 -0
  12. package/dist/openapi/schemas.js +22 -3
  13. package/dist/openapi/unfolded-document.js +7 -2
  14. package/dist/openapi/unfolded-paths.js +96 -16
  15. package/dist/openapi/unfolding.d.ts +12 -0
  16. package/dist/openapi/unfolding.js +1 -1
  17. package/dist/read-model/agent-capabilities-fetcher.d.ts +6 -1
  18. package/dist/read-model/agent-capabilities-fetcher.js +88 -6
  19. package/dist/read-model/capabilities-cache.d.ts +1 -0
  20. package/dist/read-model/capabilities-cache.js +1 -1
  21. package/dist/read-model/forest-schema-client.d.ts +3 -3
  22. package/dist/read-model/forest-schema-client.js +2 -2
  23. package/dist/read-model/read-model-store.d.ts +2 -1
  24. package/dist/read-model/read-model-store.js +3 -3
  25. package/dist/read-model/read-model.d.ts +34 -0
  26. package/dist/read-model/read-model.js +79 -4
  27. package/dist/read-model/schema-cache.d.ts +17 -1
  28. package/dist/read-model/schema-cache.js +19 -6
  29. package/dist/read-model/synthesize-capabilities.d.ts +35 -0
  30. package/dist/read-model/synthesize-capabilities.js +133 -0
  31. package/dist/validation/capabilities-validator.d.ts +6 -4
  32. package/dist/validation/capabilities-validator.js +12 -1
  33. package/dist/validation/operator-normalizer.d.ts +0 -6
  34. package/dist/validation/operator-normalizer.js +6 -14
  35. package/dist/validation/validation-errors.d.ts +1 -0
  36. package/dist/validation/validation-errors.js +7 -1
  37. package/package.json +3 -3
@@ -0,0 +1,133 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LEGACY_LIANAS = exports.LEGACY_LIANA_OPERATORS = void 0;
4
+ exports.default = synthesizeCapabilities;
5
+ const agent_client_1 = require("@forestadmin/agent-client");
6
+ const datasource_toolkit_1 = require("@forestadmin/datasource-toolkit");
7
+ const field_type_1 = require("./field-type");
8
+ /**
9
+ * The operators every supported legacy liana honours, measured against
10
+ * `forest-express-sequelize 9.6.10` and `forest_liana 9.21.0`: the scalar cases of their filter
11
+ * switch plus the date family their separate date parser handles. Names are the legacy snake_case
12
+ * wire format, which is also what a real capabilities response carries.
13
+ *
14
+ * This list exists because a legacy liana publishes a single `isFilterable` boolean per field, never
15
+ * an operator list. Advertising the column type's whole operator set instead would admit operators
16
+ * the liana rejects on its own, which the BFF maps to `422 unprocessable_entity` rather than the
17
+ * `400 invalid_filter_operator` a caller can act on.
18
+ *
19
+ * It is the intersection of the two, not the union: `includes_all` sits in the column type table for
20
+ * every array-capable type, and on a scalar column `forest-express-sequelize` answers it with a 500
21
+ * carrying SQL while `forest_liana` rejects it outright. `i_contains` goes the other way — Rails
22
+ * honours it, Express does not — so it stays out too.
23
+ */
24
+ exports.LEGACY_LIANA_OPERATORS = new Set([
25
+ 'after',
26
+ 'after_x_hours_ago',
27
+ 'before',
28
+ 'before_x_hours_ago',
29
+ 'blank',
30
+ 'contains',
31
+ 'ends_with',
32
+ 'equal',
33
+ 'future',
34
+ 'greater_than',
35
+ 'in',
36
+ 'less_than',
37
+ 'not_contains',
38
+ 'not_equal',
39
+ 'past',
40
+ 'present',
41
+ 'previous_month',
42
+ 'previous_month_to_date',
43
+ 'previous_quarter',
44
+ 'previous_quarter_to_date',
45
+ 'previous_week',
46
+ 'previous_week_to_date',
47
+ 'previous_x_days',
48
+ 'previous_x_days_to_date',
49
+ 'previous_year',
50
+ 'previous_year_to_date',
51
+ 'starts_with',
52
+ 'today',
53
+ 'yesterday',
54
+ ]);
55
+ /**
56
+ * The lianas that never served `/forest/_internal/capabilities`, as the Forest server itself
57
+ * enumerates them. The set is closed in practice — no new one is published — while the v2 agent
58
+ * family grows, so listing the legacy names keeps an unlisted agent on the failing path rather than
59
+ * silently downgrading it to the operator set above.
60
+ */
61
+ exports.LEGACY_LIANAS = new Set([
62
+ 'forest-express-sequelize',
63
+ 'forest-express-mongoose',
64
+ 'forest-rails',
65
+ ]);
66
+ const MANY_TO_ONE = 'ManyToOne';
67
+ /**
68
+ * A `Map` and not the exported object: the type name is read from the apimap, and the table is a
69
+ * frozen object literal, so a field typed `constructor` would resolve to the Object constructor —
70
+ * truthy, and fatal on the `.map` below. A `Map` answers `undefined` for anything not a real key.
71
+ */
72
+ const OPERATORS_BY_COLUMN_TYPE = new Map(Object.entries(datasource_toolkit_1.allowedOperatorsForColumnType));
73
+ /**
74
+ * An array column has no name here on purpose. Unwrapping `['Number']` to `Number` would publish the
75
+ * scalar operator table on it -- `greater_than` on a Postgres array raises in the liana, which the
76
+ * BFF answers as 503 agent_unavailable. The v2 agent publishes no operator for such a column either
77
+ * (`allowedOperatorsForColumnType` is keyed by primitive names only), so the two generations agree.
78
+ */
79
+ function primitiveNameOf(type) {
80
+ const normalized = (0, field_type_1.normalizeFieldType)(type);
81
+ return typeof normalized === 'string' ? normalized : undefined;
82
+ }
83
+ function operatorsFor(field, collection, logger) {
84
+ if (field.isFilterable === false)
85
+ return [];
86
+ const primitive = primitiveNameOf(field.type);
87
+ const allowed = primitive === undefined ? undefined : OPERATORS_BY_COLUMN_TYPE.get(primitive);
88
+ if (!allowed) {
89
+ logger('Warn', 'No operator table for a synthesized column type; field reads as not filterable', {
90
+ collection,
91
+ field: field.field,
92
+ type: JSON.stringify(field.type),
93
+ });
94
+ return [];
95
+ }
96
+ return allowed.map(agent_client_1.toWireOperator).filter(operator => exports.LEGACY_LIANA_OPERATORS.has(operator));
97
+ }
98
+ /**
99
+ * The one, none or zero capability entries a single apimap field becomes: a scalar carries its
100
+ * operators, a to-one relation is present without any (so a direct filter on it is
101
+ * `field_not_filterable`), and every other relation is dropped (so a filter on it is
102
+ * `unknown_field`).
103
+ */
104
+ function toCapabilityFields(field, collection, logger) {
105
+ if (field.relationship) {
106
+ if (field.relationship !== 'BelongsTo')
107
+ return [];
108
+ // A relation carries no operators, but it is still sortable through its target, so a sort the
109
+ // liana denies has to be published as denied here too -- otherwise the BFF accepts the sort
110
+ // and forwards it instead of answering field_not_sortable.
111
+ const relation = { name: field.field, type: MANY_TO_ONE };
112
+ return [field.isSortable === false ? { ...relation, sortable: false } : relation];
113
+ }
114
+ const entry = {
115
+ name: field.field,
116
+ type: field.type,
117
+ operators: operatorsFor(field, collection, logger),
118
+ };
119
+ return [field.isSortable === false ? { ...entry, sortable: false } : entry];
120
+ }
121
+ /**
122
+ * Build the capabilities a v1 liana would have answered, from the apimap it already pushed.
123
+ *
124
+ * The field classes mirror what the v2 agent's capabilities route emits, so the validator produces
125
+ * the same error for the same input on both generations.
126
+ */
127
+ function synthesizeCapabilities(collection, logger) {
128
+ const declared = (collection.fields ?? []).filter((field) => typeof field === 'object' && field !== null && typeof field.field === 'string');
129
+ return {
130
+ fields: declared.flatMap(field => toCapabilityFields(field, collection.name, logger)),
131
+ };
132
+ }
133
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3ludGhlc2l6ZS1jYXBhYmlsaXRpZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcmVhZC1tb2RlbC9zeW50aGVzaXplLWNhcGFiaWxpdGllcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUEwSkEseUNBWUM7QUFoS0QsNERBQTJEO0FBQzNELHdFQUFnRjtBQUVoRiw2Q0FBa0Q7QUFFbEQ7Ozs7Ozs7Ozs7Ozs7OztHQWVHO0FBQ1UsUUFBQSxzQkFBc0IsR0FBd0IsSUFBSSxHQUFHLENBQUM7SUFDakUsT0FBTztJQUNQLG1CQUFtQjtJQUNuQixRQUFRO0lBQ1Isb0JBQW9CO0lBQ3BCLE9BQU87SUFDUCxVQUFVO0lBQ1YsV0FBVztJQUNYLE9BQU87SUFDUCxRQUFRO0lBQ1IsY0FBYztJQUNkLElBQUk7SUFDSixXQUFXO0lBQ1gsY0FBYztJQUNkLFdBQVc7SUFDWCxNQUFNO0lBQ04sU0FBUztJQUNULGdCQUFnQjtJQUNoQix3QkFBd0I7SUFDeEIsa0JBQWtCO0lBQ2xCLDBCQUEwQjtJQUMxQixlQUFlO0lBQ2YsdUJBQXVCO0lBQ3ZCLGlCQUFpQjtJQUNqQix5QkFBeUI7SUFDekIsZUFBZTtJQUNmLHVCQUF1QjtJQUN2QixhQUFhO0lBQ2IsT0FBTztJQUNQLFdBQVc7Q0FDWixDQUFDLENBQUM7QUFFSDs7Ozs7R0FLRztBQUNVLFFBQUEsYUFBYSxHQUF3QixJQUFJLEdBQUcsQ0FBQztJQUN4RCwwQkFBMEI7SUFDMUIseUJBQXlCO0lBQ3pCLGNBQWM7Q0FDZixDQUFDLENBQUM7QUFFSCxNQUFNLFdBQVcsR0FBRyxXQUFXLENBQUM7QUFFaEM7Ozs7R0FJRztBQUNILE1BQU0sd0JBQXdCLEdBQUcsSUFBSSxHQUFHLENBQ3RDLE1BQU0sQ0FBQyxPQUFPLENBQUMsa0RBQTZCLENBQUMsQ0FDOUMsQ0FBQztBQUVGOzs7OztHQUtHO0FBQ0gsU0FBUyxlQUFlLENBQUMsSUFBZTtJQUN0QyxNQUFNLFVBQVUsR0FBRyxJQUFBLCtCQUFr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
@@ -5,13 +5,16 @@ export interface ValidateParams {
5
5
  sortFields?: string[];
6
6
  projectionFields?: string[];
7
7
  }
8
- interface FilterLeaf {
8
+ export interface FilterLeaf {
9
9
  field: string;
10
10
  operator?: string;
11
+ value?: unknown;
11
12
  }
12
- export declare function isBranch(node: unknown): node is {
13
+ export interface FilterBranch {
14
+ aggregator?: string;
13
15
  conditions: unknown[];
14
- };
16
+ }
17
+ export declare function isBranch(node: unknown): node is FilterBranch;
15
18
  export declare function isLeaf(node: unknown): node is FilterLeaf;
16
19
  export declare const MAX_FILTER_DEPTH = 100;
17
20
  /**
@@ -27,5 +30,4 @@ export declare function hasCapabilityConstrainedInput(params: ValidateParams): b
27
30
  */
28
31
  export declare function validateAgainstCapabilities(params: ValidateParams, capabilities: CapabilitiesResult): BffHttpError[];
29
32
  export declare function assertValidAgainstCapabilities(params: ValidateParams, capabilities: CapabilitiesResult): void;
30
- export {};
31
33
  //# sourceMappingURL=capabilities-validator.d.ts.map
@@ -69,6 +69,16 @@ function validateFilter(filter, index) {
69
69
  function validateExistence(fields, index) {
70
70
  return fields.filter(field => !index.has(field)).map(validation_errors_1.unknownField);
71
71
  }
72
+ /**
73
+ * Only the v1 synthesis states sortability, from the apimap's `isSortable`; a real capabilities
74
+ * response says nothing about it, so an absent flag means "not stated" and skips the check. Without
75
+ * this, a sort on a legacy computed field reaches the liana and raises a database error naming the
76
+ * missing column.
77
+ */
78
+ function validateSortable(fields, capabilities) {
79
+ const notSortable = new Set(capabilities.fields.filter(field => field.sortable === false).map(field => field.name));
80
+ return fields.filter(field => notSortable.has(field)).map(validation_errors_1.fieldNotSortable);
81
+ }
72
82
  function dedupe(errors) {
73
83
  const seen = new Set();
74
84
  const result = [];
@@ -101,6 +111,7 @@ function validateAgainstCapabilities(params, capabilities) {
101
111
  return dedupe([
102
112
  ...validateFilter(params.filter, index),
103
113
  ...validateExistence(params.sortFields ?? [], index),
114
+ ...validateSortable(params.sortFields ?? [], capabilities),
104
115
  ...validateExistence(params.projectionFields ?? [], index),
105
116
  ]);
106
117
  }
@@ -109,4 +120,4 @@ function assertValidAgainstCapabilities(params, capabilities) {
109
120
  if (first)
110
121
  throw first;
111
122
  }
112
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FwYWJpbGl0aWVzLXZhbGlkYXRvci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy92YWxpZGF0aW9uL2NhcGFiaWxpdGllcy12YWxpZGF0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBdUJBLDRCQU1DO0FBRUQsd0JBTUM7QUFxRkQsc0VBTUM7QUFRRCxrRUFXQztBQUVELHdFQU9DO0FBekpELCtEQUEwRDtBQUMxRCwyREFLNkI7QUFDN0IsK0RBQXdEO0FBYXhELFNBQWdCLFFBQVEsQ0FBQyxJQUFhO0lBQ3BDLE9BQU8sQ0FDTCxPQUFPLElBQUksS0FBSyxRQUFRO1FBQ3hCLElBQUksS0FBSyxJQUFJO1FBQ2IsS0FBSyxDQUFDLE9BQU8sQ0FBRSxJQUFpQyxDQUFDLFVBQVUsQ0FBQyxDQUM3RCxDQUFDO0FBQ0osQ0FBQztBQUVELFNBQWdCLE1BQU0sQ0FBQyxJQUFhO0lBQ2xDLE9BQU8sQ0FDTCxPQUFPLElBQUksS0FBSyxRQUFRO1FBQ3hCLElBQUksS0FBSyxJQUFJO1FBQ2IsT0FBUSxJQUE0QixDQUFDLEtBQUssS0FBSyxRQUFRLENBQ3hELENBQUM7QUFDSixDQUFDO0FBRVksUUFBQSxnQkFBZ0IsR0FBRyxHQUFHLENBQUM7QUFFcEMsU0FBUyxhQUFhLENBQUMsSUFBYSxFQUFFLEdBQWlCLEVBQUUsS0FBSyxHQUFHLENBQUM7SUFDaEUsSUFBSSxLQUFLLEdBQUcsd0JBQWdCO1FBQUUsTUFBTSxJQUFBLGlDQUFhLEVBQUMsd0JBQWdCLENBQUMsQ0FBQztJQUVwRSxJQUFJLFFBQVEsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO1FBQ25CLElBQUksQ0FBQyxVQUFVLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUMsYUFBYSxDQUFDLFNBQVMsRUFBRSxHQUFHLEVBQUUsS0FBSyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDakYsQ0FBQztTQUFNLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxFQUFF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
123
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FwYWJpbGl0aWVzLXZhbGlkYXRvci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy92YWxpZGF0aW9uL2NhcGFiaWxpdGllcy12YWxpZGF0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBOEJBLDRCQU1DO0FBRUQsd0JBTUM7QUFtR0Qsc0VBTUM7QUFRRCxrRUFZQztBQUVELHdFQU9DO0FBL0tELCtEQUEwRDtBQUMxRCwyREFNNkI7QUFDN0IsK0RBQXdEO0FBbUJ4RCxTQUFnQixRQUFRLENBQUMsSUFBYTtJQUNwQyxPQUFPLENBQ0wsT0FBTyxJQUFJLEtBQUssUUFBUTtRQUN4QixJQUFJLEtBQUssSUFBSTtRQUNiLEtBQUssQ0FBQyxPQUFPLENBQUUsSUFBaUMsQ0FBQyxVQUFVLENBQUMsQ0FDN0QsQ0FBQztBQUNKLENBQUM7QUFFRCxTQUFnQixNQUFNLENBQUMsSUFBYTtJQUNsQyxPQUFPLENBQ0wsT0FBTyxJQUFJLEtBQUssUUFBUTtRQUN4QixJQUFJLEtBQUssSUFBSTtRQUNiLE9BQVEsSUFBNEIsQ0FBQyxLQUFLLEtBQUssUUFBUSxDQUN4RCxDQUFDO0FBQ0osQ0FBQztBQUVZLFFBQUEsZ0JBQWdCLEdBQUcsR0FBRyxDQUFDO0FBRXBDLFNBQVMsYUFBYSxDQUFDLElBQWEsRUFBRSxHQUFpQixFQUFFLEtBQUssR0FBRyxDQUFDO0lBQ2hFLElBQUksS0FBSyxHQUFHLHdCQUFnQjtRQUFFLE1BQU0sSUFBQSxpQ0FBYSxFQUFDLHdCQUFnQixDQUFDLENBQUM7SUFFcEUsSUFBSSxRQUFRLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztRQUNuQixJQUFJLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDLGFBQWEsQ0FBQyxTQUFTLEVBQUUsR0FBRyxFQUFFLEtBQUssR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ2pGLENBQUM7U0FBTSxJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsRUFB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
@@ -1,10 +1,4 @@
1
1
  import type { Operator } from '@forestadmin/datasource-toolkit';
2
- /**
3
- * Mirrors the agent's capabilities serialization (`packages/agent/src/routes/capabilities.ts`),
4
- * which converts each PascalCase operator to snake_case before returning it. Kept identical so the
5
- * inverse map below round-trips every operator the agent can emit.
6
- */
7
- export declare function toSnakeCaseOperator(operator: string): string;
8
2
  /**
9
3
  * Maps an agent snake_case capabilities operator to the canonical PascalCase operator from
10
4
  * datasource-toolkit `allOperators`. Returns undefined when no canonical operator matches, which
@@ -1,21 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.toSnakeCaseOperator = toSnakeCaseOperator;
4
3
  exports.normalizeOperator = normalizeOperator;
5
4
  exports.toCanonicalOperatorSet = toCanonicalOperatorSet;
5
+ const agent_client_1 = require("@forestadmin/agent-client");
6
6
  const datasource_toolkit_1 = require("@forestadmin/datasource-toolkit");
7
- /**
8
- * Mirrors the agent's capabilities serialization (`packages/agent/src/routes/capabilities.ts`),
9
- * which converts each PascalCase operator to snake_case before returning it. Kept identical so the
10
- * inverse map below round-trips every operator the agent can emit.
11
- */
12
- function toSnakeCaseOperator(operator) {
13
- return operator
14
- .split(/\.?(?=[A-Z])/)
15
- .join('_')
16
- .toLowerCase();
17
- }
18
- const SNAKE_TO_PASCAL = new Map(datasource_toolkit_1.allOperators.map(operator => [toSnakeCaseOperator(operator), operator]));
7
+ // `toWireOperator` is the one PascalCase -> snake_case mapping in the monorepo, and it is the same
8
+ // spelling the agent's capabilities route emits, so the inverse map round-trips every operator the
9
+ // agent can announce.
10
+ const SNAKE_TO_PASCAL = new Map(datasource_toolkit_1.allOperators.map(operator => [(0, agent_client_1.toWireOperator)(operator), operator]));
19
11
  /**
20
12
  * Maps an agent snake_case capabilities operator to the canonical PascalCase operator from
21
13
  * datasource-toolkit `allOperators`. Returns undefined when no canonical operator matches, which
@@ -33,4 +25,4 @@ const CANONICAL_ORDER = new Map(datasource_toolkit_1.allOperators.map((operator,
33
25
  function toCanonicalOperatorSet(operators) {
34
26
  return [...new Set(operators)].sort((left, right) => CANONICAL_ORDER.get(left) - CANONICAL_ORDER.get(right));
35
27
  }
36
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3BlcmF0b3Itbm9ybWFsaXplci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy92YWxpZGF0aW9uL29wZXJhdG9yLW5vcm1hbGl6ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFTQSxrREFLQztBQVdELDhDQUVDO0FBV0Qsd0RBSUM7QUF4Q0Qsd0VBQStEO0FBRS9EOzs7O0dBSUc7QUFDSCxTQUFnQixtQkFBbUIsQ0FBQyxRQUFnQjtJQUNsRCxPQUFPLFFBQVE7U0FDWixLQUFLLENBQUMsY0FBYyxDQUFDO1NBQ3JCLElBQUksQ0FBQyxHQUFHLENBQUM7U0FDVCxXQUFXLEVBQUUsQ0FBQztBQUNuQixDQUFDO0FBRUQsTUFBTSxlQUFlLEdBQUcsSUFBSSxHQUFHLENBQzdCLGlDQUFZLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsQ0FBQyxtQkFBbUIsQ0FBQyxRQUFRLENBQUMsRUFBRSxRQUFRLENBQUMsQ0FBQyxDQUN4RSxDQUFDO0FBRUY7Ozs7R0FJRztBQUNILFNBQWdCLGlCQUFpQixDQUFDLGlCQUF5QjtJQUN6RCxPQUFPLGVBQWUsQ0FBQyxHQUFHLENBQUMsaUJBQWlCLENBQUMsQ0FBQztBQUNoRCxDQUFDO0FBRUQsTUFBTSxlQUFlLEdBQUcsSUFBSSxHQUFHLENBQzdCLGlDQUFZLENBQUMsR0FBRyxDQUFDLENBQUMsUUFBUSxFQUFFLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQyxRQUFRLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FDekQsQ0FBQztBQUVGOzs7O0dBSUc7QUFDSCxTQUFnQixzQkFBc0IsQ0FBQyxTQUFxQjtJQUMxRCxPQUFPLENBQUMsR0FBRyxJQUFJLEdBQUcsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FDakMsQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLEVBQUUsQ0FBRSxlQUFlLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBWSxHQUFJLGVBQWUsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFZLENBQ2hHLENBQUM7QUFDSixDQUFDIn0=
28
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3BlcmF0b3Itbm9ybWFsaXplci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy92YWxpZGF0aW9uL29wZXJhdG9yLW5vcm1hbGl6ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFpQkEsOENBRUM7QUFXRCx3REFJQztBQWhDRCw0REFBMkQ7QUFDM0Qsd0VBQStEO0FBRS9ELG1HQUFtRztBQUNuRyxtR0FBbUc7QUFDbkcsc0JBQXNCO0FBQ3RCLE1BQU0sZUFBZSxHQUFHLElBQUksR0FBRyxDQUM3QixpQ0FBWSxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLENBQUMsSUFBQSw2QkFBYyxFQUFDLFFBQVEsQ0FBQyxFQUFFLFFBQVEsQ0FBQyxDQUFDLENBQ25FLENBQUM7QUFFRjs7OztHQUlHO0FBQ0gsU0FBZ0IsaUJBQWlCLENBQUMsaUJBQXlCO0lBQ3pELE9BQU8sZUFBZSxDQUFDLEdBQUcsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO0FBQ2hELENBQUM7QUFFRCxNQUFNLGVBQWUsR0FBRyxJQUFJLEdBQUcsQ0FDN0IsaUNBQVksQ0FBQyxHQUFHLENBQUMsQ0FBQyxRQUFRLEVBQUUsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDLFFBQVEsRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUN6RCxDQUFDO0FBRUY7Ozs7R0FJRztBQUNILFNBQWdCLHNCQUFzQixDQUFDLFNBQXFCO0lBQzFELE9BQU8sQ0FBQyxHQUFHLElBQUksR0FBRyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUNqQyxDQUFDLElBQUksRUFBRSxLQUFLLEVBQUUsRUFBRSxDQUFFLGVBQWUsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFZLEdBQUksZUFBZSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQVksQ0FDaEcsQ0FBQztBQUNKLENBQUMifQ==
@@ -1,6 +1,7 @@
1
1
  import { BffHttpError } from '../http/bff-http-error';
2
2
  export declare function unknownField(field: string): BffHttpError;
3
3
  export declare function fieldNotFilterable(field: string): BffHttpError;
4
+ export declare function fieldNotSortable(field: string): BffHttpError;
4
5
  export declare function filterTooDeep(maxDepth: number): BffHttpError;
5
6
  export declare function invalidFilterOperator(field: string, validOperators: string[]): BffHttpError;
6
7
  export declare function missingRequiredActionFields(fields: string[]): BffHttpError;
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.unknownField = unknownField;
4
4
  exports.fieldNotFilterable = fieldNotFilterable;
5
+ exports.fieldNotSortable = fieldNotSortable;
5
6
  exports.filterTooDeep = filterTooDeep;
6
7
  exports.invalidFilterOperator = invalidFilterOperator;
7
8
  exports.missingRequiredActionFields = missingRequiredActionFields;
@@ -17,6 +18,11 @@ function fieldNotFilterable(field) {
17
18
  details: { field },
18
19
  });
19
20
  }
21
+ function fieldNotSortable(field) {
22
+ return new bff_http_error_1.BffHttpError(422, 'field_not_sortable', `Field is not sortable: ${field}`, {
23
+ details: { field },
24
+ });
25
+ }
20
26
  function filterTooDeep(maxDepth) {
21
27
  return new bff_http_error_1.BffHttpError(400, 'filter_too_deep', `Filter nesting exceeds the maximum depth of ${maxDepth}`, { details: { maxDepth } });
22
28
  }
@@ -34,4 +40,4 @@ function invalidActionValue(violations) {
34
40
  details: { fields: violations },
35
41
  });
36
42
  }
37
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFsaWRhdGlvbi1lcnJvcnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdmFsaWRhdGlvbi92YWxpZGF0aW9uLWVycm9ycy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUVBLG9DQUlDO0FBRUQsZ0RBSUM7QUFFRCxzQ0FPQztBQUVELHNEQU9DO0FBRUQsa0VBT0M7QUFPRCxnREFRQztBQXRERCwyREFBc0Q7QUFFdEQsU0FBZ0IsWUFBWSxDQUFDLEtBQWE7SUFDeEMsT0FBTyxJQUFJLDZCQUFZLENBQUMsR0FBRyxFQUFFLGVBQWUsRUFBRSxrQkFBa0IsS0FBSyxFQUFFLEVBQUU7UUFDdkUsT0FBTyxFQUFFLEVBQUUsS0FBSyxFQUFFO0tBQ25CLENBQUMsQ0FBQztBQUNMLENBQUM7QUFFRCxTQUFnQixrQkFBa0IsQ0FBQyxLQUFhO0lBQzlDLE9BQU8sSUFBSSw2QkFBWSxDQUFDLEdBQUcsRUFBRSxzQkFBc0IsRUFBRSw0QkFBNEIsS0FBSyxFQUFFLEVBQUU7UUFDeEYsT0FBTyxFQUFFLEVBQUUsS0FBSyxFQUFFO0tBQ25CLENBQUMsQ0FBQztBQUNMLENBQUM7QUFFRCxTQUFnQixhQUFhLENBQUMsUUFBZ0I7SUFDNUMsT0FBTyxJQUFJLDZCQUFZLENBQ3JCLEdBQUcsRUFDSCxpQkFBaUIsRUFDakIsK0NBQStDLFFBQVEsRUFBRSxFQUN6RCxFQUFFLE9BQU8sRUFBRSxFQUFFLFFBQVEsRUFBRSxFQUFFLENBQzFCLENBQUM7QUFDSixDQUFDO0FBRUQsU0FBZ0IscUJBQXFCLENBQUMsS0FBYSxFQUFFLGNBQXdCO0lBQzNFLE9BQU8sSUFBSSw2QkFBWSxDQUNyQixHQUFHLEVBQ0gseUJBQXlCLEVBQ3pCLG1DQUFtQyxLQUFLLEVBQUUsRUFDMUMsRUFBRSxPQUFPLEVBQUUsRUFBRSxLQUFLLEVBQUUsY0FBYyxFQUFFLEVBQUUsQ0FDdkMsQ0FBQztBQUNKLENBQUM7QUFFRCxTQUFnQiwyQkFBMkIsQ0FBQyxNQUFnQjtJQUMxRCxPQUFPLElBQUksNkJBQVksQ0FDckIsR0FBRyxFQUNILHlCQUF5QixFQUN6Qix1Q0FBdUMsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxFQUMxRCxFQUFFLE9BQU8sRUFBRSxFQUFFLE1BQU0sRUFBRSxFQUFFLENBQ3hCLENBQUM7QUFDSixDQUFDO0FBT0QsU0FBZ0Isa0JBQWtCLENBQUMsVUFBa0M7SUFDbkUsTUFBTSxPQUFPLEdBQUcsVUFBVTtTQUN2QixHQUFHLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQyxHQUFHLFNBQVMsQ0FBQyxLQUFLLGNBQWMsU0FBUyxDQUFDLFFBQVEsR0FBRyxDQUFDO1NBQ3ZFLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUVkLE9BQU8sSUFBSSw2QkFBWSxDQUFDLEdBQUcsRUFBRSxzQkFBc0IsRUFBRSxnQ0FBZ0MsT0FBTyxFQUFFLEVBQUU7UUFDOUYsT0FBTyxFQUFFLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBRTtLQUNoQyxDQUFDLENBQUM7QUFDTCxDQUFDIn0=
43
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFsaWRhdGlvbi1lcnJvcnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdmFsaWRhdGlvbi92YWxpZGF0aW9uLWVycm9ycy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUVBLG9DQUlDO0FBRUQsZ0RBSUM7QUFFRCw0Q0FJQztBQUVELHNDQU9DO0FBRUQsc0RBT0M7QUFFRCxrRUFPQztBQU9ELGdEQVFDO0FBNURELDJEQUFzRDtBQUV0RCxTQUFnQixZQUFZLENBQUMsS0FBYTtJQUN4QyxPQUFPLElBQUksNkJBQVksQ0FBQyxHQUFHLEVBQUUsZUFBZSxFQUFFLGtCQUFrQixLQUFLLEVBQUUsRUFBRTtRQUN2RSxPQUFPLEVBQUUsRUFBRSxLQUFLLEVBQUU7S0FDbkIsQ0FBQyxDQUFDO0FBQ0wsQ0FBQztBQUVELFNBQWdCLGtCQUFrQixDQUFDLEtBQWE7SUFDOUMsT0FBTyxJQUFJLDZCQUFZLENBQUMsR0FBRyxFQUFFLHNCQUFzQixFQUFFLDRCQUE0QixLQUFLLEVBQUUsRUFBRTtRQUN4RixPQUFPLEVBQUUsRUFBRSxLQUFLLEVBQUU7S0FDbkIsQ0FBQyxDQUFDO0FBQ0wsQ0FBQztBQUVELFNBQWdCLGdCQUFnQixDQUFDLEtBQWE7SUFDNUMsT0FBTyxJQUFJLDZCQUFZLENBQUMsR0FBRyxFQUFFLG9CQUFvQixFQUFFLDBCQUEwQixLQUFLLEVBQUUsRUFBRTtRQUNwRixPQUFPLEVBQUUsRUFBRSxLQUFLLEVBQUU7S0FDbkIsQ0FBQyxDQUFDO0FBQ0wsQ0FBQztBQUVELFNBQWdCLGFBQWEsQ0FBQyxRQUFnQjtJQUM1QyxPQUFPLElBQUksNkJBQVksQ0FDckIsR0FBRyxFQUNILGlCQUFpQixFQUNqQiwrQ0FBK0MsUUFBUSxFQUFFLEVBQ3pELEVBQUUsT0FBTyxFQUFFLEVBQUUsUUFBUSxFQUFFLEVBQUUsQ0FDMUIsQ0FBQztBQUNKLENBQUM7QUFFRCxTQUFnQixxQkFBcUIsQ0FBQyxLQUFhLEVBQUUsY0FBd0I7SUFDM0UsT0FBTyxJQUFJLDZCQUFZLENBQ3JCLEdBQUcsRUFDSCx5QkFBeUIsRUFDekIsbUNBQW1DLEtBQUssRUFBRSxFQUMxQyxFQUFFLE9BQU8sRUFBRSxFQUFFLEtBQUssRUFBRSxjQUFjLEVBQUUsRUFBRSxDQUN2QyxDQUFDO0FBQ0osQ0FBQztBQUVELFNBQWdCLDJCQUEyQixDQUFDLE1BQWdCO0lBQzFELE9BQU8sSUFBSSw2QkFBWSxDQUNyQixHQUFHLEVBQ0gseUJBQXlCLEVBQ3pCLHVDQUF1QyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLEVBQzFELEVBQUUsT0FBTyxFQUFFLEVBQUUsTUFBTSxFQUFFLEVBQUUsQ0FDeEIsQ0FBQztBQUNKLENBQUM7QUFPRCxTQUFnQixrQkFBa0IsQ0FBQyxVQUFrQztJQUNuRSxNQUFNLE9BQU8sR0FBRyxVQUFVO1NBQ3ZCLEdBQUcsQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDLEdBQUcsU0FBUyxDQUFDLEtBQUssY0FBYyxTQUFTLENBQUMsUUFBUSxHQUFHLENBQUM7U0FDdkUsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBRWQsT0FBTyxJQUFJLDZCQUFZLENBQUMsR0FBRyxFQUFFLHNCQUFzQixFQUFFLGdDQUFnQyxPQUFPLEVBQUUsRUFBRTtRQUM5RixPQUFPLEVBQUUsRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFO0tBQ2hDLENBQUMsQ0FBQztBQUNMLENBQUMifQ==
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@forestadmin/agent-bff",
3
- "version": "1.30.0",
3
+ "version": "1.30.2",
4
4
  "main": "dist/index.js",
5
5
  "bin": {
6
6
  "forest-bff": "dist/cli.js"
@@ -33,9 +33,9 @@
33
33
  },
34
34
  "dependencies": {
35
35
  "@asteasolutions/zod-to-openapi": "8.5.0",
36
- "@forestadmin/agent-client": "1.15.2",
36
+ "@forestadmin/agent-client": "1.16.0",
37
37
  "@forestadmin/datasource-toolkit": "1.55.1",
38
- "@forestadmin/forestadmin-client": "1.43.3",
38
+ "@forestadmin/forestadmin-client": "1.43.4",
39
39
  "@koa/bodyparser": "^6.1.0",
40
40
  "inflected": "^1.1.6",
41
41
  "jsonwebtoken": "^9.0.3",