actOn

tcmts.share.actOn · #3io6t2h5 · term · runs on the server

uses tcmts.share.servedCodebase, which uses process

Do what a contribution's page asks, as the caller may: comment, merge, close or reopen.

import { closeContribution, commentOn, ContributionError, mergeContribution } from "#codebase/tcmts/cli/contributions";
import { authorFor, refusal } from "#codebase/tcmts/cli/sync";
import { HttpError } from "#codebase/tcmts/server";
import { callerNow, servedCodebase } from "#codebase/tcmts/share";

export async function actOn(
  id: number,
  what: "comment" | "merge" | "close" | "reopen",
  o: { body?: string; about?: string | null; name?: string } = {},
): Promise<void> {
  const { cb } = servedCodebase();
  const caller = callerNow(cb);
  if (!caller || caller.role === "reader") throw new HttpError(401, "Sign in to do that.");
  const route = {
    comment: "comment",
    merge: "merge-contribution",
    close: "close-contribution",
    reopen: "reopen-contribution",
  }[what];
  const refused = refusal(caller, route, { id }, (n) => cb.store.contribution(n)?.source);
  if (refused) throw new HttpError(403, refused);
  const by = authorFor(caller, (o.name ?? "").trim() || "maintainer");
  try {
    if (what === "comment") {
      const body = (o.body ?? "").trim();
      if (!body) throw new ContributionError("A comment needs something in it.");
      commentOn(cb, id, { author: by, body, about: o.about || null });
    } else if (what === "merge") mergeContribution(cb, id, by);
    else closeContribution(cb, id, by, what === "reopen");
  } catch (e) {
    throw new HttpError(400, (e as Error).message);
  }
}

uses

used by