1/**
2 * Front-door worker for the single-origin deployment: the SPA, the API,
3 * the auth routes, and the git wire protocol all live on ONE host. API and
4 * wire requests are forwarded to the GitHost over a private service
5 * binding; everything else is served from the Vite static assets.
6 *
7 * One origin matters beyond aesthetics: the session cookie Better Auth
8 * sets is first-party for the SPA, clone URLs shown in the UI are
9 * same-host, and nothing needs CORS.
10 */
11
12interface Fetcher {
13 fetch(request: Request): Promise<Response>;
14}
15
16interface Env {
17 /** Service binding to the GitHost (REST, auth, and wire planes). */
18 GIT: Fetcher;
19 /** The Vite-built static assets. */
20 ASSETS: Fetcher;
21}
22
23/** `/api/v1/**` (REST), `/api/v3/**` (GitHub facade), `/api/auth/**` (Better Auth). */
24const API_PREFIX = /^\/api\//;
25
26/**
27 * The git smart-HTTP wire endpoints: `/:owner/:repo[.git]/info/refs`,
28 * `git-upload-pack`, `git-receive-pack`.
29 */
30const WIRE_PATH =
31 /^\/[^/]+\/[^/]+\/(?:info\/refs$|git-upload-pack$|git-receive-pack$)/;
32
33export default {
34 fetch(request: Request, env: Env): Promise<Response> {
35 const { pathname } = new URL(request.url);
36 if (API_PREFIX.test(pathname) || WIRE_PATH.test(pathname)) {
37 // Forwarded verbatim: the Host header stays this origin, so the
38 // GitHost derives same-host clone/remote URLs and Better Auth scopes
39 // its cookie to it, and push bodies stream through the binding
40 // untouched.
41 return env.GIT.fetch(request);
42 }
43 return env.ASSETS.fetch(request);
44 },
45};