Files
reverse-engineering-anything/src/domain/referenceSourcePathIdentity.ts
T
morluto 2ca3ad2386 fix(reference): preserve exact paths and unify symlink lookup
Validation: integrated changes passed formatting, typecheck, lint, resolved module-boundary verification and git diff --check. Tests and real-provider workflows were not run.
2026-10-11 00:03:20 +08:00

34 lines
1.3 KiB
TypeScript

export interface ReferenceSourcePathLookup {
readonly resolve: (path: string) => string | undefined;
readonly resolveCandidates: (paths: readonly string[]) => string | undefined;
}
/**
* Reference inventories retain filesystem spelling. Prefer that exact identity;
* canonical Unicode equivalence is a fallback only when it identifies one entry.
*/
export const createReferenceSourcePathLookup = (
paths: Iterable<string>,
): ReferenceSourcePathLookup => {
const exact = new Set(paths);
const canonical = new Map<string, string | null>();
for (const path of exact) {
const key = path.normalize("NFC");
canonical.set(key, canonical.has(key) ? null : path);
}
const equivalent = (path: string): string | undefined =>
canonical.get(path.normalize("NFC")) ?? undefined;
return {
resolve: (path) => (exact.has(path) ? path : equivalent(path)),
resolveCandidates: (candidates) =>
candidates.find((path) => exact.has(path)) ??
candidates.map(equivalent).find((path) => path !== undefined),
};
};
/** Symlink evidence can originate on a different OS from the graph reader. */
export const isPortableAbsoluteReferenceTarget = (target: string): boolean =>
target.startsWith("/") ||
/^[A-Za-z]:[\\/]/u.test(target) ||
/^\\\\[^\\/]+[\\/][^\\/]+/u.test(target);