mirror of
https://github.com/luckyyzh/pi-agent-integrated.git
synced 2026-10-03 11:09:34 +00:00
43 lines
1.5 KiB
TypeScript
43 lines
1.5 KiB
TypeScript
import { realpathSync } from "fs";
|
|
import path from "path";
|
|
|
|
const WINDOWS_ABSOLUTE_RE = /^[a-zA-Z]:[\\/]/;
|
|
|
|
function isWindowsAbsolutePath(filePath: string): boolean {
|
|
return WINDOWS_ABSOLUTE_RE.test(filePath) || filePath.startsWith("\\\\") || filePath.startsWith("//");
|
|
}
|
|
|
|
export function isPathWithinRoots(target: string, roots: Set<string>): boolean {
|
|
for (const root of roots) {
|
|
const useWindowsRules = isWindowsAbsolutePath(target) || isWindowsAbsolutePath(root);
|
|
const resolver = useWindowsRules ? path.win32 : path;
|
|
const sep = useWindowsRules ? "\\" : path.sep;
|
|
const normalized = resolver.resolve(target);
|
|
const normalizedRoot = resolver.resolve(root);
|
|
const comparable = useWindowsRules ? normalized.toLowerCase() : normalized;
|
|
const comparableRoot = useWindowsRules ? normalizedRoot.toLowerCase() : normalizedRoot;
|
|
const rootWithSep = comparableRoot.endsWith(sep) ? comparableRoot : comparableRoot + sep;
|
|
if (comparable === comparableRoot || comparable.startsWith(rootWithSep)) return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
export function isExistingPathWithinRoots(target: string, roots: Set<string>): boolean {
|
|
let realTarget: string;
|
|
try {
|
|
realTarget = realpathSync(target);
|
|
} catch {
|
|
return false;
|
|
}
|
|
|
|
const realRoots = new Set<string>();
|
|
for (const root of roots) {
|
|
try {
|
|
realRoots.add(realpathSync(root));
|
|
} catch {
|
|
// Ignore stale roots derived from removed sessions or worktrees.
|
|
}
|
|
}
|
|
return isPathWithinRoots(realTarget, realRoots);
|
|
}
|