import { mapTradingBotStatus, readBoundedJsonResponse, TRADING_BOT_PROXY_PATH, TRADING_BOT_STATUS_MAX_BYTES, TRADING_BOT_STATUS_TIMEOUT_MS, tradingBotStatusUrl, } from "@rakazo/core"; import type { Hono } from "hono"; export function mountTradingBotStatus( app: Hono, options: { /** Normalized http(s) origin. Unset leaves the route idle for SaaS builds. */ baseUrl: string | undefined; authorize: (request: Request) => Promise; fetchImpl?: typeof fetch; }, ) { const fetchImpl = options.fetchImpl ?? fetch; app.get(TRADING_BOT_PROXY_PATH, async (c) => { c.header("cache-control", "no-store"); if (!options.baseUrl) return c.json({ configured: false }); const allowed = await options.authorize(c.req.raw).catch(() => false); if (!allowed) return c.json({ error: "Unauthorized" }, 401); const timeout = linkAbort(c.req.raw.signal, TRADING_BOT_STATUS_TIMEOUT_MS); try { const response = await fetchImpl(tradingBotStatusUrl(options.baseUrl), { method: "GET", redirect: "error", cache: "no-store", signal: timeout.signal, headers: { accept: "application/json" }, }); if (!response.ok) { cancelBody(response); return c.json({ configured: true, reachable: false }, 502); } const body = await readBoundedJsonResponse( response, TRADING_BOT_STATUS_MAX_BYTES, timeout.signal, ); const status = mapTradingBotStatus(body); return c.json({ configured: true, reachable: true, status: status ?? null }); } catch { return c.json({ configured: true, reachable: false }, 502); } finally { timeout.cancel(); } }); } function linkAbort( parent: AbortSignal, timeoutMs: number, ): { signal: AbortSignal; cancel: () => void } { const controller = new AbortController(); const timer = setTimeout(() => controller.abort(), timeoutMs); const onParent = () => controller.abort(); if (parent.aborted) controller.abort(); else parent.addEventListener("abort", onParent); return { signal: controller.signal, cancel: () => { clearTimeout(timer); parent.removeEventListener("abort", onParent); }, }; } function cancelBody(response: Response): void { try { void Promise.resolve(response.body?.cancel()).catch(() => undefined); } catch { // Best-effort. The caller still reports the bot as unreachable. } }