Files
kandev/apps/web/components/diff/use-diff-metadata.ts
T
2026-02-18 18:24:41 +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]);
}