I have a path, let's say C:\temp\something.js
and I want to get case-exact version of the path on Windows - so if there is C:\Temp\someThing.js
stored on disk, I would like to get this value (path).
How can I get from the former path the later one in Node.js?
I have already gone through FS API (https://nodejs.org/api/fs.html) and I have not found anything useful (namely fs.realpathSync
, fs.statSync
, fs.accessSync
did not return what I need).
I believe the only way is to loop over the files in the parent directory, and then find the file that will match. A sample implementation for case insensitive systems is provided below.
If the file system is case insensitive, then there cannot be two files in the same folder that share the same name in lowercase letter. The following implementation takes advantage of that.
If your use case need to handle case sensitive file systems, I suggest to keep a list of potential matches, and then open the potential matches to check the content in order to determine the good one.
Platforms with case-INsensitive filesystems (Windows, macOS) make it surprisingly hard to get the case-exact form of a given, possibly case-variant path - there seem to be no system APIs for it, so environments such as Node.js (or Python, Perl, ...) are not to blame.
Update: @barsh was nice enough to package up the code below for use with
npm
, so you can install it easily withnpm install true-case-path
.The
glob
npm package with itsnocase
option comes to the rescue here (though it needed some tweaking on Windows); basically, treating the input path as a glob - even if it is a literal path - makesglob()
return the true case as stored in the filesystem:Install package
glob
in your project folder:npm install glob
(add--save
or--save-dev
as needed).Use the
trueCasePathSync()
function below; see the comments for usage and limitations; notably, while the input path is also normalized, paths starting with..
are not supported, becausepath.normalize()
doesn't resolve them relative to the current dir.trueCasePathSync()
does not return a canonical path: if you pass in a relative path, you'll get a relative output path as well, and no symlinks are resolved. If you want the canonical path, applyfs.realPathSync()
to the result.Should work on Windows, macOS, and Linux (though with limited usefulness on case-sensitive filesystems), tested with Node.js v4.1.1