Files
kandev/apps/web/components/diff/use-diff-metadata.ts
T
2026-02-19 22:18:01 +00:00

44 lines
1.5 KiB
TypeScript

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<FileDiffMetadata | null>(() => {
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]);
}