| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192 |
- import { parseDiffFromFile, type FileDiffMetadata } from "@pierre/diffs"
- import { formatPatch, parsePatch, structuredPatch } from "diff"
- import type { SnapshotFileDiff, VcsFileDiff } from "@opencode-ai/sdk/v2"
- type LegacyDiff = {
- file: string
- patch?: string
- before?: string
- after?: string
- additions: number
- deletions: number
- status?: "added" | "deleted" | "modified"
- }
- type ReviewDiff = SnapshotFileDiff | VcsFileDiff | LegacyDiff
- export type ViewDiff = {
- file: string
- patch: string
- additions: number
- deletions: number
- status?: "added" | "deleted" | "modified"
- fileDiff: FileDiffMetadata
- }
- const cache = new Map<string, FileDiffMetadata>()
- function patch(diff: ReviewDiff) {
- if (typeof diff.patch === "string") {
- const [patch] = parsePatch(diff.patch)
- const beforeLines = []
- const afterLines = []
- for (const hunk of patch.hunks) {
- for (const line of hunk.lines) {
- if (line.startsWith("-")) {
- beforeLines.push(line.slice(1))
- } else if (line.startsWith("+")) {
- afterLines.push(line.slice(1))
- } else {
- // context line (starts with ' ')
- beforeLines.push(line.slice(1))
- afterLines.push(line.slice(1))
- }
- }
- }
- return { before: beforeLines.join("\n"), after: afterLines.join("\n"), patch: diff.patch }
- }
- return {
- before: "before" in diff && typeof diff.before === "string" ? diff.before : "",
- after: "after" in diff && typeof diff.after === "string" ? diff.after : "",
- patch: formatPatch(
- structuredPatch(
- diff.file,
- diff.file,
- "before" in diff && typeof diff.before === "string" ? diff.before : "",
- "after" in diff && typeof diff.after === "string" ? diff.after : "",
- "",
- "",
- { context: Number.MAX_SAFE_INTEGER },
- ),
- ),
- }
- }
- function file(file: string, patch: string, before: string, after: string) {
- const hit = cache.get(patch)
- if (hit) return hit
- const value = parseDiffFromFile({ name: file, contents: before }, { name: file, contents: after })
- cache.set(patch, value)
- return value
- }
- export function normalize(diff: ReviewDiff): ViewDiff {
- const next = patch(diff)
- return {
- file: diff.file,
- patch: next.patch,
- additions: diff.additions,
- deletions: diff.deletions,
- status: diff.status,
- fileDiff: file(diff.file, next.patch, next.before, next.after),
- }
- }
- export function text(diff: ViewDiff, side: "deletions" | "additions") {
- if (side === "deletions") return diff.fileDiff.deletionLines.join("")
- return diff.fileDiff.additionLines.join("")
- }
|