import { useMemo } from "react"; import { parsePatchFiles, parseDiffFromFile } from "@pierre/diffs"; import type { FileDiffMetadata } from "@pierre/diffs"; import type { FileDiffData } from "@/lib/diff/types"; /** * Check if Go code contains patterns that trigger catastrophic regex backtracking * in shiki's JavaScript regex engine. */ function hasProblematicGoPattern(content: string | undefined): boolean { if (!content) return false; const problematicPattern = /interface\{\}\s*`[^`]*`/; return problematicPattern.test(content); } function isGoFile(filePath: string): boolean { return filePath.endsWith(".go"); } /** Parse diff data into FileDiffMetadata, with Go-specific safety checks. */ export function useDiffMetadata(data: FileDiffData): FileDiffMetadata | null { return useMemo(() => { let result: FileDiffMetadata | null = null; if (data.diff) { const parsed = parsePatchFiles(data.diff); result = parsed[0]?.files[0] ?? null; } else if (data.oldContent || data.newContent) { result = parseDiffFromFile( { name: data.filePath, contents: data.oldContent }, { name: data.filePath, contents: data.newContent }, ); } if (result && isGoFile(data.filePath)) { const contentToCheck = data.newContent || data.oldContent || data.diff; if (hasProblematicGoPattern(contentToCheck)) { result = { ...result, lang: "text" }; } } return result; }, [data.diff, data.oldContent, data.newContent, data.filePath]); }