import { all, chunks, first, placeholders } from "./db";
import { forbidden, notFoundError } from "./errors";
import type { Permission, RepoRow, RepoSummary, Viewer } from "~/lib/types";
const PERMISSION_RANK: Record<Permission, number> = { none: 0, read: 1, write: 2, admin: 3 };
export const REPO_SELECT = `SELECT r.*, a.name AS owner_name FROM repos r JOIN accounts a ON a.id = r.owner_id`;
export async function loadRepo(owner: string, name: string): Promise<RepoRow | null> {
return first<RepoRow>(`${REPO_SELECT} WHERE a.name = ? AND r.name = ?`, owner, name);
}
export async function loadRepoById(id: string): Promise<RepoRow | null> {
return first<RepoRow>(`${REPO_SELECT} WHERE r.id = ?`, id);
}
export async function loadRepoByArtifactsName(artifactsName: string): Promise<RepoRow | null> {
return first<RepoRow>(`${REPO_SELECT} WHERE r.artifacts_name = ?`, artifactsName);
}
export function hasPermission(actual: Permission, needed: Permission): boolean {
return PERMISSION_RANK[actual] >= PERMISSION_RANK[needed];
}
export async function repoPermission(repo: RepoRow, viewer: Viewer | null): Promise<Permission> {
const base: Permission = repo.visibility === "public" ? "read" : "none";
if (!viewer) return base;
if (viewer.isAdmin || repo.owner_id === viewer.id) return "admin";
const [membership, collaborator] = await Promise.all([
first<{ role: "owner" | "member" }>(
"SELECT role FROM org_members WHERE org_id = ? AND user_id = ?",
repo.owner_id,
viewer.id,
),
first<{ permission: Permission }>(
"SELECT permission FROM collaborators WHERE repo_id = ? AND user_id = ?",
repo.id,
viewer.id,
),