Files
my-pi/pi-permission-system/src/access-intent/bash/msys-bash-tokens.ts
T

65 lines
2.4 KiB
TypeScript

/**
* Pure shape classifier for a bash-command token on a win32 host, where Pi core
* executes commands through Git Bash and POSIX-shaped absolute tokens carry
* MSYS mount semantics rather than `node:path.win32` semantics.
*
* Consumed only by {@link PathNormalizer.forBashToken}; kept as a standalone
* module so the shape knowledge is unit-testable in isolation (no filesystem,
* no platform read).
*/
import { isSafeSystemPath } from "#src/safe-system-paths";
/**
* The MSYS interpretation of a win32 bash token:
*
* - `device` — a safe MSYS runtime device (`/dev/null`, `/dev/std{in,out,err}`);
* never a filesystem path.
* - `drive-mount` — an MSYS drive mount (`/c/…`, `/d/…`); `windowsPath` is its
* deterministic Windows equivalent (`C:\…`).
* - `posix-absolute` — any other absolute POSIX path (`/tmp/foo`, `/usr/bin`);
* its Windows target is install-dependent and not deterministically knowable,
* so it is treated literally.
* - `plain` — everything else (relative tokens, `~/…`, native Windows drive
* paths); handled by ordinary win32 resolution.
*/
export type BashTokenShape =
| { kind: "device" }
| { kind: "drive-mount"; windowsPath: string }
| { kind: "posix-absolute" }
| { kind: "plain" };
/**
* A single-letter first path segment identifies an MSYS drive mount: `/c`,
* `/c/`, or `/c/rest`. A multi-letter first segment (`/dev`, `/tmp`) is not a
* mount. The device set is checked before this pattern, so `/dev/*` never
* reaches it.
*/
const MSYS_DRIVE_MOUNT_PATTERN = /^\/([a-zA-Z])(\/.*)?$/;
export function classifyWin32BashToken(token: string): BashTokenShape {
if (isSafeSystemPath(token)) return { kind: "device" };
const driveMatch = MSYS_DRIVE_MOUNT_PATTERN.exec(token);
if (driveMatch) {
return {
kind: "drive-mount",
windowsPath: toWindowsDrivePath(driveMatch[1], driveMatch[2]),
};
}
if (token.startsWith("/")) return { kind: "posix-absolute" };
return { kind: "plain" };
}
/**
* Build the Windows equivalent of an MSYS drive mount: uppercase drive letter,
* `:\`, and the remainder with `/` separators rewritten to `\`. A bare or
* trailing-slash mount (`/c`, `/c/`) maps to the drive root (`C:\`).
*/
function toWindowsDrivePath(letter: string, rest: string | undefined): string {
const drive = `${letter.toUpperCase()}:`;
const tail = (rest ?? "").replace(/^\//, "").replaceAll("/", "\\");
return tail ? `${drive}\\${tail}` : `${drive}\\`;
}