@forestadmin/agent-bff 1.29.0 → 1.30.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.
Files changed (41) hide show
  1. package/README.md +115 -8
  2. package/dist/action/action-routes-middleware.js +8 -1
  3. package/dist/build-bff.js +3 -1
  4. package/dist/context/build-context.d.ts +1 -0
  5. package/dist/context/build-context.js +18 -4
  6. package/dist/data/agent-query.js +23 -3
  7. package/dist/data/data-routes-middleware.js +7 -2
  8. package/dist/data/pack-id.d.ts +6 -1
  9. package/dist/data/pack-id.js +96 -3
  10. package/dist/data/response-mappers.js +2 -2
  11. package/dist/http/access-log-middleware.d.ts +26 -0
  12. package/dist/http/access-log-middleware.js +68 -0
  13. package/dist/http/agent-error-mapper.js +42 -27
  14. package/dist/openapi/collect-unfolding.js +23 -9
  15. package/dist/openapi/schemas.d.ts +1 -0
  16. package/dist/openapi/schemas.js +22 -3
  17. package/dist/openapi/unfolded-document.js +7 -2
  18. package/dist/openapi/unfolded-paths.js +96 -16
  19. package/dist/openapi/unfolding.d.ts +12 -0
  20. package/dist/openapi/unfolding.js +1 -1
  21. package/dist/read-model/agent-capabilities-fetcher.d.ts +6 -1
  22. package/dist/read-model/agent-capabilities-fetcher.js +88 -6
  23. package/dist/read-model/capabilities-cache.d.ts +1 -0
  24. package/dist/read-model/capabilities-cache.js +1 -1
  25. package/dist/read-model/forest-schema-client.d.ts +3 -3
  26. package/dist/read-model/forest-schema-client.js +2 -2
  27. package/dist/read-model/read-model-store.d.ts +2 -1
  28. package/dist/read-model/read-model-store.js +3 -3
  29. package/dist/read-model/read-model.d.ts +34 -0
  30. package/dist/read-model/read-model.js +79 -4
  31. package/dist/read-model/schema-cache.d.ts +17 -1
  32. package/dist/read-model/schema-cache.js +19 -6
  33. package/dist/read-model/synthesize-capabilities.d.ts +35 -0
  34. package/dist/read-model/synthesize-capabilities.js +133 -0
  35. package/dist/validation/capabilities-validator.d.ts +6 -4
  36. package/dist/validation/capabilities-validator.js +12 -1
  37. package/dist/validation/operator-normalizer.d.ts +0 -6
  38. package/dist/validation/operator-normalizer.js +6 -14
  39. package/dist/validation/validation-errors.d.ts +1 -0
  40. package/dist/validation/validation-errors.js +7 -1
  41. package/package.json +3 -3
@@ -66,6 +66,24 @@ function fieldsEnum(pool, name, fields, description) {
66
66
  return { type: 'string' };
67
67
  return pool.add(name, { type: 'string', enum: fields, description });
68
68
  }
