276 lines · 11.6 KB
import { z } from "zod";
import { badRequest, conflict, forbidden, HttpError, notFoundError } from "../errors";
import { editorRoomStub } from "./room-client";
import { handleRoomRoute, handleRoomSocket } from "./room-api";
import { handleContainerRoute, handleContainerTerminal } from "./container-api";
import { CORS_HEADERS, json } from "./http";
import { branchSha, listRefs } from "../git/refs";
import { withStore } from "../git/store";
import type { GitStore } from "../git/store";
import { commitFileChanges } from "../git/web-commit";
import { limitBrowse, limitWrite } from "../limits";
import { MAX_POINTER_BYTES, parseLfsPointer } from "../lfs/pointer";
import { assertEditableChanges } from "./write-guard";
import { readBounded } from "./blob-read";
import type { BoundedBlob } from "./blob-read";
import { openPull } from "../pull-create";
import { publicUrl } from "../events/emit";
import { canWrite, editorSessionFromRequest, needsPullRequest } from "./session";
import type { EditorSession } from "./session";

export const EDITOR_API_PREFIX = "/api/editor/";

const MAX_TREE_ENTRIES = 5000;
const MAX_BLOB_BYTES = 1024 * 1024;
const MAX_CHANGES = 100;
const MAX_COMMIT_BYTES = 5 * 1024 * 1024;
const MAX_BODY_BYTES = MAX_COMMIT_BYTES * 2;
const MAX_PATCH_BRANCH_TRIES = 50;
const decoder = new TextDecoder();
const encoder = new TextEncoder();

async function headTree(store: GitStore, session: EditorSession): Promise<string> {
  const commit = await store.commit(session.revision.sha);
  if (!commit) throw notFoundError("Commit not found");
  return commit.treeSha;
}

async function sessionInfo(session: EditorSession): Promise<Response> {
  const writable = canWrite(session);
  return json({