@forestadmin/gateway 0.0.0-stage → 1.0.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.
@@ -0,0 +1,153 @@
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.GATEWAY_API_NAME = exports.GATEWAY_NAME = void 0;
40
+ exports.default = runGateway;
41
+ const agent_bff_1 = require("@forestadmin/agent-bff");
42
+ const mcp_server_1 = require("@forestadmin/mcp-server");
43
+ const gateway_env_1 = __importStar(require("./gateway-env"));
44
+ const standalone_handler_1 = __importStar(require("./standalone-handler"));
45
+ const version_1 = __importDefault(require("./version"));
46
+ exports.GATEWAY_NAME = 'Forest Gateway';
47
+ exports.GATEWAY_API_NAME = 'Gateway API';
48
+ const MCP_REQUIRED_VARS = ['FOREST_ENV_SECRET', 'FOREST_AUTH_SECRET'];
49
+ function missingMcpVars(env) {
50
+ return MCP_REQUIRED_VARS.filter(name => !env[name]?.trim());
51
+ }
52
+ async function buildMcpService(settings, gateway, logger) {
53
+ const { options, uploadStorageModule } = (0, mcp_server_1.parseMcpEnv)(settings.env, settings.labels);
54
+ const missing = missingMcpVars(settings.env);
55
+ if (missing.length > 0) {
56
+ logger('Error', 'The MCP service is not configured and answers 503 until restart', {
57
+ missing,
58
+ });
59
+ return { handler: (0, standalone_handler_1.createUnavailableMcpHandler)(gateway.basePath), health: 'degraded' };
60
+ }
61
+ const fileUploads = await (0, mcp_server_1.loadFileUploads)(uploadStorageModule);
62
+ const server = new mcp_server_1.ForestMCPServer({
63
+ ...options,
64
+ ...(fileUploads !== undefined && { fileUploads }),
65
+ basePath: gateway.basePath,
66
+ logger: (level, message) => logger(level, `[MCP] ${message}`),
67
+ });
68
+ const baseUrl = new URL(gateway.publicUrl ?? `http://localhost:${gateway.port}`);
69
+ return {
70
+ handler: {
71
+ matches: (0, mcp_server_1.makeIsMcpRoute)(gateway.basePath),
72
+ callback: await server.getHttpCallback(baseUrl),
73
+ },
74
+ health: 'ok',
75
+ };
76
+ }
77
+ async function buildApiService(settings, gateway, logger) {
78
+ const config = (0, agent_bff_1.parseConfig)(settings.env, settings.labels);
79
+ const bff = await (0, agent_bff_1.buildBff)({
80
+ config,
81
+ logger,
82
+ basePath: (0, gateway_env_1.apiBasePath)(gateway.basePath),
83
+ gatewayVersion: version_1.default,
84
+ labels: settings.labels,
85
+ name: exports.GATEWAY_API_NAME,
86
+ allowedOAuthClients: settings.allowedOAuthClients,
87
+ });
88
+ if (!bff.health().configured.oauth) {
89
+ logger('Warn', `API sign-in (${gateway.basePath}/oauth/*?service=api) is off`, {
90
+ ...(!config.tokenEncryptionKey && { set: settings.labels.BFF_TOKEN_ENCRYPTION_KEY }),
91
+ });
92
+ }
93
+ return {
94
+ handler: {
95
+ matches: pathname => (0, agent_bff_1.claimsBffPath)(pathname, { docs: config.openapiEnabled }),
96
+ callback: bff.callback,
97
+ },
98
+ bff,
99
+ };
100
+ }
101
+ function apiHealthOf(api) {
102
+ if (!api)
103
+ return 'disabled';
104
+ const { status, configured } = api.bff.health();
105
+ return { status, configured };
106
+ }
107
+ function logRoutes(gateway, mcp, api, logger) {
108
+ const prefix = gateway.basePath;
109
+ if (mcp) {
110
+ logger('Info', `MCP service on ${prefix}/mcp`, {
111
+ oauth: `${prefix}/oauth/*`,
112
+ discovery: `/.well-known/oauth-authorization-server${prefix}`,
113
+ status: mcp.health,
114
+ });
115
+ }
116
+ if (api) {
117
+ const apiPrefix = (0, gateway_env_1.apiBasePath)(prefix);
118
+ logger('Info', `API service on ${apiPrefix}/agent/*`, {
119
+ health: `${apiPrefix}/health`,
120
+ docs: `${apiPrefix}/docs`,
121
+ oauth: api.bff.health().configured.oauth ? `${prefix}/oauth/*?service=api` : 'API OAuth off',
122
+ });
123
+ }
124
+ logger('Info', 'Gateway health on /health');
125
+ }
126
+ async function runGateway(env, logger = (0, agent_bff_1.createConsoleLogger)()) {
127
+ const gateway = (0, gateway_env_1.default)(env);
128
+ gateway.warnings.forEach(warning => logger('Warn', warning));
129
+ const mcp = gateway.mcp ? await buildMcpService(gateway.mcp, gateway, logger) : undefined;
130
+ const api = gateway.api ? await buildApiService(gateway.api, gateway, logger) : undefined;
131
+ const gatewaySwitch = (0, mcp_server_1.createGatewaySwitch)({
132
+ basePath: gateway.basePath,
133
+ mcp: mcp?.handler,
134
+ api: api?.handler,
135
+ });
136
+ const callback = (0, standalone_handler_1.default)({
137
+ version: version_1.default,
138
+ gatewaySwitch,
139
+ health: () => (0, standalone_handler_1.describeGatewayHealth)(version_1.default, mcp?.health ?? 'disabled', apiHealthOf(api)),
140
+ });
141
+ const server = new agent_bff_1.BFFHttpServer({
142
+ port: gateway.port,
143
+ logger,
144
+ name: exports.GATEWAY_NAME,
145
+ callback,
146
+ drainActivityLogs: api?.bff.drainActivityLogs,
147
+ });
148
+ await server.start();
149
+ (0, agent_bff_1.installShutdownHandlers)(server, logger, { name: exports.GATEWAY_NAME });
150
+ logRoutes(gateway, mcp, api, logger);
151
+ return server;
152
+ }
153
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnVuLWdhdGV3YXkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvcnVuLWdhdGV3YXkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBcUpBLDZCQW9DQztBQXBMRCxzREFPZ0M7QUFDaEMsd0RBTWlDO0FBRWpDLDZEQUE2RDtBQUM3RCwyRUFHOEI7QUFDOUIsd0RBQWdDO0FBRW5CLFFBQUEsWUFBWSxHQUFHLGdCQUFnQixDQUFDO0FBQ2hDLFFBQUEsZ0JBQWdCLEdBQUcsYUFBYSxDQUFDO0FBRTlDLE1BQU0saUJBQWlCLEdBQUcsQ0FBQyxtQkFBbUIsRUFBRSxvQkFBb0IsQ0FBVSxDQUFDO0FBWS9FLFNBQVMsY0FBYyxDQUFDLEdBQXVCO0lBQzdDLE9BQU8saUJBQWlCLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztBQUM5RCxDQUFDO0FBRUQsS0FBSyxVQUFVLGVBQWUsQ0FDNUIsUUFBcUIsRUFDckIsT0FBbUIsRUFDbkIsTUFBYztJQUVkLE1BQU0sRUFBRSxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsR0FBRyxJQUFBLHdCQUFXLEVBQUMsUUFBUSxDQUFDLEdBQUcsRUFBRSxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDcEYsTUFBTSxPQUFPLEdBQUcsY0FBYyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUU3QyxJQUFJLE9BQU8sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7UUFDdkIsTUFBTSxDQUFDLE9BQU8sRUFBRSxpRUFBaUUsRUFBRTtZQUNqRixPQUFPO1NBQ1IsQ0FBQyxDQUFDO1FBRUgsT0FBTyxFQUFFLE9BQU8sRUFBRSxJQUFBLGdEQUEyQixFQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsRUFBRSxNQUFNLEVBQUUsVUFBVSxF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
@@ -0,0 +1,25 @@
1
+ import type { BffHealth } from '@forestadmin/agent-bff';
2
+ import type { GatewayHandler } from '@forestadmin/mcp-server';
3
+ import type { IncomingMessage, ServerResponse } from 'http';
4
+ export declare const GATEWAY_VERSION_HEADER = "X-Forest-Gateway-Version";
5
+ export declare const HEALTH_PATH = "/health";
6
+ export type McpHealth = 'ok' | 'degraded' | 'disabled';
7
+ export type ApiHealth = Pick<BffHealth, 'status' | 'configured'> | 'disabled';
8
+ export interface GatewayHealth {
9
+ healthy: boolean;
10
+ version: string;
11
+ services: {
12
+ mcp: McpHealth;
13
+ api: ApiHealth;
14
+ };
15
+ }
16
+ export interface StandaloneHandlerOptions {
17
+ version: string;
18
+ gatewaySwitch: GatewayHandler;
19
+ health: () => GatewayHealth;
20
+ }
21
+ export type StandaloneCallback = (req: IncomingMessage, res: ServerResponse) => void;
22
+ export declare function describeGatewayHealth(version: string, mcp: McpHealth, api: ApiHealth): GatewayHealth;
23
+ export declare function createUnavailableMcpHandler(basePath: string): GatewayHandler;
24
+ export default function createStandaloneHandler({ version, gatewaySwitch, health, }: StandaloneHandlerOptions): StandaloneCallback;
25
+ //# sourceMappingURL=standalone-handler.d.ts.map
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HEALTH_PATH = exports.GATEWAY_VERSION_HEADER = void 0;
4
+ exports.describeGatewayHealth = describeGatewayHealth;
5
+ exports.createUnavailableMcpHandler = createUnavailableMcpHandler;
6
+ exports.default = createStandaloneHandler;
7
+ const mcp_server_1 = require("@forestadmin/mcp-server");
8
+ exports.GATEWAY_VERSION_HEADER = 'X-Forest-Gateway-Version';
9
+ exports.HEALTH_PATH = '/health';
10
+ const HTTP_OK = 200;
11
+ const HTTP_NOT_FOUND = 404;
12
+ const HTTP_SERVICE_UNAVAILABLE = 503;
13
+ function answerJson(res, status, body) {
14
+ res.statusCode = status;
15
+ res.setHeader('Content-Type', 'application/json');
16
+ res.end(JSON.stringify(body));
17
+ }
18
+ function isHealthRequest(req) {
19
+ const [pathname] = (req.url ?? '/').split(/[?#]/, 1);
20
+ return (req.method === 'GET' || req.method === 'HEAD') && pathname === exports.HEALTH_PATH;
21
+ }
22
+ function describeGatewayHealth(version, mcp, api) {
23
+ const apiDegraded = api !== 'disabled' && api.status === 'degraded';
24
+ return { healthy: mcp !== 'degraded' && !apiDegraded, version, services: { mcp, api } };
25
+ }
26
+ function createUnavailableMcpHandler(basePath) {
27
+ return {
28
+ matches: (0, mcp_server_1.makeIsMcpRoute)(basePath),
29
+ callback: (_req, res) => answerJson(res, HTTP_SERVICE_UNAVAILABLE, {
30
+ error: 'service_unavailable',
31
+ error_description: 'The MCP service is not configured on this Gateway.',
32
+ }),
33
+ };
34
+ }
35
+ function createStandaloneHandler({ version, gatewaySwitch, health, }) {
36
+ return (req, res) => {
37
+ res.setHeader(exports.GATEWAY_VERSION_HEADER, version);
38
+ if (isHealthRequest(req)) {
39
+ const report = health();
40
+ answerJson(res, report.healthy ? HTTP_OK : HTTP_SERVICE_UNAVAILABLE, report);
41
+ return;
42
+ }
43
+ gatewaySwitch.callback(req, res, () => answerJson(res, HTTP_NOT_FOUND, {
44
+ error: 'not_found',
45
+ error_description: 'No Gateway service serves this path.',
46
+ }));
47
+ };
48
+ }
49
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhbmRhbG9uZS1oYW5kbGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3N0YW5kYWxvbmUtaGFuZGxlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUEwQ0Esc0RBUUM7QUFFRCxrRUFTQztBQUVELDBDQXVCQztBQWxGRCx3REFBeUQ7QUFFNUMsUUFBQSxzQkFBc0IsR0FBRywwQkFBMEIsQ0FBQztBQUNwRCxRQUFBLFdBQVcsR0FBRyxTQUFTLENBQUM7QUFFckMsTUFBTSxPQUFPLEdBQUcsR0FBRyxDQUFDO0FBQ3BCLE1BQU0sY0FBYyxHQUFHLEdBQUcsQ0FBQztBQUMzQixNQUFNLHdCQUF3QixHQUFHLEdBQUcsQ0FBQztBQW1CckMsU0FBUyxVQUFVLENBQUMsR0FBbUIsRUFBRSxNQUFjLEVBQUUsSUFBYTtJQUNwRSxHQUFHLENBQUMsVUFBVSxHQUFHLE1BQU0sQ0FBQztJQUN4QixHQUFHLENBQUMsU0FBUyxDQUFDLGNBQWMsRUFBRSxrQkFBa0IsQ0FBQyxDQUFDO0lBQ2xELEdBQUcsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO0FBQ2hDLENBQUM7QUFFRCxTQUFTLGVBQWUsQ0FBQyxHQUFvQjtJQUMzQyxNQUFNLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxJQUFJLEdBQUcsQ0FBQyxDQUFDLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFFckQsT0FBTyxDQUFDLEdBQUcsQ0FBQyxNQUFNLEtBQUssS0FBSyxJQUFJLEdBQUcsQ0FBQyxNQUFNLEtBQUssTUFBTSxDQUFDLElBQUksUUFBUSxLQUFLLG1CQUFXLENBQUM7QUFDckYsQ0FBQztBQUVELFNBQWdCLHFCQUFxQixDQUNuQyxPQUFlLEVBQ2YsR0FBYyxFQUNkLEdBQWM7SUFFZCxNQUFNLFdBQVcsR0FBRyxHQUFHLEtBQUssVUFBVSxJQUFJLEdBQUcsQ0FBQyxNQUFNLEtBQUssVUFBVSxDQUFDO0lBRXBFLE9BQU8sRUFBRSxPQUFPLEVBQUUsR0FBRyxLQUFLLFVBQVUsSUFBSSxDQUFDLFdBQVcsRUFBRSxPQUFPLEVBQUUsUUFBUSxFQUFFLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxFQUFFLENBQUM7QUFDMUYsQ0FBQztBQUVELFNBQWdCLDJCQUEyQixDQUFDLFFBQWdCO0lBQzFELE9BQU87UUFDTCxPQUFPLEVBQUUsSUFBQSwyQkFBYyxFQUFDLFFBQVEsQ0FBQztRQUNqQyxRQUFRLEVBQUUsQ0FBQyxJQUFJLEVBQUUsR0FBRyxFQUFFLEVBQUUsQ0FDdEIsVUFBVSxDQUFDLEdBQUcsRUFBRSx3QkFBd0IsRUFBRTtZQUN4QyxLQUFLLEVBQUUscUJBQXFCO1lBQzVCLGlCQUFpQixFQUFFLG9EQUFvRDtTQUN4RSxDQUFDO0tBQ0wsQ0FBQztBQUNKLENBQUM7QUFFRCxTQUF3Qix1QkFBdUIsQ0FBQyxFQUM5QyxPQUFPLEVBQ1AsYUFBYSxFQUNiLE1BQU0sR0FDbUI7SUFDekIsT0FBTyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsRUFBRTtRQUNsQixHQUFHLENBQUMsU0FBUyxDQUFDLDhCQUFzQixFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBRS9DLElBQUksZUFBZSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDekIsTUFBTSxNQUFNLEdBQUcsTUFBTSxFQUFFLENBQUM7WUFFeEIsVUFBVSxDQUFDLEdBQUcsRUFBRSxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLHdCQUF3QixFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBRTdFLE9BQU87UUFDVCxDQUFDO1FBRUQsYUFBYSxDQUFDLFFBQVEsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUNwQyxVQUFVLENBQUMsR0FBRyxFQUFFLGNBQWMsRUFBRTtZQUM5QixLQUFLLEVBQUUsV0FBVztZQUNsQixpQkFBaUIsRUFBRSxzQ0FBc0M7U0FDMUQsQ0FBQyxDQUNILENBQUM7SUFDSixDQUFDLENBQUM7QUFDSixDQUFDIn0=
@@ -0,0 +1,3 @@
1
+ declare const version: string;
2
+ export default version;
3
+ //# sourceMappingURL=version.d.ts.map
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ // eslint-disable-next-line @typescript-eslint/no-var-requires, import/no-dynamic-require, global-require
4
+ const { version } = require('../package.json');
5
+ exports.default = version;
6
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmVyc2lvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy92ZXJzaW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEseUdBQXlHO0FBQ3pHLE1BQU0sRUFBRSxPQUFPLEVBQUUsR0FBRyxPQUFPLENBQUMsaUJBQWlCLENBQXdCLENBQUM7QUFFdEUsa0JBQWUsT0FBTyxDQUFDIn0=
package/package.json CHANGED
@@ -1,6 +1,41 @@
1
1
  {
2
2
  "name": "@forestadmin/gateway",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "1.0.0",
4
+ "description": "Serves the Forest Admin MCP and API services on one port, for agents that cannot embed them",
5
+ "main": "dist/index.js",
6
+ "bin": {
7
+ "forest-gateway": "dist/cli.js"
8
+ },
9
+ "license": "GPL-3.0",
10
+ "engines": {
11
+ "node": ">=22.12.0"
12
+ },
13
+ "publishConfig": {
14
+ "access": "public"
15
+ },
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "git+https://github.com/ForestAdmin/agent-nodejs.git",
19
+ "directory": "packages/gateway"
20
+ },
21
+ "files": [
22
+ "dist/**/*.js",
23
+ "dist/**/*.d.ts"
24
+ ],
25
+ "scripts": {
26
+ "build": "tsc",
27
+ "build:watch": "tsc --watch",
28
+ "start": "node dist/cli.js",
29
+ "clean": "rm -rf coverage dist",
30
+ "lint": "eslint src test",
31
+ "test": "jest"
32
+ },
33
+ "dependencies": {
34
+ "@forestadmin/agent-bff": "^1.40.0",
35
+ "@forestadmin/forestadmin-client": "^1.43.5",
36
+ "@forestadmin/mcp-server": "^1.28.0"
37
+ },
38
+ "devDependencies": {
39
+ "supertest": "^7.1.3"
40
+ }
41
+ }
package/README.md DELETED
@@ -1,3 +0,0 @@
1
- # Temporary Holding Version
2
-
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.