Skip to content
File

Blob: src/worker/index.ts

typescript78 lines
1import { Hono } from "hono";
2import { registerGitRoutes } from "./routes/git";
3import { registerAdminRoutes } from "./routes/admin";
4import { registerUiRoutes } from "./routes/ui";
5import { registerAuthRoutes } from "./routes/auth";
6import { requestServicesMiddleware, type AppBindings, type AppContext } from "./routes/hono";
7import { renderUiDocumentResponse } from "./routes/uiResponse";
8import { loadViewer } from "./auth/session";
9import { json } from "./common";
10import { handleRepoTaskQueue } from "./tasks/queue";
11 
12const app = new Hono<AppBindings>({ strict: false });
13app.use("*", requestServicesMiddleware);
14// Register Git protocol routes (info/refs, upload-pack, receive-pack)
15registerGitRoutes(app);
16// Register Admin routes
17registerAdminRoutes(app);
18// Register Auth routes BEFORE UI to avoid /:owner shadowing /auth
19registerAuthRoutes(app);
20 
21app.get("/", async (c) => {
22 const viewer = await loadViewer(c);
23 return renderUiDocumentResponse(
24 c.env,
25 "home",
26 {},
27 { failureBody: "Failed to render page\n", viewer }
28 );
29});
30 
31// Register UI routes AFTER static/auth so that /:owner doesn't shadow them
32registerUiRoutes(app);
33 
34async function renderNotFound(c: AppContext): Promise<Response> {
35 const viewer = await loadViewer(c);
36 return renderUiDocumentResponse(
37 c.env,
38 "404",
39 {},
40 {
41 status: 404,
42 failureBody: "Not found\n",
43 failureStatus: 404,
44 viewer,
45 }
46 );
47}
48 
49app.notFound((c) => renderNotFound(c));
50 
51function errorStatus(error: Error): number {
52 if ("status" in error && typeof error.status === "number") {
53 return error.status;
54 }
55 return 500;
56}
57 
58app.onError((error) => {
59 // The previous router converted uncaught handler failures into JSON. Most
60 // routes catch expected failures themselves, but keep this last-resort shape
61 // stable for truly unexpected errors.
62 const status = errorStatus(error);
63 return json({ error: error.message || "Internal Server Error" }, status, {
64 "Content-Type": "application/json; charset=utf-8",
65 });
66});
67 
68export default {
69 fetch(request: Request, env: Env, ctx: ExecutionContext) {
70 return app.fetch(request, env, ctx);
71 },
72 async queue(batch: MessageBatch<unknown>, env: Env, ctx: ExecutionContext) {
73 return await handleRepoTaskQueue(batch, env, ctx);
74 },
75};
76 
77export { RepoDurableObject } from "./do/repo/repoDO";