@forestadmin/agent-bff 1.25.4 → 1.26.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.
Files changed (46) hide show
  1. package/dist/action/action-routes-middleware.d.ts +3 -3
  2. package/dist/action/action-routes-middleware.js +3 -4
  3. package/dist/action/agent-action-client.d.ts +3 -3
  4. package/dist/action/agent-action-client.js +4 -8
  5. package/dist/agent/agent-transport.d.ts +19 -0
  6. package/dist/agent/agent-transport.js +14 -0
  7. package/dist/agent/in-process-transport.d.ts +33 -0
  8. package/dist/agent/in-process-transport.js +77 -0
  9. package/dist/ai/ai-routes-middleware.d.ts +3 -2
  10. package/dist/ai/ai-routes-middleware.js +22 -2
  11. package/dist/build-bff.d.ts +32 -0
  12. package/dist/build-bff.js +372 -0
  13. package/dist/cli-core.d.ts +0 -12
  14. package/dist/cli-core.js +4 -339
  15. package/dist/cli-dispatch.js +5 -4
  16. package/dist/config/missing-config-warning.d.ts +9 -0
  17. package/dist/config/missing-config-warning.js +17 -0
  18. package/dist/context/context-routes-middleware.d.ts +6 -2
  19. package/dist/context/context-routes-middleware.js +3 -2
  20. package/dist/data/agent-data-client.d.ts +3 -3
  21. package/dist/data/agent-data-client.js +3 -7
  22. package/dist/data/data-routes-middleware.d.ts +3 -3
  23. package/dist/data/data-routes-middleware.js +5 -10
  24. package/dist/http/bff-http-server.d.ts +22 -5
  25. package/dist/http/bff-http-server.js +24 -27
  26. package/dist/http/bff-local-errors.d.ts +2 -0
  27. package/dist/http/bff-local-errors.js +9 -1
  28. package/dist/http/health-route.d.ts +9 -0
  29. package/dist/http/health-route.js +17 -0
  30. package/dist/http/version-header-middleware.d.ts +4 -0
  31. package/dist/http/version-header-middleware.js +12 -0
  32. package/dist/index.d.ts +2 -0
  33. package/dist/index.js +4 -2
  34. package/dist/oauth/environment-fetch-error.d.ts +15 -0
  35. package/dist/oauth/environment-fetch-error.js +34 -0
  36. package/dist/oauth/environment-id.d.ts +25 -0
  37. package/dist/oauth/environment-id.js +72 -0
  38. package/dist/oauth/forest-server-client.d.ts +2 -1
  39. package/dist/oauth/forest-server-client.js +17 -8
  40. package/dist/oauth/oauth-routes.d.ts +2 -1
  41. package/dist/oauth/oauth-routes.js +19 -2
  42. package/dist/openapi/unfolded-document.d.ts +2 -2
  43. package/dist/openapi/unfolded-document.js +2 -6
  44. package/dist/read-model/agent-capabilities-fetcher.d.ts +3 -3
  45. package/dist/read-model/agent-capabilities-fetcher.js +4 -8
  46. package/package.json +1 -1
