import { repoDb } from "./scoped-db";
import { HttpError } from "./errors";
import { randomId } from "./crypto";
import { assertBelowCap, CAPS } from "./limits";
const HTTP_UNPROCESSABLE = 422;
export type LabelRow = {
id: string;
name: string;
color: string;
description: string | null;
};
export type LabelInput = {
name: string;
color: string;
description: string | null;
};
export async function listRepoLabels(repoId: string): Promise<Array<LabelRow & { open_count: number }>> {
return repoDb(repoId).all<LabelRow & { open_count: number }>(
`SELECT l.id, l.name, l.color, l.description,
(SELECT COUNT(*) FROM issue_labels il JOIN issues i ON i.id = il.issue_id WHERE il.label_id = l.id AND i.state = 'open') AS open_count
FROM labels l WHERE l.repo_id = ? ORDER BY l.name`,
repoId,
);
}
export async function loadLabel(repoId: string, id: string): Promise<LabelRow | null> {
return repoDb(repoId).first<LabelRow>(
"SELECT id, name, color, description FROM labels WHERE id = ? AND repo_id = ?",
id,
repoId,
);
}
/** Creates (id null) or updates a label; returns its id. Callers must have checked write access. */
export async function saveLabel(repoId: string, id: string | null, input: LabelInput): Promise<string> {
const clash = await repoDb(repoId).first<{ id: string }>(
"SELECT id FROM labels WHERE repo_id = ? AND name = ? COLLATE NOCASE AND id != ?",