Skip to content

Fix: Allow absolute URLs as paths, e.g. for load() #2056

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
7 changes: 7 additions & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2423,6 +2423,13 @@ export namespace util {
/** A minimal path module to resolve Unix, Windows and URL paths alike. */
namespace path {

/**
* Gets the prefix of an absolute UNC path, Unix path, or URL that makes it absolute, if present.
* @param path Path to test
* @returns the prefix, or null if path is relative
*/
function absolutePrefix(path: string): (string|null);

/**
* Tests if the specified path is absolute.
* @param path Path to test
Expand Down
3 changes: 3 additions & 0 deletions lib/path/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,7 @@ API
* **path.resolve(originPath: `string`, includePath: `string`, [alreadyNormalized=false: `boolean`]): `string`**<br />
Resolves the specified include path against the specified origin path.

* **path.absolutePrefix(path: `string`): `string|null`**<br />
Gets the prefix of an absolute Windows, UNC, or Unix path or a URL that indicates it's absolute.

**License:** [BSD 3-Clause License](https://opensource.org/licenses/BSD-3-Clause)
7 changes: 7 additions & 0 deletions lib/path/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
/**
* Gets the prefix of an absolute Windows, UNC, or Unix path or a URL that indicates it's absolute.
* @param {string} path Path to test
* @returns {string|null} the prefix, or null if path is relative
*/
export function absolutePrefix(path: string): (string|null);

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a script to update these index.d.ts files? I saw that npm run build:types updates the one at the root, but I didn't see anything similar for these, so I just made the change manually.

/**
* Tests if the specified path is absolute.
* @param {string} path Path to test
Expand Down
47 changes: 35 additions & 12 deletions lib/path/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,39 @@
*/
var path = exports;

var absolutePrefix =
/**
* Gets the prefix of an absolute Windows, UNC, or Unix path or a URL that indicates it's absolute.
* @param {string} path Path to test
* @returns {string|null} the prefix, or null if path is relative
*/
path.absolutePrefix = function absolutePrefix(path) {
var match;
if (path.startsWith("\\\\")) {
// UNC path
return "\\\\";
} else if ((match = /^\w*:\/\//.exec(path)) !== null) {
// URL
return match[0];
} else if ((match = /^\w:/.exec(path)) !== null) {
// Windows path
return match[0];
} else if (path.startsWith("/")) {
// Unix path
return "/";
} else {
return null;
}
}

var isAbsolute =
/**
* Tests if the specified path is absolute.
* @param {string} path Path to test
* @returns {boolean} `true` if path is absolute
*/
path.isAbsolute = function isAbsolute(path) {
return /^(?:\/|\w+:|\\\\\w+)/.test(path);
return absolutePrefix(path) !== null;
};

var normalize =
Expand All @@ -24,20 +49,18 @@ var normalize =
* @returns {string} Normalized path
*/
path.normalize = function normalize(path) {
var firstTwoCharacters = path.substring(0,2);
var uncPrefix = "";
if (firstTwoCharacters === "\\\\") {
uncPrefix = firstTwoCharacters;
path = path.substring(2);
var absolute = false;
var prefix = absolutePrefix(path);
if (prefix !== null) {
absolute = true;
path = path.substring(prefix.length);
} else {
prefix = "";
}

path = path.replace(/\\/g, "/")
.replace(/\/{2,}/g, "/");
var parts = path.split("/"),
absolute = isAbsolute(path),
prefix = "";
if (absolute)
prefix = parts.shift() + "/";
var parts = path.split("/");
for (var i = 0; i < parts.length;) {
if (parts[i] === "..") {
if (i > 0 && parts[i - 1] !== "..")
Expand All @@ -51,7 +74,7 @@ path.normalize = function normalize(path) {
else
++i;
}
return uncPrefix + prefix + parts.join("/");
return prefix + parts.join("/");
};

/**
Expand Down
17 changes: 17 additions & 0 deletions lib/path/tests/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ tape.test("path", function(test) {

test.ok(path.isAbsolute("\\\\some-unc\\path\\file.js"), "should identify windows unc paths");

test.ok(path.isAbsolute("https://example.com/path/file.js"), "should identify absolute URLs");
test.ok(path.isAbsolute("://example.com/path/file.js"), "should identify protocol-relative URLs");

var paths = [
{
actual: "X:\\some\\..\\.\\path\\\\file.js",
Expand Down Expand Up @@ -61,6 +64,20 @@ tape.test("path", function(test) {
origin: "\\\\some-unc\\path\\..\\origin.js",
expected: "\\\\some-unc/file.js"
}
}, {
actual: "https://example.com/path/../file.js",
normal: "https://example.com/file.js",
resolve: {
origin: "/some/local/path",
expected: "https://example.com/file.js"
}
}, {
actual: "path/file2.js",
normal: "path/file2.js",
resolve: {
origin: "https://example.com/file1.js",
expected: "https://example.com/path/file2.js"
}
}
];

Expand Down