import { apiHandler, errorResponse, type AppDeps, type RouteDef } from "./http.ts"; import { attachmentRoutes } from "./routes/attachments.ts"; import { authRoutes } from "./routes/auth.ts"; import { changeRoutes } from "./routes/changes.ts"; import { copyRoutes } from "./routes/copies.ts"; import { customFieldRoutes } from "./routes/custom-fields.ts"; import { engagementRoutes } from "./routes/engagements.ts"; import { entryRoutes } from "./routes/entries.ts"; import { exportRoutes } from "./routes/export.ts"; import { listRoutes } from "./routes/lists.ts"; import { logRoutes } from "./routes/log.ts"; import { metaRoutes } from "./routes/meta.ts"; import { sourceRoutes } from "./routes/sources.ts"; import { workRoutes } from "./routes/works.ts"; export interface App { /** Handle `/api/v1/*` and `/ingest/*`. Anything else is a JSON 404 (the web app is served by `Bun.serve` routes). */ fetch(req: Request, server?: { requestIP(req: Request): { address: string } | null }): Promise; routes: RouteDef[]; } /** The HTTP API, testable without a listening socket. */ export function createApp(deps: AppDeps): App { const routes: RouteDef[] = [ ...authRoutes, ...entryRoutes, ...engagementRoutes, ...workRoutes, ...listRoutes, ...logRoutes, ...copyRoutes, ...customFieldRoutes, ...attachmentRoutes, ...sourceRoutes, ...changeRoutes, ...exportRoutes, ]; routes.push(...metaRoutes(() => routes)); const api = apiHandler(routes, deps); return { routes, async fetch(req, server) { const { pathname } = new URL(req.url); if (pathname.startsWith("/api/v1/")) return api(req, server?.requestIP(req)?.address ?? "unknown"); // Phase 1: the ingest mount exists but no plugin has the `ingest` capability. if (pathname.startsWith("/ingest/")) return errorResponse(404, "not_found", "No ingest endpoint for this plugin."); return errorResponse(404, "not_found", "No such endpoint."); }, }; }