Bifrost/tools/path-within.mjs
Heimdall 0ffd97baed Bridge and git gate: repo-root and excluded-dir containment by path.relative, not a hardcoded backslash
github-draft-pr threw 'Target path escapes repo root' on Linux and the gate never excluded its own wrapper dir. One helper, tools/path-within.mjs, replaces the three copies; case-insensitivity now follows the platform's path flavour.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-12 12:26:37 +00:00

15 lines
621 B
JavaScript

import path from "node:path";
// True when `candidate` is `root` itself (only if allowSelf) or lies beneath it.
// Containment is path.relative-based, so it follows the host's separator and
// case rules; pass path.win32 or path.posix to pin a flavour.
export function isWithin(root, candidate, { pathApi = path, allowSelf = true } = {}) {
const relative = pathApi.relative(pathApi.resolve(root), pathApi.resolve(candidate));
if (relative === "") {
return allowSelf;
}
if (pathApi.isAbsolute(relative) || relative === ".." || relative.startsWith(`..${pathApi.sep}`)) {
return false;
}
return true;
}