69
+ /**
70
+ * Whether the document knows which fields the collection exposes. Only `capabilities_unavailable`
71
+ * leaves it unknown — the agent could not be asked. `no_fields` is an ANSWER: capabilities were read
72
+ * and name none, so every field is rejected, and `null` carries the enumerated set. The difference
73
+ * decides whether an empty set means "do not constrain" or "nothing is valid here".
74
+ */
75
+ function isFieldSetKnown(fields) {
76
+ return fields.degraded !== 'capabilities_unavailable';
77
+ }
78
+ /**
79
+ * Whether an empty `filterable` is an answer. It is not enough that the field set is known: the
80
+ * collector also empties `filterable` by dropping every field whose operator set it cannot map, and
81
+ * that collection filters fine at runtime. Documenting it as filterable by nothing would refuse, at
82
+ * compile time in a generated client, a filter the agent honours.
83
+ */
84
+ function isFilterSetKnown(fields) {
85
+ return isFieldSetKnown(fields) && !fields.undocumentableFilter;
86
+ }
69
87
  /**
70
88
  * Groups the filterable fields by the operator set they share. One leaf per field would be as exact
71
89
  * but would multiply the document by the field count; the number of distinct operator sets is bounded
@@ -113,9 +131,15 @@ function leafShape(field, operators, description) {
113
131
  function filterLeaves(pool, plan) {
114
132
  const { name, fields } = plan.collection;
115
133
  const groups = groupByOperators(fields.filterable);
116
- // No known filterable field: the field stays free-form and every operator stays allowed, because a
117
- // collection whose capabilities could not be read still accepts whatever it really exposes.
134
+ // No filterable field, and the two reasons are not the same document. Capabilities that could not
135
+ // be read leave the field set UNKNOWN, so the leaf stays free-form: the collection still accepts
136
+ // whatever it really exposes, and the runtime is the one that rejects. Capabilities that were read
137
+ // and name nothing filterable leave no valid leaf at all — advertising a free-form one would offer
138
+ // a filter the validator answers 422 on for every field, so the tree keeps only its branch and
139
+ // empty-object alternatives.
118
140
  if (groups.length === 0) {
141
+ if (isFilterSetKnown(fields))
142
+ return [];
119
143
  return [
120
144
  pool.add(`FilterLeaf_${plan.key}`, leafShape({ type: 'string' }, schemas_1.OPERATORS, `A single condition on ${(0, names_1.quoted)(name)}.`)),
121
145
  ];
@@ -135,11 +159,18 @@ function filterSchema({ pool }, plan) {
135
159
  const treeName = `Filter_${plan.key}`;
136
160
  const treeRef = { $ref: `#/components/schemas/${treeName}` };
137
161
  const leaves = filterLeaves(pool, plan);
138
- const pairing = fields.filterable.length > 0
139
- ? ' There is one leaf alternative per operator set: a field accepts only the operators of ' +
140
- 'the alternative listing it, and an operator it does not support answers 400 ' +
141
- 'invalid_filter_operator.'
142
- : '';
162
+ const pairing = (() => {
163
+ if (fields.filterable.length > 0) {
164
+ return (' There is one leaf alternative per operator set: a field accepts only the operators of ' +
165
+ 'the alternative listing it, and an operator it does not support answers 400 ' +
166
+ 'invalid_filter_operator.');
167
+ }
168
+ if (isFilterSetKnown(fields)) {
169
+ return (' No field of this collection is filterable, so there is no leaf alternative at all: ' +
170
+ 'send the empty object, or no filter.');
171
+ }
172
+ return '';
173
+ })();
143
174
  return pool.add(treeName, {
144
175
  description: `A filter on ${(0, names_1.quoted)(name)}: either a leaf condition, a branch nesting more ` +
145
176
  'conditions, or the empty object, which is how an absent filter is spelled. A branch must ' +
@@ -164,6 +195,16 @@ function fieldRefs(deps, plan) {
164
195
  const { pool } = deps;
165
196
  const { name, fields } = plan.collection;
166
197
  const projectable = fieldsEnum(pool, `Fields_${plan.key}`, fields.projectable.map(field => field.name), `A field of ${(0, names_1.quoted)(name)}.`);
198
+ // Sortable is a subset of projectable too, but only the v1 synthesis ever narrows it: a field the
199
+ // apimap marks not sortable is projectable and filterable while a sort on it answers 422
200
+ // field_not_sortable. The enum is shared with projectable when nothing is denied, which is every
201
+ // v2 collection, so the common document gains no component.
202
+ const sortableNames = fields.projectable
203
+ .filter(field => field.sortable !== false)
204
+ .map(field => field.name);
205
+ const sortableField = sortableNames.length === fields.projectable.length
206
+ ? projectable
207
+ : fieldsEnum(pool, `SortableFields_${plan.key}`, sortableNames, `A sortable field of ${(0, names_1.quoted)(name)}.`);
167
208
  // Filterable is a strict subset of projectable: the agent reports a ManyToOne without operators, so
168
209
  // projecting or sorting on it works while filtering on it answers 422 field_not_filterable. Which is
169
210
  // why the filterable fields are not enumerated here but inside the filter leaves, where each one
@@ -171,13 +212,18 @@ function fieldRefs(deps, plan) {
171
212
  return {
172
213
  projectable,
173
214
  filter: filterSchema(deps, plan),
174
- sort: fields.projectable.length === 0
215
+ // Same split as the filter leaves: an UNKNOWN field set leaves sort unconstrained, because the
216
+ // runtime is the one that rejects. A known set with nothing sortable — every field denied, or
217
+ // capabilities naming no field at all — is a collection that takes no clause.
218
+ anySortable: sortableNames.length > 0 || !isFieldSetKnown(fields),
219
+ anyProjectable: fields.projectable.length > 0 || !isFieldSetKnown(fields),
220
+ sort: sortableNames.length === 0
175
221
  ? pool.reuse('SortClause', schemas_1.SortClauseSchema)
176
222
  : pool.add(`SortClause_${plan.key}`, {
177
223
  type: 'object',
178
224
  description: 'Omitting `direction` sorts ascending.',
179
225
  properties: {
180
- field: projectable,
226
+ field: sortableField,
181
227
  direction: { type: 'string', enum: ['asc', 'desc'] },
182
228
  },
183
229
  required: ['field'],
@@ -200,8 +246,30 @@ function requestProperties(deps, plan) {
200
246
  count,
201
247
  list: {
202
248
  filter: refs.filter,
203
- projection: { type: 'array', items: refs.projectable },
204
- sort: { type: 'array', items: refs.sort },
249
+ // Same cap as sort, on the same split: capabilities that were READ and name no field leave
250
+ // nothing to project, and `fieldsEnum` falls back to an unrestricted string for an empty
251
+ // list, which would advertise every field while each request answers 422 unknown_field. An
252
+ // UNKNOWN field set stays uncapped — the collection still projects whatever it exposes.
253
+ projection: refs.anyProjectable
254
+ ? { type: 'array', items: refs.projectable }
255
+ : {
256
+ type: 'array',
257
+ items: refs.projectable,
258
+ maxItems: 0,
259
+ description: 'This collection exposes no field: send an empty array, or omit it.',
260
+ },
261
+ // A collection whose every known field is denied sorting takes no clause at all: the shared
262
+ // SortClause leaves `field` an unrestricted string, which would advertise every field as
263
+ // sortable while each request answers 422 field_not_sortable. `maxItems: 0` says what the
264
+ // runtime does — an empty sort passes, any clause does not.
265
+ sort: refs.anySortable
266
+ ? { type: 'array', items: refs.sort }
267
+ : {
268
+ type: 'array',
269
+ items: refs.sort,
270
+ maxItems: 0,
271
+ description: 'No field of this collection is sortable: send an empty array, or omit it.',
272
+ },
205
273
  page: pool.reuse('Page', schemas_1.PageSchema),
206
274
  search,
207
275
  searchExtended,
@@ -259,15 +327,27 @@ function parentIdSchema(pool, parent, primaryKeys) {
259
327
  // A composite id only works as its packed string: a number could never carry the separator.
260
328
  type: 'string',
261
329
  pattern: request_schemas_1.NON_BLANK_PATTERN,
262
- description: `The composite id of the parent ${(0, names_1.quoted)(parent)} record: the values of ` +
263
- `${primaryKeys.map(key => key.name).join(', ')} joined by ` +
264
- `${(0, names_1.quoted)(pack_id_1.PACKED_ID_SEPARATOR)}, in that order.`,
330
+ // The order the keys are published in is not the order the agent packs them in, so naming one
331
+ // would send a client to build an id the agent unpacks onto the wrong columns.
332
+ description: `The composite id of the parent ${(0, names_1.quoted)(parent)} record, taken verbatim from that ` +
333
+ `record's own id: the values of ${primaryKeys.map(key => key.name).join(', ')} joined by ` +
334
+ `${(0, names_1.quoted)(pack_id_1.PACKED_ID_SEPARATOR)}, in the order the agent packs them. Copy it from a listed ` +
335
+ `record rather than assembling it.`,
265
336
  };
266
337
  }
267
338
  const [key] = primaryKeys;
339
+ // A DERIVED key names no verified column: the schema published no key, so the read-model guessed
340
+ // one from an `id` field, or invented the name outright. Stating `(id, String)` the way a declared
341
+ // key is stated would contradict `ForestRecordMeta`, which warns in the same document that this
342
+ // `id` may not be a column at all. The shape is unaffected — the wire takes the id opaque either
343
+ // way — so only the description hedges.
344
+ const column = key.derived
345
+ ? 'its primary key is not published by the schema, so this is the opaque agent id, which is ' +
346
+ `NOT necessarily the value of a column named ${(0, names_1.quoted)(key.name)}`
347
+ : `${key.name}, ${key.type}`;
268
348
  return {
269
349
  ...PARENT_ID_SHAPE,
270
- description: `The parent ${(0, names_1.quoted)(parent)} record id (${key.name}, ${key.type}). A number or its ` +
350
+ description: `The parent ${(0, names_1.quoted)(parent)} record id (${column}). A number or its ` +
271
351
  'string form are both accepted; the BFF forwards it to the agent as a string.',
272
352
  };
273
353
  }
@@ -492,4 +572,4 @@ function registerUnfoldedPaths(deps, unfolding) {
492
572
  registerActionOperations(deps, plan, actions);
493
573
  });
494
574
  }
495
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidW5mb2xkZWQtcGF0aHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvb3BlbmFwaS91bmZvbGRlZC1wYXRocy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQWtwQkEsd0NBNkJDO0FBaHFCRCxvRUFBNEM7QUFDNUMsaURBQThDO0FBQzlDLG1FQUFvRTtBQUNwRSx1Q0FjbUI7QUFDbkIsNkNBQXNEO0FBQ3RELDZEQUE0RDtBQUM1RCx5REFBeUQ7QUFFekQsTUFBTSxXQUFXLEdBQUcsQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLENBQUM7QUFFbEMsTUFBTSxhQUFhLEdBQThEO0lBQy9FLHdCQUF3QixFQUN0QixpRkFBaUY7UUFDakYseUZBQXlGO1FBQ3pGLDRCQUE0QjtJQUM5QixTQUFTLEVBQ1AsMEZBQTBGO1FBQzFGLDRGQUE0RjtRQUM1RixnRUFBZ0U7Q0FDbkUsQ0FBQztBQWdDRixpR0FBaUc7QUFDakcsbUdBQW1HO0FBQ25HLDZDQUE2QztBQUM3QyxTQUFTLE9BQU8sQ0FBQyxJQUFZO0lBQzNCLE9BQU8sa0JBQWtCLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDbEMsQ0FBQztBQUVELFNBQVMsVUFBVSxDQUNqQixJQUFtQixFQUNuQixJQUFZLEVBQ1osTUFBZ0IsRUFDaEIsV0FBbUI7SUFFbkIsZ0dBQWdHO0lBQ2hHLG9GQUFvRjtJQUNwRixJQUFJLE1BQU0sQ0FBQyxNQUFNLEtBQUssQ0FBQztRQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLENBQUM7SUFFbkQsT0FBTyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxXQUFXLEVBQUUsQ0FBQyxDQUFDO0FBQ3ZFLENBQUM7QUFPRDs7Ozs7OztHQU9HO0FBQ0gsU0FBUyxnQkFBZ0IsQ0FBQyxVQUE2QjtJQUNy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
575
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidW5mb2xkZWQtcGF0aHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvb3BlbmFwaS91bmZvbGRlZC1wYXRocy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQXV2QkEsd0NBNkJDO0FBcndCRCxvRUFBNEM7QUFDNUMsaURBQThDO0FBQzlDLG1FQUFvRTtBQUNwRSx1Q0FjbUI7QUFDbkIsNkNBQXNEO0FBQ3RELDZEQUE0RDtBQUM1RCx5REFBeUQ7QUFFekQsTUFBTSxXQUFXLEdBQUcsQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLENBQUM7QUFFbEMsTUFBTSxhQUFhLEdBQThEO0lBQy9FLHdCQUF3QixFQUN0QixpRkFBaUY7UUFDakYseUZBQXlGO1FBQ3pGLDRCQUE0QjtJQUM5QixTQUFTLEVBQ1AsMEZBQTBGO1FBQzFGLDRGQUE0RjtRQUM1RixnRUFBZ0U7Q0FDbkUsQ0FBQztBQWdDRixpR0FBaUc7QUFDakcsbUdBQW1HO0FBQ25HLDZDQUE2QztBQUM3QyxTQUFTLE9BQU8sQ0FBQyxJQUFZO0lBQzNCLE9BQU8sa0JBQWtCLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDbEMsQ0FBQztBQUVELFNBQVMsVUFBVSxDQUNqQixJQUFtQixFQUNuQixJQUFZLEVBQ1osTUFBZ0IsRUFDaEIsV0FBbUI7SUFFbkIsZ0dBQWdHO0lBQ2hHLG9GQUFvRjtJQUNwRixJQUFJLE1BQU0sQ0FBQyxNQUFNLEtBQUssQ0FBQztRQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLENBQUM7SUFFbkQsT0FBTyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxXQUFXLEVBQUUsQ0FBQyxDQUFDO0FBQ3ZFLENBQUM7QUFFRDs7Ozs7R0FLRztBQUNILFNBQVMsZUFBZSxDQUFDLE1BQXdCO0lBQy9DLE9B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
@@ -28,19 +28,31 @@ export interface UnfoldedRelation {
28
28
  *
29
29
  * `degraded` is set when the field set could not be established. The collection keeps its paths, but
30
30
  * their field schemas stay free-form strings — an empty enum would forbid every valid call.
31
+ *
32
+ * `undocumentableFilter` marks a THIRD state for `filterable`, orthogonal to `degraded`: the
33
+ * capabilities were read and named filterable fields, but at least one was dropped because an
34
+ * operator of it has no canonical mapping. An empty `filterable` then means "the BFF cannot
35
+ * document what this collection filters on", not "it filters on nothing", and the filter schema
36
+ * must stay free-form rather than claim the collection refuses every filter.
31
37
  */
32
38
  export interface CollectionFields {
33
39
  projectable: ProjectableField[];
34
40
  filterable: FilterableField[];
35
41
  degraded: DegradedReason | null;
42
+ undocumentableFilter?: true;
36
43
  }
37
44
  /**
38
45
  * A field the agent reports, with the column type it declares. The type is what turns the response
39
46
  * records into a typed schema; the name is what the request enums carry.
47
+ *
48
+ * `sortable` mirrors the capabilities field of the same name: only the v1 synthesis ever denies it,
49
+ * from the apimap's `isSortable`, and the sort enum drops the field so the document stops offering a
50
+ * sort the runtime answers 422 field_not_sortable on.
40
51
  */
41
52
  export interface ProjectableField {
42
53
  name: string;
43
54
  type: FieldType;
55
+ sortable?: false;
44
56
  }
45
57
  /**
46
58
  * A field the agent reports at least one operator for, with that operator set — the very set the
@@ -14,4 +14,4 @@ function isFullyDegraded(unfolding) {
14
14
  return (unfolding.collections.length > 0 &&
15
15
  unfolding.collections.every(collection => collection.fields.degraded !== null));
16
16
  }
17
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidW5mb2xkaW5nLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL29wZW5hcGkvdW5mb2xkaW5nLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBZ0VBLHNEQUVDO0FBTUQsMENBS0M7QUFkRCx3RUFBd0U7QUFDeEUsU0FBZ0IscUJBQXFCLENBQUMsU0FBb0I7SUFDeEQsT0FBTyxTQUFTLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsUUFBUSxLQUFLLElBQUksQ0FBQyxDQUFDO0FBQ3ZGLENBQUM7QUFFRDs7O0dBR0c7QUFDSCxTQUFnQixlQUFlLENBQUMsU0FBb0I7SUFDbEQsT0FBTyxDQUNMLFNBQVMsQ0FBQyxXQUFXLENBQUMsTUFBTSxHQUFHLENBQUM7UUFDaEMsU0FBUyxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLFFBQVEsS0FBSyxJQUFJLENBQUMsQ0FDL0UsQ0FBQztBQUNKLENBQUMifQ==
17
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidW5mb2xkaW5nLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL29wZW5hcGkvdW5mb2xkaW5nLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBNEVBLHNEQUVDO0FBTUQsMENBS0M7QUFkRCx3RUFBd0U7QUFDeEUsU0FBZ0IscUJBQXFCLENBQUMsU0FBb0I7SUFDeEQsT0FBTyxTQUFTLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsUUFBUSxLQUFLLElBQUksQ0FBQyxDQUFDO0FBQ3ZGLENBQUM7QUFFRDs7O0dBR0c7QUFDSCxTQUFnQixlQUFlLENBQUMsU0FBb0I7SUFDbEQsT0FBTyxDQUNMLFNBQVMsQ0FBQyxXQUFXLENBQUMsTUFBTSxHQUFHLENBQUM7UUFDaEMsU0FBUyxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLFFBQVEsS0FBSyxJQUFJLENBQUMsQ0FDL0UsQ0FBQztBQUNKLENBQUMifQ==
@@ -1,9 +1,14 @@
1
1
  import type { CapabilitiesFetcher } from './capabilities-cache';
2
+ import type ReadModelStore from './read-model-store';
2
3
  import type { AgentTransport } from '../agent/agent-transport';
4
+ import type { Logger } from '../ports/logger-port';
3
5
  export interface AgentCapabilitiesFetcherOptions {
4
6
  transport: AgentTransport;
5
7
  /** A borrowed request token, or a factory when the caller can mint one per fetch. */
