Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

path: support file urls #52672

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 60 additions & 23 deletions doc/api/path.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,15 @@ example, `path.resolve('C:\\')` can potentially return a different result than
<!-- YAML
added: v0.1.25
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/52672
description: Passing a file URL as an argument is now supported.
- version: v6.0.0
pr-url: https://github.com/nodejs/node/pull/5348
description: Passing a non-string as the `path` argument will throw now.
-->

* `path` {string}
* `path` {string|URL}
* `suffix` {string} An optional suffix to remove
* Returns: {string}

Expand Down Expand Up @@ -101,8 +104,8 @@ path.win32.basename('C:\\foo.HTML', '.html');
// Returns: 'foo.HTML'
```

A [`TypeError`][] is thrown if `path` is not a string or if `suffix` is given
and is not a string.
A [`TypeError`][] is thrown if `path` is not a string or an instance of [`URL`][],
or if `suffix` is given and is not a string.

## `path.delimiter`

Expand Down Expand Up @@ -142,12 +145,15 @@ process.env.PATH.split(path.delimiter);
<!-- YAML
added: v0.1.16
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/52672
description: Passing a file URL as an argument is now supported.
- version: v6.0.0
pr-url: https://github.com/nodejs/node/pull/5348
description: Passing a non-string as the `path` argument will throw now.
-->

* `path` {string}
* `path` {string|URL}
* Returns: {string}

The `path.dirname()` method returns the directory name of a `path`, similar to
Expand All @@ -159,19 +165,22 @@ path.dirname('/foo/bar/baz/asdf/quux');
// Returns: '/foo/bar/baz/asdf'
```

A [`TypeError`][] is thrown if `path` is not a string.
A [`TypeError`][] is thrown if `path` is not a string or an instance of [`URL`][]

## `path.extname(path)`

<!-- YAML
added: v0.1.25
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/52672
description: Passing a file URL as an argument is now supported.
- version: v6.0.0
pr-url: https://github.com/nodejs/node/pull/5348
description: Passing a non-string as the `path` argument will throw now.
-->

* `path` {string}
* `path` {string|URL}
* Returns: {string}

The `path.extname()` method returns the extension of the `path`, from the last
Expand Down Expand Up @@ -200,7 +209,7 @@ path.extname('.index.md');
// Returns: '.md'
```

A [`TypeError`][] is thrown if `path` is not a string.
A [`TypeError`][] is thrown if `path` is not a string or an instance of [`URL`][].

## `path.format(pathObject)`

Expand Down Expand Up @@ -306,9 +315,13 @@ A [`TypeError`][] is thrown if `path` or `pattern` are not strings.

<!-- YAML
added: v0.11.2
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/52672
description: Passing a file URL as an argument is now supported.
-->

* `path` {string}
* `path` {string|URL}
* Returns: {boolean}

The `path.isAbsolute()` method determines if `path` is an absolute path.
Expand Down Expand Up @@ -336,15 +349,19 @@ path.isAbsolute('bar/baz'); // false
path.isAbsolute('.'); // false
```

A [`TypeError`][] is thrown if `path` is not a string.
A [`TypeError`][] is thrown if `path` is not a string or an instance of [`URL`][].

## `path.join([...paths])`

<!-- YAML
added: v0.1.16
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/52672
description: Passing a file URL as an argument is now supported.
-->

* `...paths` {string} A sequence of path segments
* `...paths` {string|URL} A sequence of path segments
* Returns: {string}

The `path.join()` method joins all given `path` segments together using the
Expand All @@ -362,15 +379,19 @@ path.join('foo', {}, 'bar');
// Throws 'TypeError: Path must be a string. Received {}'
```

A [`TypeError`][] is thrown if any of the path segments is not a string.
A [`TypeError`][] is thrown if any of the path segments is not a string or an instance of [`URL`][].

## `path.normalize(path)`

<!-- YAML
added: v0.1.23
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/52672
description: Passing a file URL as an argument is now supported.
-->

* `path` {string}
* `path` {string|URL}
* Returns: {string}

The `path.normalize()` method normalizes the given `path`, resolving `'..'` and
Expand Down Expand Up @@ -414,15 +435,19 @@ path.win32.normalize('C:////temp\\\\/\\/\\/foo/bar');
// Returns: 'C:\\temp\\foo\\bar'
```

A [`TypeError`][] is thrown if `path` is not a string.
A [`TypeError`][] is thrown if `path` is not a string or an instance of [`URL`][].

## `path.parse(path)`

<!-- YAML
added: v0.11.15
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/52672
description: Passing a file URL as an argument is now supported.
-->

* `path` {string}
* `path` {string|URL}
* Returns: {Object}

