'use strict'; const path = require('node:path'); const fs = require('node:fs'); /** * 把路径规整到 OS 真实指向(symlink / 8.3 短名 / 盘符大小写都消除)。 * 失败时退回到 path.resolve —— 比如路径根本不存在,realpath 抛 ENOENT, * 用 resolve 至少能让 path.resolve(a) === path.resolve(b) 这条兜底成立。 * * @param {string} p * @returns {string} */ function real(p) { try { return fs.realpathSync.native(p); } catch (_) { return path.resolve(p); } } /** * 判断两个路径是否指向同一个目录。 * * Windows 文件系统大小写不敏感:`D:\Clipboard Data` 与 `d:\clipboard data` * 是同一个目录,必须按小写比较。原始 `path.resolve(a) === path.resolve(b)` * 在大小写不一致时会误判为不同目录 —— settings:choose-dir 里这会让用户 * 重选当前目录时绕过「已经是当前数据位置」提示,弹出「目标已有数据」 * 迁移对话框自己迁自己。 * * 此外 NTFS 还做 Unicode-normalization 不敏感:`café` 的 NFC / NFD 两种写法 * 指向同一文件。光是 toLowerCase 比较会把两种写法判成不同,触发自我迁移。 * 走 realpathSync.native 让 OS 自己解析到内部规范形式再比较。 * * POSIX 大小写敏感、symlink 敏感:严格比较。 * * @param {string} a * @param {string} b * @returns {boolean} */ function isSameDir(a, b) { const ra = real(a); const rb = real(b); return process.platform === 'win32' ? ra.toLowerCase() === rb.toLowerCase() : ra === rb; } module.exports = { isSameDir };