diff options
Diffstat (limited to 'op_crates/url')
-rw-r--r-- | op_crates/url/00_url.js | 409 | ||||
-rw-r--r-- | op_crates/url/Cargo.toml | 27 | ||||
-rw-r--r-- | op_crates/url/README.md | 5 | ||||
-rw-r--r-- | op_crates/url/benches/url_ops.rs | 35 | ||||
-rw-r--r-- | op_crates/url/internal.d.ts | 14 | ||||
-rw-r--r-- | op_crates/url/lib.deno_url.d.ts | 175 | ||||
-rw-r--r-- | op_crates/url/lib.rs | 173 |
7 files changed, 0 insertions, 838 deletions
diff --git a/op_crates/url/00_url.js b/op_crates/url/00_url.js deleted file mode 100644 index 340937748..000000000 --- a/op_crates/url/00_url.js +++ /dev/null @@ -1,409 +0,0 @@ -// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. -"use strict"; - -((window) => { - const core = window.Deno.core; - - function requiredArguments(name, length, required) { - if (length < required) { - const errMsg = `${name} requires at least ${required} argument${ - required === 1 ? "" : "s" - }, but only ${length} present`; - throw new TypeError(errMsg); - } - } - - const paramLists = new WeakMap(); - const urls = new WeakMap(); - - class URLSearchParams { - #params = []; - - constructor(init = "") { - if (typeof init === "string") { - // Overload: USVString - // If init is a string and starts with U+003F (?), - // remove the first code point from init. - if (init[0] == "?") { - init = init.slice(1); - } - - this.#params = core.opSync("op_url_parse_search_params", init); - } else if ( - Array.isArray(init) || - typeof init?.[Symbol.iterator] == "function" - ) { - // Overload: sequence<sequence<USVString>> - for (const pair of init) { - // If pair does not contain exactly two items, then throw a TypeError. - if (pair.length !== 2) { - throw new TypeError( - "URLSearchParams.constructor sequence argument must only contain pair elements", - ); - } - this.#params.push([String(pair[0]), String(pair[1])]); - } - } else if (Object(init) !== init) { - // pass - } else if (init instanceof URLSearchParams) { - this.#params = [...init.#params]; - } else { - // Overload: record<USVString, USVString> - for (const key of Object.keys(init)) { - this.#params.push([key, String(init[key])]); - } - } - - paramLists.set(this, this.#params); - urls.set(this, null); - } - - #updateUrlSearch = () => { - const url = urls.get(this); - if (url == null) { - return; - } - const parseArgs = { href: url.href, setSearch: this.toString() }; - parts.set(url, core.opSync("op_url_parse", parseArgs)); - }; - - append(name, value) { - requiredArguments("URLSearchParams.append", arguments.length, 2); - this.#params.push([String(name), String(value)]); - this.#updateUrlSearch(); - } - - delete(name) { - requiredArguments("URLSearchParams.delete", arguments.length, 1); - name = String(name); - let i = 0; - while (i < this.#params.length) { - if (this.#params[i][0] === name) { - this.#params.splice(i, 1); - } else { - i++; - } - } - this.#updateUrlSearch(); - } - - getAll(name) { - requiredArguments("URLSearchParams.getAll", arguments.length, 1); - name = String(name); - const values = []; - for (const entry of this.#params) { - if (entry[0] === name) { - values.push(entry[1]); - } - } - - return values; - } - - get(name) { - requiredArguments("URLSearchParams.get", arguments.length, 1); - name = String(name); - for (const entry of this.#params) { - if (entry[0] === name) { - return entry[1]; - } - } - - return null; - } - - has(name) { - requiredArguments("URLSearchParams.has", arguments.length, 1); - name = String(name); - return this.#params.some((entry) => entry[0] === name); - } - - set(name, value) { - requiredArguments("URLSearchParams.set", arguments.length, 2); - - // If there are any name-value pairs whose name is name, in list, - // set the value of the first such name-value pair to value - // and remove the others. - name = String(name); - value = String(value); - let found = false; - let i = 0; - while (i < this.#params.length) { - if (this.#params[i][0] === name) { - if (!found) { - this.#params[i][1] = value; - found = true; - i++; - } else { - this.#params.splice(i, 1); - } - } else { - i++; - } - } - - // Otherwise, append a new name-value pair whose name is name - // and value is value, to list. - if (!found) { - this.#params.push([String(name), String(value)]); - } - - this.#updateUrlSearch(); - } - - sort() { - this.#params.sort((a, b) => (a[0] === b[0] ? 0 : a[0] > b[0] ? 1 : -1)); - this.#updateUrlSearch(); - } - - forEach(callbackfn, thisArg) { - requiredArguments("URLSearchParams.forEach", arguments.length, 1); - - if (typeof thisArg !== "undefined") { - callbackfn = callbackfn.bind(thisArg); - } - - for (const [key, value] of this.#params) { - callbackfn(value, key, this); - } - } - - *keys() { - for (const [key] of this.#params) { - yield key; - } - } - - *values() { - for (const [, value] of this.#params) { - yield value; - } - } - - *entries() { - yield* this.#params; - } - - *[Symbol.iterator]() { - yield* this.#params; - } - - toString() { - return core.opSync("op_url_stringify_search_params", this.#params); - } - } - - const parts = new WeakMap(); - - class URL { - #searchParams = null; - - constructor(url, base) { - new.target; - - if (url instanceof URL && base === undefined) { - parts.set(this, parts.get(url)); - } else { - base = base !== undefined ? String(base) : base; - const parseArgs = { href: String(url), baseHref: base }; - parts.set(this, core.opSync("op_url_parse", parseArgs)); - } - } - - [Symbol.for("Deno.customInspect")](inspect) { - const object = { - href: this.href, - origin: this.origin, - protocol: this.protocol, - username: this.username, - password: this.password, - host: this.host, - hostname: this.hostname, - port: this.port, - pathname: this.pathname, - hash: this.hash, - search: this.search, - }; - return `${this.constructor.name} ${inspect(object)}`; - } - - #updateSearchParams = () => { - if (this.#searchParams != null) { - const params = paramLists.get(this.#searchParams); - const newParams = core.opSync( - "op_url_parse_search_params", - this.search.slice(1), - ); - params.splice(0, params.length, ...newParams); - } - }; - - get hash() { - return parts.get(this).hash; - } - - set hash(value) { - try { - const parseArgs = { href: this.href, setHash: String(value) }; - parts.set(this, core.opSync("op_url_parse", parseArgs)); - } catch { - /* pass */ - } - } - - get host() { - return parts.get(this).host; - } - - set host(value) { - try { - const parseArgs = { href: this.href, setHost: String(value) }; - parts.set(this, core.opSync("op_url_parse", parseArgs)); - } catch { - /* pass */ - } - } - - get hostname() { - return parts.get(this).hostname; - } - - set hostname(value) { - try { - const parseArgs = { href: this.href, setHostname: String(value) }; - parts.set(this, core.opSync("op_url_parse", parseArgs)); - } catch { - /* pass */ - } - } - - get href() { - return parts.get(this).href; - } - - set href(value) { - try { - const parseArgs = { href: String(value) }; - parts.set(this, core.opSync("op_url_parse", parseArgs)); - } catch { - throw new TypeError("Invalid URL"); - } - this.#updateSearchParams(); - } - - get origin() { - return parts.get(this).origin; - } - - get password() { - return parts.get(this).password; - } - - set password(value) { - try { - const parseArgs = { href: this.href, setPassword: String(value) }; - parts.set(this, core.opSync("op_url_parse", parseArgs)); - } catch { - /* pass */ - } - } - - get pathname() { - return parts.get(this).pathname; - } - - set pathname(value) { - try { - const parseArgs = { href: this.href, setPathname: String(value) }; - parts.set(this, core.opSync("op_url_parse", parseArgs)); - } catch { - /* pass */ - } - } - - get port() { - return parts.get(this).port; - } - - set port(value) { - try { - const parseArgs = { href: this.href, setPort: String(value) }; - parts.set(this, core.opSync("op_url_parse", parseArgs)); - } catch { - /* pass */ - } - } - - get protocol() { - return parts.get(this).protocol; - } - - set protocol(value) { - try { - const parseArgs = { href: this.href, setProtocol: String(value) }; - parts.set(this, core.opSync("op_url_parse", parseArgs)); - } catch { - /* pass */ - } - } - - get search() { - return parts.get(this).search; - } - - set search(value) { - try { - const parseArgs = { href: this.href, setSearch: String(value) }; - parts.set(this, core.opSync("op_url_parse", parseArgs)); - this.#updateSearchParams(); - } catch { - /* pass */ - } - } - - get username() { - return parts.get(this).username; - } - - set username(value) { - try { - const parseArgs = { href: this.href, setUsername: String(value) }; - parts.set(this, core.opSync("op_url_parse", parseArgs)); - } catch { - /* pass */ - } - } - - get searchParams() { - if (this.#searchParams == null) { - this.#searchParams = new URLSearchParams(this.search); - urls.set(this.#searchParams, this); - } - return this.#searchParams; - } - - toString() { - return this.href; - } - - toJSON() { - return this.href; - } - } - - /** - * This function implements application/x-www-form-urlencoded parsing. - * https://url.spec.whatwg.org/#concept-urlencoded-parser - * @param {Uint8Array} bytes - * @returns {[string, string][]} - */ - function parseUrlEncoded(bytes) { - return core.opSync("op_url_parse_search_params", null, bytes); - } - - window.__bootstrap.url = { - URL, - URLSearchParams, - parseUrlEncoded, - }; -})(this); diff --git a/op_crates/url/Cargo.toml b/op_crates/url/Cargo.toml deleted file mode 100644 index de7a3cb0a..000000000 --- a/op_crates/url/Cargo.toml +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. - -[package] -name = "deno_url" -version = "0.5.0" -edition = "2018" -description = "URL API implementation for Deno" -authors = ["the Deno authors"] -license = "MIT" -readme = "README.md" -repository = "https://github.com/denoland/deno" - -[lib] -path = "lib.rs" - -[dependencies] -deno_core = { version = "0.86.0", path = "../../core" } -idna = "0.2.2" -percent-encoding = "2.1.0" -serde = { version = "1.0.125", features = ["derive"] } - -[dev-dependencies] -bencher = "0.1" - -[[bench]] -name = "url_ops" -harness = false diff --git a/op_crates/url/README.md b/op_crates/url/README.md deleted file mode 100644 index 991dd8b20..000000000 --- a/op_crates/url/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# deno_url - -This crate implements the URL API for Deno. - -Spec: https://url.spec.whatwg.org/ diff --git a/op_crates/url/benches/url_ops.rs b/op_crates/url/benches/url_ops.rs deleted file mode 100644 index 8b3cf2705..000000000 --- a/op_crates/url/benches/url_ops.rs +++ /dev/null @@ -1,35 +0,0 @@ -use bencher::{benchmark_group, benchmark_main, Bencher}; - -use deno_core::v8; -use deno_core::JsRuntime; -use deno_core::RuntimeOptions; - -fn create_js_runtime() -> JsRuntime { - let mut runtime = JsRuntime::new(RuntimeOptions { - extensions: vec![deno_url::init()], - ..Default::default() - }); - - runtime - .execute("setup", "const { URL } = globalThis.__bootstrap.url;") - .unwrap(); - - runtime -} - -pub fn bench_runtime_js(b: &mut Bencher, src: &str) { - let mut runtime = create_js_runtime(); - let scope = &mut runtime.handle_scope(); - let code = v8::String::new(scope, src).unwrap(); - let script = v8::Script::compile(scope, code, None).unwrap(); - b.iter(|| { - script.run(scope).unwrap(); - }); -} - -fn bench_url_parse(b: &mut Bencher) { - bench_runtime_js(b, r#"new URL(`http://www.google.com/`);"#); -} - -benchmark_group!(benches, bench_url_parse,); -benchmark_main!(benches); diff --git a/op_crates/url/internal.d.ts b/op_crates/url/internal.d.ts deleted file mode 100644 index ec2c2688c..000000000 --- a/op_crates/url/internal.d.ts +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. - -/// <reference no-default-lib="true" /> -/// <reference lib="esnext" /> - -declare namespace globalThis { - declare namespace __bootstrap { - declare var url: { - URL: typeof URL; - URLSearchParams: typeof URLSearchParams; - parseUrlEncoded(bytes: Uint8Array): [string, string][]; - }; - } -} diff --git a/op_crates/url/lib.deno_url.d.ts b/op_crates/url/lib.deno_url.d.ts deleted file mode 100644 index 3f9745352..000000000 --- a/op_crates/url/lib.deno_url.d.ts +++ /dev/null @@ -1,175 +0,0 @@ -// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. - -// deno-lint-ignore-file no-explicit-any - -/// <reference no-default-lib="true" /> -/// <reference lib="esnext" /> - -declare class URLSearchParams { - constructor( - init?: string[][] | Record<string, string> | string | URLSearchParams, - ); - static toString(): string; - - /** Appends a specified key/value pair as a new search parameter. - * - * ```ts - * let searchParams = new URLSearchParams(); - * searchParams.append('name', 'first'); - * searchParams.append('name', 'second'); - * ``` - */ - append(name: string, value: string): void; - - /** Deletes the given search parameter and its associated value, - * from the list of all search parameters. - * - * ```ts - * let searchParams = new URLSearchParams([['name', 'value']]); - * searchParams.delete('name'); - * ``` - */ - delete(name: string): void; - - /** Returns all the values associated with a given search parameter - * as an array. - * - * ```ts - * searchParams.getAll('name'); - * ``` - */ - getAll(name: string): string[]; - - /** Returns the first value associated to the given search parameter. - * - * ```ts - * searchParams.get('name'); - * ``` - */ - get(name: string): string | null; - - /** Returns a Boolean that indicates whether a parameter with the - * specified name exists. - * - * ```ts - * searchParams.has('name'); - * ``` - */ - has(name: string): boolean; - - /** Sets the value associated with a given search parameter to the - * given value. If there were several matching values, this method - * deletes the others. If the search parameter doesn't exist, this - * method creates it. - * - * ```ts - * searchParams.set('name', 'value'); - * ``` - */ - set(name: string, value: string): void; - - /** Sort all key/value pairs contained in this object in place and - * return undefined. The sort order is according to Unicode code - * points of the keys. - * - * ```ts - * searchParams.sort(); - * ``` - */ - sort(): void; - - /** Calls a function for each element contained in this object in - * place and return undefined. Optionally accepts an object to use - * as this when executing callback as second argument. - * - * ```ts - * const params = new URLSearchParams([["a", "b"], ["c", "d"]]); - * params.forEach((value, key, parent) => { - * console.log(value, key, parent); - * }); - * ``` - * - */ - forEach( - callbackfn: (value: string, key: string, parent: this) => void, - thisArg?: any, - ): void; - - /** Returns an iterator allowing to go through all keys contained - * in this object. - * - * ```ts - * const params = new URLSearchParams([["a", "b"], ["c", "d"]]); - * for (const key of params.keys()) { - * console.log(key); - * } - * ``` - */ - keys(): IterableIterator<string>; - - /** Returns an iterator allowing to go through all values contained - * in this object. - * - * ```ts - * const params = new URLSearchParams([["a", "b"], ["c", "d"]]); - * for (const value of params.values()) { - * console.log(value); - * } - * ``` - */ - values(): IterableIterator<string>; - - /** Returns an iterator allowing to go through all key/value - * pairs contained in this object. - * - * ```ts - * const params = new URLSearchParams([["a", "b"], ["c", "d"]]); - * for (const [key, value] of params.entries()) { - * console.log(key, value); - * } - * ``` - */ - entries(): IterableIterator<[string, string]>; - - /** Returns an iterator allowing to go through all key/value - * pairs contained in this object. - * - * ```ts - * const params = new URLSearchParams([["a", "b"], ["c", "d"]]); - * for (const [key, value] of params) { - * console.log(key, value); - * } - * ``` - */ - [Symbol.iterator](): IterableIterator<[string, string]>; - - /** Returns a query string suitable for use in a URL. - * - * ```ts - * searchParams.toString(); - * ``` - */ - toString(): string; -} - -/** The URL interface represents an object providing static methods used for creating object URLs. */ -declare class URL { - constructor(url: string, base?: string | URL); - static createObjectURL(blob: Blob): string; - static revokeObjectURL(url: string): void; - - hash: string; - host: string; - hostname: string; - href: string; - toString(): string; - readonly origin: string; - password: string; - pathname: string; - port: string; - protocol: string; - search: string; - readonly searchParams: URLSearchParams; - username: string; - toJSON(): string; -} diff --git a/op_crates/url/lib.rs b/op_crates/url/lib.rs deleted file mode 100644 index 1d7a9b08b..000000000 --- a/op_crates/url/lib.rs +++ /dev/null @@ -1,173 +0,0 @@ -// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. - -use deno_core::error::generic_error; -use deno_core::error::type_error; -use deno_core::error::uri_error; -use deno_core::error::AnyError; -use deno_core::include_js_files; -use deno_core::op_sync; -use deno_core::url::form_urlencoded; -use deno_core::url::quirks; -use deno_core::url::Url; -use deno_core::Extension; -use deno_core::ZeroCopyBuf; -use serde::Deserialize; -use serde::Serialize; -use std::panic::catch_unwind; -use std::path::PathBuf; - -pub fn init() -> Extension { - Extension::builder() - .js(include_js_files!( - prefix "deno:op_crates/url", - "00_url.js", - )) - .ops(vec![ - ("op_url_parse", op_sync(op_url_parse)), - ( - "op_url_parse_search_params", - op_sync(op_url_parse_search_params), - ), - ( - "op_url_stringify_search_params", - op_sync(op_url_stringify_search_params), - ), - ]) - .build() -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct UrlParseArgs { - href: String, - base_href: Option<String>, - // If one of the following are present, this is a setter call. Apply the - // proper `Url::set_*()` method after (re)parsing `href`. - set_hash: Option<String>, - set_host: Option<String>, - set_hostname: Option<String>, - set_password: Option<String>, - set_pathname: Option<String>, - set_port: Option<String>, - set_protocol: Option<String>, - set_search: Option<String>, - set_username: Option<String>, -} - -#[derive(Serialize)] -pub struct UrlParts { - href: String, - hash: String, - host: String, - hostname: String, - origin: String, - password: String, - pathname: String, - port: String, - protocol: String, - search: String, - username: String, -} - -/// Parse `UrlParseArgs::href` with an optional `UrlParseArgs::base_href`, or an -/// optional part to "set" after parsing. Return `UrlParts`. -pub fn op_url_parse( - _state: &mut deno_core::OpState, - args: UrlParseArgs, - _zero_copy: Option<ZeroCopyBuf>, -) -> Result<UrlParts, AnyError> { - let base_url = args - .base_href - .as_ref() - .map(|b| Url::parse(b).map_err(|_| type_error("Invalid base URL"))) - .transpose()?; - let mut url = Url::options() - .base_url(base_url.as_ref()) - .parse(&args.href) - .map_err(|_| type_error("Invalid URL"))?; - - if let Some(hash) = args.set_hash.as_ref() { - quirks::set_hash(&mut url, hash); - } else if let Some(host) = args.set_host.as_ref() { - quirks::set_host(&mut url, host).map_err(|_| uri_error("Invalid host"))?; - } else if let Some(hostname) = args.set_hostname.as_ref() { - quirks::set_hostname(&mut url, hostname) - .map_err(|_| uri_error("Invalid hostname"))?; - } else if let Some(password) = args.set_password.as_ref() { - quirks::set_password(&mut url, password) - .map_err(|_| uri_error("Invalid password"))?; - } else if let Some(pathname) = args.set_pathname.as_ref() { - quirks::set_pathname(&mut url, pathname); - } else if let Some(port) = args.set_port.as_ref() { - quirks::set_port(&mut url, port).map_err(|_| uri_error("Invalid port"))?; - } else if let Some(protocol) = args.set_protocol.as_ref() { - quirks::set_protocol(&mut url, protocol) - .map_err(|_| uri_error("Invalid protocol"))?; - } else if let Some(search) = args.set_search.as_ref() { - quirks::set_search(&mut url, search); - } else if let Some(username) = args.set_username.as_ref() { - quirks::set_username(&mut url, username) - .map_err(|_| uri_error("Invalid username"))?; - } - - // TODO(nayeemrmn): Panic that occurs in rust-url for the `non-spec:` - // url-constructor wpt tests: https://github.com/servo/rust-url/issues/670. - let username = catch_unwind(|| quirks::username(&url)).map_err(|_| { - generic_error(format!( - "Internal error while parsing \"{}\"{}, \ - see https://github.com/servo/rust-url/issues/670", - args.href, - args - .base_href - .map(|b| format!(" against \"{}\"", b)) - .unwrap_or_default() - )) - })?; - Ok(UrlParts { - href: quirks::href(&url).to_string(), - hash: quirks::hash(&url).to_string(), - host: quirks::host(&url).to_string(), - hostname: quirks::hostname(&url).to_string(), - origin: quirks::origin(&url), - password: quirks::password(&url).to_string(), - pathname: quirks::pathname(&url).to_string(), - port: quirks::port(&url).to_string(), - protocol: quirks::protocol(&url).to_string(), - search: quirks::search(&url).to_string(), - username: username.to_string(), - }) -} - -pub fn op_url_parse_search_params( - _state: &mut deno_core::OpState, - args: Option<String>, - zero_copy: Option<ZeroCopyBuf>, -) -> Result<Vec<(String, String)>, AnyError> { - let params = match (args, zero_copy) { - (None, Some(zero_copy)) => form_urlencoded::parse(&zero_copy) - .into_iter() - .map(|(k, v)| (k.as_ref().to_owned(), v.as_ref().to_owned())) - .collect(), - (Some(args), None) => form_urlencoded::parse(args.as_bytes()) - .into_iter() - .map(|(k, v)| (k.as_ref().to_owned(), v.as_ref().to_owned())) - .collect(), - _ => return Err(type_error("invalid parameters")), - }; - Ok(params) -} - -pub fn op_url_stringify_search_params( - _state: &mut deno_core::OpState, - args: Vec<(String, String)>, - _zero_copy: Option<ZeroCopyBuf>, -) -> Result<String, AnyError> { - let search = form_urlencoded::Serializer::new(String::new()) - .extend_pairs(args) - .finish(); - Ok(search) -} - -pub fn get_declaration() -> PathBuf { - PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("lib.deno_url.d.ts") -} |