(name: string, env: NodeJS.ProcessEnv)
| 74 | } |
| 75 | |
| 76 | function lookupOnWindowsPath(name: string, env: NodeJS.ProcessEnv): string | null { |
| 77 | const exts = (env['PATHEXT'] ?? DEFAULT_PATHEXT) |
| 78 | .split(';') |
| 79 | .map((e) => e.trim()) |
| 80 | .filter(Boolean) |
| 81 | .sort((a, b) => rank(a) - rank(b)); // prefer a real .exe over a .cmd shim |
| 82 | // Windows env var casing is unstable across hosts; check both. |
| 83 | const dirs = (env['PATH'] ?? env['Path'] ?? '').split(delimiter).filter(Boolean); |
| 84 | for (const dir of dirs) { |
| 85 | for (const ext of exts) { |
| 86 | // PATHEXT is conventionally uppercase but npm shims are lowercase on disk. |
| 87 | // Windows' filesystem is case-insensitive, so we normalize the appended |
| 88 | // extension to lowercase for a clean, deterministic command string. |
| 89 | const candidate = join(dir, name + ext.toLowerCase()); |
| 90 | if (existsSync(candidate)) return candidate; |
| 91 | } |
| 92 | } |
| 93 | return null; |
| 94 | } |
| 95 | |
| 96 | function rank(ext: string): number { |
| 97 | const e = ext.toLowerCase(); |
no test coverage detected