124 lines · 3.9 KB · TypeScript
RawDownload
import type { FileDiffContentsLoader } from "@pierre/diffs";import {  squashAtomCommandFailure,  type AtomCommandResult,} from "@t3tools/client-runtime/state/runtime";import type {  EnvironmentId,  PullRequestDiffFileContentsInput,  PullRequestDiffFileContentsResult,  PullRequestRef,  ReviewDiffFileContentsInput,  ReviewDiffFileContentsResult,  ReviewDiffPreviewSourceKind,} from "@t3tools/contracts"; import { resolveFileDiffPath } from "./diffRendering"; interface GitDiffFileContentsSource {  readonly environmentId: EnvironmentId;  readonly cwd: string;  readonly sourceKind: ReviewDiffPreviewSourceKind;  readonly baseRef: string | null;  readonly headRef: string | null;  /** The comparison identity Pierre carries into its hydrated render cache. */  readonly cacheKey: string;} interface PullRequestDiffFileContentsSource {  readonly environmentId: EnvironmentId;  readonly reference: PullRequestRef;  readonly commit: string | null;  readonly cacheKey: string;} type GetDiffFileContents<E> = (request: {  readonly environmentId: EnvironmentId;  readonly input: ReviewDiffFileContentsInput;}) => Promise<AtomCommandResult<ReviewDiffFileContentsResult, E>>; type GetPullRequestDiffFileContents<E> = (request: {  readonly environmentId: EnvironmentId;  readonly input: PullRequestDiffFileContentsInput;}) => Promise<AtomCommandResult<PullRequestDiffFileContentsResult, E>>; function createDiffFileContentsLoader(  load: (input: {    readonly changeType: PullRequestDiffFileContentsInput["changeType"];    readonly oldPath: string;    readonly newPath: string;  }) => Promise<{ readonly oldContents: string; readonly newContents: string }>,  cacheKey: string,): FileDiffContentsLoader {  return async (fileDiff) => {    const newPath = resolveFileDiffPath(fileDiff);    const oldPath = fileDiff.prevName      ? resolveFileDiffPath({ ...fileDiff, name: fileDiff.prevName })      : newPath;    const contents = await load({ changeType: fileDiff.type, oldPath, newPath });    const newFile = {      name: newPath,      contents: contents.newContents,      cacheKey: `${cacheKey}:new:${newPath}`,    };    if (fileDiff.type === "rename-pure") {      return { oldFile: null, newFile };    }    return {      oldFile: {        name: oldPath,        contents: contents.oldContents,        cacheKey: `${cacheKey}:old:${oldPath}`,      },      newFile,    };  };} /** Turns the host's Git file-content RPC into the full-file loader Pierre uses for hunk expansion. */export function createGitDiffFileContentsLoader<E>(  getDiffFileContents: GetDiffFileContents<E>,  source: GitDiffFileContentsSource,): FileDiffContentsLoader {  return createDiffFileContentsLoader(async ({ changeType, oldPath, newPath }) => {    const result = await getDiffFileContents({      environmentId: source.environmentId,      input: {        cwd: source.cwd,        sourceKind: source.sourceKind,        changeType,        baseRef: source.baseRef,        headRef: source.headRef,        oldPath,        newPath,      },    });    if (result._tag !== "Success") {      throw squashAtomCommandFailure(result);    }    return result.value;  }, source.cacheKey);} /** Loads host-backed PR files, which may name revisions this checkout has never fetched. */export function createPullRequestDiffFileContentsLoader<E>(  getDiffFileContents: GetPullRequestDiffFileContents<E>,  source: PullRequestDiffFileContentsSource,): FileDiffContentsLoader {  return createDiffFileContentsLoader(async ({ changeType, oldPath, newPath }) => {    const result = await getDiffFileContents({      environmentId: source.environmentId,      input: {        ...source.reference,        ...(source.commit === null ? {} : { commit: source.commit }),        changeType,        oldPath,        newPath,      },    });    if (result._tag !== "Success") {      throw squashAtomCommandFailure(result);    }    return result.value;  }, source.cacheKey);}