31 lines · 1.3 KB
import { chunks, placeholders } from "./db";
import { replica } from "./db-replica";
import type { AccountRow } from "~/lib/types";

export type AccountRef = { id: string; name: string; displayName: string | null };

export async function accountsById(ids: Array<string | null>): Promise<Map<string, AccountRef>> {
  const unique = [...new Set(ids.filter((id): id is string => id !== null))];
  if (unique.length === 0) return new Map();
  const rows = (
    await Promise.all(
      chunks(unique).map((part) =>
        replica.all<Pick<AccountRow, "id" | "name" | "display_name">>(
          `SELECT id, name, display_name FROM accounts WHERE id IN (${placeholders(part.length)})`,
          ...part,
        ),
      ),
    )
  ).flat();
  return new Map(rows.map((row) => [row.id, { id: row.id, name: row.name, displayName: row.display_name }]));
}

export const GHOST: AccountRef = { id: "ghost", name: "ghost", displayName: "Deleted user" };

/** Who automated timeline events (merge queue, MergeFix, sweeps) are shown as; they are recorded without an actor. */
export const SYSTEM_ACTOR: AccountRef = { id: "gitfor", name: "gitfor", displayName: "gitfor" };

export function accountOrGhost(map: Map<string, AccountRef>, id: string | null): AccountRef {
  return (id ? map.get(id) : undefined) ?? GHOST;
}