import { env } from "cloudflare:workers";
import { enforceRateLimit, requestIp } from "../limits";
import { HttpError } from "../errors";
import { customHostKey, isForgeHostname, metaKey, sitesDomain, slotKey } from "./config";
import { hostLabel } from "./naming";
import { accessSubject, challenge, handleAccessRoute } from "./access";
import { runSiteWorker } from "./runtime";
import { loadManifest, plain } from "./static";
import { handleAbuseReport, handleScratchUpload } from "./scratch";
import { meteredResponse } from "./usage";
import { scratchWithinQuota } from "./metering";
import type { SiteMeta, SlotPointer } from "./config";
const POINTER_CACHE_SECONDS = 30;
const REPORT_PATH = "/__gitfor/report";
const UNMETERED = new WeakSet<Response>();
type Resolved = { label: string; pointer: SlotPointer; meta: SiteMeta };
function pointer(label: string): Promise<SlotPointer | null> {
return env.KV.get<SlotPointer>(slotKey(label), { type: "json", cacheTtl: POINTER_CACHE_SECONDS });
}
function meta(siteId: string): Promise<SiteMeta | null> {
return env.KV.get<SiteMeta>(metaKey(siteId), { type: "json", cacheTtl: POINTER_CACHE_SECONDS });
}
/** Maps a request host to the site and deployment it serves; custom domains only after verification wrote KV. */
export async function resolveSiteHost(hostname: string): Promise<Resolved | null> {
const domain = sitesDomain();
if (!domain) return null;
let label = hostLabel(hostname, domain);
if (!label) {
const custom = await env.KV.get<{ siteId: string; label: string }>(customHostKey(hostname), {
type: "json",
cacheTtl: POINTER_CACHE_SECONDS,
});
if (!custom) return null;
label = custom.label;
}