import { repoDb } from "./scoped-db";
import { randomId } from "./crypto";
import { assertBelowCap, CAPS } from "./limits";
import { toProtection } from "./protection";
import type { BranchProtection, BranchProtectionRow } from "./protection";
export type ProtectionInput = {
pattern: string;
requirePullRequest: boolean;
requiredApprovals: number;
requiredChecks: string[];
dismissStaleReviews: boolean;
allowDeletions: boolean;
allowForcePushes: boolean;
enforceAdmins: boolean;
};
/** Callers must have checked admin access on the repo. */
export async function listProtectionRules(repoId: string): Promise<BranchProtection[]> {
const rows = await repoDb(repoId).all<BranchProtectionRow>(
"SELECT * FROM branch_protections WHERE repo_id = ? ORDER BY pattern",
repoId,
);
return rows.map(toProtection);
}
export async function loadProtectionRule(repoId: string, id: string): Promise<BranchProtection | null> {
const row = await repoDb(repoId).first<BranchProtectionRow>(
"SELECT * FROM branch_protections WHERE id = ? AND repo_id = ?",
id,
repoId,
);
return row ? toProtection(row) : null;
}
/** Creates (id null) or updates a rule; returns the rule id. Callers must have checked admin access. */
export async function saveProtectionRule(repoId: string, id: string | null, input: ProtectionInput): Promise<string> {
if (!id)
assertBelowCap(
(