url: expose pathToFileURL and fileURLToPath#22506
url: expose pathToFileURL and fileURLToPath#22506guybedford wants to merge 18 commits intonodejs:masterfrom
Conversation
doc/api/url.md
Outdated
| ```js | ||
| // BAD: | ||
| // - fails in Windows | ||
| // - doesn't handle loading paths using extended non-latin characters |
There was a problem hiding this comment.
not just that, also things like " " which are percent encoded
There was a problem hiding this comment.
This isn't meant to be comprehensive, but we can certainly pad out the examples.
I expect this will also change over time, so I don't think we want to keep the docs exactly in sync with the code here either.
There was a problem hiding this comment.
agree, but examples seem more prudent than statements like this which could be taken as the only exceptions thereby leading people only on unix and in latin charsets to feel this API is not needed
lib/internal/url.js
Outdated
| } | ||
|
|
||
| function toPathIfFileUrl(fileUrlOrPath) { | ||
| if (fileUrlOrPath == null || !fileUrlOrPath[searchParams] || |
There was a problem hiding this comment.
This was what was already in place here, so I didn't want to alter it for fear of compatibility changes. We could certainly try instanceof.
There was a problem hiding this comment.
i'm curious why it wasn't using instanceof, would prefer to use that if we expose it to users
There was a problem hiding this comment.
Largely because of performance. Checking for the existence of the internal symbol is significantly faster than using instanceof
There was a problem hiding this comment.
doc/api/url.md
Outdated
| ## File URL Utility Functions | ||
|
|
||
| When working with `file:///` URLs in Node.js (eg when working with ES modules | ||
| which are keyed in the registry by File URL), the utility functions |
There was a problem hiding this comment.
I’d s/registry/module registry/ for clarity
doc/api/url.md
Outdated
| ```js | ||
| // BAD: | ||
| // - fails in Windows | ||
| // - doesn't handle loading paths using extended non-latin characters |
|
would like to see more examples added to docs to emphasize why this is a good API to use. I left some at #22502 (comment) including the fileURL in each example would help, be sure to uppercase the URL per https://url.spec.whatwg.org/#url-apis-elsewhere |
This comment has been minimized.
This comment has been minimized.
|
@bmeck thanks I've padded out the examples and renamed |
|
@vsemozhetbyt those other methods are provided under "legacy API", whereas these ones aren't part of the legacy API, but utilities that go alongside the WhatWG API. |
This comment has been minimized.
This comment has been minimized.
|
@vsemozhetbyt ah I missed that, sure I've combined it into the same section. |
vsemozhetbyt
left a comment
There was a problem hiding this comment.
Just some doc nits.
doc/api/url.md
Outdated
| For example, the following errors can occur when converting from paths to URLs: | ||
|
|
||
| ```js | ||
| // throws for missing schema (posix) |
There was a problem hiding this comment.
posix -> POSIX here and below?
doc/api/url.md
Outdated
| new URL('./foo#1', 'file:///'); | ||
|
|
||
| // 'file:///nas/foo.txt' instead of the correct 'file:///foo.txt' (posix) | ||
| new URL(`file://${'//nas/foo.txt'}`); |
There was a problem hiding this comment.
In this and the next example, template strings with string interpolation seem confusingly redundant. Maybe interpolate previously defined variables?
There was a problem hiding this comment.
I quite like having these be scannable as single-line cases, initially I wrote new URL('file://' + '//nas/foo.txt') to indicate the separation, but the linter wouldn't allow that.
doc/api/url.md
Outdated
| new URL(`file://${'//nas/foo.txt'}`); | ||
|
|
||
| // 'file:///some/path%' instead of the correct 'file:///some/path%25' (posix) | ||
| new URL(`sfile:${'/some/path%.js'}`); |
doc/api/url.md
Outdated
| new URL(`sfile:${'/some/path%.js'}`); | ||
| ``` | ||
|
|
||
| where using `pathToFileURL` we can get the correct results above. |
There was a problem hiding this comment.
`pathToFileURL` -> `url.pathToFileURL()`
doc/api/url.md
Outdated
|
|
||
| where using `pathToFileURL` we can get the correct results above. | ||
|
|
||
| ### url.fileURLToPath(url) |
There was a problem hiding this comment.
This section needs to go before ### url.format(URL[, options]) ABC-wise.
There was a problem hiding this comment.
Sure, a shame we can't keep these together though.
doc/api/url.md
Outdated
|
|
||
| ### url.fileURLToPath(url) | ||
|
|
||
| * `url` {URL} | {string} The file URL string or URL object to convert to a path. |
There was a problem hiding this comment.
{URL} | {string} -> {URL | string}
doc/api/url.md
Outdated
| new URL('file:///hello world.txt').pathname; | ||
| ``` | ||
|
|
||
| where using `fileURLToPath` we can get the correct results above. |
There was a problem hiding this comment.
`fileURLToPath` -> `url.fileURLToPath()`
| function toPathIfFileURL(fileURLOrPath) { | ||
| if (fileURLOrPath == null || !fileURLOrPath[searchParams] || | ||
| !fileURLOrPath[searchParams][searchParams]) | ||
| return fileURLOrPath; |
There was a problem hiding this comment.
What's the fileURLOrPath[searchParams][searchParams] check about?
The fileURLOrPath[searchParams] checks currently allow paths to duck-type as URLs.
There was a problem hiding this comment.
Specifically asking about the double searchParams check of
fileURLOrPath[searchParams][searchParams].
There was a problem hiding this comment.
This is exactly what is already implemented. We can switch to an instanceof, but would be good to hear from @jasnell if this would be compatible with the original logic.
There was a problem hiding this comment.
I would prefer a brand check (i.e. [searchParams]) as it's already been used everywhere else where we are checking for a URL, for consistency if nothing else. The same logic would probably apply to fileURLToPath() as well.
There was a problem hiding this comment.
Duck-typing isn't great. That it slipped in elsewhere in the project isn't a reason to continue it. It should really be reworked out when possible.
There was a problem hiding this comment.
I managed to trace down the origin of this code, and it was a performance PR made here - #11690.
If we want to change this, we should do it in all of URL and not just this function, and as a separate PR.
There was a problem hiding this comment.
a note, we shouldn't call forgable things "branding" generally. "tagging" is generally the term here (like Symbol.toStringTag)
TimothyGu
left a comment
There was a problem hiding this comment.
For this to be exposed to public, I believe we need to be more careful with input validation. For example, I'd rather have URL be the sole input for url.fileURLToPath(), and throw an exception otherwise.
|
@TimothyGu what concerns do you have about input ambiguity here? Because URL strings are encouraged by the WhatWG spec (despite any performance concerns), I'm very much for functions permitting URL strings or URL objects equally. I think cases to worry about is string parsing where different cases of strings are permitted like with the fs functions, but as we have been doing allowing URL strings or objects equally seems to me a good pattern generally to avoid the performance issues while still allowing "supposed" best practices. |
doc/api/url.md
Outdated
| new URL('file:///hello world.txt').pathname; | ||
| ``` | ||
|
|
||
| where using `url.fileURLToPath` we can get the correct results above. |
There was a problem hiding this comment.
We usually add parentheses to functions/methods as per the style guide, so:
`url.fileURLToPath` -> `url.fileURLToPath()`
doc/api/url.md
Outdated
| ``` | ||
|
|
||
| where using `fileURLToPath` we can get the correct results above. | ||
| where using `url.pathToFileURL` we can get the correct results above. |
Notable changes:
* fs
* Added a `recursive` option to `fs.mkdir` and `fs.mkdirSync`. If
this option is set to `true`, non-existing parent folders will be
automatically created.
#21875
* Fixed fsPromises.readdir `withFileTypes`.
#22832
* http2
* Added `http2stream.endAfterHeaders` property.
#22843
* module
* Added `module.createRequireFromPath(filename)`. This new method can
be used to create a custom `require` function that will resolve
modules relative to the `filename` path.
#19360
* url
* Added `url.fileURLToPath(url)` and `url.pathToFileURL(path)`. These
methods can be used to correctly convert between `file:` URLs and
absolute paths.
#22506
* util
* Added `util.types.isBoxedPrimitive(value)`.
#22620
* Windows
* The Windows msi installer now provides an option to automatically
install the tools required to build native modules.
#22645
* Added new collaborators:
* boneskull (https://github.com/boneskull) - Christopher Hiller
* The Technical Steering Committee has new members:
* apapirovski (https://github.com/apapirovski) - Anatoli Papirovski
* gabrielschulhof (https://github.com/gabrielschulhof) - Gabriel Schulhof
PR-URL: #22932
PR-URL: #22506 Reviewed-By: John-David Dalton <[email protected]> Reviewed-By: Tiancheng "Timothy" Gu <[email protected]> Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: Bradley Farias <[email protected]> Reviewed-By: Joyee Cheung <[email protected]> Reviewed-By: Gus Caplan <[email protected]>
Notable changes:
* fs
* Added a `recursive` option to `fs.mkdir` and `fs.mkdirSync`. If
this option is set to `true`, non-existing parent folders will be
automatically created.
#21875
* Fixed fsPromises.readdir `withFileTypes`.
#22832
* http2
* Added `http2stream.endAfterHeaders` property.
#22843
* module
* Added `module.createRequireFromPath(filename)`. This new method can
be used to create a custom `require` function that will resolve
modules relative to the `filename` path.
#19360
* url
* Added `url.fileURLToPath(url)` and `url.pathToFileURL(path)`. These
methods can be used to correctly convert between `file:` URLs and
absolute paths.
#22506
* util
* Added `util.types.isBoxedPrimitive(value)`.
#22620
* Added new collaborators:
* boneskull (https://github.com/boneskull) - Christopher Hiller
* The Technical Steering Committee has new members:
* apapirovski (https://github.com/apapirovski) - Anatoli Papirovski
* gabrielschulhof (https://github.com/gabrielschulhof) - Gabriel Schulhof
PR-URL: #22932
|
Depends on #21875. Marking |
PR-URL: #22506 Reviewed-By: John-David Dalton <[email protected]> Reviewed-By: Tiancheng "Timothy" Gu <[email protected]> Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: Bradley Farias <[email protected]> Reviewed-By: Joyee Cheung <[email protected]> Reviewed-By: Gus Caplan <[email protected]>
Notable changes:
* assert
* The diff output is now a tiny bit improved by sorting object
properties when inspecting the values that are compared with each
other. #22788
* cli
* The options parser now normalizes `_` to `-` in all multi-word
command-line flags, e.g. `--no_warnings` has the same effect as
`--no-warnings`. #23020
* Added bash completion for the `node` binary. To generate a bash
completion script, run `node --completion-bash`. The output can be
saved to a file which can be sourced to enable completion.
#20713
* crypto
* Added support for PEM-level encryption.
#23151
* Added an API asymmetric key pair generation. The new methods
`crypto.generateKeyPair` and `crypto.generateKeyPairSync` can be
used to generate public and private key pairs. The API supports
RSA, DSA and EC and a variety of key encodings (both PEM and DER).
#22660
* fs
* Added a `recursive` option to `fs.mkdir` and `fs.mkdirSync`. If
this option is set to true, non-existing parent folders will be
automatically created. #21875
* http2
* Added a `'ping'` event to `Http2Session` that is emitted whenever a
non-ack `PING` is received.
#23009
* Added support for the `ORIGIN` frame.
#22956
* module
* Added `module.createRequireFromPath(filename)`. This new method can
be used to create a custom require function that will resolve
modules relative to the filename path.
#19360
* process
* Added a `'multipleResolves'` process event that is emitted whenever
a `Promise` is attempted to be resolved multiple times, e.g. if the
`resolve` and `reject` functions are both called in a `Promise`
executor. #22218
* **url**
* Added `url.fileURLToPath(url)` and `url.pathToFileURL(path)`. These
methods can be used to correctly convert between file: URLs and
absolute paths. #22506
* **util**
* Added the `sorted` option to `util.inspect()`. If set to `true`,
all properties of an object and Set and Map entries will be sorted
in the returned string. If set to a function, it is used as a
compare function. #22788
* The `util.instpect.custom` symbol is now defined in the global
symbol registry as `Symbol.for('nodejs.util.inspect.custom')`.
#20857
* **Windows**
* The Windows msi installer now provides an option to automatically
install the tools required to build native modules.
#22645
* **Added new collaborators**:
* digitalinfinity - Hitesh Kanwathirtha
PR-URL: #23313
Notable changes:
* assert
* The diff output is now a tiny bit improved by sorting object
properties when inspecting the values that are compared with each
other. #22788
* cli
* The options parser now normalizes `_` to `-` in all multi-word
command-line flags, e.g. `--no_warnings` has the same effect as
`--no-warnings`. #23020
* Added bash completion for the `node` binary. To generate a bash
completion script, run `node --completion-bash`. The output can be
saved to a file which can be sourced to enable completion.
#20713
* crypto
* Added support for PEM-level encryption.
#23151
* Added an API asymmetric key pair generation. The new methods
`crypto.generateKeyPair` and `crypto.generateKeyPairSync` can be
used to generate public and private key pairs. The API supports
RSA, DSA and EC and a variety of key encodings (both PEM and DER).
#22660
* fs
* Added a `recursive` option to `fs.mkdir` and `fs.mkdirSync`. If
this option is set to true, non-existing parent folders will be
automatically created. #21875
* http2
* Added a `'ping'` event to `Http2Session` that is emitted whenever a
non-ack `PING` is received.
#23009
* Added support for the `ORIGIN` frame.
#22956
* Updated nghttp2 to 1.34.0. This adds RFC 8441 extended connect
protocol support to allow use of WebSockets over HTTP/2.
#23284
* module
* Added `module.createRequireFromPath(filename)`. This new method can
be used to create a custom require function that will resolve
modules relative to the filename path.
#19360
* process
* Added a `'multipleResolves'` process event that is emitted whenever
a `Promise` is attempted to be resolved multiple times, e.g. if the
`resolve` and `reject` functions are both called in a `Promise`
executor. #22218
* url
* Added `url.fileURLToPath(url)` and `url.pathToFileURL(path)`. These
methods can be used to correctly convert between file: URLs and
absolute paths. #22506
* util
* Added the `sorted` option to `util.inspect()`. If set to `true`,
all properties of an object and Set and Map entries will be sorted
in the returned string. If set to a function, it is used as a
compare function. #22788
* The `util.instpect.custom` symbol is now defined in the global
symbol registry as `Symbol.for('nodejs.util.inspect.custom')`.
#20857
* Added support for `BigInt` numbers in `util.format()`.
#22097
* V8 API
* A number of V8 C++ APIs have been marked as deprecated since they
have been removed in the upstream repository. Replacement APIs
are added where necessary. #23159
* Windows
* The Windows msi installer now provides an option to automatically
install the tools required to build native modules.
#22645
* Workers
* Debugging support for Workers using the DevTools protocol has been
implemented. #21364
* The public `inspector` module is now enabled in Workers.
#22769
* Added new collaborators:
* digitalinfinity - Hitesh Kanwathirtha
PR-URL: #23313
Notable changes:
* assert
* The diff output is now a tiny bit improved by sorting object
properties when inspecting the values that are compared with each
other. #22788
* cli
* The options parser now normalizes `_` to `-` in all multi-word
command-line flags, e.g. `--no_warnings` has the same effect as
`--no-warnings`. #23020
* Added bash completion for the `node` binary. To generate a bash
completion script, run `node --completion-bash`. The output can be
saved to a file which can be sourced to enable completion.
#20713
* crypto
* Added support for PEM-level encryption.
#23151
* Added an API asymmetric key pair generation. The new methods
`crypto.generateKeyPair` and `crypto.generateKeyPairSync` can be
used to generate public and private key pairs. The API supports
RSA, DSA and EC and a variety of key encodings (both PEM and DER).
#22660
* fs
* Added a `recursive` option to `fs.mkdir` and `fs.mkdirSync`. If
this option is set to true, non-existing parent folders will be
automatically created. #21875
* http2
* Added a `'ping'` event to `Http2Session` that is emitted whenever a
non-ack `PING` is received.
#23009
* Added support for the `ORIGIN` frame.
#22956
* Updated nghttp2 to 1.34.0. This adds RFC 8441 extended connect
protocol support to allow use of WebSockets over HTTP/2.
#23284
* module
* Added `module.createRequireFromPath(filename)`. This new method can
be used to create a custom require function that will resolve
modules relative to the filename path.
#19360
* process
* Added a `'multipleResolves'` process event that is emitted whenever
a `Promise` is attempted to be resolved multiple times, e.g. if the
`resolve` and `reject` functions are both called in a `Promise`
executor. #22218
* url
* Added `url.fileURLToPath(url)` and `url.pathToFileURL(path)`. These
methods can be used to correctly convert between file: URLs and
absolute paths. #22506
* util
* Added the `sorted` option to `util.inspect()`. If set to `true`,
all properties of an object and Set and Map entries will be sorted
in the returned string. If set to a function, it is used as a
compare function. #22788
* The `util.instpect.custom` symbol is now defined in the global
symbol registry as `Symbol.for('nodejs.util.inspect.custom')`.
#20857
* Added support for `BigInt` numbers in `util.format()`.
#22097
* V8 API
* A number of V8 C++ APIs have been marked as deprecated since they
have been removed in the upstream repository. Replacement APIs
are added where necessary. #23159
* Windows
* The Windows msi installer now provides an option to automatically
install the tools required to build native modules.
#22645
* Workers
* Debugging support for Workers using the DevTools protocol has been
implemented. #21364
* The public `inspector` module is now enabled in Workers.
#22769
* Added new collaborators:
* digitalinfinity - Hitesh Kanwathirtha
PR-URL: #23313
Notable changes:
* assert
* The diff output is now a tiny bit improved by sorting object
properties when inspecting the values that are compared with each
other. #22788
* cli
* The options parser now normalizes `_` to `-` in all multi-word
command-line flags, e.g. `--no_warnings` has the same effect as
`--no-warnings`. #23020
* Added bash completion for the `node` binary. To generate a bash
completion script, run `node --completion-bash`. The output can be
saved to a file which can be sourced to enable completion.
#20713
* crypto
* Added support for PEM-level encryption.
#23151
* Added an API asymmetric key pair generation. The new methods
`crypto.generateKeyPair` and `crypto.generateKeyPairSync` can be
used to generate public and private key pairs. The API supports
RSA, DSA and EC and a variety of key encodings (both PEM and DER).
#22660
* fs
* Added a `recursive` option to `fs.mkdir` and `fs.mkdirSync`. If
this option is set to true, non-existing parent folders will be
automatically created. #21875
* http2
* Added a `'ping'` event to `Http2Session` that is emitted whenever a
non-ack `PING` is received.
#23009
* Added support for the `ORIGIN` frame.
#22956
* Updated nghttp2 to 1.34.0. This adds RFC 8441 extended connect
protocol support to allow use of WebSockets over HTTP/2.
#23284
* module
* Added `module.createRequireFromPath(filename)`. This new method can
be used to create a custom require function that will resolve
modules relative to the filename path.
#19360
* process
* Added a `'multipleResolves'` process event that is emitted whenever
a `Promise` is attempted to be resolved multiple times, e.g. if the
`resolve` and `reject` functions are both called in a `Promise`
executor. #22218
* url
* Added `url.fileURLToPath(url)` and `url.pathToFileURL(path)`. These
methods can be used to correctly convert between file: URLs and
absolute paths. #22506
* util
* Added the `sorted` option to `util.inspect()`. If set to `true`,
all properties of an object and Set and Map entries will be sorted
in the returned string. If set to a function, it is used as a
compare function. #22788
* The `util.instpect.custom` symbol is now defined in the global
symbol registry as `Symbol.for('nodejs.util.inspect.custom')`.
#20857
* Added support for `BigInt` numbers in `util.format()`.
#22097
* V8 API
* A number of V8 C++ APIs have been marked as deprecated since they
have been removed in the upstream repository. Replacement APIs
are added where necessary. #23159
* Windows
* The Windows msi installer now provides an option to automatically
install the tools required to build native modules.
#22645
* Workers
* Debugging support for Workers using the DevTools protocol has been
implemented. #21364
* The public `inspector` module is now enabled in Workers.
#22769
* Added new collaborators:
* digitalinfinity - Hitesh Kanwathirtha
PR-URL: #23313
Notable changes:
* assert
* The diff output is now a tiny bit improved by sorting object
properties when inspecting the values that are compared with each
other. #22788
* cli
* The options parser now normalizes `_` to `-` in all multi-word
command-line flags, e.g. `--no_warnings` has the same effect as
`--no-warnings`. #23020
* Added bash completion for the `node` binary. To generate a bash
completion script, run `node --completion-bash`. The output can be
saved to a file which can be sourced to enable completion.
#20713
* crypto
* Added support for PEM-level encryption.
#23151
* Added an API asymmetric key pair generation. The new methods
`crypto.generateKeyPair` and `crypto.generateKeyPairSync` can be
used to generate public and private key pairs. The API supports
RSA, DSA and EC and a variety of key encodings (both PEM and DER).
#22660
* fs
* Added a `recursive` option to `fs.mkdir` and `fs.mkdirSync`. If
this option is set to true, non-existing parent folders will be
automatically created. #21875
* http2
* Added a `'ping'` event to `Http2Session` that is emitted whenever a
non-ack `PING` is received.
#23009
* Added support for the `ORIGIN` frame.
#22956
* Updated nghttp2 to 1.34.0. This adds RFC 8441 extended connect
protocol support to allow use of WebSockets over HTTP/2.
#23284
* module
* Added `module.createRequireFromPath(filename)`. This new method can
be used to create a custom require function that will resolve
modules relative to the filename path.
#19360
* process
* Added a `'multipleResolves'` process event that is emitted whenever
a `Promise` is attempted to be resolved multiple times, e.g. if the
`resolve` and `reject` functions are both called in a `Promise`
executor. #22218
* url
* Added `url.fileURLToPath(url)` and `url.pathToFileURL(path)`. These
methods can be used to correctly convert between file: URLs and
absolute paths. #22506
* util
* Added the `sorted` option to `util.inspect()`. If set to `true`,
all properties of an object and Set and Map entries will be sorted
in the returned string. If set to a function, it is used as a
compare function. #22788
* The `util.instpect.custom` symbol is now defined in the global
symbol registry as `Symbol.for('nodejs.util.inspect.custom')`.
#20857
* Added support for `BigInt` numbers in `util.format()`.
#22097
* V8 API
* A number of V8 C++ APIs have been marked as deprecated since they
have been removed in the upstream repository. Replacement APIs
are added where necessary. #23159
* Windows
* The Windows msi installer now provides an option to automatically
install the tools required to build native modules.
#22645
* Workers
* Debugging support for Workers using the DevTools protocol has been
implemented. #21364
* The public `inspector` module is now enabled in Workers.
#22769
* Added new collaborators:
* digitalinfinity - Hitesh Kanwathirtha
PR-URL: #23313
As discussed in #22502 this exposes and documents
url.pathToFileURLandurl.fileURLToPathin order to assist with cross platform support and encoding consistency.Checklist
make -j4 test(UNIX), orvcbuild test(Windows) passes