The Windows-aware path matching added for project ownership was a second copy of what the file tree's IPC layer already had — same Windows test, same containment check, one of them carrying a trailing-slash branch its own normalisation made unreachable. Both now share lib/path-compare.
24 lines
1.1 KiB
TypeScript
24 lines
1.1 KiB
TypeScript
/** Comparing two paths for identity or containment, across host spellings.
|
|
*
|
|
* A cwd reaches us from the backend, a picker, a session row and a project
|
|
* record, and the four don't agree on separator, trailing slash or drive-letter
|
|
* case. Compare through these rather than `===` / `startsWith`.
|
|
*/
|
|
|
|
/** POSIX-style spelling: one separator, no trailing slash. */
|
|
export const cleanPath = (path: string): string => path.trim().replace(/\\/g, '/').replace(/\/+$/, '') || '/'
|
|
|
|
/** Case-folded comparison key. Windows drive/UNC paths are case-insensitive;
|
|
* POSIX paths are not, and callers that display a path want its real spelling,
|
|
* so fold only the key. Expects an already-`cleanPath`ed value. */
|
|
export const comparisonPath = (path: string): string =>
|
|
/^[A-Za-z]:(?:\/|$)/.test(path) || path.startsWith('//') ? path.toLowerCase() : path
|
|
|
|
/** True when `child` IS `parent` or lives underneath it. */
|
|
export const isUnderPath = (parent: string, child: string): boolean => {
|
|
const p = comparisonPath(cleanPath(parent))
|
|
const c = comparisonPath(cleanPath(child))
|
|
|
|
return c === p || c.startsWith(`${p}/`)
|
|
}
|