@@ -0,0 +1,372 @@
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
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.resolveOAuthConfig = resolveOAuthConfig;
40
+ exports.resolveUnfoldSource = resolveUnfoldSource;
41
+ exports.default = buildBff;
42
+ const bodyparser_1 = require("@koa/bodyparser");
43
+ const koa_1 = __importDefault(require("koa"));
44
+ const action_routes_middleware_1 = __importDefault(require("./action/action-routes-middleware"));
45
+ const console_logger_1 = __importDefault(require("./adapters/console-logger"));
46
+ const agent_stub_1 = __importDefault(require("./agent/agent-stub"));
47
+ const agent_transport_1 = require("./agent/agent-transport");
48
+ const ai_proxy_client_1 = __importDefault(require("./ai/ai-proxy-client"));
49
+ const ai_routes_middleware_1 = __importStar(require("./ai/ai-routes-middleware"));
50
+ const api_key_authenticator_1 = __importDefault(require("./api-key/api-key-authenticator"));
51
+ const api_key_client_1 = __importDefault(require("./api-key/api-key-client"));
52
+ const api_key_middleware_1 = __importDefault(require("./api-key/api-key-middleware"));
53
+ const resolve_cache_1 = __importDefault(require("./api-key/resolve-cache"));
54
+ const auth_mode_middleware_1 = __importDefault(require("./auth/auth-mode-middleware"));
55
+ const missing_config_warning_1 = __importDefault(require("./config/missing-config-warning"));
56
+ const context_routes_middleware_1 = __importDefault(require("./context/context-routes-middleware"));
57
+ const cors_middleware_1 = __importDefault(require("./cors/cors-middleware"));
58
+ const per_key_origin_1 = __importDefault(require("./cors/per-key-origin"));
59
+ const data_routes_middleware_1 = __importDefault(require("./data/data-routes-middleware"));
60
+ const docs_routes_1 = __importDefault(require("./docs/docs-routes"));
61
+ const bff_http_error_1 = require("./http/bff-http-error");
62
+ const body_limit_1 = __importStar(require("./http/body-limit"));
63
+ const error_middleware_1 = __importDefault(require("./http/error-middleware"));
64
+ const health_route_1 = __importDefault(require("./http/health-route"));
65
+ const version_header_middleware_1 = __importDefault(require("./http/version-header-middleware"));
66
+ const environment_id_1 = __importStar(require("./oauth/environment-id"));
67
+ const forest_server_client_1 = __importDefault(require("./oauth/forest-server-client"));
68
+ const oauth_routes_1 = __importDefault(require("./oauth/oauth-routes"));
69
+ const session_store_1 = __importDefault(require("./oauth/session-store"));
70
+ const token_cipher_1 = __importDefault(require("./oauth/token-cipher"));
71
+ const openapi_routes_1 = __importStar(require("./openapi/openapi-routes"));
72
+ const permissions_cache_1 = __importDefault(require("./permissions/permissions-cache"));
73
+ const permissions_client_1 = __importDefault(require("./permissions/permissions-client"));
74
+ const permissions_routes_middleware_1 = __importDefault(require("./permissions/permissions-routes-middleware"));
75
+ const agent_path_1 = __importDefault(require("./rate-limit/agent-path"));
76
+ const rate_limit_middleware_1 = __importDefault(require("./rate-limit/rate-limit-middleware"));
77
+ const create_read_model_1 = __importDefault(require("./read-model/create-read-model"));
78
+ const timezone_middleware_1 = __importDefault(require("./timezone/timezone-middleware"));
79
+ const version_1 = __importDefault(require("./version"));
80
+ const SESSION_TTL_SECONDS = 24 * 60 * 60;
81
+ const BODY_METHODS = new Set(['POST', 'PUT', 'PATCH']);
82
+ const JSON_BODY_TYPES = ['application/json', 'application/*+json'];
83
+ function hasBody(ctx) {
84
+ return (ctx.request.length ?? 0) > 0 || ctx.get('transfer-encoding') !== '';
85
+ }
86
+ function createJsonOnlyGuard() {
87
+ return async function jsonOnlyGuard(ctx, next) {
88
+ if (BODY_METHODS.has(ctx.method) && hasBody(ctx) && !ctx.is(JSON_BODY_TYPES)) {
89
+ throw (0, bff_http_error_1.unsupportedMediaType)();
90
+ }
91
+ await next();
92
+ };
93
+ }
94
+ function agentScoped(middleware) {
95
+ return async function scoped(ctx, next) {
96
+ if (!(0, agent_path_1.default)(ctx.path)) {
97
+ await next();
98
+ return;
99
+ }
100
+ await middleware(ctx, next);
101
+ };
102
+ }
103
+ function createBodyParser(hasAiQueryRoute) {
104
+ const extendTypes = { json: JSON_BODY_TYPES };
105
+ const parseBody = (0, bodyparser_1.bodyParser)({ jsonLimit: body_limit_1.default, extendTypes });
106
+ if (!hasAiQueryRoute)
107
+ return parseBody;
108
+ const parseAiBody = (0, bodyparser_1.bodyParser)({
109
+ jsonLimit: body_limit_1.AI_BODY_LIMIT,
110
+ enableTypes: ['json'],
111
+ extendTypes,
112
+ });
113
+ return async function selectedBodyParser(ctx, next) {
114
+ if (ctx.path === ai_routes_middleware_1.AI_QUERY_ROUTE) {
115
+ await parseAiBody(ctx, next);
116
+ return;
117
+ }
118
+ await parseBody(ctx, next);
119
+ };
120
+ }
121
+ function createApiKeyUnavailableGuard(logger) {
122
+ return async function apiKeyUnavailableGuard(ctx, next) {
123
+ if (ctx.state.authMode === 'api-key') {
124
+ logger('Error', 'API key auth requested but the resolver is not configured');
125
+ throw (0, bff_http_error_1.unauthorized)('Credentials could not be validated');
126
+ }
127
+ await next();
128
+ };
129
+ }
130
+ function resolveOAuthConfig(config) {
131
+ const { forestServerUrl, forestEnvSecret, forestAppUrl, forestAuthSecret, tokenEncryptionKey } = config;
132
+ if (forestServerUrl &&
133
+ forestEnvSecret &&
134
+ forestAppUrl &&
135
+ forestAuthSecret &&
136
+ tokenEncryptionKey) {
137
+ return { forestServerUrl, forestEnvSecret, forestAppUrl, forestAuthSecret, tokenEncryptionKey };
138
+ }
139
+ return undefined;
140
+ }
141
+ function buildOAuthMiddlewares(config, logger) {
142
+ const oauthConfig = resolveOAuthConfig(config);
143
+ if (!oauthConfig) {
144
+ logger('Warn', 'OAuth routes disabled: required configuration is missing');
145
+ return { middlewares: [] };
146
+ }
147
+ const { forestServerUrl, forestEnvSecret, forestAppUrl, forestAuthSecret, tokenEncryptionKey } = oauthConfig;
148
+ const serverClient = new forest_server_client_1.default({ forestServerUrl, envSecret: forestEnvSecret });
149
+ const resolveEnvironmentId = (0, environment_id_1.default)(serverClient);
150
+ const sessionStore = (0, session_store_1.default)({
151
+ cipher: (0, token_cipher_1.default)(tokenEncryptionKey),
152
+ now: () => Date.now(),
153
+ sessionTtlSeconds: SESSION_TTL_SECONDS,
154
+ });
155
+ const oauthRoutes = (0, oauth_routes_1.default)({
156
+ serverClient,
157
+ sessionStore,
158
+ forestAppUrl,
159
+ authSecret: forestAuthSecret,
160
+ resolveEnvironmentId,
161
+ logger,
162
+ });
163
+ return {
164
+ middlewares: [oauthRoutes],
165
+ resolveEnvironmentId,
166
+ session: { store: sessionStore, serverClient, forestServerUrl },
167
+ };
168
+ }
169
+ function resolveApiKeyConfig(config) {
170
+ const { forestServerUrl, forestEnvSecret, forestAuthSecret } = config;
171
+ if (forestServerUrl && forestEnvSecret && forestAuthSecret) {
172
+ return { forestServerUrl, forestEnvSecret, forestAuthSecret };
173
+ }
174
+ return undefined;
175
+ }
176
+ function buildApiKeyMiddleware(config, logger) {
177
+ const apiKeyConfig = resolveApiKeyConfig(config);
178
+ if (!apiKeyConfig) {
179
+ logger('Warn', 'API key auth disabled: required configuration is missing');
180
+ return undefined;
181
+ }
182
+ const client = new api_key_client_1.default({
183
+ forestServerUrl: apiKeyConfig.forestServerUrl,
184
+ envSecret: apiKeyConfig.forestEnvSecret,
185
+ });
186
+ const cache = (0, resolve_cache_1.default)({ now: () => Date.now() });
187
+ const authenticator = (0, api_key_authenticator_1.default)({
188
+ client,
189
+ cache,
190
+ authSecret: apiKeyConfig.forestAuthSecret,
191
+ });
192
+ return (0, api_key_middleware_1.default)({ authenticator, logger });
193
+ }
194
+ /**
195
+ * The read-model store the data routes, the action routes, the permissions endpoint and the OpenAPI
196
+ * unfolding all share — one cache, one schema fetch. Needs no agent: the permissions endpoint and the
197
+ * schema itself come from the SaaS.
198
+ */
199
+ function resolveReadModelBundle(config, logger, metrics) {
200
+ const apiKeyConfig = resolveApiKeyConfig(config);
201
+ if (!apiKeyConfig)
202
+ return undefined;
203
+ const { store } = (0, create_read_model_1.default)({
204
+ forestServerUrl: apiKeyConfig.forestServerUrl,
205
+ envSecret: apiKeyConfig.forestEnvSecret,
206
+ logger,
207
+ metrics,
208
+ });
209
+ return { store, apiKeyConfig };
210
+ }
211
+ /**
212
+ * When unfolding is possible, in ONE place: the document needs the AGENT_URL the store does not,
213
+ * because a collection's field set comes from the agent capabilities. The server passes the bundle it
214
+ * already built for the data routes; the CLI goes through `resolveUnfoldSource`. Silent on purpose —
215
+ * the two report a missing configuration differently.
216
+ */
217
+ function toUnfoldSource(bundle, config, logger) {
218
+ if (!bundle || !config.agentUrl)
219
+ return undefined;
220
+ return {
221
+ store: bundle.store,
222
+ transport: (0, agent_transport_1.createHttpTransport)({
223
+ agentUrl: config.agentUrl,
224
+ timeoutMs: config.agentTimeoutMs,
225
+ }),
226
+ logger,
227
+ };
228
+ }
229
+ /**
230
+ * Metrics are dropped rather than logged: without an explicit sink `createReadModel` builds a console
231
+ * one, which reports gauges at `Info`, and `createConsoleLogger` sends `Info` to `console.info` — the
232
+ * stdout the document is written to. The server keeps its metrics; the export has no sink for them
233
+ * anyway.
234
+ */
235
+ const UNMEASURED = { increment: () => undefined, gauge: () => undefined };
236
+ function resolveUnfoldSource(config, logger) {
237
+ return toUnfoldSource(resolveReadModelBundle(config, logger, UNMEASURED), config, logger);
238
+ }
239
+ // The data middleware falls through to the action middleware on a non-data path.
240
+ function buildAgentRouteMiddlewares(bundle, config, logger) {
241
+ if (!bundle) {
242
+ logger('Warn', 'Data, action and permissions endpoints disabled: FOREST_SERVER_URL, FOREST_ENV_SECRET or FOREST_AUTH_SECRET is missing');
243
+ return [(0, agent_stub_1.default)()];
244
+ }
245
+ const { store, apiKeyConfig } = bundle;
246
+ const { agentUrl, agentTimeoutMs: timeoutMs } = config;
247
+ const permissionsMiddleware = (0, permissions_routes_middleware_1.default)({
248
+ store,
249
+ client: new permissions_client_1.default({
250
+ forestServerUrl: apiKeyConfig.forestServerUrl,
251
+ envSecret: apiKeyConfig.forestEnvSecret,
252
+ }),
253
+ cache: new permissions_cache_1.default(),
254
+ logger,
255
+ });
256
+ if (!agentUrl) {
257
+ logger('Warn', 'Data and action endpoints disabled: AGENT_URL is missing');
258
+ return [permissionsMiddleware, (0, agent_stub_1.default)()];
259
+ }
260
+ const transport = (0, agent_transport_1.createHttpTransport)({ agentUrl, timeoutMs });
261
+ return [
262
+ permissionsMiddleware,
263
+ (0, data_routes_middleware_1.default)({ store, transport, logger }),
264
+ (0, action_routes_middleware_1.default)({ store, transport, logger }),
265
+ ];
266
+ }
267
+ function buildAiMiddlewares(config, oauth, logger) {
268
+ const { session, resolveEnvironmentId } = oauth;
269
+ if (!session) {
270
+ logger('Warn', 'AI query route disabled: the deployment carries no OAuth session');
271
+ return [];
272
+ }
273
+ const client = new ai_proxy_client_1.default({
274
+ forestServerUrl: session.forestServerUrl,
275
+ timeoutMs: config.aiTimeoutMs,
276
+ });
277
+ return [
278
+ (0, ai_routes_middleware_1.default)({
279
+ client,
280
+ sessionStore: session.store,
281
+ serverClient: session.serverClient,
282
+ resolveEnvironmentId,
283
+ logger,
284
+ }),
285
+ ];
286
+ }
287
+ function buildAgentMiddlewares(config, logger, oauth, aiMiddlewares) {
288
+ const { forestAuthSecret, defaultTimezone } = config;
289
+ if (!forestAuthSecret) {
290
+ logger('Warn', 'Agent edge disabled: FOREST_AUTH_SECRET is missing');
291
+ return [];
292
+ }
293
+ const apiKeyStep = buildApiKeyMiddleware(config, logger) ?? createApiKeyUnavailableGuard(logger);
294
+ // One store for the whole edge. The document only unfolds when the agent is reachable too: with no
295
+ // AGENT_URL every data path answers 501, so concrete paths would advertise a dead surface.
296
+ const bundle = resolveReadModelBundle(config, logger);
297
+ const source = toUnfoldSource(bundle, config, logger);
298
+ const chain = [
299
+ (0, auth_mode_middleware_1.default)({ authSecret: forestAuthSecret }),
300
+ apiKeyStep,
301
+ (0, rate_limit_middleware_1.default)({
302
+ maxRequests: config.rateLimitMaxRequests,
303
+ windowMs: config.rateLimitWindowMs,
304
+ }),
305
+ (0, per_key_origin_1.default)({ logger, serverAllowedOrigins: config.allowedOrigins }),
306
+ (0, openapi_routes_1.default)({
307
+ version: version_1.default,
308
+ enabled: config.openapiEnabled,
309
+ source,
310
+ hasAiQueryRoute: aiMiddlewares.length > 0,
311
+ publicUrl: config.publicUrl,
312
+ }),
313
+ ...(bundle
314
+ ? [
315
+ (0, context_routes_middleware_1.default)({
316
+ store: bundle.store,
317
+ resolveEnvironmentId: oauth.resolveEnvironmentId
318
+ ? (0, environment_id_1.tolerateEnvironmentIdFailure)(oauth.resolveEnvironmentId, logger)
319
+ : undefined,
320
+ }),
321
+ ]
322
+ : []),
323
+ ...aiMiddlewares,
324
+ (0, timezone_middleware_1.default)({ defaultTimezone }),
325
+ ...buildAgentRouteMiddlewares(bundle, config, logger),
326
+ ];
327
+ return chain.map(agentScoped);
328
+ }
329
+ /**
330
+ * Assemble the whole BFF — `/health`, the version header, and every middleware in the one order both
331
+ * deployment modes must share — and hand back the request handler. `runCli` puts it behind a
332
+ * listener; an embedding host mounts it at the root of its own server. The handler is terminal — it
333
+ * answers 404 itself instead of yielding to a host `next()` — and every path it serves is absolute,
334
+ * so a prefix mount would move `/health` and `/agent/...` off the paths the frontend calls.
335
+ */
336
+ async function buildBff({ config, logger = (0, console_logger_1.default)(), }) {
337
+ if (config.invalidAllowedOrigins.length > 0) {
338
+ logger('Warn', 'Ignoring malformed BFF_ALLOWED_ORIGINS entries', {
339
+ entries: config.invalidAllowedOrigins,
340
+ });
341
+ }
342
+ (0, missing_config_warning_1.default)(config, logger);
343
+ const oauth = buildOAuthMiddlewares(config, logger);
344
+ const aiMiddlewares = buildAiMiddlewares(config, oauth, logger);
345
+ const agentMiddlewares = buildAgentMiddlewares(config, logger, oauth, aiMiddlewares);
346
+ const hasAgentEdge = agentMiddlewares.length > 0;
347
+ const agentErrorMiddleware = hasAgentEdge ? [agentScoped((0, error_middleware_1.default)({ logger }))] : [];
348
+ const agentJsonOnlyGuard = hasAgentEdge ? [agentScoped(createJsonOnlyGuard())] : [];
349
+ const middlewares = [
350
+ (0, version_header_middleware_1.default)(version_1.default),
351
+ (0, health_route_1.default)({ config, version: version_1.default }),
352
+ (0, cors_middleware_1.default)({ allowedOrigins: config.allowedOrigins, logger }),
353
+ ...agentErrorMiddleware,
354
+ ...agentJsonOnlyGuard,
355
+ createBodyParser(aiMiddlewares.length > 0),
356
+ ...oauth.middlewares,
357
+ // Outside the agent-scoped chain on purpose: the viewer is a public page, the document it fetches
358
+ // is not. Gated on the edge being mounted too, like the error middleware above: with no agent
359
+ // chain there is no document to fetch, and the page would only ever reach a bare Koa 404.
360
+ (0, docs_routes_1.default)({
361
+ enabled: config.openapiEnabled && agentMiddlewares.length > 0,
362
+ documentPath: openapi_routes_1.OPENAPI_PATH,
363
+ logger,
364
+ }),
365
+ ...agentMiddlewares,
366
+ ];
367
+ const app = new koa_1.default();
368
+ for (const middleware of middlewares)
369
+ app.use(middleware);
370
+ return { callback: app.callback() };
371
+ }
372
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnVpbGQtYmZmLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2J1aWxkLWJmZi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQXdJQSxnREFlQztBQXNKRCxrREFFQztBQWtJRCwyQkEwQ0M7QUFqZEQsZ0RBQTZDO0FBQzdDLDhDQUFzQjtBQUV0QixpR0FBNkU7QUFDN0UsK0VBQTREO0FBQzVELG9FQUEyRDtBQUMzRCw2REFBOEQ7QUFDOUQsMkVBQWlEO0FBQ2pELGtGQUFxRjtBQUNyRiw0RkFBd0U7QUFDeEUsOEVBQW9EO0FBQ3BELHNGQUFrRTtBQUNsRSw0RUFBeUQ7QUFDekQsdUZBQW1FO0FBQ25FLDZGQUFnRTtBQUNoRSxvR0FBZ0Y7QUFDaEYsNkVBQTBEO0FBQzFELDJFQUFpRTtBQUNqRSwyRkFBdUU7QUFDdkUscUVBQWtEO0FBQ2xELDBEQUEyRTtBQUMzRSxnRUFBOEQ7QUFDOUQsK0VBQTREO0FBQzVELHVFQUFvRDtBQUNwRCxpR0FBNkU7QUFDN0UseUVBQW1HO0FBQ25HLHdGQUE4RDtBQUM5RCx3RUFBcUQ7QUFDckQsMEVBQStEO0FBQy9ELHdFQUFxRDtBQUNyRCwyRUFBNkU7QUFDN0Usd0ZBQStEO0FBQy9ELDBGQUFpRTtBQUNqRSxnSEFBNEY7QUFDNUYseUVBQWtEO0FBQ2xELCtGQUEyRTtBQUMzRSx1RkFBNkQ7QUFDN0QseUZBQXNFO0FBQ3RFLHdEQUFnQztBQWNoQyxNQUFNLG1CQUFtQixHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDO0FBRXpDLE1BQU0sWUFBWSxHQUFHLElBQUksR0FBRyxDQUFDLENBQUMsTUFBTSxFQUFFLEtBQUssRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDO0FBRXZELE1BQU0sZUFBZSxHQUFHLENBQUMsa0JBQWtCLEVBQUUsb0JBQW9CLENBQUMsQ0FBQztBQUVuRSxTQUFTLE9BQU8sQ0FBQyxHQUE4QjtJQUM3QyxP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
@@ -1,17 +1,5 @@
1
- import type { BFFConfig } from './config/env-config';
2
- import type { UnfoldSource } from './openapi/unfolded-document';
3
1
  import type { Logger } from './ports/logger-port';
4
2
  import BFFHttpServer from './http/bff-http-server';
5
- interface ResolvedOAuthConfig {
6
- forestServerUrl: string;
7
- forestEnvSecret: string;
8
- forestAppUrl: string;
9
- forestAuthSecret: string;
10
- tokenEncryptionKey: string;
11
- }
12
- export declare function resolveOAuthConfig(config: BFFConfig): ResolvedOAuthConfig | undefined;
13
- export declare function resolveUnfoldSource(config: BFFConfig, logger: Logger): UnfoldSource | undefined;
14
3
  export default function runCli(env: NodeJS.ProcessEnv, logger?: Logger): Promise<BFFHttpServer>;
15
4
  export declare function reportFatalError(err: unknown): void;
16
- export {};
17
5
  //# sourceMappingURL=cli-core.d.ts.map