6
8
  token: string | (() => string);
9
+ /** Holds the schema snapshot a 404 is answered from when a legacy liana published it. */
10
+ store: ReadModelStore;
11
+ logger: Logger;
7
12
  }
8
13
  /**
9
14
  * Builds a capabilities fetcher bound to an agent token. The cache calls it only on a miss, so the
@@ -13,5 +18,5 @@ export interface AgentCapabilitiesFetcherOptions {
13
18
  * hundreds of collections can outlive a single one, and the tail of that fan-out would fail on an
14
19
  * expired token. A request can only borrow its caller's, so it passes the string.
15
20
  */
16
- export default function createAgentCapabilitiesFetcher({ transport, token, }: AgentCapabilitiesFetcherOptions): CapabilitiesFetcher;
21
+ export default function createAgentCapabilitiesFetcher({ transport, token, store, logger, }: AgentCapabilitiesFetcherOptions): CapabilitiesFetcher;
17
22
  //# sourceMappingURL=agent-capabilities-fetcher.d.ts.map
@@ -1,7 +1,69 @@
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 __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 () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
2
35
  Object.defineProperty(exports, "__esModule", { value: true });
3
36
  exports.default = createAgentCapabilitiesFetcher;
4
37
  const agent_client_1 = require("@forestadmin/agent-client");
38
+ const synthesize_capabilities_1 = __importStar(require("./synthesize-capabilities"));
39
+ /**
40
+ * The capabilities a legacy liana cannot serve, synthesized from the schema it published, or null
41
+ * when this agent is not one — a proxy blocking `/forest/_internal` answers 404 just the same, so
42
+ * the liana name decides, not the status.
43
+ */
44
+ async function synthesizeForLegacyLiana(collection, { transport, store, logger }) {
45
+ const { collections, meta } = await store.getSchemaSnapshot();
46
+ const schema = collections.find(entry => entry.name === collection);
47
+ if (!schema)
48
+ return null;
49
+ if (!meta.liana || !synthesize_capabilities_1.LEGACY_LIANAS.has(meta.liana)) {
50
+ logger('Error', 'Agent serves no capabilities route, and its liana is not a legacy one', {
51
+ agentUrl: transport.url,
52
+ collection,
53
+ liana: meta.liana ?? 'absent from the published schema',
54
+ lianaVersion: meta.liana_version ?? 'unknown',
55
+ causes: 'a proxy blocking /forest/_internal, or a collection the agent no longer serves',
56
+ });
57
+ return null;
58
+ }
59
+ logger('Warn', 'Legacy liana: synthesizing the capabilities from the apimap', {
60
+ agentUrl: transport.url,
61
+ collection,
62
+ liana: meta.liana,
63
+ lianaVersion: meta.liana_version ?? 'unknown',
64
+ });
65
+ return (0, synthesize_capabilities_1.default)(schema, logger);
66
+ }
5
67
  /**
6
68
  * Builds a capabilities fetcher bound to an agent token. The cache calls it only on a miss, so the
7
69
  * token of whichever request first populates a collection is the one used.
@@ -10,16 +72,36 @@ const agent_client_1 = require("@forestadmin/agent-client");
10
72
  * hundreds of collections can outlive a single one, and the tail of that fan-out would fail on an
11
73
  * expired token. A request can only borrow its caller's, so it passes the string.
12
74
  */
