import { z } from "zod";
import { repoDb } from "../scoped-db";
import { accountsById } from "../people";
import { badRequest, conflict, forbidden, notFoundError } from "../errors";
import { loadIssue } from "../issues";
import { limitHeavy, limitWrite } from "../limits";
import { pullAutomation } from "../merge-queue";
import { codeOwnerBlockers } from "../merge-automation";
import { pullCodeOwners } from "../codeowners";
import { openPull } from "../pull-create";
import { linkIssue, listLinkedIssues, unlinkIssue } from "../pull-links";
import { headBranchConflicts, requireHeadPush, updateHeadBranch } from "../pull-merge";
import { readPullTemplate } from "../pull-templates";
import { addIssueEvent, loadPull, mergeGate, MergeError } from "../pulls";
import type { PullRow } from "../pulls";
import { hasPermission, loadRepoById } from "../repos";
import { combinedState, listCommitStatuses, setCommitStatus } from "../statuses";
import { applySuggestions, MAX_BATCHED_SUGGESTIONS } from "../suggestions";
import { scopedRepoPermission } from "../token-scope";
import { markdownBody, title } from "~/lib/validation";
import { noContent, pullJson, readJson, requireScopedRepo, unprocessable } from "./http";
import type { ApiContext } from "./http";
const HTTP_CONFLICT = 409;
const MAX_RESOLVED_CHARS = 1024 * 1024;
const MAX_LISTED = 100;
const SHA = /^[0-9a-f]{40}$/;
function rethrowMerge(error: unknown): never {
if (error instanceof MergeError) throw conflict(error.message);
throw error;
}
async function scopedPull(ctx: ApiContext, owner: string, name: string, number: number, needed: "read" | "write") {
const scoped = await requireScopedRepo(ctx, owner, name, "pulls", needed);
const pull = await loadPull(scoped.repo.id, number);
if (!pull) throw notFoundError("Pull request not found");
const headRepo = pull.head_repo_id === scoped.repo.id ? scoped.repo : await loadRepoById(pull.head_repo_id);
if (!headRepo) throw notFoundError("Head repository was deleted");
return { ...scoped, pull, headRepo };