| 1 | // @effect-diagnostics nodeBuiltinImport:off - one synchronous probe at module load, outside any Effect runtime. |
| 2 | import * as NodeFS from "node:fs"; |
| 3 | import * as NodeOS from "node:os"; |
| 4 | import * as NodePath from "node:path"; |
| 5 | |
| 6 | /** |
| 7 | * Whether this host lets an unprivileged process create symlinks. Windows |
| 8 | * refuses without Developer Mode or elevation, so tests that plant a symlink |
| 9 | * to prove containment or escape detection should `skipIf(!symlinksSupported)` |
| 10 | * rather than fail at setup. Probed once per process. |
| 11 | */ |
| 12 | export const symlinksSupported: boolean = (() => { |
| 13 | let directory: string | undefined; |
| 14 | try { |
| 15 | directory = NodeFS.mkdtempSync(NodePath.join(NodeOS.tmpdir(), "t3-symlink-probe-")); |
| 16 | NodeFS.symlinkSync(NodePath.join(directory, "target"), NodePath.join(directory, "link")); |
| 17 | return true; |
| 18 | } catch { |
| 19 | return false; |
| 20 | } finally { |
| 21 | // Cleanup must not decide the answer: a transient EPERM/EBUSY on the |
| 22 | // probe directory would otherwise throw out of module initialisation. |
| 23 | try { |
| 24 | if (directory !== undefined) NodeFS.rmSync(directory, { recursive: true, force: true }); |
| 25 | } catch { |
| 26 | // Leave the probe directory behind rather than fail every importer. |
| 27 | } |
| 28 | } |
| 29 | })(); |