13
- function createAgentCapabilitiesFetcher({ transport, token, }) {
75
+ function createAgentCapabilitiesFetcher({ transport, token, store, logger, }) {
14
76
  const clientFor = (bearer) => (0, agent_client_1.createRemoteAgentClient)({
15
77
  url: transport.url,
16
78
  token: bearer,
17
79
  httpRequester: transport.createRequester(bearer),
18
80
  });
19
- if (typeof token === 'string') {
20
- const client = clientFor(token);
21
- return collection => client.collection(collection).capabilities();
81
+ // A borrowed token cannot be renewed, so its client is built once; a factory mints one per fetch.
82
+ function createFetch() {
83
+ if (typeof token === 'string') {
84
+ const client = clientFor(token);
85
+ return collection => client.collection(collection).capabilities();
86
+ }
87
+ return collection => clientFor(token()).collection(collection).capabilities();
22
88
  }
23
- return collection => clientFor(token()).collection(collection).capabilities();
89
+ const fetch = createFetch();
90
+ // The liana is read from the cached snapshot, so it lags a migration by at most a schema
91
+ // generation; the synthesis is returned like a normal result, letting the cache stop the doomed
92
+ // POST from repeating on every constrained request.
93
+ return async (collection) => {
94
+ try {
95
+ return await fetch(collection);
96
+ }
97
+ catch (error) {
98
+ if (!(error instanceof agent_client_1.AgentHttpError) || error.status !== 404)
99
+ throw error;
100
+ const synthesized = await synthesizeForLegacyLiana(collection, { transport, store, logger });
101
+ if (!synthesized)
102
+ throw error;
103
+ return synthesized;
104
+ }
105
+ };
24
106
  }
25
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWdlbnQtY2FwYWJpbGl0aWVzLWZldGNoZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcmVhZC1tb2RlbC9hZ2VudC1jYXBhYmlsaXRpZXMtZmV0Y2hlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQW1CQSxpREFrQkM7QUFsQ0QsNERBQW9FO0FBUXBFOzs7Ozs7O0dBT0c7QUFDSCxTQUF3Qiw4QkFBOEIsQ0FBQyxFQUNyRCxTQUFTLEVBQ1QsS0FBSyxHQUMyQjtJQUNoQyxNQUFNLFNBQVMsR0FBRyxDQUFDLE1BQWMsRUFBRSxFQUFFLENBQ25DLElBQUEsc0NBQXVCLEVBQUM7UUFDdEIsR0FBRyxFQUFFLFNBQVMsQ0FBQyxHQUFHO1FBQ2xCLEtBQUssRUFBRSxNQUFNO1FBQ2IsYUFBYSxFQUFFLFNBQVMsQ0FBQyxlQUFlLENBQUMsTUFBTSxDQUFDO0tBQ2pELENBQUMsQ0FBQztJQUVMLElBQUksT0FBTyxLQUFLLEtBQUssUUFBUSxFQUFFLENBQUM7UUFDOUIsTUFBTSxNQUFNLEdBQUcsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBRWhDLE9BQU8sVUFBVSxDQUFDLEVBQUUsQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQyxDQUFDLFlBQVksRUFBRSxDQUFDO0lBQ3BFLENBQUM7SUFFRCxPQUFPLFVBQVUsQ0FBQyxFQUFFLENBQUMsU0FBUyxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQyxDQUFDLFlBQVksRUFBRSxDQUFDO0FBQ2hGLENBQUMifQ==
107
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWdlbnQtY2FwYWJpbGl0aWVzLWZldGNoZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcmVhZC1tb2RlbC9hZ2VudC1jYXBhYmlsaXRpZXMtZmV0Y2hlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQWdFQSxpREEwQ0M7QUFyR0QsNERBQW9GO0FBRXBGLHFGQUFrRjtBQWFsRjs7OztHQUlHO0FBQ0gsS0FBSyxVQUFVLHdCQUF3QixDQUNyQyxVQUFrQixFQUNsQixFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFjO0lBRXhDLE1BQU0sRUFBRSxXQUFXLEVBQUUsSUFBSSxFQUFFLEdBQUcsTUFBTSxLQUFLLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztJQUM5RCxNQUFNLE1BQU0sR0FBRyxXQUFXLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLElBQUksS0FBSyxVQUFVLENBQUMsQ0FBQztJQUVwRSxJQUFJLENBQUMsTUFBTTtRQUFFLE9BQU8sSUFBSSxDQUFDO0lBRXpCLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxJQUFJLENBQUMsdUNBQWEsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7UUFDbEQsTUFBTSxDQUFDLE9BQU8sRUFBRSx1RUFBdUUsRUFBRTtZQUN2RixRQUFRLEVBQUUsU0FBUyxDQUFDLEdBQUc7WUFDdkIsVUFBVTtZQUNWLEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSyxJQUFJLGtDQUFrQztZQUN2RCxZQUFZLEVBQUUsSUFBSSxDQUFDLGFBQWEsSUFBSSxTQUFTO1lBQzdDLE1BQU0sRUFBRSxnRkFBZ0Y7U0FDekYsQ0FBQyxDQUFDO1FBRUgsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQsTUFBTSxDQUFDLE1BQU0sRUFBRSw2REFBNkQsRUFBRTtRQUM1RSxRQUFRLEVBQUUsU0FBUyxDQUFDLEdBQUc7UUFDdkIsVUFBVTtRQUNWLEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSztRQUNqQixZQUFZLEVBQUUsSUFBSSxDQUFDLGFBQWEsSUFBSSxTQUFTO0tBQzlDLENBQUMsQ0FBQztJQUVILE9BQU8sSUFBQSxpQ0FBc0IsRUFBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUM7QUFDaEQsQ0FBQztBQUVEOzs7Ozs7O0dBT0c7QUFDSCxTQUF3Qiw4QkFBOEIsQ0FBQyxFQUNyRCxTQUFTLEVBQ1QsS0FBSyxFQUNMLEtBQUssRUFDTCxNQUFNLEdBQzBCO0lBQ2hDLE1BQU0sU0FBUyxHQUFHLENBQUMsTUFBYyxFQUFFLEVBQUUsQ0FDbkMsSUFBQSxzQ0FBdUIsRUFBQztRQUN0QixHQUFHLEVBQUUsU0FBUyxDQUFDLEdBQUc7UUFDbEIsS0FBSyxFQUFFLE1BQU07UUFDYixhQUFhLEVBQUUsU0FBUyxDQUFDLGVBQWUsQ0FBQyxNQUFNLENBQUM7S0FDakQsQ0FBQyxDQUFDO0lBRUwsa0dBQWtHO0lBQ2xHLFNBQVMsV0FBVztRQUNsQixJQUFJLE9BQU8sS0FBSyxLQUFLLFFBQVEsRUFBRSxDQUFDO1lBQzlCLE1BQU0sTUFBTSxHQUFHLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUVoQyxPQUFPLFVBQVUsQ0FBQyxFQUFFLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxVQUFVLENBQUMsQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUNwRSxDQUFDO1FBRUQsT0FBTyxVQUFVLENBQUMsRUFBRSxDQUFDLFNBQVMsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxVQUFVLENBQUMsQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQUNoRixDQUFDO0lBRUQsTUFBTSxLQUFLLEdBQUcsV0FBVyxFQUFFLENBQUM7SUFFNUIseUZBQXlGO0lBQ3pGLGdHQUFnRztJQUNoRyxvREFBb0Q7SUFDcEQsT0FBTyxLQUFLLEVBQUUsVUFBa0IsRUFBRSxFQUFFO1FBQ2xDLElBQUksQ0FBQztZQUNILE9BQU8sTUFBTSxLQUFLLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDakMsQ0FBQztRQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDZixJQUFJLENBQUMsQ0FBQyxLQUFLLFlBQVksNkJBQWMsQ0FBQyxJQUFJLEtBQUssQ0FBQyxNQUFNLEtBQUssR0FBRztnQkFBRSxNQUFNLEtBQUssQ0FBQztZQUU1RSxNQUFNLFdBQVcsR0FBRyxNQUFNLHdCQUF3QixDQUFDLFVBQVUsRUFBRSxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQztZQUU3RixJQUFJLENBQUMsV0FBVztnQkFBRSxNQUFNLEtBQUssQ0FBQztZQUU5QixPQUFPLFdBQVcsQ0FBQztRQUNyQixDQUFDO0lBQ0gsQ0FBQyxDQUFDO0FBQ0osQ0FBQyJ9
@@ -4,6 +4,7 @@ export interface CapabilitiesResult {
4
4
  name: string;
5
5
  type: FieldType;
6
6
  operators?: string[];
7
+ sortable?: false;
7
8
  }[];
8
9
  }
9
10
  export type CapabilitiesFetcher = (collection: string) => Promise<CapabilitiesResult>;
@@ -44,4 +44,4 @@ class CapabilitiesCache {
44
44
  }
45
45
  }
46
46
  exports.default = CapabilitiesCache;
