199 lines · 8.4 KB
import { waitUntil } from "cloudflare:workers";
import { syncHostingForRepo } from "../sites/sync";
import { z } from "zod";
import { all, first, run } from "../db";
import { conflict, forbidden, notFoundError } from "../errors";
import { listRefs } from "../git/refs";
import { syncRefsFromSource } from "../git/ref-sync";
import { dropHiddenRefsForRepo, requestHiddenRefCleanup } from "../git/pull-bridge";
import { assertBelowCap, CAPS, limitHeavy, limitWrite } from "../limits";
import { canCreateInAccount, hasPrivateForkAncestor, loadRepo, REPO_SELECT, visibleReposClause } from "../repos";
import {
  createRepository,
  deleteRepository,
  forkRepository,
  importRepository,
  refreshRepoStatus,
  reindexRepo,
} from "../repo-ops";
import { credentialAllows } from "../token-scope";
import { syncSiteForRepo } from "../sites/sync";
import { findCollaboratorUser, setCollaborator } from "../collaborators";
import { repoName } from "~/lib/validation";
import type { RepoRow } from "~/lib/types";
import {
  noContent,
  ownerAccount,
  readJson,
  repoJson,
  requireAccountScope,
  requireScopedRepo,
  unprocessable,
} from "./http";
import type { ApiContext } from "./http";

const LIST_LIMIT = 100;

async function assertOwnerCap(ownerId: string): Promise<void> {
  assertBelowCap(
    (await first<{ count: number }>("SELECT COUNT(*) AS count FROM repos WHERE owner_id = ?", ownerId))?.count ?? 0,
    CAPS.reposPerOwner,