import { first, run } from "./db";
import { notFoundError } from "./errors";
import { assertBelowCap, CAPS } from "./limits";
import type { RepoRow } from "~/lib/types";
export async function ownerAccount(name: string): Promise<{ id: string; name: string; kind: string }> {
const account = await first<{ id: string; name: string; kind: string }>(
"SELECT id, name, kind FROM accounts WHERE name = ?",
name,
);
if (!account) throw notFoundError("Owner not found");
return account;
}
export async function findCollaboratorUser(username: string): Promise<{ id: string }> {
const user = await first<{ id: string }>(
"SELECT a.id FROM accounts a JOIN users u ON u.account_id = a.id WHERE a.name = ?",
username,
);
if (!user) throw notFoundError("User not found");
return user;
}
/** Grants, changes or (with "none") removes a user's collaborator permission; callers check admin access. */
export async function setCollaborator(
repo: Pick<RepoRow, "id">,
username: string,
permission: "read" | "write" | "admin" | "none",
): Promise<void> {
const user = await findCollaboratorUser(username);
const existing = await first("SELECT 1 AS ok FROM collaborators WHERE repo_id = ? AND user_id = ?", repo.id, user.id);
if (!existing && permission !== "none") {
const count = await first<{ count: number }>(
"SELECT COUNT(*) AS count FROM collaborators WHERE repo_id = ?",
repo.id,
);
assertBelowCap(count?.count ?? 0, CAPS.collaboratorsPerRepo, "collaborators");
}
if (permission === "none") {
await run("DELETE FROM collaborators WHERE repo_id = ? AND user_id = ?", repo.id, user.id);