import { Hono } from "hono"; import { serveStatic } from "hono/bun"; import { cors } from "hono/cors"; import dashboardRoutes from "./api/dashboard"; import executeRoutes from "./api/execute"; import pathsRoutes from "./api/paths"; import reviewRoutes from "./api/review"; import scanRoutes from "./api/scan"; import setupRoutes from "./api/setup"; import subtitlesRoutes from "./api/subtitles"; import { getDb } from "./db/index"; import { log } from "./lib/log"; const app = new Hono(); // ─── CORS (dev: Vite on :5173 talks to Hono on :3000) ──────────────────────── app.use("/api/*", cors({ origin: ["http://localhost:5173", "http://localhost:3000"] })); // ─── Request logging ────────────────────────────────────────────────────────── app.use("/api/*", async (c, next) => { const start = Date.now(); await next(); const ms = Date.now() - start; // Skip noisy SSE/polling endpoints if (c.req.path.endsWith("/events")) return; log(`${c.req.method} ${c.req.path} → ${c.res.status} (${ms}ms)`); }); // ─── API routes ─────────────────────────────────────────────────────────────── import pkg from "../package.json"; app.get("/api/version", (c) => c.json({ version: pkg.version })); app.route("/api/dashboard", dashboardRoutes); app.route("/api/setup", setupRoutes); app.route("/api/scan", scanRoutes); app.route("/api/review", reviewRoutes); app.route("/api/execute", executeRoutes); app.route("/api/subtitles", subtitlesRoutes); app.route("/api/paths", pathsRoutes); // ─── Static assets (production: serve Vite build) ──────────────────────────── app.use("/assets/*", serveStatic({ root: "./dist" })); app.use("/favicon.ico", serveStatic({ path: "./dist/favicon.ico" })); // ─── SPA fallback ───────────────────────────────────────────────────────────── // All non-API routes serve the React index.html so TanStack Router handles them. app.get("*", (c) => { const _accept = c.req.header("Accept") ?? ""; if (c.req.path.startsWith("/api/")) return c.notFound(); // In dev the Vite server handles the SPA. In production serve dist/index.html. try { const html = Bun.file("./dist/index.html").text(); return html.then((text) => c.html(text)); } catch { return c.text("Run `bun build` first to generate the frontend.", 503); } }); // ─── Start ──────────────────────────────────────────────────────────────────── const port = Number(process.env.PORT ?? "3000"); log(`netfelix-audio-fix v${pkg.version} starting on http://localhost:${port}`); getDb(); export default { port, fetch: app.fetch, idleTimeout: 0, };