1import type { PullRequestDiffResult } from "@t3tools/contracts";
2import { buildReviewParsedDiff, type ReviewParsedDiff } from "../review/reviewModel";
3
4export interface PullRequestDiffPage {
5 readonly cursor: string | null;
6 readonly result: PullRequestDiffResult;
7}
8
9/** A changed page invalidates later cursors, which belong to the previous patch. */
10export function retainPullRequestDiffPage(
11 pages: readonly PullRequestDiffPage[],
12 cursor: string | null,
13 result: PullRequestDiffResult,
14): readonly PullRequestDiffPage[] {
15 const index = pages.findIndex((page) => page.cursor === cursor);
16 if (index === -1) return [...pages, { cursor, result }];
17 const previous = pages[index]?.result;
18 if (
19 previous === result ||
20 (previous?.patch === result.patch &&
21 previous.truncated === result.truncated &&
22 previous.nextCursor === result.nextCursor &&
23 JSON.stringify(previous.omittedFileStats ?? []) ===
24 JSON.stringify(result.omittedFileStats ?? []))
25 )
26 return pages;
27 return [...pages.slice(0, index), { cursor, result }];
28}
29
30export function combinePullRequestDiffPages(
31 pages: readonly PullRequestDiffPage[],
32 cache: WeakMap<PullRequestDiffResult, ReviewParsedDiff>,
33 scope: string,
34): ReviewParsedDiff {
35 const parsed = pages.map((page) => {
36 const cached = cache.get(page.result);
37 if (cached) return cached;
38 const value = buildReviewParsedDiff(page.result.patch, `${scope}:${page.cursor ?? "first"}`);
39 cache.set(page.result, value);
40 return value;
41 });
42 const files = parsed.flatMap((page) => (page.kind === "files" ? page.files : []));
43 if (files.length === 0) return parsed[0] ?? { kind: "empty" };
44 return {
45 kind: "files",
46 files,
47 fileCount: files.length,
48 additions: files.reduce((total, file) => total + file.additions, 0),
49 deletions: files.reduce((total, file) => total + file.deletions, 0),
50 notice:
51 pages.some((page) => page.result.truncated) || parsed.some((page) => page.kind === "raw")
52 ? "Some file contents are unavailable. Open the pull request on its provider to see the full changes."
53 : null,
54 };
55}