import type { IncomingMessage, ServerResponse } from "node:http"; import type { createSubsystemLogger } from "../../logging/subsystem.js"; import type { PluginRegistry } from "../../plugins/registry.js"; type SubsystemLogger = ReturnType; export type PluginHttpRequestHandler = ( req: IncomingMessage, res: ServerResponse, ) => Promise; export function createGatewayPluginRequestHandler(params: { registry: PluginRegistry; log: SubsystemLogger; }): PluginHttpRequestHandler { const { registry, log } = params; return async (req, res) => { const routes = registry.httpRoutes ?? []; const handlers = registry.httpHandlers ?? []; if (routes.length === 0 && handlers.length === 0) return false; if (routes.length > 0) { const url = new URL(req.url ?? "/", "http://localhost"); const route = routes.find((entry) => entry.path === url.pathname); if (route) { try { await route.handler(req, res); return true; } catch (err) { log.warn(`plugin http route failed (${route.pluginId ?? "unknown"}): ${String(err)}`); if (!res.headersSent) { res.statusCode = 500; res.setHeader("Content-Type", "text/plain; charset=utf-8"); res.end("Internal Server Error"); } return true; } } } for (const entry of handlers) { try { const handled = await entry.handler(req, res); if (handled) return true; } catch (err) { log.warn(`plugin http handler failed (${entry.pluginId}): ${String(err)}`); if (!res.headersSent) { res.statusCode = 500; res.setHeader("Content-Type", "text/plain; charset=utf-8"); res.end("Internal Server Error"); } return true; } } return false; }; }