node
node copied to clipboard
Add a utility to convert file URL or path to one of them?
What is the problem this feature will solve?
It's a nice way to accept both URL
and path string in API, but we need covert it to either string or URL, it would be nice to have a built-in method to do this.
What is the feature you are proposing to solve the problem?
For converting to string:
Maybe add path.from(URL | string)
? @sindresorhus proposed here.
For converting to URL:
url.from(URL | string)
I'm not sure, since URL
is a standard, I guess adding method URL
object won't be acceptable, maybe to node:url
module?
What alternatives have you considered?
No response
We have a toPathIfFileURL
internal API already, maybe we could expose it in the node:url
module
https://github.com/nodejs/node/blob/38b7961ce6ca906ac8bad4d32c347f7a724989f9/lib/internal/url.js#L1558-L1562
For converting to URL:
url.from(URL | string)
I don't think there is any reliable way to check if a string is a path or a file URL... I'm afraid the best option here is to assume that a string is a path and call pathToFileURL(string)
(which is what is doing Node.js internally as well) β or if you prefer to assume strings are URLs in your application, call new URL(string)
.
We have a toPathIfFileURL internal API already, maybe we could expose it in the node:url module
Wouldn't it be more natural to have it in node:path
, since we want to convert it to a path? My proposal for path.from()
was inspired by Array.from
and Buffer.from
type methods.
I don't think there is any reliable way to check if a string is a path or a file URL...
To be clear, the string
in that example is meant to be a file path, not a string file URL.
Example usage:
import path from 'node:path';
// Passthrough
path.from('/Users/sindresorhus/dev');
//=> '/Users/sindresorhus/dev'
path.from(new URL('file:///Users/sindresorhus/dev'));
//=> '/Users/sindresorhus/dev'
Is this what you had in mind in terms of semantics? https://github.com/benjamingr/io.js/commit/070485195abe41dce9bf1143bb4f3e47b170f2ca#diff-6610c8d452ba38a0db8c591e06af555bc7755ace17065a066c853ffcc5271559R7-R20
Yes, that's what I want.
@aduh95 wdyt about an implementation that does that? ( https://github.com/nodejs/node/issues/41521#issuecomment-1042071145 )
@aduh95 wdyt about an implementation that does that? ( #41521 (comment) )
I don't think we'll get consensus landing in core something that treats differently a string depending on if it starts with file:
or not βΒ what if the user meant ./file:/
(i.e. they really have a local directory named file:
)?
The workarounds that come to mind are:
- only support absolute paths β or require relative paths to start with a
.
(like inrequire
calls). - always treat a string as a path.
- publish this as an npm module instead (I think npm module would get away with not supporting having directory named
file:
).
Any combination of the above would address my concern, but I'm open to other ideas if someone thinks of something else.
@aduh95 I think it's safe to say "if this can be an npm module, sindre has already probably published one" :D Making small useful modules kind of their thing.
Edit: lol found it https://www.npmjs.com/package/file-url Edit2: actually that's the other side of conversion
Basically: I think the main issue with this being on npm is that file urls and paths are both very common in modern Node.js and not having a utility to convert them in core is weird.
I'm sure we can bikeshed the name and semantics as long as the core use case (convert file url to path) is addressed.
Would it be better if the name was explicit path.fromFileUrl
that only takes either a file://
url string or an actual URL
with the file protocol and throws an error on non-file urls?
I have no need for supporting file://
strings.
What I would like is:
export const from = urlOrPath => urlOrPath instanceof URL ? fileURLToPath(urlOrPath) : urlOrPath;
import path from 'path';
path.from('/Users/sindresorhus');
//=> '/Users/sindresorhus'
path.from(new URL('file:///Users/sindresorhus'));
//=> '/Users/sindresorhus'
Would it be better if the name was explicit path.fromFileUrl that only takes either a file:// url string or an actual URL with the file protocol and throws an error on non-file urls?
No, this does not solve the request.
So you would expect:
path.from('file:///Users/sindresorhus');
//=> file:///Users/sindresorhus
?
Edit: was already mentioned above
I have no need for supporting
file://
strings.What I would like is:
export const from = urlOrPath => urlOrPath instanceof URL ? fileURLToPath(urlOrPath) : urlOrPath;
import path from 'path'; path.from('/Users/sindresorhus'); //=> '/Users/sindresorhus' path.from(new URL('file:///Users/sindresorhus')); //=> '/Users/sindresorhus'
So basically you would like toPathIfFileURL
to become public API?
https://github.com/nodejs/node/blob/9caceb28aaa88c0f2126ae478a58b659db152481/lib/internal/url.js#L1555-L1563
FYI: I have url-or-path
published myself, and I found check protocol not that useful, and I removed recently.
@benjamingr Yes
So basically you would like toPathIfFileURL to become public API?
Yes
Would it be fine if the name was more explicit like path.fromURL
or path.fromFileURL
?
I don't think we can be much more explicit than url.toPathIfFileURL
.
There has been no activity on this feature request for 5 months and it is unlikely to be implemented. It will be closed 6 months after the last non-automated comment.
For more information on how the project manages feature requests, please consult the feature request management document.
Please keep this open.
@MoLow wanna take a look?
Sure, once I'm back from vacation
Would it be fine if the name was more explicit like path.fromURL or path.fromFileURL ?
+1 to this, the semantics seems more concise with the rest of the API
The pull request for this issue was recently closed for lack of response from one of the reviewers.
The main open question is how file URL strings ('file:///c:/foo.txt'
) should be handled. Should they be normalized to a path or passed through?
I would argue they should be either passed through or even throw a user-friendly error. Node.js APIs do not seem to currently handle file URL strings and I don't think they should either:
fs.readFileSync('file:///Users/sindresorhus/x.md');
// Error: ENOENT: no such file or directory, open
Node.js APIs do not seem to currently handle file URL strings
Just to clarify, it does handle it but as a relative path (i.e. in your example it tries to read ./file:/Users/sindresorhus/x.md
).
This solution would particularly be useful for converting import.meta.url
into a file path.
This solution would particularly be useful for converting
import.meta.url
into a file path.
You can already use fileURLToPath(import.meta.url)
for that.
Oh, sorry. Got mislead by reading as this issue is still open.
There has been no activity on this feature request for 5 months and it is unlikely to be implemented. It will be closed 6 months after the last non-automated comment.
For more information on how the project manages feature requests, please consult the feature request management document.
Please keep this open.