mirror of
https://github.com/denoland/deno.git
synced 2024-12-23 15:49:44 -05:00
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.
This commit is contained in:
parent
1ab16e2426
commit
76b173b60c
8 changed files with 89 additions and 75 deletions
8
core/lib.deno_core.d.ts
vendored
8
core/lib.deno_core.d.ts
vendored
|
@ -184,5 +184,13 @@ declare namespace Deno {
|
|||
after_hook?: (promise: Promise<unknown>) => void,
|
||||
resolve_hook?: (promise: Promise<unknown>) => void,
|
||||
): void;
|
||||
|
||||
const build: {
|
||||
target: string;
|
||||
arch: string;
|
||||
os: string;
|
||||
vendor: string;
|
||||
env: string | undefined;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
const core = globalThis.Deno.core;
|
||||
const ops = core.ops;
|
||||
const internals = globalThis.__bootstrap.internals;
|
||||
const primordials = globalThis.__bootstrap.primordials;
|
||||
const {
|
||||
ArrayPrototypeMap,
|
||||
|
@ -28,6 +27,7 @@ const {
|
|||
SymbolFor,
|
||||
WeakMap,
|
||||
} = primordials;
|
||||
import { pathFromURL } from "internal:deno_web/00_infra.js";
|
||||
|
||||
const promiseIdSymbol = SymbolFor("Deno.core.internalPromiseId");
|
||||
|
||||
|
@ -542,9 +542,6 @@ class DynamicLibrary {
|
|||
}
|
||||
|
||||
function dlopen(path, symbols) {
|
||||
// TODO(@crowlKats): remove me
|
||||
// URL support is progressively enhanced by util in `runtime/js`.
|
||||
const pathFromURL = internals.pathFromURL ?? ((p) => p);
|
||||
return new DynamicLibrary(pathFromURL(path), symbols);
|
||||
}
|
||||
|
||||
|
|
|
@ -83,6 +83,7 @@ pub(crate) struct FfiState {
|
|||
|
||||
pub fn init<P: FfiPermissions + 'static>(unstable: bool) -> Extension {
|
||||
Extension::builder(env!("CARGO_PKG_NAME"))
|
||||
.dependencies(vec!["deno_web"])
|
||||
.esm(include_js_files!("00_ffi.js",))
|
||||
.ops(vec![
|
||||
op_ffi_load::decl::<P>(),
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -1,18 +1,10 @@
|
|||
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
const core = globalThis.Deno.core;
|
||||
const internals = globalThis.__bootstrap.internals;
|
||||
const primordials = globalThis.__bootstrap.primordials;
|
||||
const {
|
||||
decodeURIComponent,
|
||||
ObjectPrototypeIsPrototypeOf,
|
||||
Promise,
|
||||
SafeArrayIterator,
|
||||
SafeRegExp,
|
||||
StringPrototypeReplace,
|
||||
TypeError,
|
||||
} = primordials;
|
||||
import { URLPrototype } from "internal:deno_url/00_url.js";
|
||||
let logDebug = false;
|
||||
let logSource = "JS";
|
||||
|
||||
|
@ -46,64 +38,6 @@ function createResolvable() {
|
|||
return promise;
|
||||
}
|
||||
|
||||
// Keep in sync with `fromFileUrl()` in `std/path/win32.ts`.
|
||||
function pathFromURLWin32(url) {
|
||||
let p = StringPrototypeReplace(
|
||||
url.pathname,
|
||||
new SafeRegExp(/^\/*([A-Za-z]:)(\/|$)/),
|
||||
"$1/",
|
||||
);
|
||||
p = StringPrototypeReplace(
|
||||
p,
|
||||
/\//g,
|
||||
"\\",
|
||||
);
|
||||
p = StringPrototypeReplace(
|
||||
p,
|
||||
new SafeRegExp(/%(?![0-9A-Fa-f]{2})/g),
|
||||
"%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`.
|
||||
function pathFromURLPosix(url) {
|
||||
if (url.hostname !== "") {
|
||||
throw new TypeError(`Host must be empty.`);
|
||||
}
|
||||
|
||||
return decodeURIComponent(
|
||||
StringPrototypeReplace(
|
||||
url.pathname,
|
||||
new SafeRegExp(/%(?![0-9A-Fa-f]{2})/g),
|
||||
"%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;
|
||||
}
|
||||
|
||||
// TODO(bartlomieju): remove
|
||||
internals.pathFromURL = pathFromURL;
|
||||
|
||||
function writable(value) {
|
||||
return {
|
||||
value,
|
||||
|
@ -145,7 +79,6 @@ export {
|
|||
getterOnly,
|
||||
log,
|
||||
nonEnumerable,
|
||||
pathFromURL,
|
||||
readOnly,
|
||||
setLogDebug,
|
||||
writable,
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
const core = globalThis.Deno.core;
|
||||
const ops = core.ops;
|
||||
import { pathFromURL } from "internal:deno_web/00_infra.js";
|
||||
import { Event, EventTarget } from "internal:deno_web/02_event.js";
|
||||
import { pathFromURL } from "internal:runtime/06_util.js";
|
||||
const primordials = globalThis.__bootstrap.primordials;
|
||||
const {
|
||||
ArrayIsArray,
|
||||
|
|
|
@ -24,7 +24,7 @@ import {
|
|||
ReadableStreamPrototype,
|
||||
writableStreamForRid,
|
||||
} from "internal:deno_web/06_streams.js";
|
||||
import { pathFromURL } from "internal:runtime/06_util.js";
|
||||
import { pathFromURL } from "internal:deno_web/00_infra.js";
|
||||
|
||||
function chmodSync(path, mode) {
|
||||
ops.op_chmod_sync(pathFromURL(path), mode);
|
||||
|
|
|
@ -18,8 +18,7 @@ const {
|
|||
} = primordials;
|
||||
import { FsFile } from "internal:runtime/30_fs.js";
|
||||
import { readAll } from "internal:deno_io/12_io.js";
|
||||
import { pathFromURL } from "internal:runtime/06_util.js";
|
||||
import { assert } from "internal:deno_web/00_infra.js";
|
||||
import { assert, pathFromURL } from "internal:deno_web/00_infra.js";
|
||||
import * as abortSignal from "internal:deno_web/03_abort_signal.js";
|
||||
import {
|
||||
readableStreamCollectIntoUint8Array,
|
||||
|
|
Loading…
Reference in a new issue