import { sameOriginReport } from "./report-origin";
import { env } from "cloudflare:workers";
import { all, first, run } from "../db";
import { sha256Hex } from "../crypto";
import { HttpError, badRequest } from "../errors";
import { enforceRateLimit, requestIp } from "../limits";
import { extractArtifact, storeFile } from "../pages/collect";
import { manifestKey, metaKey, publishMeta, SCRATCH_LIMITS, slotKey } from "./config";
import { assertLabelFree, loadSiteById, unpublishSite } from "./deploy";
import { claimedLabel } from "./naming";
import { onScratchClaimed } from "./metering";
import { CLAIM_PREFIX, deployUpload, reserveScratch, scratchResult } from "./scratch-core";
import {
assertScratchRepoTransferable,
createScratchRepo,
sweepOrphanScratchRepos,
transferScratchRepo,
} from "./scratch-git";
import type { CollectedFiles } from "../pages/collect";
import type { ScratchResult } from "./scratch-core";
import { plain } from "./static";
import { guessAbuseCategory, recordAbuseReport } from "../abuse";
import type { SiteMeta, SiteRow } from "./config";
import type { Viewer } from "~/lib/types";
const HTTP_TOO_LARGE = 413;
const MIB = 1024 * 1024;
const SWEEP_BATCH = 50;
async function readCapped(
request: Request,
limit: number = SCRATCH_LIMITS.maxUploadBytes,
allowEmpty = false,
): Promise<Uint8Array<ArrayBuffer>> {
const tooLarge = () => new HttpError(HTTP_TOO_LARGE, `Upload exceeds ${Math.round(limit / MIB)} MiB`);
const declared = Number(request.headers.get("content-length") ?? "0");
if (declared > limit) throw tooLarge();
if (!request.body) {
if (allowEmpty) return new Uint8Array(0);
throw badRequest("Send a .tar.gz archive as the request body");