Skip to content
File

Blob: src/worker/routes/ui/adminPage.ts

typescript76 lines
1import type { HeadInfo, Ref } from "@/worker/git";
2import { getRepoActivity, getRepoStub } from "@/worker/common";
3import {
4 computeStorageMetrics,
5 computeCompactionStatus,
6 getDefaultBranchFromHead,
7 loadAdminPackRefIndexState,
8 loadHeadAndRefsCached,
9 resolveAdminPageRepoAccess,
10 type DebugState,
11} from "./helpers";
12import type { AppContext } from "../hono";
13import { renderUiDocumentResponse } from "../uiResponse";
14 
15export async function handleAdminPage(c: AppContext<"/:owner/:repo/admin">) {
16 const env = c.env;
17 const owner = c.req.param("owner");
18 const repo = c.req.param("repo");
19 
20 const access = await resolveAdminPageRepoAccess(c, owner, repo);
21 if (access.kind === "response") return access.response;
22 const { route, cacheCtx, viewer, limiter } = access;
23 const repoId = route.doName;
24 const stub = getRepoStub(env, repoId);
25 
26 const [rawState, refsData, progress] = await Promise.all([
27 limiter
28 .run("do:admin-page-debug-state", () => stub.debugState())
29 .catch(() => ({}) as Partial<DebugState>),
30 loadHeadAndRefsCached(env, cacheCtx, repoId),
31 getRepoActivity(env, repoId, cacheCtx),
32 ]);
33 const state = await loadAdminPackRefIndexState({
34 env,
35 repoId,
36 state: rawState,
37 cacheCtx,
38 });
39 const head: HeadInfo | undefined = refsData?.head || undefined;
40 const refs: Ref[] = refsData?.refs || [];
41 
42 const { storageSize, packCount, packList, supersededPackCount } = computeStorageMetrics(state);
43 const { compactionStatus, compactionStartedAt } = computeCompactionStatus(state.compaction);
44 
45 const defaultBranch = getDefaultBranchFromHead(head);
46 const refEnc = encodeURIComponent(defaultBranch);
47 
48 return renderUiDocumentResponse(
49 env,
50 "admin",
51 {
52 title: `Admin · ${owner}/${repo}`,
53 owner,
54 repo,
55 refEnc,
56 head,
57 refs,
58 storageSize,
59 packCount,
60 packList,
61 state,
62 defaultBranch,
63 compactionStatus,
64 compactionStartedAt,
65 compactionData: state.compaction,
66 supersededPackCount,
67 progress,
68 },
69 {
70 cacheControl: "no-store",
71 failureBody: "Failed to render view",
72 viewer,
73 }
74 );
75}