47
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FwYWJpbGl0aWVzLWNhY2hlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3JlYWQtbW9kZWwvY2FwYWJpbGl0aWVzLWNhY2hlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBRUEsaURBQTRDO0FBb0I1Qzs7O0dBR0c7QUFDSCxNQUFxQixpQkFBaUI7SUFRcEMsWUFBWSxFQUFFLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLEtBQUssR0FBRyx5QkFBVSxLQUErQixFQUFFO1FBSmhFLFlBQU8sR0FBRyxJQUFJLEdBQUcsRUFBc0IsQ0FBQztRQUN4QyxhQUFRLEdBQUcsSUFBSSxHQUFHLEVBQXVDLENBQUM7UUFDbkUsZUFBVSxHQUFHLENBQUMsQ0FBQztRQUdyQixJQUFJLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQztRQUNmLElBQUksQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDO0lBQ3JCLENBQUM7SUFFRCxLQUFLLENBQUMsR0FBRyxDQUFDLFVBQWtCLEVBQUUsT0FBNEI7UUFDeEQsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDM0MsSUFBSSxLQUFLLElBQUksSUFBSSxDQUFDLEdBQUcsRUFBRSxHQUFHLEtBQUssQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLEtBQUs7WUFBRSxPQUFPLEtBQUssQ0FBQyxNQUFNLENBQUM7UUFFNUUsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDOUMsSUFBSSxPQUFPO1lBQUUsT0FBTyxPQUFPLENBQUM7UUFFNUIsTUFBTSxFQUFFLFVBQVUsRUFBRSxHQUFHLElBQUksQ0FBQztRQUM1QixNQUFNLEtBQUssR0FBRyxPQUFPLENBQUMsVUFBVSxDQUFDO2FBQzlCLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRTtZQUNiLHlGQUF5RjtZQUN6RixxRkFBcUY7WUFDckYsSUFBSSxJQUFJLENBQUMsVUFBVSxLQUFLLFVBQVUsRUFBRSxDQUFDO2dCQUNuQyxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxVQUFVLEVBQUUsRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFFLElBQUksQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDbEUsQ0FBQztZQUVELE9BQU8sTUFBTSxDQUFDO1FBQ2hCLENBQUMsQ0FBQzthQUNELE9BQU8sQ0FBQyxHQUFHLEVBQUU7WUFDWixJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxLQUFLLEtBQUs7Z0JBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDaEYsQ0FBQyxDQUFDLENBQUM7UUFFTCxJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxVQUFVLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFFckMsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0lBRUQsS0FBSztRQUNILElBQUksQ0FBQyxVQUFVLElBQUksQ0FBQyxDQUFDO1FBQ3JCLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDckIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLEVBQUUsQ0FBQztJQUN4QixDQUFDO0NBQ0Y7QUE3Q0Qsb0NBNkNDIn0=
47
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FwYWJpbGl0aWVzLWNhY2hlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3JlYWQtbW9kZWwvY2FwYWJpbGl0aWVzLWNhY2hlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBRUEsaURBQTRDO0FBdUI1Qzs7O0dBR0c7QUFDSCxNQUFxQixpQkFBaUI7SUFRcEMsWUFBWSxFQUFFLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLEtBQUssR0FBRyx5QkFBVSxLQUErQixFQUFFO1FBSmhFLFlBQU8sR0FBRyxJQUFJLEdBQUcsRUFBc0IsQ0FBQztRQUN4QyxhQUFRLEdBQUcsSUFBSSxHQUFHLEVBQXVDLENBQUM7UUFDbkUsZUFBVSxHQUFHLENBQUMsQ0FBQztRQUdyQixJQUFJLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQztRQUNmLElBQUksQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDO0lBQ3JCLENBQUM7SUFFRCxLQUFLLENBQUMsR0FBRyxDQUFDLFVBQWtCLEVBQUUsT0FBNEI7UUFDeEQsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDM0MsSUFBSSxLQUFLLElBQUksSUFBSSxDQUFDLEdBQUcsRUFBRSxHQUFHLEtBQUssQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLEtBQUs7WUFBRSxPQUFPLEtBQUssQ0FBQyxNQUFNLENBQUM7UUFFNUUsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDOUMsSUFBSSxPQUFPO1lBQUUsT0FBTyxPQUFPLENBQUM7UUFFNUIsTUFBTSxFQUFFLFVBQVUsRUFBRSxHQUFHLElBQUksQ0FBQztRQUM1QixNQUFNLEtBQUssR0FBRyxPQUFPLENBQUMsVUFBVSxDQUFDO2FBQzlCLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRTtZQUNiLHlGQUF5RjtZQUN6RixxRkFBcUY7WUFDckYsSUFBSSxJQUFJLENBQUMsVUFBVSxLQUFLLFVBQVUsRUFBRSxDQUFDO2dCQUNuQyxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxVQUFVLEVBQUUsRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFFLElBQUksQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDbEUsQ0FBQztZQUVELE9BQU8sTUFBTSxDQUFDO1FBQ2hCLENBQUMsQ0FBQzthQUNELE9BQU8sQ0FBQyxHQUFHLEVBQUU7WUFDWixJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxLQUFLLEtBQUs7Z0JBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDaEYsQ0FBQyxDQUFDLENBQUM7UUFFTCxJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxVQUFVLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFFckMsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0lBRUQsS0FBSztRQUNILElBQUksQ0FBQyxVQUFVLElBQUksQ0FBQyxDQUFDO1FBQ3JCLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDckIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLEVBQUUsQ0FBQztJQUN4QixDQUFDO0NBQ0Y7QUE3Q0Qsb0NBNkNDIn0=
@@ -1,14 +1,14 @@
1
- import type { ForestSchemaCollection } from '@forestadmin/forestadmin-client';
1
+ import type { ForestSchemaWithMeta } from '@forestadmin/forestadmin-client';
2
2
  export interface ForestSchemaClientOptions {
3
3
  forestServerUrl: string;
4
4
  envSecret: string;
5
5
  }
6
6
  export interface SchemaFetcher {
7
- fetchSchema(): Promise<ForestSchemaCollection[]>;
7
+ fetchSchema(): Promise<ForestSchemaWithMeta>;
8
8
  }
9
9
  export default class ForestSchemaClient implements SchemaFetcher {
10
10
  private readonly schemaService;
11
11
  constructor({ forestServerUrl, envSecret }: ForestSchemaClientOptions);
12
- fetchSchema(): Promise<ForestSchemaCollection[]>;
12
+ fetchSchema(): Promise<ForestSchemaWithMeta>;
13
13
  }
14
14
  //# sourceMappingURL=forest-schema-client.d.ts.map
@@ -6,8 +6,8 @@ class ForestSchemaClient {
6
6
  this.schemaService = new forestadmin_client_1.SchemaService(new forestadmin_client_1.ForestHttpApi(), { forestServerUrl, envSecret });
7
7
  }
8
8
  async fetchSchema() {
9
- return this.schemaService.getSchema();
9
+ return this.schemaService.getSchemaWithMeta();
10
10
  }
11
11
  }
12
12
  exports.default = ForestSchemaClient;
13
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm9yZXN0LXNjaGVtYS1jbGllbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcmVhZC1tb2RlbC9mb3Jlc3Qtc2NoZW1hLWNsaWVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUVBLHdFQUErRTtBQVcvRSxNQUFxQixrQkFBa0I7SUFHckMsWUFBWSxFQUFFLGVBQWUsRUFBRSxTQUFTLEVBQTZCO1FBQ25FLElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxrQ0FBYSxDQUFDLElBQUksa0NBQWEsRUFBRSxFQUFFLEVBQUUsZUFBZSxFQUFFLFNBQVMsRUFBRSxDQUFDLENBQUM7SUFDOUYsQ0FBQztJQUVELEtBQUssQ0FBQyxXQUFXO1FBQ2YsT0FBTyxJQUFJLENBQUMsYUFBYSxDQUFDLFNBQVMsRUFBRSxDQUFDO0lBQ3hDLENBQUM7Q0FDRjtBQVZELHFDQVVDIn0=
13
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm9yZXN0LXNjaGVtYS1jbGllbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcmVhZC1tb2RlbC9mb3Jlc3Qtc2NoZW1hLWNsaWVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUVBLHdFQUErRTtBQVcvRSxNQUFxQixrQkFBa0I7SUFHckMsWUFBWSxFQUFFLGVBQWUsRUFBRSxTQUFTLEVBQTZCO1FBQ25FLElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxrQ0FBYSxDQUFDLElBQUksa0NBQWEsRUFBRSxFQUFFLEVBQUUsZUFBZSxFQUFFLFNBQVMsRUFBRSxDQUFDLENBQUM7SUFDOUYsQ0FBQztJQUVELEtBQUssQ0FBQyxXQUFXO1FBQ2YsT0FBTyxJQUFJLENBQUMsYUFBYSxDQUFDLGlCQUFpQixFQUFFLENBQUM7SUFDaEQsQ0FBQztDQUNGO0FBVkQscUNBVUMifQ==
@@ -1,10 +1,11 @@
1
1
  import type CapabilitiesCache from './capabilities-cache';
