125 lines · 5.2 KB
import { createServerFn } from "@tanstack/react-start";
import { z } from "zod";
import { requireViewer, viewerMiddleware } from "./middleware";
import { limitHeavy, limitWrite } from "~/server/limits";
import { assertVerifiedForWrites } from "~/server/verified-writes";
import { assertNotArchived, requireRepoAccess } from "~/server/repos";
import { badRequest } from "~/server/errors";
import { advertisement, assertPublicHttpsUrl } from "~/server/git/relay";
import { assertResolvesPublic } from "~/server/net/resolve-guard";
import { sourceAuthorization } from "~/server/git/ref-sync";
import { publicUrl } from "~/server/events/emit";
import { assertMirrorAllowed } from "~/server/mirror/mirror-do";
import {
  configureMirror,
  mirrorStatus,
  removeMirror,
  requestMirrorSync,
  rotateMirrorWebhookSecret,
} from "~/server/mirror/client";
import { CONFLICT_STRATEGIES, MIRROR_DIRECTIONS } from "~/lib/mirror";
import { repoRef } from "~/lib/validation";

const MAX_TOKEN = 1000;
const MAX_PATTERNS = 50;

function hookUrl(repoId: string): string {
  return publicUrl(`/integrations/hooks/mirror/${repoId}`);
}

export const getMirror = createServerFn({ method: "GET" })
  .middleware([viewerMiddleware])
  .validator(repoRef)
  .handler(async ({ data, context }) => {
    const { repo } = await requireRepoAccess(data.owner, data.repo, context.viewer, "admin");
    return { status: await mirrorStatus(repo.id), webhookUrl: hookUrl(repo.id) };
  });

const saveInput = repoRef.extend({
  remoteUrl: z.string().trim().min(1).max(500),
  username: z.string().trim().max(100).nullable(),