mirror of
https://github.com/denoland/deno.git
synced 2025-03-03 17:34:47 -05:00
feat(std/path): Add toFileUrl() (#7971)
This commit is contained in:
parent
342b151b5d
commit
19b918d112
4 changed files with 89 additions and 5 deletions
|
@ -24,6 +24,7 @@ export const {
|
||||||
relative,
|
relative,
|
||||||
resolve,
|
resolve,
|
||||||
sep,
|
sep,
|
||||||
|
toFileUrl,
|
||||||
toNamespacedPath,
|
toNamespacedPath,
|
||||||
} = path;
|
} = path;
|
||||||
|
|
||||||
|
|
|
@ -440,3 +440,16 @@ export function fromFileUrl(url: string | URL): string {
|
||||||
url.pathname.replace(/%(?![0-9A-Fa-f]{2})/g, "%25"),
|
url.pathname.replace(/%(?![0-9A-Fa-f]{2})/g, "%25"),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Converts a path string to a file URL.
|
||||||
|
*
|
||||||
|
* toFileUrl("/home/foo"); // new URL("file:///home/foo")
|
||||||
|
*/
|
||||||
|
export function toFileUrl(path: string): URL {
|
||||||
|
if (!isAbsolute(path)) {
|
||||||
|
throw new TypeError("Must be an absolute path.");
|
||||||
|
}
|
||||||
|
const url = new URL("file:///");
|
||||||
|
url.pathname = path.replace(/%/g, "%25").replace(/\\/g, "%5C");
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
49
std/path/to_file_url_test.ts
Normal file
49
std/path/to_file_url_test.ts
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
||||||
|
import { posix, win32 } from "./mod.ts";
|
||||||
|
import { assertEquals, assertThrows } from "../testing/asserts.ts";
|
||||||
|
|
||||||
|
Deno.test("[path] toFileUrl", function () {
|
||||||
|
assertEquals(posix.toFileUrl("/home/foo").href, "file:///home/foo");
|
||||||
|
assertEquals(posix.toFileUrl("/home/ ").href, "file:///home/%20");
|
||||||
|
assertEquals(posix.toFileUrl("/home/%20").href, "file:///home/%2520");
|
||||||
|
assertEquals(posix.toFileUrl("/home\\foo").href, "file:///home%5Cfoo");
|
||||||
|
assertThrows(
|
||||||
|
() => posix.toFileUrl("foo").href,
|
||||||
|
TypeError,
|
||||||
|
"Must be an absolute path.",
|
||||||
|
);
|
||||||
|
assertThrows(
|
||||||
|
() => posix.toFileUrl("C:/"),
|
||||||
|
TypeError,
|
||||||
|
"Must be an absolute path.",
|
||||||
|
);
|
||||||
|
assertEquals(
|
||||||
|
posix.toFileUrl("//localhost/home/foo").href,
|
||||||
|
"file:////localhost/home/foo",
|
||||||
|
);
|
||||||
|
assertEquals(posix.toFileUrl("//localhost/").href, "file:////localhost/");
|
||||||
|
assertEquals(posix.toFileUrl("//:/home/foo").href, "file:////:/home/foo");
|
||||||
|
});
|
||||||
|
|
||||||
|
Deno.test("[path] toFileUrl (win32)", function () {
|
||||||
|
assertEquals(win32.toFileUrl("/home/foo").href, "file:///home/foo");
|
||||||
|
assertEquals(win32.toFileUrl("/home/ ").href, "file:///home/%20");
|
||||||
|
assertEquals(win32.toFileUrl("/home/%20").href, "file:///home/%2520");
|
||||||
|
assertEquals(win32.toFileUrl("/home\\foo").href, "file:///home/foo");
|
||||||
|
assertThrows(
|
||||||
|
() => win32.toFileUrl("foo").href,
|
||||||
|
TypeError,
|
||||||
|
"Must be an absolute path.",
|
||||||
|
);
|
||||||
|
assertEquals(win32.toFileUrl("C:/").href, "file:///C:/");
|
||||||
|
assertEquals(
|
||||||
|
win32.toFileUrl("//localhost/home/foo").href,
|
||||||
|
"file://localhost/home/foo",
|
||||||
|
);
|
||||||
|
assertEquals(win32.toFileUrl("//localhost/").href, "file:////localhost/");
|
||||||
|
assertThrows(
|
||||||
|
() => win32.toFileUrl("//:/home/foo").href,
|
||||||
|
TypeError,
|
||||||
|
"Invalid hostname.",
|
||||||
|
);
|
||||||
|
});
|
|
@ -917,11 +917,8 @@ export function fromFileUrl(url: string | URL): string {
|
||||||
throw new TypeError("Must be a file URL.");
|
throw new TypeError("Must be a file URL.");
|
||||||
}
|
}
|
||||||
let path = decodeURIComponent(
|
let path = decodeURIComponent(
|
||||||
url.pathname
|
url.pathname.replace(/\//g, "\\").replace(/%(?![0-9A-Fa-f]{2})/g, "%25"),
|
||||||
.replace(/^\/*([A-Za-z]:)(\/|$)/, "$1/")
|
).replace(/^\\*([A-Za-z]:)(\\|$)/, "$1\\");
|
||||||
.replace(/\//g, "\\")
|
|
||||||
.replace(/%(?![0-9A-Fa-f]{2})/g, "%25"),
|
|
||||||
);
|
|
||||||
if (url.hostname != "") {
|
if (url.hostname != "") {
|
||||||
// Note: The `URL` implementation guarantees that the drive letter and
|
// Note: The `URL` implementation guarantees that the drive letter and
|
||||||
// hostname are mutually exclusive. Otherwise it would not have been valid
|
// hostname are mutually exclusive. Otherwise it would not have been valid
|
||||||
|
@ -930,3 +927,27 @@ export function fromFileUrl(url: string | URL): string {
|
||||||
}
|
}
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Converts a path string to a file URL.
|
||||||
|
*
|
||||||
|
* toFileUrl("\\home\\foo"); // new URL("file:///home/foo")
|
||||||
|
* toFileUrl("C:\\Users\\foo"); // new URL("file:///C:/Users/foo")
|
||||||
|
* toFileUrl("\\\\localhost\\home\\foo"); // new URL("file://localhost/home/foo")
|
||||||
|
*/
|
||||||
|
export function toFileUrl(path: string): URL {
|
||||||
|
if (!isAbsolute(path)) {
|
||||||
|
throw new TypeError("Must be an absolute path.");
|
||||||
|
}
|
||||||
|
const [, hostname, pathname] = path.match(
|
||||||
|
/^(?:[/\\]{2}([^/\\]+)(?=[/\\][^/\\]))?(.*)/,
|
||||||
|
)!;
|
||||||
|
const url = new URL("file:///");
|
||||||
|
url.pathname = pathname.replace(/%/g, "%25");
|
||||||
|
if (hostname != null) {
|
||||||
|
url.hostname = hostname;
|
||||||
|
if (!url.hostname) {
|
||||||
|
throw new TypeError("Invalid hostname.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue