diff --git a/Cargo.lock b/Cargo.lock index b30c86e989f346..80e883a2886845 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -642,8 +642,10 @@ dependencies = [ "deno_core", "deno_crypto", "deno_fetch", + "deno_url", "deno_web", "deno_webgpu", + "deno_webidl", "deno_websocket", "dlopen", "encoding_rs", @@ -675,14 +677,21 @@ dependencies = [ "winres", ] +[[package]] +name = "deno_url" +version = "0.1.0" +dependencies = [ + "deno_core", + "idna", + "serde", +] + [[package]] name = "deno_web" version = "0.30.0" dependencies = [ "deno_core", "futures", - "idna", - "serde", ] [[package]] @@ -696,6 +705,13 @@ dependencies = [ "wgpu-types", ] +[[package]] +name = "deno_webidl" +version = "0.1.0" +dependencies = [ + "deno_core", +] + [[package]] name = "deno_websocket" version = "0.5.0" diff --git a/cli/build.rs b/cli/build.rs index 236097cbf88c99..3f97a71b7465b9 100644 --- a/cli/build.rs +++ b/cli/build.rs @@ -10,6 +10,7 @@ use deno_core::JsRuntime; use deno_core::RuntimeOptions; use deno_runtime::deno_crypto; use deno_runtime::deno_fetch; +use deno_runtime::deno_url; use deno_runtime::deno_web; use deno_runtime::deno_webgpu; use deno_runtime::deno_websocket; @@ -61,6 +62,7 @@ fn create_compiler_snapshot( ) { // libs that are being provided by op crates. let mut op_crate_libs = HashMap::new(); + op_crate_libs.insert("deno.url", deno_url::get_declaration()); op_crate_libs.insert("deno.web", deno_web::get_declaration()); op_crate_libs.insert("deno.fetch", deno_fetch::get_declaration()); op_crate_libs.insert("deno.webgpu", deno_webgpu::get_declaration()); @@ -254,6 +256,10 @@ fn main() { println!("cargo:rustc-env=TS_VERSION={}", ts_version()); println!("cargo:rustc-env=GIT_COMMIT_HASH={}", git_commit_hash()); + println!( + "cargo:rustc-env=DENO_URL_LIB_PATH={}", + deno_url::get_declaration().display() + ); println!( "cargo:rustc-env=DENO_WEB_LIB_PATH={}", deno_web::get_declaration().display() diff --git a/cli/main.rs b/cli/main.rs index 2b958ff55352b2..cb25d604c12186 100644 --- a/cli/main.rs +++ b/cli/main.rs @@ -278,8 +278,9 @@ fn print_cache_info( pub fn get_types(unstable: bool) -> String { let mut types = format!( - "{}\n{}\n{}\n{}\n{}\n{}\n{}", + "{}\n{}\n{}\n{}\n{}\n{}\n{}\n{}", crate::tsc::DENO_NS_LIB, + crate::tsc::DENO_URL_LIB, crate::tsc::DENO_WEB_LIB, crate::tsc::DENO_FETCH_LIB, crate::tsc::DENO_WEBGPU_LIB, diff --git a/cli/tsc.rs b/cli/tsc.rs index 8d28b959d37d41..6bf8546509f737 100644 --- a/cli/tsc.rs +++ b/cli/tsc.rs @@ -29,6 +29,7 @@ use std::sync::Mutex; // Declaration files pub static DENO_NS_LIB: &str = include_str!("dts/lib.deno.ns.d.ts"); +pub static DENO_URL_LIB: &str = include_str!(env!("DENO_URL_LIB_PATH")); pub static DENO_WEB_LIB: &str = include_str!(env!("DENO_WEB_LIB_PATH")); pub static DENO_FETCH_LIB: &str = include_str!(env!("DENO_FETCH_LIB_PATH")); pub static DENO_WEBGPU_LIB: &str = include_str!(env!("DENO_WEBGPU_LIB_PATH")); diff --git a/op_crates/crypto/Cargo.toml b/op_crates/crypto/Cargo.toml index 641a1cf6615392..3464671295e297 100644 --- a/op_crates/crypto/Cargo.toml +++ b/op_crates/crypto/Cargo.toml @@ -4,7 +4,7 @@ name = "deno_crypto" version = "0.13.0" edition = "2018" -description = "Collection of WebCrypto APIs" +description = "Web Cryptography API implementation for Deno" authors = ["the Deno authors"] license = "MIT" readme = "README.md" diff --git a/op_crates/crypto/README.md b/op_crates/crypto/README.md index 0e1c248e64ce46..be07244584e75b 100644 --- a/op_crates/crypto/README.md +++ b/op_crates/crypto/README.md @@ -1,3 +1,5 @@ -# deno crypto +# deno_crypto -Op crate that implements crypto functions. +This crate implements the Web Cryptography API. + +Spec: https://www.w3.org/TR/WebCryptoAPI/ diff --git a/op_crates/fetch/Cargo.toml b/op_crates/fetch/Cargo.toml index de5f252a50b0b0..e7bef336446b1b 100644 --- a/op_crates/fetch/Cargo.toml +++ b/op_crates/fetch/Cargo.toml @@ -4,7 +4,7 @@ name = "deno_fetch" version = "0.22.0" edition = "2018" -description = "provides fetch Web API to deno_core" +description = "Fetch API implementation for Deno" authors = ["the Deno authors"] license = "MIT" readme = "README.md" diff --git a/op_crates/fetch/README.md b/op_crates/fetch/README.md index 1a6dcab1745c09..2c946197e053bc 100644 --- a/op_crates/fetch/README.md +++ b/op_crates/fetch/README.md @@ -1 +1,5 @@ -This crate provides the web standard fetch API to `deno_core`. +# deno_fetch + +This crate implements the Fetch API. + +Spec: https://fetch.spec.whatwg.org/ diff --git a/op_crates/web/11_url.js b/op_crates/url/00_url.js similarity index 99% rename from op_crates/web/11_url.js rename to op_crates/url/00_url.js index eac6795492944f..fea1c2e045d602 100644 --- a/op_crates/web/11_url.js +++ b/op_crates/url/00_url.js @@ -34,19 +34,18 @@ domain, { beStrict = false } = {}, ) { - return core.jsonOpSync("op_domain_to_ascii", { domain, beStrict }); + return core.jsonOpSync("op_url_domain_to_ascii", { domain, beStrict }); } function decodeSearchParam(p) { const s = p.replaceAll("+", " "); - const decoder = new TextDecoder(); return s.replace(/(%[0-9a-f]{2})+/gi, (matched) => { const buf = new Uint8Array(Math.ceil(matched.length / 3)); for (let i = 0, offset = 0; i < matched.length; i += 3, offset += 1) { buf[offset] = parseInt(matched.slice(i + 1, i + 3), 16); } - return decoder.decode(buf); + return core.decode(buf); }); } @@ -808,10 +807,8 @@ return charInUserinfoSet(c) || ["\u0021", "\u0024", "\u0025", "\u0026", "\u0027", "\u0028", "\u0029", "\u002B", "\u002C", "\u007E"].includes(c); } - const encoder = new TextEncoder(); - function encodeChar(c) { - return [...encoder.encode(c)] + return [...core.encode(c)] .map((n) => `%${n.toString(16).padStart(2, "0")}`) .join("") .toUpperCase(); diff --git a/op_crates/url/Cargo.toml b/op_crates/url/Cargo.toml new file mode 100644 index 00000000000000..372023c61983d2 --- /dev/null +++ b/op_crates/url/Cargo.toml @@ -0,0 +1,19 @@ +# Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. + +[package] +name = "deno_url" +version = "0.1.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.79.0", path = "../../core" } +idna = "0.2.1" +serde = { version = "1.0.123", features = ["derive"] } diff --git a/op_crates/url/README.md b/op_crates/url/README.md new file mode 100644 index 00000000000000..991dd8b20078ad --- /dev/null +++ b/op_crates/url/README.md @@ -0,0 +1,5 @@ +# deno_url + +This crate implements the URL API for Deno. + +Spec: https://url.spec.whatwg.org/ diff --git a/op_crates/url/internal.d.ts b/op_crates/url/internal.d.ts new file mode 100644 index 00000000000000..ab2f21de524893 --- /dev/null +++ b/op_crates/url/internal.d.ts @@ -0,0 +1,14 @@ +// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. +// deno-lint-ignore-file no-explicit-any ban-types + +/// +/// + +declare namespace globalThis { + declare namespace __bootstrap { + declare var url: { + URL: typeof URL; + URLSearchParams: typeof URLSearchParams; + }; + } +} diff --git a/op_crates/url/lib.deno_url.d.ts b/op_crates/url/lib.deno_url.d.ts new file mode 100644 index 00000000000000..2a27fe6933692e --- /dev/null +++ b/op_crates/url/lib.deno_url.d.ts @@ -0,0 +1,175 @@ +// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. + +// deno-lint-ignore-file no-explicit-any + +/// +/// + +declare class URLSearchParams { + constructor( + init?: string[][] | Record | 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; + + /** 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; + + /** 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); + createObjectURL(object: any): string; + 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 new file mode 100644 index 00000000000000..0553473e3cb294 --- /dev/null +++ b/op_crates/url/lib.rs @@ -0,0 +1,55 @@ +// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. + +use deno_core::error::uri_error; +use deno_core::error::AnyError; +use deno_core::serde_json; +use deno_core::serde_json::json; +use deno_core::serde_json::Value; +use deno_core::JsRuntime; +use deno_core::ZeroCopyBuf; +use idna::domain_to_ascii; +use idna::domain_to_ascii_strict; +use serde::Deserialize; +use std::path::PathBuf; + +pub fn op_url_domain_to_ascii( + _state: &mut deno_core::OpState, + args: Value, + _zero_copy: &mut [ZeroCopyBuf], +) -> Result { + #[derive(Deserialize)] + #[serde(rename_all = "camelCase")] + struct DomainToAscii { + domain: String, + be_strict: bool, + } + + let args: DomainToAscii = serde_json::from_value(args)?; + if args.be_strict { + domain_to_ascii_strict(args.domain.as_str()) + } else { + domain_to_ascii(args.domain.as_str()) + } + .map_err(|err| { + let message = format!("Invalid IDNA encoded domain name: {:?}", err); + uri_error(message) + }) + .map(|domain| json!(domain)) +} + +/// Load and execute the javascript code. +pub fn init(isolate: &mut JsRuntime) { + let files = vec![ + ( + "deno:op_crates/url/00_url.js", + include_str!("00_url.js"), + ), + ]; + for (url, source_code) in files { + isolate.execute(url, source_code).unwrap(); + } +} + +pub fn get_declaration() -> PathBuf { + PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("lib.deno_url.d.ts") +} diff --git a/op_crates/web/01_dom_exception.js b/op_crates/web/01_dom_exception.js index 14f4ca8e9346d0..f5bd3289bf43c6 100644 --- a/op_crates/web/01_dom_exception.js +++ b/op_crates/web/01_dom_exception.js @@ -2,6 +2,7 @@ // @ts-check /// +/// /// /// diff --git a/op_crates/web/Cargo.toml b/op_crates/web/Cargo.toml index 9e0cd5f7988c2c..74eb6626f90d10 100644 --- a/op_crates/web/Cargo.toml +++ b/op_crates/web/Cargo.toml @@ -15,8 +15,6 @@ path = "lib.rs" [dependencies] deno_core = { version = "0.79.0", path = "../../core" } -idna = "0.2.1" -serde = { version = "1.0.123", features = ["derive"] } [dev-dependencies] futures = "0.3.12" diff --git a/op_crates/web/internal.d.ts b/op_crates/web/internal.d.ts index 8be80c8a520752..458f4a173c5a33 100644 --- a/op_crates/web/internal.d.ts +++ b/op_crates/web/internal.d.ts @@ -1,283 +1,14 @@ // Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. -// deno-lint-ignore-file no-explicit-any ban-types /// /// declare namespace globalThis { declare namespace __bootstrap { - declare namespace webidl { - declare interface ConverterOpts { - /** - * The prefix for error messages created by this converter. - * Examples: - * - `Failed to construct 'Event'` - * - `Failed to execute 'removeEventListener' on 'EventTarget'` - */ - prefix: string; - } - declare interface ValueConverterOpts extends ConverterOpts { - /** - * The context of this value error messages created by this converter. - * Examples: - * - `Argument 1` - * - `Argument 3` - */ - context: string; - } - declare interface IntConverterOpts extends ValueConverterOpts { - /** - * Wether to throw if the number is outside of the acceptable values for - * this type. - */ - enforceRange?: boolean; - /** - * Wether to clamp this number to the acceptable values for this type. - */ - clamp?: boolean; - } - declare interface StringConverterOpts extends ValueConverterOpts { - /** - * Wether to treat `null` value as an empty string. - */ - treatNullAsEmptyString?: boolean; - } - declare interface BufferConverterOpts extends ValueConverterOpts { - /** - * Wether to allow `SharedArrayBuffer` (not just `ArrayBuffer`). - */ - allowShared?: boolean; - } - declare const converters: { - any(v: any): any; - /** - * Convert a value into a `boolean` (bool). - */ - boolean(v: any, opts?: IntConverterOpts): boolean; - /** - * Convert a value into a `byte` (int8). - */ - byte(v: any, opts?: IntConverterOpts): number; - /** - * Convert a value into a `octet` (uint8). - */ - octet(v: any, opts?: IntConverterOpts): number; - /** - * Convert a value into a `short` (int16). - */ - short(v: any, opts?: IntConverterOpts): number; - /** - * Convert a value into a `unsigned short` (uint16). - */ - ["unsigned short"](v: any, opts?: IntConverterOpts): number; - /** - * Convert a value into a `long` (int32). - */ - long(v: any, opts?: IntConverterOpts): number; - /** - * Convert a value into a `unsigned long` (uint32). - */ - ["unsigned long"](v: any, opts?: IntConverterOpts): number; - /** - * Convert a value into a `long long` (int64). - * **Note this is truncated to a JS number (53 bit precision).** - */ - ["long long"](v: any, opts?: IntConverterOpts): number; - /** - * Convert a value into a `unsigned long long` (uint64). - * **Note this is truncated to a JS number (53 bit precision).** - */ - ["unsigned long long"](v: any, opts?: IntConverterOpts): number; - /** - * Convert a value into a `float` (f32). - */ - float(v: any, opts?: ValueConverterOpts): number; - /** - * Convert a value into a `unrestricted float` (f32, infinity, or NaN). - */ - ["unrestricted float"](v: any, opts?: ValueConverterOpts): number; - /** - * Convert a value into a `double` (f64). - */ - double(v: any, opts?: ValueConverterOpts): number; - /** - * Convert a value into a `unrestricted double` (f64, infinity, or NaN). - */ - ["unrestricted double"](v: any, opts?: ValueConverterOpts): number; - /** - * Convert a value into a `DOMString` (string). - */ - DOMString(v: any, opts?: StringConverterOpts): string; - /** - * Convert a value into a `ByteString` (string with only u8 codepoints). - */ - ByteString(v: any, opts?: StringConverterOpts): string; - /** - * Convert a value into a `USVString` (string with only valid non - * surrogate Unicode code points). - */ - USVString(v: any, opts?: StringConverterOpts): string; - /** - * Convert a value into an `object` (object). - */ - object(v: any, opts?: ValueConverterOpts): object; - /** - * Convert a value into an `ArrayBuffer` (ArrayBuffer). - */ - ArrayBuffer(v: any, opts?: BufferConverterOpts): ArrayBuffer; - /** - * Convert a value into a `DataView` (ArrayBuffer). - */ - DataView(v: any, opts?: BufferConverterOpts): DataView; - /** - * Convert a value into a `Int8Array` (Int8Array). - */ - Int8Array(v: any, opts?: BufferConverterOpts): Int8Array; - /** - * Convert a value into a `Int16Array` (Int16Array). - */ - Int16Array(v: any, opts?: BufferConverterOpts): Int16Array; - /** - * Convert a value into a `Int32Array` (Int32Array). - */ - Int32Array(v: any, opts?: BufferConverterOpts): Int32Array; - /** - * Convert a value into a `Uint8Array` (Uint8Array). - */ - Uint8Array(v: any, opts?: BufferConverterOpts): Uint8Array; - /** - * Convert a value into a `Uint16Array` (Uint16Array). - */ - Uint16Array(v: any, opts?: BufferConverterOpts): Uint16Array; - /** - * Convert a value into a `Uint32Array` (Uint32Array). - */ - Uint32Array(v: any, opts?: BufferConverterOpts): Uint32Array; - /** - * Convert a value into a `Uint8ClampedArray` (Uint8ClampedArray). - */ - Uint8ClampedArray( - v: any, - opts?: BufferConverterOpts, - ): Uint8ClampedArray; - /** - * Convert a value into a `Float32Array` (Float32Array). - */ - Float32Array(v: any, opts?: BufferConverterOpts): Float32Array; - /** - * Convert a value into a `Float64Array` (Float64Array). - */ - Float64Array(v: any, opts?: BufferConverterOpts): Float64Array; - /** - * Convert a value into an `ArrayBufferView` (ArrayBufferView). - */ - ArrayBufferView(v: any, opts?: BufferConverterOpts): ArrayBufferView; - /** - * Convert a value into a `BufferSource` (ArrayBuffer or ArrayBufferView). - */ - BufferSource( - v: any, - opts?: BufferConverterOpts, - ): ArrayBuffer | ArrayBufferView; - /** - * Convert a value into a `DOMTimeStamp` (u64). Alias for unsigned long long - */ - DOMTimeStamp(v: any, opts?: IntConverterOpts): number; - /** - * Convert a value into a `Function` ((...args: any[]) => any). - */ - Function(v: any, opts?: ValueConverterOpts): (...args: any) => any; - /** - * Convert a value into a `VoidFunction` (() => void). - */ - VoidFunction(v: any, opts?: ValueConverterOpts): () => void; - - [type: string]: (v: any, opts: ValueConverterOpts) => any; - }; - - /** - * Assert that the a function has at least a required amount of arguments. - */ - declare function requiredArguments( - length: number, - required: number, - opts: ConverterOpts, - ): void; - declare type Dictionary = DictionaryMember[]; - declare interface DictionaryMember { - key: string; - converter: (v: any, opts: ValueConverterOpts) => any; - defaultValue?: any; - required?: boolean; - } - - /** - * Create a converter for dictionaries. - */ - declare function createDictionaryConverter( - name: string, - ...dictionaries: Dictionary[] - ): (v: any, opts: ValueConverterOpts) => T; - - /** - * Create a converter for enums. - */ - declare function createEnumConverter( - name: string, - values: string[], - ): (v: any, opts: ValueConverterOpts) => string; - - /** - * Create a converter that makes the contained type nullable. - */ - declare function createNullableConverter( - converter: (v: any, opts: ValueConverterOpts) => T, - ): (v: any, opts: ValueConverterOpts) => T | null; - - /** - * Create a converter that converts a sequence of the inner type. - */ - declare function createSequenceConverter( - converter: (v: any, opts: ValueConverterOpts) => T, - ): (v: any, opts: ValueConverterOpts) => T[]; - - /** - * Throw an illegal constructor error. - */ - declare function illegalConstructor(): never; - - /** - * The branding symbol. - */ - declare const brand: unique symbol; - - /** - * Create a branded instance of an interface. - */ - declare function createBranded(self: any): any; - - /** - * Assert that self is branded. - */ - declare function assertBranded(self: any, type: any): void; - - /** - * Create a converter for interfaces. - */ - declare function createInterfaceConverter( - name: string, - prototype: any, - ): (v: any, opts: ValueConverterOpts) => any; - } - declare var eventTarget: { EventTarget: typeof EventTarget; }; - declare var url: { - URLSearchParams: typeof URLSearchParams; - }; - declare var location: { getLocationHref(): string | undefined; }; diff --git a/op_crates/web/lib.deno_web.d.ts b/op_crates/web/lib.deno_web.d.ts index 24a8f929d26996..79b56f68e28c42 100644 --- a/op_crates/web/lib.deno_web.d.ts +++ b/op_crates/web/lib.deno_web.d.ts @@ -313,172 +313,3 @@ declare var FileReader: { readonly EMPTY: number; readonly LOADING: number; }; - -declare class URLSearchParams { - constructor( - init?: string[][] | Record | 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; - - /** 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; - - /** 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); - createObjectURL(object: any): string; - 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/web/lib.rs b/op_crates/web/lib.rs index 00088409206c9c..e80d221cf9fe42 100644 --- a/op_crates/web/lib.rs +++ b/op_crates/web/lib.rs @@ -1,49 +1,11 @@ // Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. -use deno_core::error::uri_error; -use deno_core::error::AnyError; -use deno_core::serde_json; -use deno_core::serde_json::json; -use deno_core::serde_json::Value; -use deno_core::JsRuntime; -use deno_core::ZeroCopyBuf; -use idna::domain_to_ascii; -use idna::domain_to_ascii_strict; -use serde::Deserialize; use std::path::PathBuf; - -pub fn op_domain_to_ascii( - _state: &mut deno_core::OpState, - args: Value, - _zero_copy: &mut [ZeroCopyBuf], -) -> Result { - #[derive(Deserialize)] - #[serde(rename_all = "camelCase")] - struct DomainToAscii { - domain: String, - be_strict: bool, - } - - let args: DomainToAscii = serde_json::from_value(args)?; - if args.be_strict { - domain_to_ascii_strict(args.domain.as_str()) - } else { - domain_to_ascii(args.domain.as_str()) - } - .map_err(|err| { - let message = format!("Invalid IDNA encoded domain name: {:?}", err); - uri_error(message) - }) - .map(|domain| json!(domain)) -} +use deno_core::JsRuntime; /// Load and execute the javascript code. pub fn init(isolate: &mut JsRuntime) { let files = vec![ - ( - "deno:op_crates/web/00_webidl.js", - include_str!("00_webidl.js"), - ), ( "deno:op_crates/web/01_dom_exception.js", include_str!("01_dom_exception.js"), @@ -64,7 +26,6 @@ pub fn init(isolate: &mut JsRuntime) { "deno:op_crates/web/08_text_encoding.js", include_str!("08_text_encoding.js"), ), - ("deno:op_crates/web/11_url.js", include_str!("11_url.js")), ( "deno:op_crates/web/12_location.js", include_str!("12_location.js"), diff --git a/op_crates/webgpu/Cargo.toml b/op_crates/webgpu/Cargo.toml index 92d9e01f342bcb..2d5ee6737f6900 100644 --- a/op_crates/webgpu/Cargo.toml +++ b/op_crates/webgpu/Cargo.toml @@ -4,7 +4,7 @@ name = "deno_webgpu" version = "0.1.0" edition = "2018" -description = "provides webgpu Web API to deno_core" +description = "WebGPU implementation for Deno" authors = ["the Deno authors"] license = "MIT" readme = "README.md" diff --git a/op_crates/web/00_webidl.js b/op_crates/webidl/00_webidl.js similarity index 100% rename from op_crates/web/00_webidl.js rename to op_crates/webidl/00_webidl.js diff --git a/op_crates/webidl/Cargo.toml b/op_crates/webidl/Cargo.toml new file mode 100644 index 00000000000000..45e07749359ed7 --- /dev/null +++ b/op_crates/webidl/Cargo.toml @@ -0,0 +1,17 @@ +# Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. + +[package] +name = "deno_webidl" +version = "0.1.0" +edition = "2018" +description = "WebIDL 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.79.0", path = "../../core" } diff --git a/op_crates/webidl/README.md b/op_crates/webidl/README.md new file mode 100644 index 00000000000000..b48941087facb0 --- /dev/null +++ b/op_crates/webidl/README.md @@ -0,0 +1,6 @@ +# deno_webidl + +This crate implements WebIDL for Deno. It consists of infrastructure to +do ECMA -> WebIDL conversions. + +Spec: https://heycam.github.io/webidl/ diff --git a/op_crates/webidl/internal.d.ts b/op_crates/webidl/internal.d.ts new file mode 100644 index 00000000000000..0b54ebbfcafa49 --- /dev/null +++ b/op_crates/webidl/internal.d.ts @@ -0,0 +1,273 @@ +// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. +// deno-lint-ignore-file no-explicit-any ban-types + +/// +/// + +declare namespace globalThis { + declare namespace __bootstrap { + declare namespace webidl { + declare interface ConverterOpts { + /** + * The prefix for error messages created by this converter. + * Examples: + * - `Failed to construct 'Event'` + * - `Failed to execute 'removeEventListener' on 'EventTarget'` + */ + prefix: string; + } + declare interface ValueConverterOpts extends ConverterOpts { + /** + * The context of this value error messages created by this converter. + * Examples: + * - `Argument 1` + * - `Argument 3` + */ + context: string; + } + declare interface IntConverterOpts extends ValueConverterOpts { + /** + * Wether to throw if the number is outside of the acceptable values for + * this type. + */ + enforceRange?: boolean; + /** + * Wether to clamp this number to the acceptable values for this type. + */ + clamp?: boolean; + } + declare interface StringConverterOpts extends ValueConverterOpts { + /** + * Wether to treat `null` value as an empty string. + */ + treatNullAsEmptyString?: boolean; + } + declare interface BufferConverterOpts extends ValueConverterOpts { + /** + * Wether to allow `SharedArrayBuffer` (not just `ArrayBuffer`). + */ + allowShared?: boolean; + } + declare const converters: { + any(v: any): any; + /** + * Convert a value into a `boolean` (bool). + */ + boolean(v: any, opts?: IntConverterOpts): boolean; + /** + * Convert a value into a `byte` (int8). + */ + byte(v: any, opts?: IntConverterOpts): number; + /** + * Convert a value into a `octet` (uint8). + */ + octet(v: any, opts?: IntConverterOpts): number; + /** + * Convert a value into a `short` (int16). + */ + short(v: any, opts?: IntConverterOpts): number; + /** + * Convert a value into a `unsigned short` (uint16). + */ + ["unsigned short"](v: any, opts?: IntConverterOpts): number; + /** + * Convert a value into a `long` (int32). + */ + long(v: any, opts?: IntConverterOpts): number; + /** + * Convert a value into a `unsigned long` (uint32). + */ + ["unsigned long"](v: any, opts?: IntConverterOpts): number; + /** + * Convert a value into a `long long` (int64). + * **Note this is truncated to a JS number (53 bit precision).** + */ + ["long long"](v: any, opts?: IntConverterOpts): number; + /** + * Convert a value into a `unsigned long long` (uint64). + * **Note this is truncated to a JS number (53 bit precision).** + */ + ["unsigned long long"](v: any, opts?: IntConverterOpts): number; + /** + * Convert a value into a `float` (f32). + */ + float(v: any, opts?: ValueConverterOpts): number; + /** + * Convert a value into a `unrestricted float` (f32, infinity, or NaN). + */ + ["unrestricted float"](v: any, opts?: ValueConverterOpts): number; + /** + * Convert a value into a `double` (f64). + */ + double(v: any, opts?: ValueConverterOpts): number; + /** + * Convert a value into a `unrestricted double` (f64, infinity, or NaN). + */ + ["unrestricted double"](v: any, opts?: ValueConverterOpts): number; + /** + * Convert a value into a `DOMString` (string). + */ + DOMString(v: any, opts?: StringConverterOpts): string; + /** + * Convert a value into a `ByteString` (string with only u8 codepoints). + */ + ByteString(v: any, opts?: StringConverterOpts): string; + /** + * Convert a value into a `USVString` (string with only valid non + * surrogate Unicode code points). + */ + USVString(v: any, opts?: StringConverterOpts): string; + /** + * Convert a value into an `object` (object). + */ + object(v: any, opts?: ValueConverterOpts): object; + /** + * Convert a value into an `ArrayBuffer` (ArrayBuffer). + */ + ArrayBuffer(v: any, opts?: BufferConverterOpts): ArrayBuffer; + /** + * Convert a value into a `DataView` (ArrayBuffer). + */ + DataView(v: any, opts?: BufferConverterOpts): DataView; + /** + * Convert a value into a `Int8Array` (Int8Array). + */ + Int8Array(v: any, opts?: BufferConverterOpts): Int8Array; + /** + * Convert a value into a `Int16Array` (Int16Array). + */ + Int16Array(v: any, opts?: BufferConverterOpts): Int16Array; + /** + * Convert a value into a `Int32Array` (Int32Array). + */ + Int32Array(v: any, opts?: BufferConverterOpts): Int32Array; + /** + * Convert a value into a `Uint8Array` (Uint8Array). + */ + Uint8Array(v: any, opts?: BufferConverterOpts): Uint8Array; + /** + * Convert a value into a `Uint16Array` (Uint16Array). + */ + Uint16Array(v: any, opts?: BufferConverterOpts): Uint16Array; + /** + * Convert a value into a `Uint32Array` (Uint32Array). + */ + Uint32Array(v: any, opts?: BufferConverterOpts): Uint32Array; + /** + * Convert a value into a `Uint8ClampedArray` (Uint8ClampedArray). + */ + Uint8ClampedArray( + v: any, + opts?: BufferConverterOpts, + ): Uint8ClampedArray; + /** + * Convert a value into a `Float32Array` (Float32Array). + */ + Float32Array(v: any, opts?: BufferConverterOpts): Float32Array; + /** + * Convert a value into a `Float64Array` (Float64Array). + */ + Float64Array(v: any, opts?: BufferConverterOpts): Float64Array; + /** + * Convert a value into an `ArrayBufferView` (ArrayBufferView). + */ + ArrayBufferView(v: any, opts?: BufferConverterOpts): ArrayBufferView; + /** + * Convert a value into a `BufferSource` (ArrayBuffer or ArrayBufferView). + */ + BufferSource( + v: any, + opts?: BufferConverterOpts, + ): ArrayBuffer | ArrayBufferView; + /** + * Convert a value into a `DOMTimeStamp` (u64). Alias for unsigned long long + */ + DOMTimeStamp(v: any, opts?: IntConverterOpts): number; + /** + * Convert a value into a `Function` ((...args: any[]) => any). + */ + Function(v: any, opts?: ValueConverterOpts): (...args: any) => any; + /** + * Convert a value into a `VoidFunction` (() => void). + */ + VoidFunction(v: any, opts?: ValueConverterOpts): () => void; + + [type: string]: (v: any, opts: ValueConverterOpts) => any; + }; + + /** + * Assert that the a function has at least a required amount of arguments. + */ + declare function requiredArguments( + length: number, + required: number, + opts: ConverterOpts, + ): void; + declare type Dictionary = DictionaryMember[]; + declare interface DictionaryMember { + key: string; + converter: (v: any, opts: ValueConverterOpts) => any; + defaultValue?: any; + required?: boolean; + } + + /** + * Create a converter for dictionaries. + */ + declare function createDictionaryConverter( + name: string, + ...dictionaries: Dictionary[] + ): (v: any, opts: ValueConverterOpts) => T; + + /** + * Create a converter for enums. + */ + declare function createEnumConverter( + name: string, + values: string[], + ): (v: any, opts: ValueConverterOpts) => string; + + /** + * Create a converter that makes the contained type nullable. + */ + declare function createNullableConverter( + converter: (v: any, opts: ValueConverterOpts) => T, + ): (v: any, opts: ValueConverterOpts) => T | null; + + /** + * Create a converter that converts a sequence of the inner type. + */ + declare function createSequenceConverter( + converter: (v: any, opts: ValueConverterOpts) => T, + ): (v: any, opts: ValueConverterOpts) => T[]; + + /** + * Throw an illegal constructor error. + */ + declare function illegalConstructor(): never; + + /** + * The branding symbol. + */ + declare const brand: unique symbol; + + /** + * Create a branded instance of an interface. + */ + declare function createBranded(self: any): any; + + /** + * Assert that self is branded. + */ + declare function assertBranded(self: any, type: any): void; + + /** + * Create a converter for interfaces. + */ + declare function createInterfaceConverter( + name: string, + prototype: any, + ): (v: any, opts: ValueConverterOpts) => any; + } + } +} diff --git a/op_crates/webidl/lib.rs b/op_crates/webidl/lib.rs new file mode 100644 index 00000000000000..bcfad4e2f064f7 --- /dev/null +++ b/op_crates/webidl/lib.rs @@ -0,0 +1,16 @@ +// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. + +use deno_core::JsRuntime; + +/// Load and execute the javascript code. +pub fn init(isolate: &mut JsRuntime) { + let files = vec![ + ( + "deno:op_crates/webidl/00_webidl.js", + include_str!("00_webidl.js"), + ), + ]; + for (url, source_code) in files { + isolate.execute(url, source_code).unwrap(); + } +} \ No newline at end of file diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml index 30912c07827a4e..1be0281c4ff2b5 100644 --- a/runtime/Cargo.toml +++ b/runtime/Cargo.toml @@ -22,6 +22,8 @@ deno_core = { path = "../core", version = "0.79.0" } deno_crypto = { path = "../op_crates/crypto", version = "0.13.0" } deno_fetch = { path = "../op_crates/fetch", version = "0.22.0" } deno_web = { path = "../op_crates/web", version = "0.30.0" } +deno_url = { path = "../op_crates/url", version = "0.1.0" } +deno_webidl = { path = "../op_crates/webidl", version = "0.1.0" } deno_websocket = { path = "../op_crates/websocket", version = "0.5.0" } deno_webgpu = { path = "../op_crates/webgpu", version = "0.1.0" } @@ -34,6 +36,8 @@ deno_core = { path = "../core", version = "0.79.0" } deno_crypto = { path = "../op_crates/crypto", version = "0.13.0" } deno_fetch = { path = "../op_crates/fetch", version = "0.22.0" } deno_web = { path = "../op_crates/web", version = "0.30.0" } +deno_url = { path = "../op_crates/url", version = "0.1.0" } +deno_webidl = { path = "../op_crates/webidl", version = "0.1.0" } deno_websocket = { path = "../op_crates/websocket", version = "0.5.0" } deno_webgpu = { path = "../op_crates/webgpu", version = "0.1.0" } diff --git a/runtime/build.rs b/runtime/build.rs index 2481485684b762..67f80c8672bd17 100644 --- a/runtime/build.rs +++ b/runtime/build.rs @@ -13,6 +13,8 @@ fn create_snapshot( snapshot_path: &Path, files: Vec, ) { + deno_webidl::init(&mut js_runtime); + deno_url::init(&mut js_runtime); deno_web::init(&mut js_runtime); deno_fetch::init(&mut js_runtime); deno_websocket::init(&mut js_runtime); diff --git a/runtime/lib.rs b/runtime/lib.rs index c523b24b7abf71..73306b822d5a8d 100644 --- a/runtime/lib.rs +++ b/runtime/lib.rs @@ -12,6 +12,8 @@ pub use deno_fetch; pub use deno_web; pub use deno_webgpu; pub use deno_websocket; +pub use deno_webidl; +pub use deno_url; pub mod colors; pub mod errors; diff --git a/runtime/web_worker.rs b/runtime/web_worker.rs index 7f258b3eb994e8..aafe7fbf1a55ae 100644 --- a/runtime/web_worker.rs +++ b/runtime/web_worker.rs @@ -233,8 +233,8 @@ impl WebWorker { ops::reg_json_sync(js_runtime, "op_resources", deno_core::op_resources); ops::reg_json_sync( js_runtime, - "op_domain_to_ascii", - deno_web::op_domain_to_ascii, + "op_url_domain_to_ascii", + deno_url::op_url_domain_to_ascii, ); ops::io::init(js_runtime); ops::webgpu::init(js_runtime); diff --git a/runtime/worker.rs b/runtime/worker.rs index be6951f5112e97..5faf4a115cb7aa 100644 --- a/runtime/worker.rs +++ b/runtime/worker.rs @@ -128,8 +128,8 @@ impl MainWorker { ops::reg_json_sync(js_runtime, "op_resources", deno_core::op_resources); ops::reg_json_sync( js_runtime, - "op_domain_to_ascii", - deno_web::op_domain_to_ascii, + "op_url_domain_to_ascii", + deno_url::op_url_domain_to_ascii, ); ops::fs_events::init(js_runtime); ops::fs::init(js_runtime);