"use server";
import { revalidatePath } from "next/cache";
import { redirect } from "next/navigation";
import { person } from "@/lib/actor";
import { filter, findFirst } from "@/lib/db";
import { getEvent } from "@/lib/events";
import { isRevertable } from "@/lib/event-text";
import { GitError } from "@/lib/git";
import { RevertError, revertCommit, revertPush } from "@/lib/revert";
import { findRepoById } from "@/lib/repos";
import { ActionError, repoForAction, viewerOrThrow } from "./guard";
/** Undoes a push one of the viewer's agents made, from the activity page. */
export async function revertPushAction(eventId: string) {
const viewer = await viewerOrThrow();
// Only pushes your own agents made are yours to undo here.
const own = await findFirst("events", filter("id = {:id} && actor = {:actor}", { id: eventId, actor: viewer.id }), { fields: "id" });
const event = own ? await getEvent(eventId) : null;
if (!event || !isRevertable(event)) throw new ActionError("That push can't be undone.");
const record = await findRepoById(event.repoId);
if (!record) throw new ActionError("The repository was deleted.");
const { repo } = await repoForAction(record.owner, record.name, "write");
let result: Awaited<ReturnType<typeof revertPush>>;
try {
result = await revertPush(repo, person(viewer.id), event);
} catch (e) {
if (e instanceof RevertError || e instanceof GitError) throw new ActionError(e.message);
throw e;
}
revalidatePath("/settings/activity");
redirect(result.pull ? `/${repo.owner}/${repo.name}/pulls/${result.pull}` : `/${repo.owner}/${repo.name}/commit/${result.commit}`);
}
/** Reverts one commit, from the commit page or a commit list: a new commit on the branch that has it (or a pull request, if that branch is protected). */
export async function revertCommitAction(owner: string, name: string, sha: string) {
const { repo, viewer } = await repoForAction(owner, name, "write");
let result: Awaited<ReturnType<typeof revertCommit>>;
try {
result = await revertCommit(repo, person(viewer.id), sha);
} catch (e) {
if (e instanceof RevertError || e instanceof GitError) throw new ActionError(e.message);
throw e;
}
revalidatePath(`/${repo.owner}/${repo.name}`, "layout");
redirect(result.pull ? `/${repo.owner}/${repo.name}/pulls/${result.pull}` : `/${repo.owner}/${repo.name}/commit/${result.commit}`);
}