import type { RuntimeMode } from "../shared/api"; import type { Logger } from "./logger"; import type { StaticAssets } from "./static"; import { createApiError, jsonResponse } from "./helpers"; import { handleMeta } from "./routes/meta"; import { serveStaticAsset } from "./static"; import { readAppVersion } from "./version"; export interface StartServerOptions { config: { host: string; port: number }; logger: Logger; mode: RuntimeMode; staticAssets?: StaticAssets; version?: string; } export function startServer(options: StartServerOptions) { const { config, logger, mode, staticAssets, version } = options; const resolveVersion = (): Promise => { if (version) return Promise.resolve(version); return readAppVersion(); }; const server = Bun.serve({ fetch(req) { if (staticAssets) { return serveStaticAsset(new URL(req.url).pathname, staticAssets); } return new Response("Frontend is served by Vite dev server on :5173", { status: 404 }); }, hostname: config.host, port: config.port, routes: { "/api/*": () => jsonResponse(createApiError("API route not found", 404), { mode, status: 404 }), "/api/meta": { GET: async () => { const resolvedVersion = await resolveVersion(); return handleMeta(mode, resolvedVersion); }, }, }, }); logger.info({ host: config.host, port: config.port, url: server.url.toString() }, "服务启动"); return server; }