@forestadmin/agent 1.108.2 → 1.109.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/dist/agent.d.ts +14 -9
- package/dist/agent.js +129 -6
- package/dist/bff-routes.d.ts +6 -0
- package/dist/bff-routes.js +51 -2
- package/dist/embedded-bff.d.ts +23 -6
- package/dist/embedded-bff.js +70 -32
- package/dist/framework-mounter.d.ts +2 -1
- package/dist/framework-mounter.js +4 -1
- package/dist/gateway.d.ts +19 -0
- package/dist/gateway.js +96 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/types.d.ts +14 -0
- package/dist/types.js +1 -1
- package/dist/utils/express-to-koa.js +3 -1
- package/package.json +7 -7
package/dist/agent.d.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import type { ForestAdminHttpDriverServices } from './services';
|
|
2
|
-
import type { AgentOptions, AgentOptionsWithDefaults, BffEmbedOptions, WorkflowExecutorEmbedOptions } from './types';
|
|
2
|
+
import type { AgentOptions, AgentOptionsWithDefaults, BffEmbedOptions, GatewayOptions, McpEmbedOptions, WorkflowExecutorEmbedOptions } from './types';
|
|
3
3
|
import type { CollectionCustomizer, DataSourceChartDefinition, DataSourceOptions, Plugin, TCollectionName, TSchema } from '@forestadmin/datasource-customizer';
|
|
4
4
|
import type { DataSource, DataSourceFactory } from '@forestadmin/datasource-toolkit';
|
|
5
|
-
import type { FileUploadsOptions, TokenTtlOptions, ToolName } from '@forestadmin/mcp-server';
|
|
6
5
|
import { DataSourceCustomizer } from '@forestadmin/datasource-customizer';
|
|
7
6
|
import FrameworkMounter from './framework-mounter';
|
|
8
7
|
import CustomizationService from './services/model-customizations/customization';
|
|
@@ -34,7 +33,9 @@ export default class Agent<S extends TSchema = TSchema> extends FrameworkMounter
|
|
|
34
33
|
private embeddedExecutor;
|
|
35
34
|
/** In-process BFF, created only when addBff() is called. */
|
|
36
35
|
private embeddedBff;
|
|
36
|
+
private gateway;
|
|
37
37
|
private isRestarting;
|
|
38
|
+
private isStopped;
|
|
38
39
|
/**
|
|
39
40
|
* Set as soon as start() begins, not once it finishes: mount() drains the `onFirstStart` hooks
|
|
40
41
|
* partway through, so a builder call landing mid-startup is already too late. Cleared again when
|
|
@@ -126,7 +127,10 @@ export default class Agent<S extends TSchema = TSchema> extends FrameworkMounter
|
|
|
126
127
|
* agent.use(advancedExportPlugin, { format: 'xlsx' });
|
|
127
128
|
*/
|
|
128
129
|
use<Options>(plugin: Plugin<Options>, options?: Options): this;
|
|
130
|
+
addGateway(options: GatewayOptions): this;
|
|
129
131
|
/**
|
|
132
|
+
* @deprecated Use `addGateway({ mcp })`. Keeps its current paths and semantics.
|
|
133
|
+
*
|
|
130
134
|
* Enable MCP (Model Context Protocol) server support.
|
|
131
135
|
* This allows AI assistants to interact with your Forest Admin data.
|
|
132
136
|
*
|
|
@@ -156,13 +160,7 @@ export default class Agent<S extends TSchema = TSchema> extends FrameworkMounter
|
|
|
156
160
|
* agent.mountAiMcpServer({ fileUploads: { storage } });
|
|
157
161
|
* agent.mountAiMcpServer({ fileUploads: false });
|
|
158
162
|
*/
|
|
159
|
-
mountAiMcpServer(options?:
|
|
160
|
-
enabledTools?: ToolName[];
|
|
161
|
-
basePath?: string;
|
|
162
|
-
tokenTtl?: TokenTtlOptions;
|
|
163
|
-
allowedOAuthClients?: string[];
|
|
164
|
-
fileUploads?: false | FileUploadsOptions;
|
|
165
|
-
}): this;
|
|
163
|
+
mountAiMcpServer(options?: McpEmbedOptions): this;
|
|
166
164
|
/**
|
|
167
165
|
* Run a workflow executor in-process, alongside the agent. The agent boots it on start(),
|
|
168
166
|
* stops it on stop(), and proxies `/_internal/executor/*` to it — no separate deployment.
|
|
@@ -188,6 +186,8 @@ export default class Agent<S extends TSchema = TSchema> extends FrameworkMounter
|
|
|
188
186
|
*/
|
|
189
187
|
addWorkflowExecutor(options?: WorkflowExecutorEmbedOptions): this;
|
|
190
188
|
/**
|
|
189
|
+
* @deprecated Use `addGateway({ api })`. Keeps serving on `/bff`.
|
|
190
|
+
*
|
|
191
191
|
* Serve a BFF in-process, alongside the agent, at `/bff` — no second deployment, no second port.
|
|
192
192
|
* The agent builds it on start(), stops it on stop(), and hands it a dispatcher that reaches its
|
|
193
193
|
* own stack without a socket, so this works the same on every mount target.
|
|
@@ -216,6 +216,11 @@ export default class Agent<S extends TSchema = TSchema> extends FrameworkMounter
|
|
|
216
216
|
* .start();
|
|
217
217
|
*/
|
|
218
218
|
addBff(options?: BffEmbedOptions): this;
|
|
219
|
+
private prepareGateway;
|
|
220
|
+
private gatewayApi;
|
|
221
|
+
private warnIfMcpAliasUsed;
|
|
222
|
+
private setRootHandlers;
|
|
223
|
+
private logGatewayRoutes;
|
|
219
224
|
protected getRoutes(dataSource: DataSource, services: ForestAdminHttpDriverServices): import("./routes/base-route").default[];
|
|
220
225
|
/**
|
|
221
226
|
* Create an http handler which can respond to all queries which are expected from an agent.
|
package/dist/agent.js
CHANGED
|
@@ -37,6 +37,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
37
37
|
};
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
39
|
const datasource_customizer_1 = require("@forestadmin/datasource-customizer");
|
|
40
|
+
const forestadmin_client_1 = require("@forestadmin/forestadmin-client");
|
|
40
41
|
const bodyparser_1 = __importDefault(require("@koa/bodyparser"));
|
|
41
42
|
const cors_1 = __importDefault(require("@koa/cors"));
|
|
42
43
|
const router_1 = __importDefault(require("@koa/router"));
|
|
@@ -47,6 +48,7 @@ const bff_routes_1 = require("./bff-routes");
|
|
|
47
48
|
const embedded_bff_1 = __importDefault(require("./embedded-bff"));
|
|
48
49
|
const embedded_workflow_executor_1 = __importDefault(require("./embedded-workflow-executor"));
|
|
49
50
|
const framework_mounter_1 = __importDefault(require("./framework-mounter"));
|
|
51
|
+
const gateway_1 = require("./gateway");
|
|
50
52
|
const routes_1 = __importDefault(require("./routes"));
|
|
51
53
|
const services_1 = __importDefault(require("./services"));
|
|
52
54
|
const customization_1 = __importDefault(require("./services/model-customizations/customization"));
|
|
@@ -60,6 +62,8 @@ const normalizeMcpBasePath = (basePath) => `/${(basePath ?? '').trim()}`.replace
|
|
|
60
62
|
const bffMcpCollision = (mcpBasePath) => `Cannot use addBff together with mountAiMcpServer({ basePath: '${mcpBasePath}' }): the MCP ` +
|
|
61
63
|
`server would claim ${bff_routes_1.BFF_PREFIX} paths the embedded BFF answers on (${bff_routes_1.BFF_PREFIX}/oauth, ` +
|
|
62
64
|
`${bff_routes_1.BFF_PREFIX}/mcp). Mount the MCP server elsewhere.`;
|
|
65
|
+
const GATEWAY_MIXING = 'addGateway() cannot be combined with mountAiMcpServer() or addBff(): configure every ' +
|
|
66
|
+
'service through addGateway({ mcp, api }), or keep both aliases.';
|
|
63
67
|
/**
|
|
64
68
|
* Allow to create a new Forest Admin agent from scratch.
|
|
65
69
|
* Builds the application by composing and configuring all the collection decorators.
|
|
@@ -96,7 +100,9 @@ class Agent extends framework_mounter_1.default {
|
|
|
96
100
|
this.embeddedExecutor = null;
|
|
97
101
|
/** In-process BFF, created only when addBff() is called. */
|
|
98
102
|
this.embeddedBff = null;
|
|
103
|
+
this.gateway = null;
|
|
99
104
|
this.isRestarting = false;
|
|
105
|
+
this.isStopped = false;
|
|
100
106
|
/**
|
|
101
107
|
* Set as soon as start() begins, not once it finishes: mount() drains the `onFirstStart` hooks
|
|
102
108
|
* partway through, so a builder call landing mid-startup is already too late. Cleared again when
|
|
@@ -116,22 +122,36 @@ class Agent extends framework_mounter_1.default {
|
|
|
116
122
|
async start() {
|
|
117
123
|
let mounted = false;
|
|
118
124
|
this.startupBegun = true;
|
|
125
|
+
this.isStopped = false;
|
|
119
126
|
try {
|
|
120
127
|
// First, before anything is mounted or subscribed: everything it validates is what the caller
|
|
121
128
|
// handed to addBff(), so a mistyped key must fail on that line rather than leave the host
|
|
122
129
|
// serving /forest with a permanently bricked /bff.
|
|
130
|
+
await this.prepareGateway();
|
|
123
131
|
await this.embeddedBff?.prepare();
|
|
132
|
+
if (this.isStopped)
|
|
133
|
+
await this.embeddedBff?.stop();
|
|
134
|
+
if (this.gateway)
|
|
135
|
+
this.setRootHandlers();
|
|
136
|
+
if (this.isStopped)
|
|
137
|
+
return;
|
|
138
|
+
this.warnIfMcpAliasUsed();
|
|
124
139
|
const { router, mcp } = await this.buildRouterAndSendSchema();
|
|
140
|
+
if (this.isStopped)
|
|
141
|
+
return;
|
|
125
142
|
await this.options.forestAdminClient.subscribeToServerEvents();
|
|
126
143
|
this.options.forestAdminClient.onRefreshCustomizations(this.restart.bind(this));
|
|
127
|
-
this.
|
|
144
|
+
this.setRootHandlers(mcp);
|
|
128
145
|
await this.mount(router);
|
|
129
146
|
mounted = true;
|
|
130
147
|
// Boot after mount(): the embedded executor reaches the agent over HTTP, and the
|
|
131
148
|
// standalone server's host/port (used to derive that URL) are only known once mounted.
|
|
132
149
|
await this.embeddedExecutor?.start(this.standaloneServerHost, this.standaloneServerPort);
|
|
150
|
+
if (this.isStopped)
|
|
151
|
+
return;
|
|
133
152
|
// Same reason, without the socket: the dispatcher injects into the stack mount() just built.
|
|
134
153
|
await this.embeddedBff?.start(this.getInProcessDispatcher());
|
|
154
|
+
this.logGatewayRoutes();
|
|
135
155
|
// Here rather than in initializeMcpServer(): that one reruns on every restart() and each run
|
|
136
156
|
// would cost a SaaS round-trip for a warning already given.
|
|
137
157
|
if (this.mcpEnabled)
|
|
@@ -167,6 +187,9 @@ class Agent extends framework_mounter_1.default {
|
|
|
167
187
|
* Stop the agent.
|
|
168
188
|
*/
|
|
169
189
|
async stop() {
|
|
190
|
+
this.isStopped = true;
|
|
191
|
+
if (this.gateway?.build)
|
|
192
|
+
this.setRootHandlers();
|
|
170
193
|
// Stop answering before the stack it dispatches into goes away: the host application keeps
|
|
171
194
|
// whatever middleware it registered, so a stopped agent would otherwise still serve BFF data.
|
|
172
195
|
await this.embeddedBff?.stop();
|
|
@@ -201,7 +224,9 @@ class Agent extends framework_mounter_1.default {
|
|
|
201
224
|
try {
|
|
202
225
|
// We force sending schema when restarting
|
|
203
226
|
const { router, mcp } = await this.buildRouterAndSendSchema();
|
|
204
|
-
this.
|
|
227
|
+
if (this.isStopped)
|
|
228
|
+
return;
|
|
229
|
+
this.setRootHandlers(mcp);
|
|
205
230
|
await this.remount(router);
|
|
206
231
|
// A restart means the customizations changed, so the schema the BFF read is stale.
|
|
207
232
|
this.embeddedBff?.invalidate();
|
|
@@ -285,7 +310,34 @@ class Agent extends framework_mounter_1.default {
|
|
|
285
310
|
this.customizer.use(plugin, options);
|
|
286
311
|
return this;
|
|
287
312
|
}
|
|
313
|
+
addGateway(options) {
|
|
314
|
+
if (this.gateway)
|
|
315
|
+
throw new Error('addGateway can only be called once.');
|
|
316
|
+
if (this.startupBegun) {
|
|
317
|
+
throw new Error('addGateway must be called before start(): the agent is already starting.');
|
|
318
|
+
}
|
|
319
|
+
if (this.mcpEnabled || this.embeddedBff)
|
|
320
|
+
throw new Error(GATEWAY_MIXING);
|
|
321
|
+
const services = (0, gateway_1.resolveGatewayServices)(options);
|
|
322
|
+
this.gateway = {
|
|
323
|
+
basePath: options.basePath ?? '',
|
|
324
|
+
services,
|
|
325
|
+
allowedOAuthClients: options.allowedOAuthClients,
|
|
326
|
+
};
|
|
327
|
+
if (services.mcp) {
|
|
328
|
+
this.mcpEnabled = true;
|
|
329
|
+
this.mcpEnabledTools = services.mcp.enabledTools;
|
|
330
|
+
this.mcpTokenTtl = services.mcp.tokenTtl;
|
|
331
|
+
this.mcpAllowedOAuthClients = options.allowedOAuthClients;
|
|
332
|
+
this.mcpFileUploads = services.mcp.fileUploads;
|
|
333
|
+
}
|
|
334
|
+
if (services.api)
|
|
335
|
+
this.getInProcessDispatcher();
|
|
336
|
+
return this;
|
|
337
|
+
}
|
|
288
338
|
/**
|
|
339
|
+
* @deprecated Use `addGateway({ mcp })`. Keeps its current paths and semantics.
|
|
340
|
+
*
|
|
289
341
|
* Enable MCP (Model Context Protocol) server support.
|
|
290
342
|
* This allows AI assistants to interact with your Forest Admin data.
|
|
291
343
|
*
|
|
@@ -316,6 +368,8 @@ class Agent extends framework_mounter_1.default {
|
|
|
316
368
|
* agent.mountAiMcpServer({ fileUploads: false });
|
|
317
369
|
*/
|
|
318
370
|
mountAiMcpServer(options) {
|
|
371
|
+
if (this.gateway)
|
|
372
|
+
throw new Error(GATEWAY_MIXING);
|
|
319
373
|
if (this.embeddedBff && (0, bff_routes_1.collidesWithBff)(options?.basePath)) {
|
|
320
374
|
throw new Error(bffMcpCollision(options?.basePath));
|
|
321
375
|
}
|
|
@@ -363,6 +417,8 @@ class Agent extends framework_mounter_1.default {
|
|
|
363
417
|
return this;
|
|
364
418
|
}
|
|
365
419
|
/**
|
|
420
|
+
* @deprecated Use `addGateway({ api })`. Keeps serving on `/bff`.
|
|
421
|
+
*
|
|
366
422
|
* Serve a BFF in-process, alongside the agent, at `/bff` — no second deployment, no second port.
|
|
367
423
|
* The agent builds it on start(), stops it on stop(), and hands it a dispatcher that reaches its
|
|
368
424
|
* own stack without a socket, so this works the same on every mount target.
|
|
@@ -391,6 +447,8 @@ class Agent extends framework_mounter_1.default {
|
|
|
391
447
|
* .start();
|
|
392
448
|
*/
|
|
393
449
|
addBff(options = {}) {
|
|
450
|
+
if (this.gateway)
|
|
451
|
+
throw new Error(GATEWAY_MIXING);
|
|
394
452
|
if (this.embeddedBff) {
|
|
395
453
|
throw new Error('addBff can only be called once.');
|
|
396
454
|
}
|
|
@@ -405,15 +463,75 @@ class Agent extends framework_mounter_1.default {
|
|
|
405
463
|
if ((0, bff_routes_1.collidesWithBff)(this.mcpBasePath)) {
|
|
406
464
|
throw new Error(bffMcpCollision(this.mcpBasePath));
|
|
407
465
|
}
|
|
408
|
-
const bff = new embedded_bff_1.default(this.options, options);
|
|
466
|
+
const bff = new embedded_bff_1.default(this.options, options, { prefix: bff_routes_1.BFF_PREFIX });
|
|
409
467
|
this.embeddedBff = bff;
|
|
410
468
|
// Registered now rather than at start(): getInProcessDispatcher() pushes its hook the first
|
|
411
469
|
// time it is called, and mount() only runs the hooks registered before it — asked for later,
|
|
412
470
|
// the dispatcher would have no handler until the first restart.
|
|
413
471
|
this.getInProcessDispatcher();
|
|
414
|
-
this.setBffCallback(bff.handle);
|
|
472
|
+
this.setBffCallback((0, bff_routes_1.createBffAliasCallback)(bff.handle, this.options.logger));
|
|
415
473
|
return this;
|
|
416
474
|
}
|
|
475
|
+
async prepareGateway() {
|
|
476
|
+
if (!this.gateway)
|
|
477
|
+
return;
|
|
478
|
+
const { services } = this.gateway;
|
|
479
|
+
if (!services.mcp && !services.api) {
|
|
480
|
+
throw new Error('addGateway() enables no service: pass mcp, api, or both, e.g. addGateway({ mcp: true }).');
|
|
481
|
+
}
|
|
482
|
+
(0, forestadmin_client_1.normalizeDomainList)(this.gateway.allowedOAuthClients);
|
|
483
|
+
const { createGatewaySwitch, makeIsMcpRoute, normalizeMountPath } = await Promise.resolve().then(() => __importStar(require('@forestadmin/mcp-server')));
|
|
484
|
+
const basePath = normalizeMountPath(this.gateway.basePath, 'basePath');
|
|
485
|
+
(0, gateway_1.assertNoGatewayOverlap)(basePath, this.completeMountPrefix, services);
|
|
486
|
+
this.gateway.basePath = basePath;
|
|
487
|
+
if (services.mcp)
|
|
488
|
+
this.mcpBasePath = basePath || undefined;
|
|
489
|
+
const bff = services.api ? this.gatewayApi(basePath, services.api) : null;
|
|
490
|
+
const api = bff ? { matches: (path) => bff.claims(path), callback: bff.handle } : null;
|
|
491
|
+
const isMcpRoute = makeIsMcpRoute(basePath);
|
|
492
|
+
const mcpStarting = services.mcp ? (0, gateway_1.mcpUnavailable)(isMcpRoute, 'starting') : null;
|
|
493
|
+
if (services.mcp)
|
|
494
|
+
this.gateway.mcpStopped = (0, gateway_1.mcpUnavailable)(isMcpRoute, 'stopped');
|
|
495
|
+
this.gateway.build = mcp => createGatewaySwitch({
|
|
496
|
+
basePath,
|
|
497
|
+
mcp: mcp ?? mcpStarting ?? undefined,
|
|
498
|
+
api: api ?? undefined,
|
|
499
|
+
});
|
|
500
|
+
}
|
|
501
|
+
gatewayApi(basePath, options) {
|
|
502
|
+
this.embeddedBff ?? (this.embeddedBff = new embedded_bff_1.default(this.options, options, {
|
|
503
|
+
prefix: `${basePath}/api`,
|
|
504
|
+
name: 'The Gateway API',
|
|
505
|
+
requiredVersion: gateway_1.AGENT_BFF_PEER_VERSION,
|
|
506
|
+
skipIpWhitelistWarning: Boolean(this.gateway?.services.mcp),
|
|
507
|
+
allowedOAuthClients: this.gateway?.allowedOAuthClients,
|
|
508
|
+
gateway: true,
|
|
509
|
+
}));
|
|
510
|
+
return this.embeddedBff;
|
|
511
|
+
}
|
|
512
|
+
warnIfMcpAliasUsed() {
|
|
513
|
+
if (!this.mcpEnabled || this.gateway)
|
|
514
|
+
return;
|
|
515
|
+
this.options.logger('Warn', '[MCP] mountAiMcpServer() is deprecated: use addGateway({ mcp }) instead. ' +
|
|
516
|
+
'It keeps serving on its current paths.');
|
|
517
|
+
}
|
|
518
|
+
setRootHandlers(mcp) {
|
|
519
|
+
if (!this.gateway?.build) {
|
|
520
|
+
this.setMcpCallback(mcp ?? null);
|
|
521
|
+
return;
|
|
522
|
+
}
|
|
523
|
+
const stopped = this.isStopped ? this.gateway.mcpStopped : undefined;
|
|
524
|
+
this.setGatewayCallback(this.gateway.build(stopped ?? mcp));
|
|
525
|
+
}
|
|
526
|
+
logGatewayRoutes() {
|
|
527
|
+
if (!this.gateway)
|
|
528
|
+
return;
|
|
529
|
+
const { basePath, services, allowedOAuthClients } = this.gateway;
|
|
530
|
+
(0, gateway_1.describeGatewayRoutes)(basePath, services).forEach(line => this.options.logger('Info', line));
|
|
531
|
+
if (allowedOAuthClients && !(0, gateway_1.servesOAuth)(services)) {
|
|
532
|
+
this.options.logger('Warn', '[Gateway] allowedOAuthClients is set but no OAuth route is served (MCP off, API OAuth off).');
|
|
533
|
+
}
|
|
534
|
+
}
|
|
417
535
|
getRoutes(dataSource, services) {
|
|
418
536
|
return (0, routes_1.default)(dataSource, this.options, services);
|
|
419
537
|
}
|
|
@@ -455,12 +573,17 @@ class Agent extends framework_mounter_1.default {
|
|
|
455
573
|
if (!isFeatureEnabled)
|
|
456
574
|
return;
|
|
457
575
|
const base = normalizeMcpBasePath(this.mcpBasePath);
|
|
576
|
+
const apiNote = this.gateway?.services.api
|
|
577
|
+
? ` The Gateway API on ${base}/api/* escapes it too: it reaches the agent in-process, ` +
|
|
578
|
+
'which the whitelist exempts as a trusted loopback caller. API calls still require an ' +
|
|
579
|
+
'API key or an OAuth session.'
|
|
580
|
+
: '';
|
|
458
581
|
this.options.logger('Warn', '[MCP] The IP whitelist is enabled for this environment, but it filters none of the MCP ' +
|
|
459
582
|
`routes (${base}/mcp, ${base}/mcp/uploads, ${base}/oauth/*, ` +
|
|
460
583
|
`/.well-known/oauth-authorization-server${base}, ` +
|
|
461
584
|
`/.well-known/oauth-protected-resource${base}/mcp): its middleware is mounted on the ` +
|
|
462
585
|
`/forest router only, so these routes escape it for any caller. Tool calls on ${base}/mcp ` +
|
|
463
|
-
|
|
586
|
+
`still require a valid MCP OAuth token.${apiNote}`);
|
|
464
587
|
}
|
|
465
588
|
catch (error) {
|
|
466
589
|
this.options.logger('Debug', `[MCP] Could not read the IP whitelist configuration: ${error instanceof Error ? error.message : String(error)}`);
|
|
@@ -616,4 +739,4 @@ class Agent extends framework_mounter_1.default {
|
|
|
616
739
|
}
|
|
617
740
|
}
|
|
618
741
|
exports.default = Agent;
|
|
619
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWdlbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvYWdlbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFxQkEsOEVBQTBFO0FBQzFFLGlFQUF5QztBQUN6QyxxREFBNkI7QUFDN0IseURBQWlDO0FBQ2pDLDBDQUFrRDtBQUNsRCxrR0FBc0Q7QUFFdEQsK0NBQXVEO0FBQ3ZELDZDQUEyRDtBQUMzRCxrRUFBeUM7QUFDekMsOEZBQW9FO0FBQ3BFLDRFQUFtRDtBQUNuRCxzREFBa0M7QUFDbEMsMERBQXNDO0FBQ3RDLGtHQUFpRjtBQUNqRiwyREFBd0Y7QUFDeEYsZ0ZBQThEO0FBQzlELGtGQUF5RDtBQUV6RCw2RkFBNkY7QUFDN0YsK0ZBQStGO0FBQy9GLHFGQUFxRjtBQUNyRixNQUFNLG9CQUFvQixHQUFHLENBQUMsUUFBaUIsRUFBVSxFQUFFLENBQ3pELElBQUksQ0FBQyxRQUFRLElBQUksRUFBRSxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxPQUFPLENBQUMsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7QUFFeEUsTUFBTSxlQUFlLEdBQUcsQ0FBQyxXQUFtQixFQUFFLEVBQUUsQ0FDOUMsaUVBQWlFLFdBQVcsZ0JBQWdCO0lBQzVGLHNCQUFzQix1QkFBVSx1Q0FBdUMsdUJBQVUsVUFBVTtJQUMzRixHQUFHLHVCQUFVLHdDQUF3QyxDQUFDO0FBRXhEOzs7Ozs7Ozs7R0FTRztBQUNILE1BQXFCLEtBQW1DLFNBQVEsMkJBQWdCO0lBOEI5RTs7Ozs7Ozs7Ozs7Ozs7O09BZUc7SUFDSCxZQUFZLE9BQXFCO1FBQy9CLE1BQU0sVUFBVSxHQUFHLDJCQUFnQixDQUFDLFFBQVEsQ0FBQywyQkFBZ0IsQ0FBQyxZQUFZLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztRQUNyRixLQUFLLENBQUMsVUFB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
|
|
742
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWdlbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvYWdlbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUF3QkEsOEVBQTBFO0FBQzFFLHdFQUFzRTtBQUN0RSxpRUFBeUM7QUFDekMscURBQTZCO0FBQzdCLHlEQUFpQztBQUNqQywwQ0FBa0Q7QUFDbEQsa0dBQXNEO0FBRXRELCtDQUF1RDtBQUN2RCw2Q0FBbUY7QUFDbkYsa0VBQXlDO0FBQ3pDLDhGQUFvRTtBQUNwRSw0RUFBbUQ7QUFDbkQsdUNBT21CO0FBQ25CLHNEQUFrQztBQUNsQywwREFBc0M7QUFDdEMsa0dBQWlGO0FBQ2pGLDJEQUF3RjtBQUN4RixnRkFBOEQ7QUFDOUQsa0ZBQXlEO0FBRXpELDZGQUE2RjtBQUM3RiwrRkFBK0Y7QUFDL0YscUZBQXFGO0FBQ3JGLE1BQU0sb0JBQW9CLEdBQUcsQ0FBQyxRQUFpQixFQUFVLEVBQUUsQ0FDekQsSUFBSSxDQUFDLFFBQVEsSUFBSSxFQUFFLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQztBQUV4RSxNQUFNLGVBQWUsR0FBRyxDQUFDLFdBQW1CLEVBQUUsRUFBRSxDQUM5QyxpRUFBaUUsV0FBVyxnQkFBZ0I7SUFDNUYsc0JBQXNCLHVCQUFVLHVDQUF1Qyx1QkFBVSxVQUFVO0lBQzNGLEdBQUcsdUJBQVUsd0NBQXdDLENBQUM7QUFFeEQsTUFBTSxjQUFjLEdBQ2xCLHVGQUF1RjtJQUN2RixpRUFBaUUsQ0FBQztBQUVwRTs7Ozs7Ozs7O0dBU0c7QUFDSCxNQUFxQixLQUFtQyxTQUFRLDJCQUFnQjtJQXVDOUU7Ozs7Ozs7Ozs7Ozs7OztPQWVHO0lBQ0gsWUFBWSxPQUFxQjtRQUMvQixNQUFNLFVBQVUsR0FBRywyQkFBZ0IsQ0FB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
|
package/dist/bff-routes.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { HttpCallback } from './types';
|
|
2
|
+
import type { Logger } from '@forestadmin/datasource-toolkit';
|
|
1
3
|
/**
|
|
2
4
|
* Where an embedded BFF answers, at the root of the host application. Fixed: the BFF serves its own
|
|
3
5
|
* `/oauth/*` and `/docs`, which would otherwise collide with the MCP server's root paths and with
|
|
@@ -14,6 +16,10 @@ export declare function isBffRoute(url: string): boolean;
|
|
|
14
16
|
* as a malformed request rather than as the root.
|
|
15
17
|
*/
|
|
16
18
|
export declare function stripBffPrefix(url: string): string;
|
|
19
|
+
export declare const BFF_DEPRECATION_TIMESTAMP: number;
|
|
20
|
+
export declare const BFF_DEPRECATION_LINK = "https://docs.forestadmin.com/product/embed/bff";
|
|
21
|
+
export declare const BFF_DEPRECATION_LOG_INTERVAL_MS: number;
|
|
22
|
+
export declare function createBffAliasCallback(handle: HttpCallback, logger: Logger): HttpCallback;
|
|
17
23
|
/**
|
|
18
24
|
* Whether an MCP mount path would land inside `/bff`. The MCP server normalizes its `basePath`
|
|
19
25
|
* (trim, leading slash, collapsed and stripped trailing slashes) before deriving
|
package/dist/bff-routes.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.BFF_PREFIX = void 0;
|
|
3
|
+
exports.BFF_DEPRECATION_LOG_INTERVAL_MS = exports.BFF_DEPRECATION_LINK = exports.BFF_DEPRECATION_TIMESTAMP = exports.BFF_PREFIX = void 0;
|
|
4
4
|
exports.isBffRoute = isBffRoute;
|
|
5
5
|
exports.stripBffPrefix = stripBffPrefix;
|
|
6
|
+
exports.createBffAliasCallback = createBffAliasCallback;
|
|
6
7
|
exports.collidesWithBff = collidesWithBff;
|
|
7
8
|
/**
|
|
8
9
|
* Where an embedded BFF answers, at the root of the host application. Fixed: the BFF serves its own
|
|
@@ -23,11 +24,59 @@ function isBffRoute(url) {
|
|
|
23
24
|
* as a malformed request rather than as the root.
|
|
24
25
|
*/
|
|
25
26
|
function stripBffPrefix(url) {
|
|
27
|
+
if (!isBffRoute(url))
|
|
28
|
+
return url;
|
|
26
29
|
const remainder = url.slice(exports.BFF_PREFIX.length);
|
|
27
30
|
if (remainder === '')
|
|
28
31
|
return '/';
|
|
29
32
|
return remainder.startsWith('/') ? remainder : `/${remainder}`;
|
|
30
33
|
}
|
|
34
|
+
exports.BFF_DEPRECATION_TIMESTAMP = Date.UTC(2026, 9, 5) / 1000;
|
|
35
|
+
exports.BFF_DEPRECATION_LINK = 'https://docs.forestadmin.com/product/embed/bff';
|
|
36
|
+
exports.BFF_DEPRECATION_LOG_INTERVAL_MS = 60 * 60 * 1000;
|
|
37
|
+
const EXPOSE_HEADERS = 'Access-Control-Expose-Headers';
|
|
38
|
+
const DEPRECATION_HEADERS = ['Deprecation', 'Link'];
|
|
39
|
+
const DEPRECATION_LINK = `<${exports.BFF_DEPRECATION_LINK}>; rel="deprecation"`;
|
|
40
|
+
function headerValues(res, name) {
|
|
41
|
+
const value = res.getHeader(name);
|
|
42
|
+
return value === undefined ? [] : [value].flat().map(String);
|
|
43
|
+
}
|
|
44
|
+
function markDeprecated(res) {
|
|
45
|
+
const exposed = headerValues(res, EXPOSE_HEADERS)
|
|
46
|
+
.flatMap(value => value.split(','))
|
|
47
|
+
.map(name => name.trim())
|
|
48
|
+
.filter(Boolean);
|
|
49
|
+
const links = headerValues(res, 'Link');
|
|
50
|
+
res.setHeader('Deprecation', `@${exports.BFF_DEPRECATION_TIMESTAMP}`);
|
|
51
|
+
if (!links.includes(DEPRECATION_LINK)) {
|
|
52
|
+
res.setHeader('Link', [...links, DEPRECATION_LINK].join(', '));
|
|
53
|
+
}
|
|
54
|
+
res.setHeader(EXPOSE_HEADERS, [...new Set([...exposed, ...DEPRECATION_HEADERS])].join(', '));
|
|
55
|
+
}
|
|
56
|
+
function markDeprecatedOnWriteHead(res) {
|
|
57
|
+
const { writeHead } = res;
|
|
58
|
+
res.writeHead = ((...args) => {
|
|
59
|
+
markDeprecated(res);
|
|
60
|
+
return writeHead.apply(res, args);
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
function createBffAliasCallback(handle, logger) {
|
|
64
|
+
let lastWarnedAt = null;
|
|
65
|
+
return (req, res, next) => {
|
|
66
|
+
const now = Date.now();
|
|
67
|
+
if (lastWarnedAt === null || now - lastWarnedAt >= exports.BFF_DEPRECATION_LOG_INTERVAL_MS) {
|
|
68
|
+
lastWarnedAt = now;
|
|
69
|
+
logger('Warn', `[BFF] ${exports.BFF_PREFIX}/* is deprecated and was called: use addGateway({ api }), ` +
|
|
70
|
+
`which serves the same routes under <basePath>/api (/api by default). ` +
|
|
71
|
+
`See ${exports.BFF_DEPRECATION_LINK}`);
|
|
72
|
+
}
|
|
73
|
+
const aliasReq = req;
|
|
74
|
+
aliasReq.originalUrl ?? (aliasReq.originalUrl = req.url);
|
|
75
|
+
req.url = stripBffPrefix(req.url ?? exports.BFF_PREFIX);
|
|
76
|
+
markDeprecatedOnWriteHead(res);
|
|
77
|
+
handle(req, res, next);
|
|
78
|
+
};
|
|
79
|
+
}
|
|
31
80
|
/**
|
|
32
81
|
* Whether an MCP mount path would land inside `/bff`. The MCP server normalizes its `basePath`
|
|
33
82
|
* (trim, leading slash, collapsed and stripped trailing slashes) before deriving
|
|
@@ -46,4 +95,4 @@ function collidesWithBff(mcpBasePath) {
|
|
|
46
95
|
.replace(/\/+$/, '');
|
|
47
96
|
return isBffRoute(`${normalized}/mcp`);
|
|
48
97
|
}
|
|
49
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
98
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmZmLXJvdXRlcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9iZmYtcm91dGVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQWNBLGdDQUlDO0FBT0Qsd0NBUUM7QUEwQ0Qsd0RBc0JDO0FBU0QsMENBWUM7QUFsSEQ7Ozs7R0FJRztBQUNVLFFBQUEsVUFBVSxHQUFHLE1BQU0sQ0FBQztBQUVqQzs7R0FFRztBQUNILFNBQWdCLFVBQVUsQ0FBQyxHQUFXO0lBQ3BDLE1BQU0sQ0FBQyxRQUFRLENBQUMsR0FBRyxHQUFHLENBQUMsS0FBSyxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQztJQUV4QyxPQUFPLFFBQVEsS0FBSyxrQkFBVSxJQUFJLFFBQVEsQ0FBQyxVQUFVLENBQUMsR0FBRyxrQkFBVSxHQUFHLENBQUMsQ0FBQztBQUMxRSxDQUFDO0FBRUQ7Ozs7R0FJRztBQUNILFNBQWdCLGNBQWMsQ0FBQyxHQUFXO0lBQ3hDLElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDO1FBQUUsT0FBTyxHQUFHLENBQUM7SUFFakMsTUFBTSxTQUFTLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQyxrQkFBVSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBRS9DLElBQUksU0FBUyxLQUFLLEVBQUU7UUFBRSxPQUFPLEdBQUcsQ0FBQztJQUVqQyxPQUFPLFNBQVMsQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsSUFBSSxTQUFTLEVBQUUsQ0FBQztBQUNqRSxDQUFDO0FBRVksUUFBQSx5QkFBeUIsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDO0FBQ3hELFFBQUEsb0JBQW9CLEdBQUcsZ0RBQWdELENBQUM7QUFDeEUsUUFBQSwrQkFBK0IsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQztBQUU5RCxNQUFNLGNBQWMsR0FBRywrQkFBK0IsQ0FBQztBQUN2RCxNQUFNLG1CQUFtQixHQUFHLENBQUMsYUFBYSxFQUFFLE1BQU0sQ0FBQyxDQUFDO0FBQ3BELE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSw0QkFBb0Isc0JBQXNCLENBQUM7QUFFeEUsU0FBUyxZQUFZLENBQUMsR0FBbUIsRUFBRSxJQUFZO0lBQ3JELE1BQU0sS0FBSyxHQUFHLEdBQUcsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLENBQUM7SUFFbEMsT0FBTyxLQUFLLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0FBQy9ELENBQUM7QUFFRCxTQUFTLGNBQWMsQ0FBQyxHQUFtQjtJQUN6QyxNQUFNLE9BQU8sR0FBRyxZQUFZLENBQUMsR0FBRyxFQUFFLGNBQWMsQ0FBQztTQUM5QyxPQUFPLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1NBQ2xDLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztTQUN4QixNQUFNLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDbkIsTUFBTSxLQUFLLEdBQUcsWUFBWSxDQUFDLEdBQUcsRUFBRSxNQUFNLENBQUMsQ0FBQztJQUV4QyxHQUFHLENBQUMsU0FBUyxDQUFDLGFBQWEsRUFBRSxJQUFJLGlDQUF5QixFQUFFLENBQUMsQ0FBQztJQUU5RCxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxFQUFFLENBQUM7UUFDdEMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxHQUFHLEtBQUssRUFBRSxnQkFBZ0IsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO0lBQ2pFLENBQUM7SUFFRCxHQUFHLENBQUMsU0FBUyxDQUFDLGNBQWMsRUFBRSxDQUFDLEdBQUcsSUFBSSxHQUFHLENBQUMsQ0FBQyxHQUFHLE9BQU8sRUFBRSxHQUFHLG1CQUFtQixDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO0FBQy9GLENBQUM7QUFFRCxTQUFTLHlCQUF5QixDQUFDLEdBQW1CO0lBQ3BELE1BQU0sRUFBRSxTQUFTLEVBQUUsR0FBRyxHQUFHLENBQUM7SUFFMUIsR0FBRyxDQUFDLFNBQVMsR0FBRyxDQUFDLENBQUMsR0FBRyxJQUFrQyxFQUFFLEVBQUU7UUFDekQsY0FBYyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBRXBCLE9BQU8sU0FBUyxDQUFDLEtBQUssQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFDcEMsQ0FBQyxDQUFxQixDQUFDO0FBQ3pCLENBQUM7QUFFRCxTQUFnQixzQkFBc0IsQ0FBQyxNQUFvQixFQUFFLE1BQWM7SUFDekUsSUFBSSxZQUFZLEdBQWtCLElBQUksQ0FBQztJQUV2QyxPQUFPLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsRUFBRTtRQUN4QixNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7UUFFdkIsSUFBSSxZQUFZLEtBQUssSUFBSSxJQUFJLEdBQUcsR0FBRyxZQUFZLElBQUksdUNBQStCLEVBQUUsQ0FBQztZQUNuRixZQUFZLEdBQUcsR0FBRyxDQUFDO1lBQ25CLE1BQU0sQ0FDSixNQUFNLEVBQ04sU0FBUyxrQkFBVSw0REFBNEQ7Z0JBQzdFLHVFQUF1RTtnQkFDdkUsT0FBTyw0QkFBb0IsRUFBRSxDQUNoQyxDQUFDO1FBQ0osQ0FBQztRQUVELE1BQU0sUUFBUSxHQUFHLEdBQTRDLENBQUM7UUFDOUQsUUFBUSxDQUFDLFdBQVcsS0FBcEIsUUFBUSxDQUFDLFdBQVcsR0FBSyxHQUFHLENBQUMsR0FBRyxFQUFDO1FBQ2pDLEdBQUcsQ0FBQyxHQUFHLEdBQUcsY0FBYyxDQUFDLEdBQUcsQ0FBQyxHQUFHLElBQUksa0JBQVUsQ0FBQyxDQUFDO1FBQ2hELHlCQUF5QixDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQy9CLE1BQU0sQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLElBQUksQ0FBQyxDQUFDO0lBQ3pCLENBQUMsQ0FBQztBQUNKLENBQUM7QUFFRDs7Ozs7O0dBTUc7QUFDSCxTQUFnQixlQUFlLENBQUMsV0FBb0I7SUFDbEQsSUFBSSxDQUFDLFdBQVc7UUFBRSxPQUFPLEtBQUssQ0FBQztJQUUvQixNQUFNLE9BQU8sR0FBRyxXQUFXLENBQUMsSUFBSSxFQUFFLENBQUM7SUFFbkMsSUFBSSxPQUFPLEtBQUssRUFBRSxJQUFJLE9BQU8sS0FBSyxHQUFHO1FBQUUsT0FBTyxLQUFLLENBQUM7SUFFcEQsTUFBTSxVQUFVLEdBQUcsQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLElBQUksT0FBTyxFQUFFLENBQUM7U0FDbkUsT0FBTyxDQUFDLE1BQU0sRUFBRSxHQUFHLENBQUM7U0FDcEIsT0FBTyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsQ0FBQztJQUV2QixPQUFPLFVBQVUsQ0FBQyxHQUFHLFVBQVUsTUFBTSxDQUFDLENBQUM7QUFDekMsQ0FBQyJ9
|
package/dist/embedded-bff.d.ts
CHANGED
|
@@ -1,19 +1,32 @@
|
|
|
1
1
|
import type { AgentOptionsWithDefaults, BffEmbedOptions, HttpCallback } from './types';
|
|
2
|
-
import type { AgentDispatcher } from '@forestadmin/agent-bff';
|
|
2
|
+
import type { AgentDispatcher, ConfigLabels } from '@forestadmin/agent-bff';
|
|
3
|
+
export declare const GATEWAY_API_CONFIG_LABELS: ConfigLabels;
|
|
4
|
+
export type EmbeddedBffMount = {
|
|
5
|
+
prefix: string;
|
|
6
|
+
name?: string;
|
|
7
|
+
requiredVersion?: string;
|
|
8
|
+
skipIpWhitelistWarning?: boolean;
|
|
9
|
+
allowedOAuthClients?: string[];
|
|
10
|
+
gateway?: boolean;
|
|
11
|
+
};
|
|
3
12
|
/** How long `stop()` waits for the activity-log writes no connection holds. */
|
|
4
13
|
export declare const SHUTDOWN_TIMEOUT_MS = 10000;
|
|
5
14
|
/**
|
|
6
15
|
* Owns the lifecycle of a BFF embedded in the agent process: configuration, dynamic loading of the
|
|
7
|
-
* optional package, build, and the request handler the agent mounts
|
|
8
|
-
* the callback and delegates start/stop.
|
|
16
|
+
* optional package, build, and the request handler the agent mounts under its prefix. The agent
|
|
17
|
+
* only wires the callback and delegates start/stop.
|
|
9
18
|
*/
|
|
10
19
|
export default class EmbeddedBff {
|
|
11
20
|
private readonly options;
|
|
12
21
|
private readonly embedOptions;
|
|
22
|
+
private readonly mount;
|
|
13
23
|
private config;
|
|
14
24
|
private bff;
|
|
15
25
|
private stopped;
|
|
16
|
-
|
|
26
|
+
private claimsBffPath;
|
|
27
|
+
constructor(options: AgentOptionsWithDefaults, embedOptions: BffEmbedOptions, mount: EmbeddedBffMount);
|
|
28
|
+
private get name();
|
|
29
|
+
private log;
|
|
17
30
|
/**
|
|
18
31
|
* Load the package and validate the options the caller handed to `addBff()`. Called before the
|
|
19
32
|
* agent mounts anything: everything checked here is caller input, and `parseConfig` throws on a
|
|
@@ -21,6 +34,8 @@ export default class EmbeddedBff {
|
|
|
21
34
|
* where failing after mount() would leave the host with a live `/forest` and a bricked `/bff`.
|
|
22
35
|
*/
|
|
23
36
|
prepare(): Promise<void>;
|
|
37
|
+
private assertRequiredVersion;
|
|
38
|
+
claims(pathname: string): boolean;
|
|
24
39
|
/**
|
|
25
40
|
* Build the BFF. Called from agent.start() after mount(), because the dispatcher only reaches the
|
|
26
41
|
* agent's own stack once that stack is mounted.
|
|
@@ -56,8 +71,10 @@ export default class EmbeddedBff {
|
|
|
56
71
|
*/
|
|
57
72
|
stop(): Promise<void>;
|
|
58
73
|
/**
|
|
59
|
-
* The callback the agent registers
|
|
60
|
-
*
|
|
74
|
+
* The callback the agent registers under the mount prefix, handed requests already stripped of
|
|
75
|
+
* it: terminal, it never strips nor calls `next`. Answers 503 rather than falling through while
|
|
76
|
+
* the BFF is not serving: a 404 from the host would read as "wrong url" instead of "not
|
|
77
|
+
* available".
|
|
61
78
|
* Boot and shutdown are told apart, because a probe should wait on the first and drain on the
|
|
62
79
|
* second.
|
|
63
80
|
*/
|
package/dist/embedded-bff.js
CHANGED
|
@@ -33,8 +33,21 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.SHUTDOWN_TIMEOUT_MS = void 0;
|
|
37
|
-
const
|
|
36
|
+
exports.SHUTDOWN_TIMEOUT_MS = exports.GATEWAY_API_CONFIG_LABELS = void 0;
|
|
37
|
+
const gateway_1 = require("./gateway");
|
|
38
|
+
const BFF_PACKAGE = '@forestadmin/agent-bff';
|
|
39
|
+
exports.GATEWAY_API_CONFIG_LABELS = {
|
|
40
|
+
FOREST_AUTH_SECRET: 'authSecret',
|
|
41
|
+
FOREST_ENV_SECRET: 'envSecret',
|
|
42
|
+
FOREST_SERVER_URL: 'forestServerUrl',
|
|
43
|
+
FOREST_APP_URL: 'forestAppUrl',
|
|
44
|
+
BFF_TOKEN_ENCRYPTION_KEY: 'api.tokenEncryptionKey',
|
|
45
|
+
BFF_ALLOWED_ORIGINS: 'api.allowedOrigins',
|
|
46
|
+
BFF_DEFAULT_TIMEZONE: 'api.defaultTimezone',
|
|
47
|
+
BFF_AGENT_TIMEOUT_MS: 'api.agentTimeoutMs',
|
|
48
|
+
BFF_AI_TIMEOUT_MS: 'api.aiTimeoutMs',
|
|
49
|
+
BFF_OPENAPI_ENABLED: 'api.openapiEnabled',
|
|
50
|
+
};
|
|
38
51
|
/** How long `stop()` waits for the activity-log writes no connection holds. */
|
|
39
52
|
exports.SHUTDOWN_TIMEOUT_MS = 10000;
|
|
40
53
|
/**
|
|
@@ -43,34 +56,38 @@ exports.SHUTDOWN_TIMEOUT_MS = 10000;
|
|
|
43
56
|
* hand — their `message` and `stack` are not enumerable, so `JSON.stringify` alone turns the one
|
|
44
57
|
* value worth logging into `{}`. Never throws — logging must not break a request.
|
|
45
58
|
*/
|
|
46
|
-
function formatLog(message, context) {
|
|
59
|
+
function formatLog(tag, message, context) {
|
|
47
60
|
if (!context || Object.keys(context).length === 0)
|
|
48
|
-
return
|
|
61
|
+
return `${tag} ${message}`;
|
|
49
62
|
try {
|
|
50
63
|
const serialized = JSON.stringify(context, (_key, value) => value instanceof Error
|
|
51
64
|
? { name: value.name, message: value.message, stack: value.stack }
|
|
52
65
|
: value);
|
|
53
|
-
return
|
|
66
|
+
return `${tag} ${message} ${serialized}`;
|
|
54
67
|
}
|
|
55
68
|
catch {
|
|
56
|
-
return
|
|
69
|
+
return `${tag} ${message} [unserializable context]`;
|
|
57
70
|
}
|
|
58
71
|
}
|
|
59
72
|
/**
|
|
60
73
|
* Owns the lifecycle of a BFF embedded in the agent process: configuration, dynamic loading of the
|
|
61
|
-
* optional package, build, and the request handler the agent mounts
|
|
62
|
-
* the callback and delegates start/stop.
|
|
74
|
+
* optional package, build, and the request handler the agent mounts under its prefix. The agent
|
|
75
|
+
* only wires the callback and delegates start/stop.
|
|
63
76
|
*/
|
|
64
77
|
class EmbeddedBff {
|
|
65
|
-
constructor(options, embedOptions) {
|
|
78
|
+
constructor(options, embedOptions, mount) {
|
|
66
79
|
this.options = options;
|
|
67
80
|
this.embedOptions = embedOptions;
|
|
81
|
+
this.mount = mount;
|
|
68
82
|
this.config = null;
|
|
69
83
|
this.bff = null;
|
|
70
84
|
this.stopped = false;
|
|
85
|
+
this.claimsBffPath = null;
|
|
71
86
|
/**
|
|
72
|
-
* The callback the agent registers
|
|
73
|
-
*
|
|
87
|
+
* The callback the agent registers under the mount prefix, handed requests already stripped of
|
|
88
|
+
* it: terminal, it never strips nor calls `next`. Answers 503 rather than falling through while
|
|
89
|
+
* the BFF is not serving: a 404 from the host would read as "wrong url" instead of "not
|
|
90
|
+
* available".
|
|
74
91
|
* Boot and shutdown are told apart, because a probe should wait on the first and drain on the
|
|
75
92
|
* second.
|
|
76
93
|
*/
|
|
@@ -78,21 +95,22 @@ class EmbeddedBff {
|
|
|
78
95
|
if (!this.bff) {
|
|
79
96
|
const type = this.stopped ? 'bff_stopped' : 'bff_not_started';
|
|
80
97
|
const message = this.stopped
|
|
81
|
-
?
|
|
82
|
-
:
|
|
98
|
+
? `${this.name} was stopped with the agent.`
|
|
99
|
+
: `${this.name} is not started yet.`;
|
|
83
100
|
res.statusCode = 503;
|
|
84
101
|
res.setHeader('Content-Type', 'application/json');
|
|
85
102
|
res.end(JSON.stringify({ error: { type, status: 503, message } }));
|
|
86
103
|
return;
|
|
87
104
|
}
|
|
88
|
-
// The BFF knows nothing of the prefix it is served under. `originalUrl` is claimed before the
|
|
89
|
-
// rewrite so a host logger reading it still reports the url the client asked for.
|
|
90
|
-
const bffReq = req;
|
|
91
|
-
bffReq.originalUrl ?? (bffReq.originalUrl = bffReq.url);
|
|
92
|
-
req.url = (0, bff_routes_1.stripBffPrefix)(req.url ?? bff_routes_1.BFF_PREFIX);
|
|
93
105
|
this.bff.callback(req, res);
|
|
94
106
|
};
|
|
95
107
|
}
|
|
108
|
+
get name() {
|
|
109
|
+
return this.mount.name ?? 'The embedded BFF';
|
|
110
|
+
}
|
|
111
|
+
log(message, context) {
|
|
112
|
+
return formatLog(this.mount.gateway ? '[Gateway API]' : '[BFF]', message, context);
|
|
113
|
+
}
|
|
96
114
|
/**
|
|
97
115
|
* Load the package and validate the options the caller handed to `addBff()`. Called before the
|
|
98
116
|
* agent mounts anything: everything checked here is caller input, and `parseConfig` throws on a
|
|
@@ -100,9 +118,12 @@ class EmbeddedBff {
|
|
|
100
118
|
* where failing after mount() would leave the host with a live `/forest` and a bricked `/bff`.
|
|
101
119
|
*/
|
|
102
120
|
async prepare() {
|
|
103
|
-
const
|
|
121
|
+
const bffPackage = await this.importPackage();
|
|
122
|
+
const { parseConfig, IN_PROCESS_AGENT_URL } = bffPackage;
|
|
104
123
|
const { embedOptions } = this;
|
|
105
|
-
this.
|
|
124
|
+
this.assertRequiredVersion(bffPackage.version);
|
|
125
|
+
this.claimsBffPath = bffPackage.claimsBffPath;
|
|
126
|
+
const env = {
|
|
106
127
|
FOREST_AUTH_SECRET: this.options.authSecret,
|
|
107
128
|
FOREST_ENV_SECRET: this.options.envSecret,
|
|
108
129
|
FOREST_SERVER_URL: this.options.forestServerUrl,
|
|
@@ -117,7 +138,20 @@ class EmbeddedBff {
|
|
|
117
138
|
// Off unless asked for: the document is not filtered per caller, so mounting a BFF must not
|
|
118
139
|
// publish the name of every exposed collection and field on an already-open port.
|
|
119
140
|
BFF_OPENAPI_ENABLED: String(embedOptions.openapiEnabled ?? false),
|
|
120
|
-
}
|
|
141
|
+
};
|
|
142
|
+
this.config = parseConfig(env, this.mount.gateway ? exports.GATEWAY_API_CONFIG_LABELS : undefined);
|
|
143
|
+
}
|
|
144
|
+
assertRequiredVersion(installed) {
|
|
145
|
+
const { requiredVersion } = this.mount;
|
|
146
|
+
if (!requiredVersion || installed === requiredVersion)
|
|
147
|
+
return;
|
|
148
|
+
throw new Error(`addGateway({ api }) requires ${BFF_PACKAGE} ${requiredVersion}, found ${installed}. ` +
|
|
149
|
+
`Install it with \`npm install ${BFF_PACKAGE}@${requiredVersion}\`.`);
|
|
150
|
+
}
|
|
151
|
+
claims(pathname) {
|
|
152
|
+
if (!this.claimsBffPath)
|
|
153
|
+
return false;
|
|
154
|
+
return this.claimsBffPath(pathname, { docs: this.embedOptions.openapiEnabled ?? false });
|
|
121
155
|
}
|
|
122
156
|
/**
|
|
123
157
|
* Build the BFF. Called from agent.start() after mount(), because the dispatcher only reaches the
|
|
@@ -133,7 +167,10 @@ class EmbeddedBff {
|
|
|
133
167
|
const bff = await buildBff({
|
|
134
168
|
config: this.config,
|
|
135
169
|
dispatcher,
|
|
136
|
-
basePath:
|
|
170
|
+
basePath: this.mount.prefix,
|
|
171
|
+
allowedOAuthClients: this.mount.allowedOAuthClients,
|
|
172
|
+
gatewayVersion: gateway_1.AGENT_VERSION,
|
|
173
|
+
...(this.mount.gateway ? { labels: exports.GATEWAY_API_CONFIG_LABELS, name: 'Gateway API' } : {}),
|
|
137
174
|
// Counters are the schema cache's and the action-endpoint resolver's only channel — they take
|
|
138
175
|
// no logger — and every one of them reports a failure, so they go to the host's logs. Gauges
|
|
139
176
|
// do not: they are periodic cache sizes, and the default console sink reports them at Info,
|
|
@@ -142,18 +179,19 @@ class EmbeddedBff {
|
|
|
142
179
|
// Tags carried through: `action_endpoint_error` and `action_endpoint_miss` name the
|
|
143
180
|
// rendering, collection and action that failed, which is the whole of what makes the line
|
|
144
181
|
// actionable — the metric name alone says only that something, somewhere, did not resolve.
|
|
145
|
-
increment: (name, tags) => this.options.logger('Warn',
|
|
182
|
+
increment: (name, tags) => this.options.logger('Warn', this.log(`metric ${name}`, tags)),
|
|
146
183
|
gauge: () => undefined,
|
|
147
184
|
},
|
|
148
|
-
logger: (level, message, context) => this.options.logger(level,
|
|
185
|
+
logger: (level, message, context) => this.options.logger(level, this.log(message, context)),
|
|
149
186
|
});
|
|
150
187
|
// stop() may have landed while buildBff() was in flight. Assigning anyway would resurrect a
|
|
151
188
|
// stopped agent's /bff — dispatching into the stack it just tore down instead of answering 503.
|
|
152
189
|
if (this.stopped)
|
|
153
190
|
return;
|
|
154
191
|
this.bff = bff;
|
|
155
|
-
this.options.logger('Info',
|
|
156
|
-
|
|
192
|
+
this.options.logger('Info', this.log(`${this.mount.name ?? 'Embedded BFF'} mounted on ${this.mount.prefix}`));
|
|
193
|
+
if (!this.mount.skipIpWhitelistWarning)
|
|
194
|
+
await this.warnIfExemptFromIpWhitelist();
|
|
157
195
|
}
|
|
158
196
|
/**
|
|
159
197
|
* The whitelist exempts a caller arriving over a loopback socket with no proxy hop, which is
|
|
@@ -173,13 +211,13 @@ class EmbeddedBff {
|
|
|
173
211
|
const { isFeatureEnabled } = await this.options.forestAdminClient.getIpWhitelistConfiguration();
|
|
174
212
|
if (!isFeatureEnabled)
|
|
175
213
|
return;
|
|
176
|
-
this.options.logger('Warn',
|
|
177
|
-
`${
|
|
214
|
+
this.options.logger('Warn', this.log(`The IP whitelist is enabled for this environment, but requests served under ` +
|
|
215
|
+
`${this.mount.prefix} are not subject to it: they reach the agent in-process, which the ` +
|
|
178
216
|
`whitelist exempts as a trusted loopback caller. A resolved API key or a valid OAuth ` +
|
|
179
217
|
`session is still required.`));
|
|
180
218
|
}
|
|
181
219
|
catch (error) {
|
|
182
|
-
this.options.logger('Debug',
|
|
220
|
+
this.options.logger('Debug', this.log('Could not read the IP whitelist configuration', {
|
|
183
221
|
cause: error instanceof Error ? error.message : String(error),
|
|
184
222
|
}));
|
|
185
223
|
}
|
|
@@ -210,7 +248,7 @@ class EmbeddedBff {
|
|
|
210
248
|
const unfinished = await bff.drainActivityLogs(timeoutMs);
|
|
211
249
|
if (unfinished.length === 0)
|
|
212
250
|
return;
|
|
213
|
-
this.options.logger('Warn',
|
|
251
|
+
this.options.logger('Warn', this.log(`Stopped ${this.mount.gateway ? 'the Gateway API' : 'the embedded BFF'} with activity logs still in flight`, {
|
|
214
252
|
timeoutMs,
|
|
215
253
|
unfinished,
|
|
216
254
|
}));
|
|
@@ -228,7 +266,7 @@ class EmbeddedBff {
|
|
|
228
266
|
// also fires on a broken transitive dependency, a SyntaxError from a partial install, or a
|
|
229
267
|
// throw during the package's own evaluation — none of which "install it" would fix.
|
|
230
268
|
const { message } = error;
|
|
231
|
-
const wrapped = new Error(
|
|
269
|
+
const wrapped = new Error(`${this.name} requires the \`@forestadmin/agent-bff\` package, which failed to ` +
|
|
232
270
|
`load: ${message}. Install it with \`npm install @forestadmin/agent-bff\`.`);
|
|
233
271
|
// Assigned rather than passed to the constructor: the repo targets ES2020, whose lib types no
|
|
234
272
|
// options bag on Error. A plain assignment carries the cause on every runtime, and the reason
|
|
@@ -239,4 +277,4 @@ class EmbeddedBff {
|
|
|
239
277
|
}
|
|
240
278
|
}
|
|
241
279
|
exports.default = EmbeddedBff;
|
|
242
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
280
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW1iZWRkZWQtYmZmLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2VtYmVkZGVkLWJmZi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFTQSx1Q0FBMEM7QUFFMUMsTUFBTSxXQUFXLEdBQUcsd0JBQXdCLENBQUM7QUFFaEMsUUFBQSx5QkFBeUIsR0FBaUI7SUFDckQsa0JBQWtCLEVBQUUsWUFBWTtJQUNoQyxpQkFBaUIsRUFBRSxXQUFXO0lBQzlCLGlCQUFpQixFQUFFLGlCQUFpQjtJQUNwQyxjQUFjLEVBQUUsY0FBYztJQUM5Qix3QkFBd0IsRUFBRSx3QkFBd0I7SUFDbEQsbUJBQW1CLEVBQUUsb0JBQW9CO0lBQ3pDLG9CQUFvQixFQUFFLHFCQUFxQjtJQUMzQyxvQkFBb0IsRUFBRSxvQkFBb0I7SUFDMUMsaUJBQWlCLEVBQUUsaUJBQWlCO0lBQ3BDLG1CQUFtQixFQUFFLG9CQUFvQjtDQUMxQyxDQUFDO0FBV0YsK0VBQStFO0FBQ2xFLFFBQUEsbUJBQW1CLEdBQUcsS0FBTSxDQUFDO0FBRTFDOzs7OztHQUtHO0FBQ0gsU0FBUyxTQUFTLENBQUMsR0FBVyxFQUFFLE9BQWUsRUFBRSxPQUFpQztJQUNoRixJQUFJLENBQUMsT0FBTyxJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsTUFBTSxLQUFLLENBQUM7UUFBRSxPQUFPLEdBQUcsR0FBRyxJQUFJLE9BQU8sRUFBRSxDQUFDO0lBRTlFLElBQUksQ0FBQztRQUNILE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsT0FBTyxFQUFFLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBRSxFQUFFLENBQ3pELEtBQUssWUFBWSxLQUFLO1lBQ3BCLENBQUMsQ0FBQyxFQUFFLElBQUksRUFBRSxLQUFLLENBQUMsSUFBSSxFQUFFLE9BQU8sRUFBRSxLQUFLLENBQUMsT0FBTyxFQUFFLEtBQUssRUFB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
|
|
@@ -15,7 +15,7 @@ export default class FrameworkMounter {
|
|
|
15
15
|
private readonly inProcessDispatcher;
|
|
16
16
|
private inProcessHookRegistered;
|
|
17
17
|
/** Compute the prefix that the main router should be mounted at in the client's application */
|
|
18
|
-
|
|
18
|
+
protected get completeMountPrefix(): string;
|
|
19
19
|
constructor(prefix: string, logger: Logger);
|
|
20
20
|
/**
|
|
21
21
|
* Register the MCP server at the root of the host application, or `null` to unregister it. The
|
|
@@ -24,6 +24,7 @@ export default class FrameworkMounter {
|
|
|
24
24
|
*/
|
|
25
25
|
protected setMcpCallback(handler: RootHandler | null): void;
|
|
26
26
|
/** Serve an embedded BFF at `/bff`. Pass null to stop answering there. */
|
|
27
|
+
protected setGatewayCallback(handler: RootHandler): void;
|
|
27
28
|
protected setBffCallback(callback: HttpCallback | null): void;
|
|
28
29
|
/**
|
|
29
30
|
* Dispatcher that runs agent-client requests against the agent's own `/forest` stack in-memory.
|
|
@@ -36,6 +36,9 @@ class FrameworkMounter {
|
|
|
36
36
|
this.rootMiddleware.set('mcp', handler);
|
|
37
37
|
}
|
|
38
38
|
/** Serve an embedded BFF at `/bff`. Pass null to stop answering there. */
|
|
39
|
+
setGatewayCallback(handler) {
|
|
40
|
+
this.rootMiddleware.set('gateway', handler);
|
|
41
|
+
}
|
|
39
42
|
setBffCallback(callback) {
|
|
40
43
|
this.rootMiddleware.set('bff', callback && { callback, matches: bff_routes_1.isBffRoute });
|
|
41
44
|
}
|
|
@@ -208,4 +211,4 @@ class FrameworkMounter {
|
|
|
208
211
|
}
|
|
209
212
|
}
|
|
210
213
|
exports.default = FrameworkMounter;
|
|
211
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
214
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZnJhbWV3b3JrLW1vdW50ZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvZnJhbWV3b3JrLW1vdW50ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFLQSx5REFBaUM7QUFDakMsK0JBQW9DO0FBQ3BDLDhDQUFzQjtBQUN0QixnREFBd0I7QUFFeEIsNkNBQTBDO0FBQzFDLHdFQUErQztBQUMvQyw0RkFBOEQ7QUFDOUQsd0VBQStDO0FBRS9DLE1BQXFCLGdCQUFnQjtJQWdCbkMsK0ZBQStGO0lBQy9GLElBQWMsbUJBQW1CO1FBQy9CLE9BQU8sY0FBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxNQUFNLEVBQUUsUUFBUSxDQUFDLENBQUM7SUFDckQsQ0FBQztJQUVELFlBQVksTUFBYyxFQUFFLE1BQWM7UUFqQnpCLGlCQUFZLEdBQTRCLEVBQUUsQ0FBQztRQUMzQyxnQkFBVyxHQUEwQyxFQUFFLENBQUM7UUFFeEQsV0FBTSxHQUE0QixFQUFFLENBQUM7UUFPOUMsNEJBQXVCLEdBQUcsS0FBSyxDQUFDO1FBUXRDLElBQUksQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDO1FBQ3JCLElBQUksQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDO1FBQ3JCLElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSx5QkFBYyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ2pELElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSx5QkFBYyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ2pELElBQUksQ0FBQyxtQkFBbUIsR0FBRyxJQUFJLG1DQUFtQixDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQzdELENBQUM7SUFFRDs7OztPQUlHO0lBQ08sY0FBYyxDQUFDLE9BQTJCO1FBQ2xELElBQUksQ0FBQyxjQUFjLENBQUMsR0FBRyxDQUFDLEtBQUssRUFBRSxPQUFPLENBQUMsQ0FBQztJQUMxQyxDQUFDO0lBRUQsMEVBQTBFO0lBQ2hFLGtC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
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { BffEmbedOptions, GatewayOptions, McpEmbedOptions, RootHandler } from './types';
|
|
2
|
+
export declare const AGENT_BFF_PEER_VERSION: string;
|
|
3
|
+
export declare const AGENT_VERSION: string;
|
|
4
|
+
declare const MCP_UNAVAILABLE: {
|
|
5
|
+
starting: string;
|
|
6
|
+
stopped: string;
|
|
7
|
+
};
|
|
8
|
+
export declare function mcpUnavailable(isMcpRoute: (url: string) => boolean, state: keyof typeof MCP_UNAVAILABLE): RootHandler;
|
|
9
|
+
export type GatewayMcpOptions = Omit<McpEmbedOptions, 'basePath' | 'allowedOAuthClients'>;
|
|
10
|
+
export type GatewayServices = {
|
|
11
|
+
mcp: GatewayMcpOptions | null;
|
|
12
|
+
api: BffEmbedOptions | null;
|
|
13
|
+
};
|
|
14
|
+
export declare function resolveGatewayServices({ mcp, api }: GatewayOptions): GatewayServices;
|
|
15
|
+
export declare function assertNoGatewayOverlap(basePath: string, forestPath: string, { mcp, api }: GatewayServices): void;
|
|
16
|
+
export declare function servesOAuth({ mcp, api }: GatewayServices): boolean;
|
|
17
|
+
export declare function describeGatewayRoutes(basePath: string, { mcp, api }: GatewayServices): string[];
|
|
18
|
+
export {};
|
|
19
|
+
//# sourceMappingURL=gateway.d.ts.map
|
package/dist/gateway.js
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AGENT_VERSION = exports.AGENT_BFF_PEER_VERSION = void 0;
|
|
4
|
+
exports.mcpUnavailable = mcpUnavailable;
|
|
5
|
+
exports.resolveGatewayServices = resolveGatewayServices;
|
|
6
|
+
exports.assertNoGatewayOverlap = assertNoGatewayOverlap;
|
|
7
|
+
exports.servesOAuth = servesOAuth;
|
|
8
|
+
exports.describeGatewayRoutes = describeGatewayRoutes;
|
|
9
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires, import/no-dynamic-require, global-require
|
|
10
|
+
const { peerDependencies, version } = require('../package.json');
|
|
11
|
+
exports.AGENT_BFF_PEER_VERSION = peerDependencies['@forestadmin/agent-bff'];
|
|
12
|
+
exports.AGENT_VERSION = version;
|
|
13
|
+
const isWithin = (path, root) => path === root || path.startsWith(`${root}/`);
|
|
14
|
+
const HTTP_SERVICE_UNAVAILABLE = 503;
|
|
15
|
+
const MCP_UNAVAILABLE = {
|
|
16
|
+
starting: 'The MCP server is not started yet.',
|
|
17
|
+
stopped: 'The MCP server was stopped with the agent.',
|
|
18
|
+
};
|
|
19
|
+
function mcpUnavailable(isMcpRoute, state) {
|
|
20
|
+
return {
|
|
21
|
+
matches: isMcpRoute,
|
|
22
|
+
callback: (_req, res) => {
|
|
23
|
+
res.statusCode = HTTP_SERVICE_UNAVAILABLE;
|
|
24
|
+
res.setHeader('Content-Type', 'application/json');
|
|
25
|
+
res.end(JSON.stringify({
|
|
26
|
+
error: 'temporarily_unavailable',
|
|
27
|
+
error_description: MCP_UNAVAILABLE[state],
|
|
28
|
+
}));
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
const TOP_LEVEL_OPTIONS = ['basePath', 'allowedOAuthClients'];
|
|
33
|
+
function resolveService(service) {
|
|
34
|
+
if (service === true)
|
|
35
|
+
return {};
|
|
36
|
+
return service || null;
|
|
37
|
+
}
|
|
38
|
+
function resolveGatewayServices({ mcp, api }) {
|
|
39
|
+
const mcpOptions = resolveService(mcp);
|
|
40
|
+
const nested = TOP_LEVEL_OPTIONS.find(option => mcpOptions && option in mcpOptions);
|
|
41
|
+
if (nested) {
|
|
42
|
+
throw new Error(`addGateway({ mcp: { ${nested} } }) is not supported: ${nested} covers every Gateway ` +
|
|
43
|
+
`service, set it as addGateway({ ${nested} }).`);
|
|
44
|
+
}
|
|
45
|
+
return { mcp: mcpOptions, api: resolveService(api) };
|
|
46
|
+
}
|
|
47
|
+
function assertNoGatewayOverlap(basePath, forestPath, { mcp, api }) {
|
|
48
|
+
if (basePath && isWithin(basePath, forestPath)) {
|
|
49
|
+
throw new Error(`basePath "${basePath}" overlaps the agent routes on ${forestPath}: ` +
|
|
50
|
+
'change the Gateway basePath or the agent prefix.');
|
|
51
|
+
}
|
|
52
|
+
const claimed = [
|
|
53
|
+
...(mcp ? [{ path: `${basePath}/mcp`, service: 'MCP' }] : []),
|
|
54
|
+
...(mcp || api ? [{ path: `${basePath}/oauth`, service: mcp ? 'MCP' : 'API' }] : []),
|
|
55
|
+
...(api ? [{ path: `${basePath}/api/agent`, service: 'API' }] : []),
|
|
56
|
+
];
|
|
57
|
+
const overlap = claimed.find(({ path }) => isWithin(forestPath, path));
|
|
58
|
+
if (overlap) {
|
|
59
|
+
throw new Error(`The agent routes on ${forestPath} overlap ${overlap.path}, claimed by the Gateway ` +
|
|
60
|
+
`${overlap.service}: change the agent prefix or the Gateway basePath.`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
function servesInMemoryUploads({ fileUploads, enabledTools }) {
|
|
64
|
+
if (fileUploads === false || fileUploads?.storage)
|
|
65
|
+
return false;
|
|
66
|
+
return !enabledTools || enabledTools.includes('requestActionFileUpload');
|
|
67
|
+
}
|
|
68
|
+
function servesOAuth({ mcp, api }) {
|
|
69
|
+
return Boolean(mcp || api?.tokenEncryptionKey);
|
|
70
|
+
}
|
|
71
|
+
function describeGatewayRoutes(basePath, { mcp, api }) {
|
|
72
|
+
const lines = [];
|
|
73
|
+
if (mcp) {
|
|
74
|
+
const routes = [
|
|
75
|
+
`${basePath}/mcp`,
|
|
76
|
+
...(servesInMemoryUploads(mcp) ? [`${basePath}/mcp/uploads`] : []),
|
|
77
|
+
`${basePath}/oauth/*`,
|
|
78
|
+
`/.well-known/oauth-authorization-server${basePath}`,
|
|
79
|
+
`/.well-known/oauth-protected-resource${basePath}/mcp`,
|
|
80
|
+
];
|
|
81
|
+
lines.push(`[Gateway] MCP: ${routes.join(', ')}`);
|
|
82
|
+
}
|
|
83
|
+
if (api) {
|
|
84
|
+
const routes = [
|
|
85
|
+
`${basePath}/api/agent/*`,
|
|
86
|
+
`${basePath}/api/health`,
|
|
87
|
+
...(api.openapiEnabled ? [`${basePath}/api/docs`] : []),
|
|
88
|
+
];
|
|
89
|
+
const oauth = api.tokenEncryptionKey
|
|
90
|
+
? `, ${basePath}/oauth/*?service=api`
|
|
91
|
+
: ' (API OAuth off: no tokenEncryptionKey)';
|
|
92
|
+
lines.push(`[Gateway] API: ${routes.join(', ')}${oauth}`);
|
|
93
|
+
}
|
|
94
|
+
return lines;
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2F0ZXdheS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9nYXRld2F5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQXFCQSx3Q0FpQkM7QUFjRCx3REFZQztBQUVELHdEQXlCQztBQVFELGtDQUVDO0FBRUQsc0RBNkJDO0FBbElELHlHQUF5RztBQUN6RyxNQUFNLEVBQUUsZ0JBQWdCLEVBQUUsT0FBTyxFQUFFLEdBQUcsT0FBTyxDQUFDLGlCQUFpQixDQUc5RCxDQUFDO0FBRVcsUUFBQSxzQkFBc0IsR0FBRyxnQkFBZ0IsQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDO0FBRXBFLFFBQUEsYUFBYSxHQUFHLE9BQU8sQ0FBQztBQUVyQyxNQUFNLFFBQVEsR0FBRyxDQUFDLElBQVksRUFBRSxJQUFZLEVBQUUsRUFBRSxDQUFDLElBQUksS0FBSyxJQUFJLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLElBQUksR0FBRyxDQUFDLENBQUM7QUFFOUYsTUFBTSx3QkFBd0IsR0FBRyxHQUFHLENBQUM7QUFFckMsTUFBTSxlQUFlLEdBQUc7SUFDdEIsUUFBUSxFQUFFLG9DQUFvQztJQUM5QyxPQUFPLEVBQUUsNENBQTRDO0NBQ3RELENBQUM7QUFFRixTQUFnQixjQUFjLENBQzVCLFVBQW9DLEVBQ3BDLEtBQW1DO0lBRW5DLE9BQU87UUFDTCxPQUFPLEVBQUUsVUFBVTtRQUNuQixRQUFRLEVBQUUsQ0FBQyxJQUFJLEVBQUUsR0FBRyxFQUFFLEVBQUU7WUFDdEIsR0FBRyxDQUFDLFVBQVUsR0FBRyx3QkFBd0IsQ0FBQztZQUMxQyxHQUFHLENBQUMsU0FBUyxDQUFDLGNBQWMsRUFBRSxrQkFBa0IsQ0FBQyxDQUFDO1lBQ2xELEdBQUcsQ0FBQyxHQUFHLENBQ0wsSUFBSSxDQUFDLFNBQVMsQ0FBQztnQkFDYixLQUFLLEVBQUUseUJBQXlCO2dCQUNoQyxpQkFBaUIsRUFBRSxlQUFlLENBQUMsS0FBSyxDQUFDO2FBQzFDLENBQUMsQ0FDSCxDQUFD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
|
package/dist/index.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import type { TSchema } from '@forestadmin/datasource-customizer';
|
|
|
3
3
|
import Agent from './agent';
|
|
4
4
|
export declare function createAgent<S extends TSchema = TSchema>(options: AgentOptions): Agent<S>;
|
|
5
5
|
export { Agent };
|
|
6
|
-
export { AgentOptions, BffEmbedOptions, WorkflowExecutorEmbedOptions } from './types';
|
|
6
|
+
export { AgentOptions, BffEmbedOptions, GatewayOptions, McpEmbedOptions, WorkflowExecutorEmbedOptions, } from './types';
|
|
7
7
|
export * from '@forestadmin/datasource-customizer';
|
|
8
8
|
export { default as SchemaGenerator } from './utils/forest-schema/generator';
|
|
9
9
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
CHANGED
|
@@ -28,4 +28,4 @@ __exportStar(require("@forestadmin/datasource-customizer"), exports);
|
|
|
28
28
|
// export is necessary for the agent-generator package
|
|
29
29
|
var generator_1 = require("./utils/forest-schema/generator");
|
|
30
30
|
Object.defineProperty(exports, "SchemaGenerator", { enumerable: true, get: function () { return __importDefault(generator_1).default; } });
|
|
31
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
31
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFLQSxrQ0FFQztBQUpELG9EQUE0QjtBQU1uQixnQkFORixlQUFLLENBTUU7QUFKZCxTQUFnQixXQUFXLENBQThCLE9BQXFCO0lBQzVFLE9BQU8sSUFBSSxlQUFLLENBQUksT0FBTyxDQUFDLENBQUM7QUFDL0IsQ0FBQztBQVVELHFFQUFtRDtBQUVuRCxzREFBc0Q7QUFDdEQsNkRBQTZFO0FBQXBFLDZIQUFBLE9BQU8sT0FBbUIifQ==
|
package/dist/types.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { AuditStore } from './audit-trail/types';
|
|
2
2
|
import type { CompositeId, Logger, LoggerLevel } from '@forestadmin/datasource-toolkit';
|
|
3
3
|
import type { ForestAdminClient } from '@forestadmin/forestadmin-client';
|
|
4
|
+
import type { FileUploadsOptions, TokenTtlOptions, ToolName } from '@forestadmin/mcp-server';
|
|
4
5
|
import type { WorkflowExecutorTuningOptions } from '@forestadmin/workflow-executor';
|
|
5
6
|
import type { IncomingMessage, ServerResponse } from 'http';
|
|
6
7
|
export type AuditTrailConfig = {
|
|
@@ -212,6 +213,19 @@ export type BffEmbedOptions = {
|
|
|
212
213
|
*/
|
|
213
214
|
shutdownTimeoutMs?: number;
|
|
214
215
|
};
|
|
216
|
+
export type McpEmbedOptions = {
|
|
217
|
+
enabledTools?: ToolName[];
|
|
218
|
+
basePath?: string;
|
|
219
|
+
tokenTtl?: TokenTtlOptions;
|
|
220
|
+
allowedOAuthClients?: string[];
|
|
221
|
+
fileUploads?: false | FileUploadsOptions;
|
|
222
|
+
};
|
|
223
|
+
export type GatewayOptions = {
|
|
224
|
+
basePath?: string;
|
|
225
|
+
allowedOAuthClients?: string[];
|
|
226
|
+
mcp?: Omit<McpEmbedOptions, 'basePath' | 'allowedOAuthClients'> | boolean;
|
|
227
|
+
api?: BffEmbedOptions | boolean;
|
|
228
|
+
};
|
|
215
229
|
export type AuditTrailRuntime = AuditTrailConfig & {
|
|
216
230
|
store: AuditStore;
|
|
217
231
|
close: () => Promise<void>;
|
package/dist/types.js
CHANGED
|
@@ -22,4 +22,4 @@ var RouteType;
|
|
|
22
22
|
RouteType[RouteType["Authentication"] = 3] = "Authentication";
|
|
23
23
|
RouteType[RouteType["PrivateRoute"] = 4] = "PrivateRoute";
|
|
24
24
|
})(RouteType || (exports.RouteType = RouteType = {}));
|
|
25
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
25
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvdHlwZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBcVBBLElBQVksUUFVWDtBQVZELFdBQVksUUFBUTtJQUNsQixxREFBZ0IsQ0FBQTtJQUNoQix5REFBa0IsQ0FBQTtJQUNsQixtREFBZSxDQUFBO0lBQ2YsaURBQWMsQ0FBQTtJQUNkLDJEQUFtQixDQUFBO0lBQ25CLCtEQUFxQixDQUFBO0lBQ3JCLHVFQUF5QixDQUFBO0lBQ3pCLG1EQUFlLENBQUE7SUFDZixxQ0FBUSxDQUFBO0FBQ1YsQ0FBQyxFQVZXLFFBQVEsd0JBQVIsUUFBUSxRQVVuQjtBQUVELElBQVksU0FPWDtBQVBELFdBQVksU0FBUztJQUNuQixpR0FBaUc7SUFDakcsMkRBQWlCLENBQUE7SUFDakIseURBQWdCLENBQUE7SUFDaEIsdURBQWUsQ0FBQTtJQUNmLDZEQUFrQixDQUFBO0lBQ2xCLHlEQUFnQixDQUFBO0FBQ2xCLENBQUMsRUFQVyxTQUFTLHlCQUFULFNBQVMsUUFPcEIifQ==
|
|
@@ -20,12 +20,14 @@ exports.default = expressToKoa;
|
|
|
20
20
|
*/
|
|
21
21
|
function expressToKoa(expressApp, shouldHandle) {
|
|
22
22
|
return async (ctx, next) => {
|
|
23
|
+
var _a;
|
|
23
24
|
const url = ctx.url || '/';
|
|
24
25
|
// Skip if shouldHandle returns false
|
|
25
26
|
if (shouldHandle && !shouldHandle(url)) {
|
|
26
27
|
await next();
|
|
27
28
|
return;
|
|
28
29
|
}
|
|
30
|
+
(_a = ctx.req).originalUrl ?? (_a.originalUrl = ctx.originalUrl);
|
|
29
31
|
// Let Express handle the request
|
|
30
32
|
const handled = await new Promise(resolve => {
|
|
31
33
|
// Tell Koa not to respond - Express will handle it
|
|
@@ -46,4 +48,4 @@ function expressToKoa(expressApp, shouldHandle) {
|
|
|
46
48
|
}
|
|
47
49
|
};
|
|
48
50
|
}
|
|
49
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
51
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXhwcmVzcy10by1rb2EuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdXRpbHMvZXhwcmVzcy10by1rb2EudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUEwQkEsK0JBc0NDO0FBdkREOzs7Ozs7Ozs7Ozs7Ozs7O0dBZ0JHO0FBQ0gsU0FBd0IsWUFBWSxDQUNsQyxVQUFrQyxFQUNsQyxZQUF1QztJQUV2QyxPQUFPLEtBQUssRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLEVBQUU7O1FBQ3pCLE1BQU0sR0FBRyxHQUFHLEdBQUcsQ0FBQyxHQUFHLElBQUksR0FBRyxDQUFDO1FBRTNCLHFDQUFxQztRQUNyQyxJQUFJLFlBQVksSUFBSSxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQ3ZDLE1BQU0sSUFBSSxFQUFFLENBQUM7WUFFYixPQUFPO1FBQ1QsQ0FBQztRQUVELE1BQUMsR0FBRyxDQUFDLEdBQWlELEVBQUMsV0FBVyxRQUFYLFdBQVcsR0FBSyxHQUFHLENBQUMsV0FBVyxFQUFDO1FBRXZGLGlDQUFpQztRQUNqQyxNQUFNLE9BQU8sR0FBRyxNQUFNLElBQUksT0FBTyxDQUFVLE9BQU8sQ0FBQyxFQUFFO1lBQ25ELG1EQUFtRDtZQUNuRCxHQUFHLENBQUMsT0FBTyxHQUFHLEtBQUssQ0FBQztZQUVwQixNQUFNLFFBQVEsR0FBRyxVQUEwQixDQUFDO1lBQzVDLFFBQVEsQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFO2dCQUM5Qix1REFBdUQ7Z0JBQ3ZELEdBQUcsQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDO2dCQUNuQixPQUFPLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDakIsQ0FBQyxDQUFDLENBQUM7WUFFSCwyQ0FBMkM7WUFDM0MsR0FBRyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLEdBQUcsRUFBRSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO1lBQzVDLEdBQUcsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxHQUFHLEVBQUUsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztRQUM3QyxDQUFDLENBQUMsQ0FBQztRQUVILGlEQUFpRDtRQUNqRCxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDYixNQUFNLElBQUksRUFBRSxDQUFDO1FBQ2YsQ0FBQztJQUNILENBQUMsQ0FBQztBQUNKLENBQUMifQ==
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@forestadmin/agent",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.109.0",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"publishConfig": {
|
|
@@ -16,8 +16,8 @@
|
|
|
16
16
|
"@forestadmin/agent-toolkit": "1.2.1",
|
|
17
17
|
"@forestadmin/datasource-customizer": "1.73.1",
|
|
18
18
|
"@forestadmin/datasource-toolkit": "1.56.1",
|
|
19
|
-
"@forestadmin/forestadmin-client": "1.
|
|
20
|
-
"@forestadmin/mcp-server": "1.
|
|
19
|
+
"@forestadmin/forestadmin-client": "1.44.0",
|
|
20
|
+
"@forestadmin/mcp-server": "1.29.0",
|
|
21
21
|
"@koa/bodyparser": "^6.0.0",
|
|
22
22
|
"@koa/cors": "^5.0.0",
|
|
23
23
|
"@koa/router": "^13.1.0",
|
|
@@ -49,9 +49,9 @@
|
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
51
|
"@fastify/express": "^1.1.0",
|
|
52
|
-
"@forestadmin/agent-bff": "1.
|
|
52
|
+
"@forestadmin/agent-bff": "1.41.0",
|
|
53
53
|
"@forestadmin/datasource-sql": "1.17.16",
|
|
54
|
-
"@forestadmin/workflow-executor": "1.33.
|
|
54
|
+
"@forestadmin/workflow-executor": "1.33.1",
|
|
55
55
|
"@nestjs/common": "^11.1.24",
|
|
56
56
|
"@nestjs/core": "^11.1.24",
|
|
57
57
|
"@nestjs/platform-express": "^11.1.24",
|
|
@@ -75,8 +75,8 @@
|
|
|
75
75
|
},
|
|
76
76
|
"peerDependencies": {
|
|
77
77
|
"@fastify/express": "^1.1.0 || ^2.0.0 || ^3.0.0 || ^4.0.0",
|
|
78
|
-
"@forestadmin/agent-bff": "1.
|
|
79
|
-
"@forestadmin/workflow-executor": "1.33.
|
|
78
|
+
"@forestadmin/agent-bff": "1.41.0",
|
|
79
|
+
"@forestadmin/workflow-executor": "1.33.1"
|
|
80
80
|
},
|
|
81
81
|
"peerDependenciesMeta": {
|
|
82
82
|
"@fastify/express": {
|