180 lines · 8.4 KB
import { createServerFn } from "@tanstack/react-start";
import { withAuthorAccounts } from "~/server/commit-authors";
import { assertVisibleRevision } from "~/server/git/reachable";
import { z } from "zod";
import { viewerMiddleware } from "./middleware";
import { limitBrowse, limitHeavy } from "~/server/limits";
import { assertRepoReady, requireRepoAccess } from "~/server/repos";
import { listRefs, resolveRevision, splitRevisionPath } from "~/server/git/refs";
import { withStore } from "~/server/git/store";
import { HttpError, notFoundError } from "~/server/errors";
import { blameFile, BlameUnavailable } from "~/server/code/blame";
import { lastCommitsForDirectory, pathHistory } from "~/server/code/path-history";
import { listAllFiles } from "~/server/code/files";
import {
  CODE_MAX_PAGES,
  codeIndexStatus,
  contentTerms,
  ftsQuery,
  searchOwnerCode,
  searchRepoCode,
  type IndexStatus,
} from "~/server/code/search";
import { ensureCodeIndex } from "~/server/code/search-index";
import { renderNotebook } from "~/server/code/notebook";
import { repoRef } from "~/lib/validation";
import type { CodeSearchPage } from "~/lib/code-intel";
import type { Viewer } from "~/lib/types";

const HTTP_UNPROCESSABLE = 422;
const MAX_NOTEBOOK_BYTES = 5 * 1024 * 1024;
const decoder = new TextDecoder();
const splatInput = repoRef.extend({ splat: z.string().default("") });

async function resolveSplat(owner: string, name: string, splat: string, viewer: Viewer | null) {
  const { repo } = await requireRepoAccess(owner, name, viewer, "read");
  assertRepoReady(repo);
  const refs = await listRefs(repo);
  const resolved = splitRevisionPath(refs, splat);
  if (!resolved) throw notFoundError("Branch or path not found");
  await assertVisibleRevision(repo, resolved.revision);