Files
ThothII/backend/src/app.ts
T

52 lines
2.0 KiB
TypeScript

import Fastify, { type FastifyInstance } from "fastify";
import cors from "@fastify/cors";
import type { AppConfig } from "./config.js";
import { ThtRunner } from "./tht/tht-runner.js";
import { PiProcessManager } from "./pi/pi-process-manager.js";
import { SseHub } from "./sse/sse-hub.js";
import { authPreHandler } from "./auth/auth.js";
import { sessionRoutes } from "./routes/sessions.js";
import { sqlRoutes } from "./routes/sql.js";
import { metaRoutes, type ListModelsFn } from "./routes/meta.js";
import { settingsRoutes, effectiveSettings } from "./routes/settings.js";
import { createPiModelLister } from "./pi/list-models.js";
import { loadSettings, type Settings } from "./settings/settings-store.js";
export interface BuildAppDeps {
thtRunner?: ThtRunner;
spawnFn?: () => any;
listModels?: ListModelsFn;
getSettings?: () => Settings;
}
export function buildApp(config: AppConfig, deps?: BuildAppDeps): FastifyInstance {
const app = Fastify({ logger: false });
// Allow any origin in dev/e2e; tighten in production via config if needed.
app.register(cors, {
origin: true,
credentials: true,
methods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
});
const tht = deps?.thtRunner ?? new ThtRunner({
thtBin: config.thtBin,
harnessDir: config.harnessDir,
configPath: "config/tht.yaml",
});
const mgr = new PiProcessManager(config, deps?.spawnFn ? { spawnFn: deps.spawnFn } : undefined);
const hub = new SseHub();
const listModels = deps?.listModels ?? createPiModelLister(config);
const getSettings = deps?.getSettings ?? (() => effectiveSettings(config, loadSettings(config)));
app.addHook("preHandler", authPreHandler(config.authMode));
app.get("/health", async () => ({ status: "ok" }));
sessionRoutes(app, { mgr, tht: tht as ThtRunner, hub, getSettings });
sqlRoutes(app, { tht: tht as ThtRunner });
metaRoutes(app, { harnessDir: config.harnessDir, listModels });
settingsRoutes(app, { cfg: config, listModels });
return app;
}