summaryrefslogtreecommitdiff
path: root/std/path
diff options
context:
space:
mode:
Diffstat (limited to 'std/path')
-rw-r--r--std/path/mod.ts1
-rw-r--r--std/path/posix.ts13
-rw-r--r--std/path/to_file_url_test.ts49
-rw-r--r--std/path/win32.ts31
4 files changed, 89 insertions, 5 deletions
diff --git a/std/path/mod.ts b/std/path/mod.ts
index 0b4156e69..58c2c4561 100644
--- a/std/path/mod.ts
+++ b/std/path/mod.ts
@@ -24,6 +24,7 @@ export const {
relative,
resolve,
sep,
+ toFileUrl,
toNamespacedPath,
} = path;
diff --git a/std/path/posix.ts b/std/path/posix.ts
index 68ffb06c9..d2845f3da 100644
--- a/std/path/posix.ts
+++ b/std/path/posix.ts
@@ -440,3 +440,16 @@ export function fromFileUrl(url: string | URL): string {
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;
+}
diff --git a/std/path/to_file_url_test.ts b/std/path/to_file_url_test.ts
new file mode 100644
index 000000000..6d0ca8d80
--- /dev/null
+++ b/std/path/to_file_url_test.ts
@@ -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.",
+ );
+});
diff --git a/std/path/win32.ts b/std/path/win32.ts
index 246c18a97..1684a2c45 100644
--- a/std/path/win32.ts
+++ b/std/path/win32.ts
@@ -917,11 +917,8 @@ export function fromFileUrl(url: string | URL): string {
throw new TypeError("Must be a file URL.");
}
let path = decodeURIComponent(
- url.pathname
- .replace(/^\/*([A-Za-z]:)(\/|$)/, "$1/")
- .replace(/\//g, "\\")
- .replace(/%(?![0-9A-Fa-f]{2})/g, "%25"),
- );
+ url.pathname.replace(/\//g, "\\").replace(/%(?![0-9A-Fa-f]{2})/g, "%25"),
+ ).replace(/^\\*([A-Za-z]:)(\\|$)/, "$1\\");
if (url.hostname != "") {
// Note: The `URL` implementation guarantees that the drive letter and
// hostname are mutually exclusive. Otherwise it would not have been valid
@@ -930,3 +927,27 @@ export function fromFileUrl(url: string | URL): string {
}
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;
+}