summaryrefslogtreecommitdiff
path: root/ext/web/00_infra.js
diff options
context:
space:
mode:
authorBartek IwaƄczuk <biwanczuk@gmail.com>2023-03-05 18:46:37 -0400
committerGitHub <noreply@github.com>2023-03-05 22:46:37 +0000
commit76b173b60c975fe7540d04aac5b7a40be67fe466 (patch)
tree0d1a58abce1b336e1e20ceeeeb7319030a3142b5 /ext/web/00_infra.js
parent1ab16e2426819af2c534e8a99b98f244626de512 (diff)
refactor: move "pathFromURL" to deno_web extension (#18037)
This API is required by several extensions like "ext/node", "ext/ffi" and also FS APIs that we want to move to a separate crate. Because of that "pathFromURL" API was moved to "deno_web" extension so other extension crates can rely on it.
Diffstat (limited to 'ext/web/00_infra.js')
-rw-r--r--ext/web/00_infra.js76
1 files changed, 76 insertions, 0 deletions
diff --git a/ext/web/00_infra.js b/ext/web/00_infra.js
index cff0f66d8..0c062f89c 100644
--- a/ext/web/00_infra.js
+++ b/ext/web/00_infra.js
@@ -7,14 +7,17 @@
/// <reference path="../web/lib.deno_web.d.ts" />
const core = globalThis.Deno.core;
+const internals = globalThis.__bootstrap.internals;
const ops = core.ops;
const primordials = globalThis.__bootstrap.primordials;
const {
ArrayPrototypeJoin,
ArrayPrototypeMap,
+ decodeURIComponent,
Error,
JSONStringify,
NumberPrototypeToString,
+ ObjectPrototypeIsPrototypeOf,
SafeArrayIterator,
SafeRegExp,
String,
@@ -29,6 +32,7 @@ const {
StringPrototypeToUpperCase,
TypeError,
} = primordials;
+import { URLPrototype } from "internal:deno_url/00_url.js";
const ASCII_DIGIT = ["\u0030-\u0039"];
const ASCII_UPPER_ALPHA = ["\u0041-\u005A"];
@@ -362,6 +366,77 @@ function serializeJSValueToJSONString(value) {
return result;
}
+const PATHNAME_WIN_RE = new SafeRegExp(/^\/*([A-Za-z]:)(\/|$)/);
+const SLASH_WIN_RE = new SafeRegExp(/\//g);
+const PERCENT_RE = new SafeRegExp(/%(?![0-9A-Fa-f]{2})/g);
+
+// Keep in sync with `fromFileUrl()` in `std/path/win32.ts`.
+/**
+ * @param {URL} url
+ * @returns {string}
+ */
+function pathFromURLWin32(url) {
+ let p = StringPrototypeReplace(
+ url.pathname,
+ PATHNAME_WIN_RE,
+ "$1/",
+ );
+ p = StringPrototypeReplace(
+ p,
+ SLASH_WIN_RE,
+ "\\",
+ );
+ p = StringPrototypeReplace(
+ p,
+ PERCENT_RE,
+ "%25",
+ );
+ let path = decodeURIComponent(p);
+ if (url.hostname != "") {
+ // Note: The `URL` implementation guarantees that the drive letter and
+ // hostname are mutually exclusive. Otherwise it would not have been valid
+ // to append the hostname and path like this.
+ path = `\\\\${url.hostname}${path}`;
+ }
+ return path;
+}
+
+// Keep in sync with `fromFileUrl()` in `std/path/posix.ts`.
+/**
+ * @param {URL} url
+ * @returns {string}
+ */
+function pathFromURLPosix(url) {
+ if (url.hostname !== "") {
+ throw new TypeError(`Host must be empty.`);
+ }
+
+ return decodeURIComponent(
+ StringPrototypeReplace(
+ url.pathname,
+ PERCENT_RE,
+ "%25",
+ ),
+ );
+}
+
+function pathFromURL(pathOrUrl) {
+ if (ObjectPrototypeIsPrototypeOf(URLPrototype, pathOrUrl)) {
+ if (pathOrUrl.protocol != "file:") {
+ throw new TypeError("Must be a file URL.");
+ }
+
+ return core.build.os == "windows"
+ ? pathFromURLWin32(pathOrUrl)
+ : pathFromURLPosix(pathOrUrl);
+ }
+ return pathOrUrl;
+}
+
+// NOTE(bartlomieju): this is exposed on `internals` so we can test
+// it in unit tests
+internals.pathFromURL = pathFromURL;
+
export {
ASCII_ALPHA,
ASCII_ALPHANUMERIC,
@@ -389,6 +464,7 @@ export {
HTTP_WHITESPACE_PREFIX_RE,
HTTP_WHITESPACE_SUFFIX_RE,
httpTrim,
+ pathFromURL,
regexMatcher,
serializeJSValueToJSONString,
};