The `path.parse()` method returns an object whose properties represent
Expand Down Expand Up @@ -481,7 +506,7 @@ path.parse('C:\\path\\dir\\file.txt');
(All spaces in the "" line should be ignored. They are purely for formatting.)
```

A [`TypeError`][] is thrown if `path` is not a string.
A [`TypeError`][] is thrown if `path` is not a string or an instance of [`URL`][].

## `path.posix`

Expand All @@ -505,14 +530,17 @@ The API is accessible via `require('node:path').posix` or `require('node:path/po
<!-- YAML
added: v0.5.0
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/52672
description: Passing a file URL as an argument is now supported.
- version: v6.8.0
pr-url: https://github.com/nodejs/node/pull/8523
description: On Windows, the leading slashes for UNC paths are now included
in the return value.
-->

* `from` {string}
* `to` {string}
* `from` {string|URL}
* `to` {string|URL}
* Returns: {string}

The `path.relative()` method returns the relative path from `from` to `to` based
Expand All @@ -536,15 +564,19 @@ path.relative('C:\\orandea\\test\\aaa', 'C:\\orandea\\impl\\bbb');
// Returns: '..\\..\\impl\\bbb'
```

A [`TypeError`][] is thrown if either `from` or `to` is not a string.
A [`TypeError`][] is thrown if either `from` or `to` is not a string or an instance of [`URL`][].

## `path.resolve([...paths])`

<!-- YAML
added: v0.3.4
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/52672
description: Passing a file URL as an argument is now supported.
-->

* `...paths` {string} A sequence of paths or path segments
* `...paths` {string|URL} A sequence of paths or path segments
* Returns: {string}

The `path.resolve()` method resolves a sequence of paths or path segments into
Expand Down Expand Up @@ -579,7 +611,7 @@ path.resolve('wwwroot', 'static_files/png/', '../gif/image.gif');
// this returns '/home/myself/node/wwwroot/static_files/gif/image.gif'
```

A [`TypeError`][] is thrown if any of the arguments is not a string.
A [`TypeError`][] is thrown if any of the arguments is not a string or an instance of [`URL`][].

## `path.sep`

Expand Down Expand Up @@ -616,14 +648,18 @@ slashes (`\`).

<!-- YAML
added: v9.0.0
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/52672
description: Passing a file URL as an argument is now supported.
-->

* `path` {string}
* `path` {string|URL}
* Returns: {string}

On Windows systems only, returns an equivalent [namespace-prefixed path][] for
the given `path`. If `path` is not a string, `path` will be returned without
modifications.
the given `path`. If `path` is not a string or URL, `path` will be returned
without modifications.

This method is meaningful only on Windows systems. On POSIX systems, the
method is non-operational and always returns `path` without modifications.
Expand All @@ -647,6 +683,7 @@ The API is accessible via `require('node:path').win32` or `require('node:path/wi

[MSDN-Rel-Path]: https://docs.microsoft.com/en-us/windows/desktop/FileIO/naming-a-file#fully-qualified-vs-relative-paths
[`TypeError`]: errors.md#class-typeerror
[`URL`]: url.md#the-whatwg-url-api
[`path.parse()`]: #pathparsepath
[`path.posix`]: #pathposix
[`path.sep`]: #pathsep
Expand Down
11 changes: 6 additions & 5 deletions lib/internal/url.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ const {
kEnumerableProperty,
kEmptyObject,
SideEffectFreeRegExpPrototypeSymbolReplace,
getLazy,
} = require('internal/util');

const {
Expand Down Expand Up @@ -77,7 +78,7 @@ const {
CHAR_PERCENT,
CHAR_PLUS,
} = require('internal/constants');
const path = require('path');
const lazyPath = getLazy(() => require('path'));

const {
validateFunction,
Expand Down Expand Up @@ -1555,13 +1556,13 @@ function pathToFileURL(filepath, options = kEmptyObject) {
);
return outURL;
}
let resolved = (windows ?? isWindows) ? path.win32.resolve(filepath) : path.posix.resolve(filepath);
let resolved = (windows ?? isWindows) ? lazyPath().win32.resolve(filepath) : lazyPath().posix.resolve(filepath);
// path.resolve strips trailing slashes so we must add them back
const filePathLast = StringPrototypeCharCodeAt(filepath,
filepath.length - 1);
if ((filePathLast === CHAR_FORWARD_SLASH ||
((windows ?? isWindows) && filePathLast === CHAR_BACKWARD_SLASH)) &&
resolved[resolved.length - 1] !== path.sep)
resolved[resolved.length - 1] !== lazyPath().sep)
resolved += '/';

// Call encodePathChars first to avoid encoding % again for ? and #.
Expand All @@ -1578,10 +1579,10 @@ function pathToFileURL(filepath, options = kEmptyObject) {
return new URL(`file://${resolved}`);
}

function toPathIfFileURL(fileURLOrPath) {
function toPathIfFileURL(fileURLOrPath, options = kEmptyObject) {
if (!isURL(fileURLOrPath))
return fileURLOrPath;
return fileURLToPath(fileURLOrPath);
return fileURLToPath(fileURLOrPath, options);
}

/**
Expand Down
Loading
Loading