380 lines · 15.8 KB
import { createServerFn } from "@tanstack/react-start";
import { resolveMentions } from "~/server/mentions";
import type { MentionMap } from "~/server/mentions";
import { z } from "zod";
import { requireViewer, viewerMiddleware } from "./middleware";
import { all, batch, first, run, stmt } from "~/server/db";
import { randomId } from "~/server/crypto";
import { assertBelowCap, limitWrite, MAX_PAGE } from "~/server/limits";
import { hasPermission } from "~/server/repos";
import { createDiscussion, loadDiscussion, repoCategories, requireDiscussionAccess } from "~/server/discussions";
import { PLANNING_CAPS } from "~/server/planning";
import { reactionSummaries } from "~/server/reactions";
import { renderMarkdown } from "~/server/markdown";
import { accountOrGhost, accountsById } from "~/server/people";
import { emitNotification, publicUrl, recordActivity } from "~/server/events/emit";
import { badRequest, forbidden, notFoundError } from "~/server/errors";
import { markdownBody, repoRef, title } from "~/lib/validation";
import type { RepoRow } from "~/lib/types";

const PAGE_SIZE = 25;
const THREAD_LIMIT = 500;
const discussionRef = repoRef.extend({ number: z.number().int().positive() });

function md(repo: RepoRow, body: string, mentions: MentionMap): string {
  return renderMarkdown(
    body,
    { owner: repo.owner_name, repo: repo.name, ref: repo.default_branch, basePath: "" },
    mentions,
  );
}

function discussionUrl(repo: RepoRow, number: number): string {
  return publicUrl(`/${repo.owner_name}/${repo.name}/discussions/${number}`);
}

export const listDiscussions = createServerFn({ method: "GET" })
  .middleware([viewerMiddleware])
  .validator(
    repoRef.extend({
      category: z.string().max(64).optional(),