2
2
  import type { CapabilitiesFetcher, CapabilitiesResult } from './capabilities-cache';
3
3
  import type SchemaCache from './schema-cache';
4
- import type { ForestSchemaCollection } from '@forestadmin/forestadmin-client';
4
+ import type { ForestSchemaCollection, ForestSchemaMeta } from '@forestadmin/forestadmin-client';
5
5
  import ReadModel from './read-model';
6
6
  export interface SchemaSnapshot {
7
7
  collections: ForestSchemaCollection[];
8
+ meta: ForestSchemaMeta;
8
9
  readModel: ReadModel;
9
10
  revision: number;
10
11
  }
@@ -32,14 +32,14 @@ class ReadModelStore {
32
32
  this.builtRevision = -1;
33
33
  }
34
34
  async getSchemaSnapshot() {
35
- const collections = await this.schemaCache.get();
35
+ const { collections, meta } = await this.schemaCache.getPayload();
36
36
  const { revision } = this.schemaCache;
37
37
  if (revision !== this.builtRevision || !this.readModel) {
38
38
  this.readModel = new read_model_1.default(collections);
39
39
  this.builtRevision = revision;
40
40
  this.capabilitiesCache.clear();
41
41
  }
42
- return { collections, readModel: this.readModel, revision };
42
+ return { collections, meta, readModel: this.readModel, revision };
43
43
  }
44
44
  /**
45
45
  * Returns the capabilities together with the read-model they belong to, so a caller cannot mix a
@@ -70,4 +70,4 @@ class ReadModelStore {
70
70
  }
71
71
  }
72
72
  exports.default = ReadModelStore;
73
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVhZC1tb2RlbC1zdG9yZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9yZWFkLW1vZGVsL3JlYWQtbW9kZWwtc3RvcmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFLQSw4REFBcUM7QUFFckMsTUFBTSxzQkFBc0IsR0FBRyxDQUFDLENBQUM7QUFRakM7Ozs7R0FJRztBQUNILE1BQXFCLGNBQWM7SUFPakMsWUFBWSxXQUF3QixFQUFFLGlCQUFvQztRQUhsRSxrQkFBYSxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBQ25CLGNBQVMsR0FBcUIsSUFBSSxDQUFDO1FBR3pDLElBQUksQ0FBQyxXQUFXLEdBQUcsV0FBVyxDQUFDO1FBQy9CLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxpQkFBaUIsQ0FBQztJQUM3QyxDQUFDO0lBRUQsS0FBSyxDQUFDLFlBQVk7UUFDaEIsT0FBTyxDQUFDLE1BQU0sSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUMsQ0FBQyxTQUFTLENBQUM7SUFDcEQsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0gsVUFBVTtRQUNSLElBQUksQ0FBQyxXQUFXLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDekIsSUFBSSxDQUFDLGlCQUFpQixDQUFDLEtBQUssRUFBRSxDQUFDO1FBQy9CLElBQUksQ0FBQyxhQUFhLEdBQUcsQ0FBQyxDQUFDLENBQUM7SUFDMUIsQ0FBQztJQUVELEtBQUssQ0FBQyxpQkFBaUI7UUFDckIsTUFBTSxXQUFXLEdBQUcsTUFBTSxJQUFJLENBQUMsV0FBVyxDQUFDLEdBQUcsRUFBRSxDQUFDO1FBQ2pELE1BQU0sRUFBRSxRQUFRLEVBQUUsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDO1FBRXRDLElBQUksUUFBUSxLQUFLLElBQUksQ0FBQyxhQUFhLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7WUFDdkQsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLG9CQUFTLENBQUMsV0FBVyxDQUFDLENBQUM7WUFDNUMsSUFBSSxDQUFDLGFBQWEsR0FBRyxRQUFRLENBQUM7WUFDOUIsSUFBSSxDQUFDLGlCQUFpQixDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ2pDLENBQUM7UUFFRCxPQUFPLEVBQUUsV0FBVyxFQUFFLFNBQVMsRUFBRSxJQUFJLENBQUMsU0FBUyxFQUFFLFFBQVEsRUFBRSxDQUFDO0lBQzlELENBQUM7SUFFRDs7OztPQUlHO0lBQ0gsS0FBSyxDQUFDLGVBQWUsQ0FDbkIsVUFBa0IsRUFDbEIsT0FBNEIsRUFDNUIsWUFBWSxHQUFHLHNCQUFzQjtRQUVyQyxJQUFJLFlBQVksSUFBSSxDQUFDLEVBQUUsQ0FBQztZQUN0QixNQUFNLElBQUksS0FBSyxDQUNiLG1FQUFtRSxVQUFVLEdBQUcsQ0FDakYsQ0FBQztRQUNKLENBQUM7UUFFRCxvRkFBb0Y7UUFDcEYsTUFBTSxTQUFTLEdBQUcsTUFBTSxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDNUMsTUFBTSxFQUFFLFFBQVEsRUFBRSxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUM7UUFDdEMsTUFBTSxZQUFZLEdBQUcsTUFBTSxJQUFJLENBQUMsaUJBQWlCLENBQUMsR0FBRyxDQUFDLFVBQVUsRUFBRSxPQUFPLENBQUMsQ0FBQztRQUUzRSw2RkFBNkY7UUFDN0YsaUdBQWlHO1FBQ2pHLCtGQUErRjtRQUMvRiw4RkFBOEY7UUFDOUYsNkZBQTZGO1FBQzdGLHVEQUF1RDtRQUN2RCxJQUFJLElBQUksQ0FBQyxXQUFXLENBQUMsUUFBUSxLQUFLLFFBQVEsRUFBRSxDQUFDO1lBQzNDLE9BQU8sSUFBSSxDQUFDLGVBQWUsQ0FBQyxVQUFVLEVBQUUsT0FBTyxFQUFFLFlBQVksR0FBRyxDQUFDLENBQUMsQ0FBQztRQUNyRSxDQUFDO1FBRUQsT0FBTyxFQUFFLFlBQVksRUFBRSxTQUFTLEVBQUUsQ0FBQztJQUNyQyxDQUFDO0lBRUQsVUFBVTtRQUNSLE9BQU8sSUFBSSxDQUFDLFdBQVcsQ0FBQyxVQUFVLEVBQUUsQ0FBQztJQUN2QyxDQUFDO0NBQ0Y7QUE5RUQsaUNBOEVDIn0=
73
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVhZC1tb2RlbC1zdG9yZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9yZWFkLW1vZGVsL3JlYWQtbW9kZWwtc3RvcmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFLQSw4REFBcUM7QUFFckMsTUFBTSxzQkFBc0IsR0FBRyxDQUFDLENBQUM7QUFTakM7Ozs7R0FJRztBQUNILE1BQXFCLGNBQWM7SUFPakMsWUFBWSxXQUF3QixFQUFFLGlCQUFvQztRQUhsRSxrQkFBYSxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBQ25CLGNBQVMsR0FBcUIsSUFBSSxDQUFDO1FBR3pDLElBQUksQ0FBQyxXQUFXLEdBQUcsV0FBVyxDQUFDO1FBQy9CLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxpQkFBaUIsQ0FBQztJQUM3QyxDQUFDO0lBRUQsS0FBSyxDQUFDLFlBQVk7UUFDaEIsT0FBTyxDQUFDLE1BQU0sSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUMsQ0FBQyxTQUFTLENBQUM7SUFDcEQsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0gsVUFBVTtRQUNSLElBQUksQ0FBQyxXQUFXLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDekIsSUFBSSxDQUFDLGlCQUFpQixDQUFDLEtBQUssRUFBRSxDQUFDO1FBQy9CLElBQUksQ0FBQyxhQUFhLEdBQUcsQ0FBQyxDQUFDLENBQUM7SUFDMUIsQ0FBQztJQUVELEtBQUssQ0FBQyxpQkFBaUI7UUFDckIsTUFBTSxFQUFFLFdBQVcsRUFBRSxJQUFJLEVBQUUsR0FBRyxNQUFNLElBQUksQ0FBQyxXQUFXLENBQUMsVUFBVSxFQUFFLENBQUM7UUFDbEUsTUFBTSxFQUFFLFFBQVEsRUFBRSxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUM7UUFFdEMsSUFBSSxRQUFRLEtBQUssSUFBSSxDQUFDLGFBQWEsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUN2RCxJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksb0JBQVMsQ0FBQyxXQUFXLENBQUMsQ0FBQztZQUM1QyxJQUFJLENBQUMsYUFBYSxHQUFHLFFBQVEsQ0FBQztZQUM5QixJQUFJLENBQUMsaUJBQWlCLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDakMsQ0FBQztRQUVELE9BQU8sRUFBRSxXQUFXLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxJQUFJLENBQUMsU0FBUyxFQUFFLFFBQVEsRUFBRSxDQUFDO0lBQ3BFLENBQUM7SUFFRDs7OztPQUlHO0lBQ0gsS0FBSyxDQUFDLGVBQWUsQ0FDbkIsVUFBa0IsRUFDbEIsT0FBNEIsRUFDNUIsWUFBWSxHQUFHLHNCQUFzQjtRQUVyQyxJQUFJLFlBQVksSUFBSSxDQUFDLEVBQUUsQ0FBQztZQUN0QixNQUFNLElBQUksS0FBSyxDQUNiLG1FQUFtRSxVQUFVLEdBQUcsQ0FDakYsQ0FBQztRQUNKLENBQUM7UUFFRCxvRkFBb0Y7UUFDcEYsTUFBTSxTQUFTLEdBQUcsTUFBTSxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDNUMsTUFBTSxFQUFFLFFBQVEsRUFBRSxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUM7UUFDdEMsTUFBTSxZQUFZLEdBQUcsTUFBTSxJQUFJLENBQUMsaUJBQWlCLENBQUMsR0FBRyxDQUFDLFVBQVUsRUFBRSxPQUFPLENBQUMsQ0FBQztRQUUzRSw2RkFBNkY7UUFDN0YsaUdBQWlHO1FBQ2pHLCtGQUErRjtRQUMvRiw4RkFBOEY7UUFDOUYsNkZBQTZGO1FBQzdGLHVEQUF1RDtRQUN2RCxJQUFJLElBQUksQ0FBQyxXQUFXLENBQUMsUUFBUSxLQUFLLFFBQVEsRUFBRSxDQUFDO1lBQzNDLE9BQU8sSUFBSSxDQUFDLGVBQWUsQ0FBQyxVQUFVLEVBQUUsT0FBTyxFQUFFLFlBQVksR0FBRyxDQUFDLENBQUMsQ0FBQztRQUNyRSxDQUFDO1FBRUQsT0FBTyxFQUFFLFlBQVksRUFBRSxTQUFTLEVBQUUsQ0FBQztJQUNyQyxDQUFDO0lBRUQsVUFBVTtRQUNSLE9BQU8sSUFBSSxDQUFDLFdBQVcsQ0FBQyxVQUFVLEVBQUUsQ0FBQztJQUN2QyxDQUFDO0NBQ0Y7QUE5RUQsaUNBOEVDIn0=
@@ -14,6 +14,13 @@ export type RelationTarget = {
14
14
  export type PrimaryKeyField = {
15
15
  name: string;
16
16
  type: string;
17
+ derived?: true;
18
+ /**
19
+ * Set when this key shares its response key with another field of the collection. The record then
20
+ * holds one value under that key and there is no telling whose, so the key cannot be read back
21
+ * from a record — see `unpackPrimaryKey`.
22
+ */
23
+ ambiguousRecordKey?: true;
17
24
  };
