101 lines · 4.1 KB
import { Link } from "@tanstack/react-router";
import { useMutation } from "@tanstack/react-query";
import { useEffect, useRef, useState } from "react";
import { mintEditorSession } from "~/fns/editor";
import { FieldError } from "~/ui/Field";

/**
 * The workbench runs on its own origin, so it is a normal (not opaque) document there: VS Code needs
 * IndexedDB, workers and webviews. It still can't reach forge cookies or pages, because those live on
 * a different origin, and the CSP on that origin pins what it may load and contact.
 */
const FRAME_SANDBOX =
  "allow-scripts allow-same-origin allow-forms allow-modals allow-popups allow-popups-to-escape-sandbox allow-downloads";

function isRecord(value: unknown): value is Record<string, unknown> {
  return typeof value === "object" && value !== null;
}

/**
 * Hosts VS Code for the Web for one ref. This page mints a ref-scoped editor token with the session
 * cookie and hands it to the editor origin over postMessage (exact target origin, re-checked after the
 * await), and re-mints when the editor asks for a refresh. The editor never sees cookies.
 */
export function WorkspaceEditor({
  owner,
  repo,
  gitRef,
  editorOrigin,
  openPath,
  startContainer = false,
}: {
  owner: string;
  repo: string;
  gitRef: string;
  editorOrigin: string | null;
  openPath: string | null;
  /** From `?container=1` ("Open in container"): the extension boots a container and opens a terminal. */
  startContainer?: boolean;
}) {
  const frame = useRef<HTMLIFrameElement>(null);