Skip to content
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
97 changes: 78 additions & 19 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/52497
description: Passing a URL as the `path` argument will now be allowed.
- 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 All @@ -86,6 +89,9 @@ path.basename('/foo/bar/baz/asdf/quux.html');

path.basename('/foo/bar/baz/asdf/quux.html', '.html');
// Returns: 'quux'

path.basename(new URL('file:///foo/bar/baz/asdf/quux.html'), '.html');
// Returns: 'quux'
```

Although Windows usually treats file names, including file extensions, in a
Expand All @@ -101,8 +107,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/URL or if `suffix` is
given and is not a string.

## `path.delimiter`

Expand Down Expand Up @@ -142,12 +148,15 @@ process.env.PATH.split(path.delimiter);
<!-- YAML
added: v0.1.16
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/52497
description: Passing a URL as the `path` argument will now be allowed.
- 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 @@ -157,21 +166,27 @@ the Unix `dirname` command. Trailing directory separators are ignored, see
```js
path.dirname('/foo/bar/baz/asdf/quux');
// Returns: '/foo/bar/baz/asdf'

path.dirname(new URL('file:///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/URL.

## `path.extname(path)`

<!-- YAML
added: v0.1.25
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/52497
description: Passing a URL as the `path` argument will now be allowed.
- 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 All @@ -187,6 +202,9 @@ path.extname('index.html');
path.extname('index.coffee.md');
// Returns: '.md'

path.extname(new URL('file:///index.coffee.md'));
// Returns: '.md'

path.extname('index.');
// Returns: '.'

Expand All @@ -200,7 +218,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/URL.

## `path.format(pathObject)`

Expand Down Expand Up @@ -283,9 +301,13 @@ path.format({

<!-- YAML
added: v0.11.2
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/52497
description: Passing a URL as the `path` argument will now be allowed.
-->

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

The `path.isAbsolute()` method determines if `path` is an absolute path.
Expand All @@ -296,6 +318,7 @@ For example, on POSIX:

```js
path.isAbsolute('/foo/bar'); // true
path.isAbsolute(new URL('file:///foo/bar')); // true
path.isAbsolute('/baz/..'); // true
path.isAbsolute('qux/'); // false
path.isAbsolute('.'); // false
Expand All @@ -304,6 +327,7 @@ path.isAbsolute('.'); // false
On Windows:

```js
path.isAbsolute(new URL('file:///foo/bar')); // true
path.isAbsolute('//server'); // true
path.isAbsolute('\\\\server'); // true
path.isAbsolute('C:/foo/..'); // true
Expand All @@ -313,15 +337,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/URL.

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

<!-- YAML
added: v0.1.16
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/52497
description: Passing a URL as one of the arguments will now be allowed.
-->

* `...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 @@ -335,19 +363,26 @@ working directory.
path.join('/foo', 'bar', 'baz/asdf', 'quux', '..');
// Returns: '/foo/bar/baz/asdf'

path.join(new URL('file:///foo'), 'bar', 'baz/asdf', 'quux', '..');
// Returns: '/foo/bar/baz/asdf'

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/URL.

## `path.normalize(path)`

<!-- YAML
added: v0.1.23
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/52497
description: Passing a URL as the `path` argument will now be allowed.
-->

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

The `path.normalize()` method normalizes the given `path`, resolving `'..'` and
Expand All @@ -374,13 +409,19 @@ For example, on POSIX:
```js
path.normalize('/foo/bar//baz/asdf/quux/..');
// Returns: '/foo/bar/baz/asdf'

path.normalize(new URL('file:///foo/bar//baz/asdf/quux/..'));
// Returns: '/foo/bar/baz/asdf'
```

On Windows:

```js
path.normalize('C:\\temp\\\\foo\\bar\\..\\');
// Returns: 'C:\\temp\\foo\\'

path.normalize(new URL('file://C:\\temp\\\\foo\\bar\\..\\'));
// Returns: 'C:\\temp\\foo\\'
```

Since Windows recognizes multiple path separators, both separators will be
Expand All @@ -391,15 +432,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/URL.

## `path.parse(path)`

<!-- YAML
added: v0.11.15
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/52497
description: Passing a URL as the `path` argument will now be allowed.
-->

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

The `path.parse()` method returns an object whose properties represent
Expand Down Expand Up @@ -458,7 +503,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/URL.

## `path.posix`

Expand All @@ -482,6 +527,9 @@ 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/52497
description: Passing a URL as one of the arguments will now be allowed.
- 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
Expand Down Expand Up @@ -519,9 +567,13 @@ A [`TypeError`][] is thrown if either `from` or `to` is not a string.

<!-- YAML
added: v0.3.4
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/52497
description: Passing a URL as one of the arguments will now be allowed.
-->

* `...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 All @@ -548,6 +600,9 @@ of the current working directory.
path.resolve('/foo/bar', './baz');
// Returns: '/foo/bar/baz'

path.resolve(new URL('file:///foo/bar'), './baz');
// Returns: '/foo/bar/baz'

path.resolve('/foo/bar', '/tmp/file/');
// Returns: '/tmp/file'

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

<!-- YAML
added: v9.0.0
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/52497
description: Passing a URL as the `path` argument will now be allowed.
-->

* `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/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 Down
13 changes: 10 additions & 3 deletions lib/internal/url.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,14 +76,20 @@ const {
CHAR_PERCENT,
CHAR_PLUS,
} = require('internal/constants');
const path = require('path');

const {
validateFunction,
} = require('internal/validators');

const querystring = require('querystring');

let lazyLoadPath;

function lazyLoadPathSync() {
lazyLoadPath ??= require('path');
return lazyLoadPath;
}

const { platform } = process;
const isWindows = platform === 'win32';

Expand Down Expand Up @@ -1529,13 +1535,14 @@ function pathToFileURL(filepath) {
RegExpPrototypeSymbolReplace(backslashRegEx, StringPrototypeSlice(filepath, hostnameEndIndex), '/'));
return outURL;
}
let resolved = path.resolve(filepath);
const { resolve, sep } = lazyLoadPathSync();
let resolved = 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 ||
(isWindows && filePathLast === CHAR_BACKWARD_SLASH)) &&
resolved[resolved.length - 1] !== path.sep)
resolved[resolved.length - 1] !== sep)
resolved += '/';

// Call encodePathChars first to avoid encoding % again for ? and #.
Expand Down
Loading