|
1 | 1 | import fs from 'node:fs'
|
2 | 2 | import os from 'node:os'
|
3 | 3 | import path from 'node:path'
|
| 4 | +import { exec } from 'node:child_process' |
4 | 5 | import { createHash } from 'node:crypto'
|
5 | 6 | import { promisify } from 'node:util'
|
6 | 7 | import { URL, URLSearchParams } from 'node:url'
|
@@ -597,10 +598,51 @@ export const renameDir = isWindows ? promisify(gracefulRename) : fs.renameSync
|
597 | 598 | // `fs.realpathSync.native` resolves differently in Windows network drive,
|
598 | 599 | // causing file read errors. skip for now.
|
599 | 600 | // https://github.com/nodejs/node/issues/37737
|
600 |
| -export const safeRealpathSync = isWindows |
601 |
| - ? fs.realpathSync |
| 601 | +export let safeRealpathSync = isWindows |
| 602 | + ? windowsSafeRealPathSync |
602 | 603 | : fs.realpathSync.native
|
603 | 604 |
|
| 605 | +// Based on https://github.com/larrybahr/windows-network-drive |
| 606 | +// MIT License, Copyright (c) 2017 Larry Bahr |
| 607 | +const windowsNetworkMap = new Map() |
| 608 | +function windowsMappedRealpathSync(path: string) { |
| 609 | + const realPath = fs.realpathSync.native(path) |
| 610 | + if (realPath.startsWith('\\\\')) { |
| 611 | + for (const [network, volume] of windowsNetworkMap) { |
| 612 | + if (realPath.startsWith(network)) return realPath.replace(network, volume) |
| 613 | + } |
| 614 | + } |
| 615 | + return realPath |
| 616 | +} |
| 617 | +const parseNetUseRE = /^(\w+) +(\w:) +([^ ]+)\s/ |
| 618 | +let firstSafeRealPathSyncRun = false |
| 619 | + |
| 620 | +function windowsSafeRealPathSync(path: string): string { |
| 621 | + if (!firstSafeRealPathSyncRun) { |
| 622 | + optimizeSafeRealPathSync() |
| 623 | + firstSafeRealPathSyncRun = true |
| 624 | + } |
| 625 | + return fs.realpathSync(path) |
| 626 | +} |
| 627 | + |
| 628 | +function optimizeSafeRealPathSync() { |
| 629 | + exec('net use', (error, stdout) => { |
| 630 | + if (error) return |
| 631 | + const lines = stdout.split('\n') |
| 632 | + // OK Y: \\NETWORKA\Foo Microsoft Windows Network |
| 633 | + // OK Z: \\NETWORKA\Bar Microsoft Windows Network |
| 634 | + for (const line of lines) { |
| 635 | + const m = line.match(parseNetUseRE) |
| 636 | + if (m) windowsNetworkMap.set(m[3], m[2]) |
| 637 | + } |
| 638 | + if (windowsNetworkMap.size === 0) { |
| 639 | + safeRealpathSync = fs.realpathSync.native |
| 640 | + } else { |
| 641 | + safeRealpathSync = windowsMappedRealpathSync |
| 642 | + } |
| 643 | + }) |
| 644 | +} |
| 645 | + |
604 | 646 | export function ensureWatchedFile(
|
605 | 647 | watcher: FSWatcher,
|
606 | 648 | file: string | null,
|
|
0 commit comments