import { z } from "zod";
import { repoDb } from "../scoped-db";
import { badRequest, conflict, forbidden, notFoundError } from "../errors";
import { requireHeadPush, updateHeadBranch } from "../pull-merge";
import { directUpdateViolation, loadProtections, protectionFor } from "../protection";
import { limitWrite } from "../limits";
import { findForkHead, mergePullRequest, openPull } from "../pull-create";
import { loadPull, MergeError, PULL_SELECT } from "../pulls";
import type { PullRow } from "../pulls";
import { assertNotArchived, hasPermission, loadRepo, loadRepoById } from "../repos";
import { scopedRepoPermission } from "../token-scope";
import { markdownBody, title } from "~/lib/validation";
import type { RepoRow } from "~/lib/types";
import { pullJson, readJson, requireScopedRepo, requireTokenWrite, unprocessable } from "./http";
import type { ApiContext } from "./http";
const LIST_LIMIT = 100;
const HTTP_CONFLICT = 409;
export async function listPulls(ctx: ApiContext, owner: string, name: string): Promise<Response> {
const { repo } = await requireScopedRepo(ctx, owner, name, "pulls", "read");
const state = ctx.url.searchParams.get("state") ?? "open";
if (state !== "open" && state !== "closed" && state !== "all") throw unprocessable("Invalid state");
const db = repoDb(repo.id);
const rows =
state === "all"
? await db.all<PullRow>(
`${PULL_SELECT} WHERE i.repo_id = ? AND i.is_pull = 1 AND i.hidden_at IS NULL ORDER BY i.number DESC LIMIT ${LIST_LIMIT}`,
repo.id,
)
: await db.all<PullRow>(
`${PULL_SELECT} WHERE i.repo_id = ? AND i.is_pull = 1 AND i.hidden_at IS NULL AND i.state = ? ORDER BY i.number DESC LIMIT ${LIST_LIMIT}`,
repo.id,
state,
);
return Response.json(await Promise.all(rows.map((row) => pullJson(row, repo))));
}
export async function getPull(ctx: ApiContext, owner: string, name: string, number: number): Promise<Response> {
const { repo } = await requireScopedRepo(ctx, owner, name, "pulls", "read");