Vectrum
Sign In
40 lines · 1.8 KB · TypeScript
"use server";

import { revalidatePath } from "next/cache";
import { person } from "@/lib/actor";
import { createBranch, removeBranch } from "@/lib/branches";
import { GitError } from "@/lib/git";
import { ProtectionError } from "@/lib/protection";
import { ActionError, repoForAction } from "./guard";
import type { FormState } from "./types";

// Branches on their own, from the branches page. Both need push access, and the branch rules apply.

const isUserError = (e: unknown) => e instanceof ActionError || e instanceof GitError || e instanceof ProtectionError;

export async function createBranchAction(owner: string, name: string, _prev: FormState, formData: FormData): Promise<FormState> {
  try {
    const { repo, viewer } = await repoForAction(owner, name, "write");
    const branch = String(formData.get("name") ?? "").trim();
    if (!branch) throw new ActionError("Name the branch.");
    await createBranch(repo, person(viewer.id), branch, String(formData.get("from") ?? "").trim() || undefined);
    revalidatePath(`/${repo.owner}/${repo.name}`, "layout");
    return { success: `Created ${branch}.` };
  } catch (e) {
    if (isUserError(e)) return { error: (e as Error).message };
    throw e;
  }
}

export async function deleteBranchAction(owner: string, name: string, branch: string, sha: string): Promise<FormState> {
  try {
    const { repo, viewer } = await repoForAction(owner, name, "write");
    const { open } = await removeBranch(repo, person(viewer.id), branch, sha);
    revalidatePath(`/${repo.owner}/${repo.name}`, "layout");
    const note = open.length ? ` Pull requests from it can't be merged until it's pushed again.` : "";
    return { success: `Deleted ${branch}.${note}` };
  } catch (e) {
    if (isUserError(e)) return { error: (e as Error).message };
    throw e;
  }
}