18
25
  export type ListableRelation = {
19
26
  name: string;
@@ -34,6 +41,33 @@ export default class ReadModel {
34
41
  constructor(collections: ForestSchemaCollection[]);
35
42
  private buildRelations;
36
43
  private buildActionEndpoints;
44
+ /**
45
+ * A schema that declares no primary key at all gets one derived from its `id` field.
46
+ *
47
+ * `forest_liana` only started publishing `isPrimaryKey` in 9.17.6 (2026-06-04), and an older one
48
+ * leaves every collection without a key — which makes `unpackPrimaryKey` reject every record the
49
+ * agent returns, so a plain list answers `500 mapping_error`. The record id is there regardless:
50
+ * the agent serialises it as the JSON:API `id`, and 257 of the 269 collections in the schema this
51
+ * was measured against carry a field literally named `id`.
52
+ *
53
+ * Keyed on the shape of the schema, not on the liana: a collection that declares a key keeps it,
54
+ * and every v2 agent declares one, so this only fires where the alternative is a 500. `String`
55
+ * when no `id` field is declared, because the packed id survives a string round-trip untouched
56
+ * while a wrong numeric cast would not.
57
+ *
58
+ * The derived key is flagged, because its arity is a guess: the schema publishes no key, so a
59
+ * collection whose real one is composite packs `tenant|42` behind the same silence. Splitting
60
+ * that on the separator would find two values against one declared key and 500 the whole list,
61
+ * so `unpackPrimaryKey` passes a derived key through opaque instead of splitting it.
62
+ *
63
+ * That last case names a column the collection does not declare, which `__forest.primaryKey`
64
+ * otherwise promises is a real one. It is the deliberate trade: the 12 collections concerned are
65
+ * ordinary listable ones carrying ordinary data columns, and the alternative is a 500 on a plain
66
+ * list of them. Every route takes the id packed and opaque, so the invented name only misses for
67
+ * a consumer filtering ON the key — which a keyless collection could not do either way.
68
+ * `ForestRecordMeta` says so, and `buildContext` publishes no `isPrimaryKey` where there is no
69
+ * field to carry it.
70
+ */
37
71
  private buildPrimaryKeys;
38
72
  isCollectionAllowed(collection: string): boolean;
39
73
  /** A fresh copy per call, so a consumer cannot mutate the shared cached read-model. */