diff --git a/.github/workflows/webassembly-pr-build.yml b/.github/workflows/webassembly-pr-build.yml index be20e565f..a8c86145e 100644 --- a/.github/workflows/webassembly-pr-build.yml +++ b/.github/workflows/webassembly-pr-build.yml @@ -7,7 +7,7 @@ on: - reopened - synchronize paths: - - 'JS/**' + - 'JS/wasm/**' jobs: changes: @@ -50,52 +50,37 @@ jobs: toolchain: stable override: true - - name: Cache wasmjs-engine + - name: Cache Javy Core uses: actions/cache@v2 with: - path: ./JS/wasm/crates/wasmjs-engine/target - key: wasmjs-engine + path: ./target + key: javy-core restore-keys: | - wasmjs-engine + javy-core - - name: Check if wasmjs-engine is cached - id: wasmjs-engine-hit + - name: Check if Javy Core is cached + id: cache-hit run: | - echo "cache-hit=$(test -d ./JS/wasm/crates/wasmjs-engine/target && echo true || echo false)" >> $GITHUB_OUTPUT + # echo "cache-hit=$(test -d ./target && echo true || echo false)" >> $GITHUB_OUTPUT + echo "cache-hit=$(test -d ./target && echo true || echo false)" >> $GITHUB_OUTPUT - - name: Build wasmjs-engine - if: steps.wasmjs-engine-hit.outputs.cache-hit != 'true' - working-directory: ./JS/wasm/crates/wasmjs-engine + - name: Build Javy Core + if: + working-directory: . run: | - npm install -g @go-task/cli - task build - - - name: Cache wasmjs-runtime - uses: actions/cache@v2 - with: - path: ./JS/wasm/crates/wasmjs-runtime/target - key: wasmjs-runtime - restore-keys: | - wasmjs-runtime - - - name: Check if wasmjs-runtime is cached - id: wasmjs-runtime-hit + make add build-cors + - name: Build CLI + working-directory: . run: | - echo "cache-hit=$(test -d ./JS/wasm/crates/wasmjs-runtime/target && echo true || echo false)" >> $GITHUB_OUTPUT - - - name: Build wasmjs-runtime - if: steps.wasmjs-runtime-hit.outputs.cache-hit != 'true' - working-directory: ./JS/wasm/crates/wasmjs-runtime - run: | - cargo build --release - - - name: Build ec-wasmjs-hono - working-directory: ./JS/wasm/examples/ec-wasmjs-hono + make + - name: Build Jsonnet + working-directory: . run: | - npm install - npm run build + make build-jsonnet + - name: Build Release Binary + run: cargo build --release - - name: Run ec-wasmjs-hono - working-directory: ./JS/wasm/crates/wasmjs-runtime - run: | - ./target/release/wasmjs-runtime run ../../examples/ec-wasmjs-hono/bin \ No newline at end of file + - name: Upload to GitHub Releases + uses: actions/upload-rust-binary-action@v1 + with: + bin: your_binary_name \ No newline at end of file diff --git a/.gitignore b/.gitignore index dd8d39e43..bfdabff34 100644 --- a/.gitignore +++ b/.gitignore @@ -33,4 +33,12 @@ build/ .vscode/ ### Node Modules ### -node_modules \ No newline at end of file +node_modules + +### rust ### +/target/ +index.wasm +index.wit +Cargo.lock + +.DS_Store diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 000000000..8f2e29361 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,30 @@ +[workspace] +members = [ + "JS/wasm/crates/apis", + "JS/wasm/crates/arakoo-core", + "JS/wasm/crates/cli", + "JS/wasm/crates/serve", + "JS/wasm/types/jsonnet", +] +resolver = "2" + +[workspace.package] +edition = "2021" +version = "0.0.1" + +[workspace.dependencies] +wizer = "4.0.0" +wasmtime = "16" +wasmtime-wasi = "16" +wasi-common = "16" +javy = { version = "2.1.0" } +anyhow = "1.0.79" +once_cell = "1.19.0" +serde = { version = "1", features = ["derive"] } +serde_json = "1" +[profile.release] +lto = true +opt-level = 's' + +[profile.dev] +incremental = true diff --git a/JS/wasm/crates/apis/Cargo.toml b/JS/wasm/crates/apis/Cargo.toml new file mode 100644 index 000000000..0711d4b0e --- /dev/null +++ b/JS/wasm/crates/apis/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "apis" +edition.workspace = true +version.workspace = true + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[features] +console = [] +random = ["dep:fastrand"] +stream_io = [] +text_encoding = [] + +[dependencies] +anyhow = { workspace = true } +fastrand = { version = "2.0.1", optional = true } +javy = { workspace = true } +# wit-bindgen-rust = { git = "https://github.com/bytecodealliance/wit-bindgen", tag = "v0.2.0" } +tokio = "1.36.0" +serde = { workspace = true } +serde_json = { workspace = true } diff --git a/JS/wasm/crates/apis/src/api_config.rs b/JS/wasm/crates/apis/src/api_config.rs new file mode 100644 index 000000000..0b0955adc --- /dev/null +++ b/JS/wasm/crates/apis/src/api_config.rs @@ -0,0 +1,12 @@ +/// A configuration for APIs added in this crate. +/// +/// Example usage: +/// ``` +/// # use javy_apis::APIConfig; +/// let api_config = APIConfig::default(); +/// ``` +#[derive(Debug, Default)] +pub struct APIConfig { + #[cfg(feature = "console")] + pub(crate) console: crate::console::ConsoleConfig, +} diff --git a/JS/wasm/crates/apis/src/console/config.rs b/JS/wasm/crates/apis/src/console/config.rs new file mode 100644 index 000000000..3eb2152fb --- /dev/null +++ b/JS/wasm/crates/apis/src/console/config.rs @@ -0,0 +1,51 @@ +use std::io::{self, Write}; + +use crate::APIConfig; + +/// A selection of possible destination streams for `console.log` and +/// `console.error`. +#[derive(Debug)] +pub enum LogStream { + /// The standard output stream. + StdOut, + /// The standard error stream. + StdErr, +} + +impl LogStream { + pub(super) fn to_stream(&self) -> Box { + match self { + Self::StdErr => Box::new(io::stderr()), + Self::StdOut => Box::new(io::stdout()), + } + } +} + +#[derive(Debug)] +pub(crate) struct ConsoleConfig { + pub(super) log_stream: LogStream, + pub(super) error_stream: LogStream, +} + +impl Default for ConsoleConfig { + fn default() -> Self { + Self { + log_stream: LogStream::StdOut, + error_stream: LogStream::StdErr, + } + } +} + +impl APIConfig { + /// Sets the destination stream for `console.log`. + pub fn log_stream(&mut self, stream: LogStream) -> &mut Self { + self.console.log_stream = stream; + self + } + + /// Sets the destination stream for `console.error`. + pub fn error_stream(&mut self, stream: LogStream) -> &mut Self { + self.console.error_stream = stream; + self + } +} diff --git a/JS/wasm/crates/apis/src/console/mod.rs b/JS/wasm/crates/apis/src/console/mod.rs new file mode 100644 index 000000000..eb75d3427 --- /dev/null +++ b/JS/wasm/crates/apis/src/console/mod.rs @@ -0,0 +1,187 @@ +use std::io::Write; + +use anyhow::Result; +use javy::{ + quickjs::{JSContextRef, JSValue, JSValueRef}, + Runtime, +}; + +use crate::{APIConfig, JSApiSet}; + +pub(super) use config::ConsoleConfig; +pub use config::LogStream; + +mod config; + +pub(super) struct Console {} + +impl Console { + pub(super) fn new() -> Self { + Console {} + } +} + +impl JSApiSet for Console { + fn register(&self, runtime: &Runtime, config: &APIConfig) -> Result<()> { + register_console( + runtime.context(), + config.console.log_stream.to_stream(), + config.console.error_stream.to_stream(), + ) + } +} + +fn register_console(context: &JSContextRef, log_stream: T, error_stream: U) -> Result<()> +where + T: Write + 'static, + U: Write + 'static, +{ + let console_log_callback = context.wrap_callback(console_log_to(log_stream))?; + let console_error_callback = context.wrap_callback(console_log_to(error_stream))?; + let console_object = context.object_value()?; + console_object.set_property("log", console_log_callback)?; + console_object.set_property("error", console_error_callback)?; + context + .global_object()? + .set_property("console", console_object)?; + Ok(()) +} + +fn console_log_to( + mut stream: T, +) -> impl FnMut(&JSContextRef, JSValueRef, &[JSValueRef]) -> Result +where + T: Write + 'static, +{ + move |_ctx: &JSContextRef, _this: JSValueRef, args: &[JSValueRef]| { + // Write full string to in-memory destination before writing to stream since each write call to the stream + // will invoke a hostcall. + let mut log_line = String::new(); + for (i, arg) in args.iter().enumerate() { + if i != 0 { + log_line.push(' '); + } + let line = arg.to_string(); + log_line.push_str(&line); + } + + writeln!(stream, "{log_line}")?; + + Ok(JSValue::Undefined) + } +} + +#[cfg(test)] +mod tests { + use anyhow::Result; + use javy::Runtime; + use std::cell::RefCell; + use std::rc::Rc; + use std::{cmp, io}; + + use crate::console::register_console; + use crate::{APIConfig, JSApiSet}; + + use super::Console; + + #[test] + fn test_register() -> Result<()> { + let runtime = Runtime::default(); + Console::new().register(&runtime, &APIConfig::default())?; + let console = runtime.context().global_object()?.get_property("console")?; + assert!(console.get_property("log").is_ok()); + assert!(console.get_property("error").is_ok()); + Ok(()) + } + + #[test] + fn test_console_log() -> Result<()> { + let mut stream = SharedStream::default(); + + let runtime = Runtime::default(); + let ctx = runtime.context(); + register_console(ctx, stream.clone(), stream.clone())?; + + ctx.eval_global("main", "console.log(\"hello world\");")?; + assert_eq!(b"hello world\n", stream.buffer.borrow().as_slice()); + + stream.clear(); + + ctx.eval_global("main", "console.log(\"bonjour\", \"le\", \"monde\")")?; + assert_eq!(b"bonjour le monde\n", stream.buffer.borrow().as_slice()); + + stream.clear(); + + ctx.eval_global( + "main", + "console.log(2.3, true, { foo: 'bar' }, null, undefined)", + )?; + assert_eq!( + b"2.3 true [object Object] null undefined\n", + stream.buffer.borrow().as_slice() + ); + Ok(()) + } + + #[test] + fn test_console_error() -> Result<()> { + let mut stream = SharedStream::default(); + + let runtime = Runtime::default(); + let ctx = runtime.context(); + register_console(ctx, stream.clone(), stream.clone())?; + + ctx.eval_global("main", "console.error(\"hello world\");")?; + assert_eq!(b"hello world\n", stream.buffer.borrow().as_slice()); + + stream.clear(); + + ctx.eval_global("main", "console.error(\"bonjour\", \"le\", \"monde\")")?; + assert_eq!(b"bonjour le monde\n", stream.buffer.borrow().as_slice()); + + stream.clear(); + + ctx.eval_global( + "main", + "console.error(2.3, true, { foo: 'bar' }, null, undefined)", + )?; + assert_eq!( + b"2.3 true [object Object] null undefined\n", + stream.buffer.borrow().as_slice() + ); + Ok(()) + } + + #[derive(Clone)] + struct SharedStream { + buffer: Rc>>, + capacity: usize, + } + + impl Default for SharedStream { + fn default() -> Self { + Self { + buffer: Default::default(), + capacity: usize::MAX, + } + } + } + + impl SharedStream { + fn clear(&mut self) { + (*self.buffer).borrow_mut().clear(); + } + } + + impl io::Write for SharedStream { + fn write(&mut self, buf: &[u8]) -> io::Result { + let available_capacity = self.capacity - (*self.buffer).borrow().len(); + let leftover = cmp::min(available_capacity, buf.len()); + (*self.buffer).borrow_mut().write(&buf[..leftover]) + } + + fn flush(&mut self) -> io::Result<()> { + (*self.buffer).borrow_mut().flush() + } + } +} diff --git a/JS/wasm/crates/apis/src/http/mod.rs b/JS/wasm/crates/apis/src/http/mod.rs new file mode 100644 index 000000000..a95ad2175 --- /dev/null +++ b/JS/wasm/crates/apis/src/http/mod.rs @@ -0,0 +1,77 @@ +pub mod types; + +use std::collections::HashMap; + +use anyhow::Result; +use javy::quickjs::{JSContextRef, JSValue, JSValueRef}; + +use crate::{fetch, get_response, get_response_len, http::types::Request, JSApiSet}; + +pub(super) struct Http; + +impl JSApiSet for Http { + fn register(&self, runtime: &javy::Runtime, _config: &crate::APIConfig) -> Result<()> { + let context = runtime.context(); + let global = context.global_object()?; + global.set_property("arakoo", context.value_from_bool(true)?)?; + global.set_property("fetch", context.wrap_callback(fetch_callback())?)?; + context.eval_global("http.js", include_str!("shims/dist/index.js"))?; + + Ok(()) + } +} + +fn fetch_callback( +) -> impl FnMut(&JSContextRef, JSValueRef, &[JSValueRef]) -> anyhow::Result { + move |_ctx, _this, args| { + if args.len() < 1 { + return Err(anyhow::anyhow!( + "Expected at least 1 argument, got {}", + args.len() + )); + } + let uri = args.get(0).unwrap().to_string(); + let opts: HashMap = args[1].try_into()?; + let method = opts.get("method").unwrap_or(&"GET".into()).to_string(); + let headers = match opts.get("headers") { + Some(JSValue::Object(headers)) => headers + .iter() + .map(|(k, v)| (k.to_string(), v.to_string())) + .collect(), + _ => HashMap::default(), + }; + let body = opts.get("body").unwrap_or(&"".into()).to_string(); + let params = match opts.get("params") { + Some(JSValue::Object(params)) => params + .iter() + .map(|(k, v)| (k.to_string(), v.to_string())) + .collect(), + _ => HashMap::default(), + }; + + let request = + serde_json::to_string(&Request::new(uri, method, headers, body, params)).unwrap(); + let request_ptr = request.as_ptr(); + let request_len = request.len() as i32; + unsafe { fetch(request_ptr, request_len) } + let response_len = unsafe { get_response_len() }; + let mut response_buffer = Vec::with_capacity(response_len as usize); + let response_ptr = response_buffer.as_mut_ptr(); + let response_buffer = unsafe { + get_response(response_ptr); + Vec::from_raw_parts(response_ptr, response_len as usize, response_len as usize) + }; + let response: serde_json::Value = match serde_json::from_slice(&response_buffer) { + Ok(response) => response, + Err(e) => { + eprintln!("Failed to parse fetch response: {}", e); + return Err(anyhow::anyhow!( + "Failed to parse fetch response: {}", + e.to_string() + )); + } + }; + + todo!("fetch"); + } +} diff --git a/JS/wasm/crates/apis/src/http/shims/.gitignore b/JS/wasm/crates/apis/src/http/shims/.gitignore new file mode 100644 index 000000000..1eae0cf67 --- /dev/null +++ b/JS/wasm/crates/apis/src/http/shims/.gitignore @@ -0,0 +1,2 @@ +dist/ +node_modules/ diff --git a/JS/wasm/crates/apis/src/http/shims/build.js b/JS/wasm/crates/apis/src/http/shims/build.js new file mode 100644 index 000000000..6e463e218 --- /dev/null +++ b/JS/wasm/crates/apis/src/http/shims/build.js @@ -0,0 +1,15 @@ +import { build } from "esbuild"; + +// Build for index.js +build({ + entryPoints: ["index.js"], + bundle: true, + outfile: "dist/index.js", + format: "esm", + target: "esnext", + platform: "node", + treeShaking: false, +}).catch((error) => { + console.error(error); + process.exit(1); +}); diff --git a/JS/wasm/crates/apis/src/http/shims/index.js b/JS/wasm/crates/apis/src/http/shims/index.js new file mode 100644 index 000000000..3c9521fba --- /dev/null +++ b/JS/wasm/crates/apis/src/http/shims/index.js @@ -0,0 +1,303 @@ +import { TextEncoder, TextDecoder } from "@sinonjs/text-encoding"; +import httpStatus from "http-status"; +import Url from "url-parse"; +import _queryString from "query-string"; + +class URL { + constructor(urlStr, base = undefined) { + let url = Url(urlStr, base); + this.url = url; + this.protocol = url.protocol; + this.slashes = url.slashes; + this.auth = url.auth; + this.username = url.username; + this.password = url.password; + this.host = url.host; + this.port = url.port; + this.pathname = url.pathname; + this.search = url.query; + this.searchParams = new URLSearchParams(this.search); + this.hash = url.hash; + this.href = url.origin; + this.origin = url.origin; + } + + set(key, value) { + this.url.set(key, value); + } + + toString() { + return this.url.toString(); + } + + toJson() { + return this.url.toString(); + } +} + +class URLSearchParams { + queryParams = {}; + + constructor(val) { + this.queryParams = { + ..._queryString.parse(val), + }; + } + append(key, val) { + this.queryParams[key] = val; + } + delete(key) { + delete this.queryParams[key]; + } + entries() { + let arr = []; + Object.entries(this.queryParams).map((o) => { + if (Array.isArray(o[1])) { + o[1].map((k) => { + arr.push([o[0], k]); + }); + } else { + arr.push([o[0], o[1]]); + } + }); + let iterLength = arr.length; + let iterIndex = 0; + return { + next: function () { + return iterIndex < iterLength + ? { value: arr[iterIndex++], done: false } + : { done: true }; + }, + }; + } + get(key) { + let val = this.queryParams[key]; + if (val) { + if (typeof val == "object") { + return val[0]; + } + return val; + } + return null; + } + getAll(key) { + let val = this.queryParams[key]; + if (val) { + return val; + } + return null; + } + has(key) { + return this.queryParams[key] != undefined ? true : false; + } + keys() { + return Object.keys(this.queryParams); + } + set(key, val) { + this.queryParams[key] = val; + } + toString() { + return _queryString.stringify(this.queryParams); + } + values() { + return Object.keys(this.queryParams).map((k) => this.queryParams[k]); + } + [Symbol.iterator]() { + return this.entries(); + } +} + +globalThis.URL = URL; +globalThis.URLSearchParams = URLSearchParams; + +function atob(b64) { + return Buffer.from(b64, "base64").toString(); +} + +function btoa(data) { + return Buffer.from(data).toString("base64"); +} + +globalThis.btoa = btoa; +globalThis.atob = atob; + +class Headers { + constructor(initialHeaders) { + let headers = {}; + + for (const key in initialHeaders) { + let value = initialHeaders[key]; + + if (typeof value === "string") { + headers[key] = value; + } + } + + this.headers = headers; + } + + append(key, value) { + this.headers[key] = value; + return value; + } + + set(key, value) { + this.append(key, value); + return value; + } + + delete(key) { + let dropValue = delete this.headers[key]; + return dropValue; + } + + get(key) { + return this.headers[key]; + } + + toJSON() { + return this.headers; + } +} + +class Request { + constructor(input) { + this.url = input.url; + this.method = input.method; + this.headers = new Headers(input.headers || {}); + this.body = input.body; + this.params = input.params || {}; + this.geo = input.geo || {}; + } + + text() { + return this.body; + } +} + +class Response { + constructor(body, options = {}) { + if (body instanceof String) { + this.body = body.toString(); + } else { + this.body = body; + } + + if (options.headers instanceof Headers) { + this.headers = options.headers; + } else if (options.headers instanceof Object) { + this.headers = new Headers(options.headers); + } else { + this.headers = new Headers({}); + } + + this.status = options.status || 200; + this.statusText = options.statusText || httpStatus[this.status]; + } + + static redirect(url, status = 307) { + return new Response(`Redirecting to ${url}`, { + status, + headers: { + Location: url, + }, + }); + } + + get ok() { + return this.status >= 200 && this.status < 300; + } + + defaultEncoding() { + return "utf-8"; + } + + arrayBuffer() { + let parsedBody = this.body; + + if (typeof this.body === "string") { + try { + parsedBody = new TextEncoder().encode(this.body); + } catch (e) { + return Promise.reject(`err: ${e}`); + } + } + + return parsedBody; + } + + json() { + let parsedBody = this.body; + + if (typeof this.body !== "string") { + try { + parsedBody = new TextDecoder(this.defaultEncoding()).decode(this.body); + } catch (e) { + return Promise.reject(`err: ${e}`); + } + } + + try { + return Promise.resolve(JSON.parse(parsedBody)); + } catch (e) { + return Promise.reject(`err: ${e}`); + } + } + + text() { + let parsedBody = this.body; + + if (typeof this.body !== "string") { + try { + parsedBody = new TextDecoder(this.defaultEncoding()).decode(this.body); + } catch (e) { + return Promise.reject(`err: ${e}`); + } + } + + return parsedBody; + } + + toString() { + return this.body; + } +} +let handlerFunction; +globalThis.addEventListener = (_eventName, handler) => { + handlerFunction = handler; +}; + +const requestToHandler = (input) => { + const request = new Request(input); + const event = { + request, + response: {}, + respondWith(res) { + this.response = res; + }, + }; + + try { + handlerFunction(event); + + Promise.resolve(event.response) + .then((res) => { + console.log("res: ", res); + result = { + body: res.body, + headers: res.headers.headers, + status: res.status, + statusText: res.statusText, + }; + }) + .catch((err) => { + error = `err: \n${err}`; + }); + } catch (err) { + error = `err: ${err}\n${err.stack}`; + } +}; + +globalThis.entrypoint = requestToHandler; +globalThis.result = {}; +globalThis.error = null; diff --git a/JS/wasm/crates/apis/src/http/shims/package-lock.json b/JS/wasm/crates/apis/src/http/shims/package-lock.json new file mode 100644 index 000000000..033db7ab7 --- /dev/null +++ b/JS/wasm/crates/apis/src/http/shims/package-lock.json @@ -0,0 +1,161 @@ +{ + "name": "shims", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "shims", + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "@sinonjs/text-encoding": "^0.7.2", + "esbuild": "^0.20.0", + "http-status": "^1.7.3", + "query-string": "^8.1.0", + "url-parse": "^1.5.10" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.0.tgz", + "integrity": "sha512-AjEcivGAlPs3UAcJedMa9qYg9eSfU6FnGHJjT8s346HSKkrcWlYezGE8VaO2xKfvvlZkgAhyvl06OJOxiMgOYQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@sinonjs/text-encoding": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.2.tgz", + "integrity": "sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==", + "license": "(Unlicense OR Apache-2.0)" + }, + "node_modules/decode-uri-component": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.4.1.tgz", + "integrity": "sha512-+8VxcR21HhTy8nOt6jf20w0c9CADrw1O8d+VZ/YzzCt4bJ3uBjw+D1q2osAB8RnpwwaeYBxy0HyKQxD5JBMuuQ==", + "license": "MIT", + "engines": { + "node": ">=14.16" + } + }, + "node_modules/esbuild": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.0.tgz", + "integrity": "sha512-6iwE3Y2RVYCME1jLpBqq7LQWK3MW6vjV2bZy6gt/WrqkY+WE74Spyc0ThAOYpMtITvnjX09CrC6ym7A/m9mebA==", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.20.0", + "@esbuild/android-arm": "0.20.0", + "@esbuild/android-arm64": "0.20.0", + "@esbuild/android-x64": "0.20.0", + "@esbuild/darwin-arm64": "0.20.0", + "@esbuild/darwin-x64": "0.20.0", + "@esbuild/freebsd-arm64": "0.20.0", + "@esbuild/freebsd-x64": "0.20.0", + "@esbuild/linux-arm": "0.20.0", + "@esbuild/linux-arm64": "0.20.0", + "@esbuild/linux-ia32": "0.20.0", + "@esbuild/linux-loong64": "0.20.0", + "@esbuild/linux-mips64el": "0.20.0", + "@esbuild/linux-ppc64": "0.20.0", + "@esbuild/linux-riscv64": "0.20.0", + "@esbuild/linux-s390x": "0.20.0", + "@esbuild/linux-x64": "0.20.0", + "@esbuild/netbsd-x64": "0.20.0", + "@esbuild/openbsd-x64": "0.20.0", + "@esbuild/sunos-x64": "0.20.0", + "@esbuild/win32-arm64": "0.20.0", + "@esbuild/win32-ia32": "0.20.0", + "@esbuild/win32-x64": "0.20.0" + } + }, + "node_modules/filter-obj": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/filter-obj/-/filter-obj-5.1.0.tgz", + "integrity": "sha512-qWeTREPoT7I0bifpPUXtxkZJ1XJzxWtfoWWkdVGqa+eCr3SHW/Ocp89o8vLvbUuQnadybJpjOKu4V+RwO6sGng==", + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/http-status": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/http-status/-/http-status-1.7.3.tgz", + "integrity": "sha512-GS8tL1qHT2nBCMJDYMHGkkkKQLNkIAHz37vgO68XKvzv+XyqB4oh/DfmMHdtRzfqSJPj1xKG2TaELZtlCz6BEQ==", + "license": "BSD-3-Clause", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/query-string": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-8.1.0.tgz", + "integrity": "sha512-BFQeWxJOZxZGix7y+SByG3F36dA0AbTy9o6pSmKFcFz7DAj0re9Frkty3saBn3nHo3D0oZJ/+rx3r8H8r8Jbpw==", + "license": "MIT", + "dependencies": { + "decode-uri-component": "^0.4.1", + "filter-obj": "^5.1.0", + "split-on-first": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", + "license": "MIT" + }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "license": "MIT" + }, + "node_modules/split-on-first": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/split-on-first/-/split-on-first-3.0.0.tgz", + "integrity": "sha512-qxQJTx2ryR0Dw0ITYyekNQWpz6f8dGd7vffGNflQQ3Iqj9NJ6qiZ7ELpZsJ/QBhIVAiDfXdag3+Gp8RvWa62AA==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "license": "MIT", + "dependencies": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + } + } +} diff --git a/JS/wasm/crates/apis/src/http/shims/package.json b/JS/wasm/crates/apis/src/http/shims/package.json new file mode 100644 index 000000000..afb62cc72 --- /dev/null +++ b/JS/wasm/crates/apis/src/http/shims/package.json @@ -0,0 +1,18 @@ +{ + "name": "shims", + "version": "1.0.0", + "description": "Shims for http", + "main": "index.js", + "type": "module", + "license": "MIT", + "scripts": { + "build": "node build.js" + }, + "dependencies": { + "@sinonjs/text-encoding": "^0.7.2", + "esbuild": "^0.20.0", + "http-status": "^1.7.3", + "query-string": "^8.1.0", + "url-parse": "^1.5.10" + } +} diff --git a/JS/wasm/crates/apis/src/http/shims/yarn.lock b/JS/wasm/crates/apis/src/http/shims/yarn.lock new file mode 100644 index 000000000..5c89199f2 --- /dev/null +++ b/JS/wasm/crates/apis/src/http/shims/yarn.lock @@ -0,0 +1,89 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@esbuild/darwin-arm64@0.20.0": + version "0.20.0" + resolved "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.0.tgz" + integrity sha512-AjEcivGAlPs3UAcJedMa9qYg9eSfU6FnGHJjT8s346HSKkrcWlYezGE8VaO2xKfvvlZkgAhyvl06OJOxiMgOYQ== + +"@sinonjs/text-encoding@^0.7.2": + version "0.7.2" + resolved "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.2.tgz" + integrity sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ== + +decode-uri-component@^0.4.1: + version "0.4.1" + resolved "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.4.1.tgz" + integrity sha512-+8VxcR21HhTy8nOt6jf20w0c9CADrw1O8d+VZ/YzzCt4bJ3uBjw+D1q2osAB8RnpwwaeYBxy0HyKQxD5JBMuuQ== + +esbuild@^0.20.0: + version "0.20.0" + resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.20.0.tgz" + integrity sha512-6iwE3Y2RVYCME1jLpBqq7LQWK3MW6vjV2bZy6gt/WrqkY+WE74Spyc0ThAOYpMtITvnjX09CrC6ym7A/m9mebA== + optionalDependencies: + "@esbuild/aix-ppc64" "0.20.0" + "@esbuild/android-arm" "0.20.0" + "@esbuild/android-arm64" "0.20.0" + "@esbuild/android-x64" "0.20.0" + "@esbuild/darwin-arm64" "0.20.0" + "@esbuild/darwin-x64" "0.20.0" + "@esbuild/freebsd-arm64" "0.20.0" + "@esbuild/freebsd-x64" "0.20.0" + "@esbuild/linux-arm" "0.20.0" + "@esbuild/linux-arm64" "0.20.0" + "@esbuild/linux-ia32" "0.20.0" + "@esbuild/linux-loong64" "0.20.0" + "@esbuild/linux-mips64el" "0.20.0" + "@esbuild/linux-ppc64" "0.20.0" + "@esbuild/linux-riscv64" "0.20.0" + "@esbuild/linux-s390x" "0.20.0" + "@esbuild/linux-x64" "0.20.0" + "@esbuild/netbsd-x64" "0.20.0" + "@esbuild/openbsd-x64" "0.20.0" + "@esbuild/sunos-x64" "0.20.0" + "@esbuild/win32-arm64" "0.20.0" + "@esbuild/win32-ia32" "0.20.0" + "@esbuild/win32-x64" "0.20.0" + +filter-obj@^5.1.0: + version "5.1.0" + resolved "https://registry.npmjs.org/filter-obj/-/filter-obj-5.1.0.tgz" + integrity sha512-qWeTREPoT7I0bifpPUXtxkZJ1XJzxWtfoWWkdVGqa+eCr3SHW/Ocp89o8vLvbUuQnadybJpjOKu4V+RwO6sGng== + +http-status@^1.7.3: + version "1.7.3" + resolved "https://registry.npmjs.org/http-status/-/http-status-1.7.3.tgz" + integrity sha512-GS8tL1qHT2nBCMJDYMHGkkkKQLNkIAHz37vgO68XKvzv+XyqB4oh/DfmMHdtRzfqSJPj1xKG2TaELZtlCz6BEQ== + +query-string@^8.1.0: + version "8.1.0" + resolved "https://registry.npmjs.org/query-string/-/query-string-8.1.0.tgz" + integrity sha512-BFQeWxJOZxZGix7y+SByG3F36dA0AbTy9o6pSmKFcFz7DAj0re9Frkty3saBn3nHo3D0oZJ/+rx3r8H8r8Jbpw== + dependencies: + decode-uri-component "^0.4.1" + filter-obj "^5.1.0" + split-on-first "^3.0.0" + +querystringify@^2.1.1: + version "2.2.0" + resolved "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz" + integrity sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ== + +requires-port@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz" + integrity sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ== + +split-on-first@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/split-on-first/-/split-on-first-3.0.0.tgz" + integrity sha512-qxQJTx2ryR0Dw0ITYyekNQWpz6f8dGd7vffGNflQQ3Iqj9NJ6qiZ7ELpZsJ/QBhIVAiDfXdag3+Gp8RvWa62AA== + +url-parse@^1.5.10: + version "1.5.10" + resolved "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz" + integrity sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ== + dependencies: + querystringify "^2.1.1" + requires-port "^1.0.0" diff --git a/JS/wasm/crates/apis/src/http/types.rs b/JS/wasm/crates/apis/src/http/types.rs new file mode 100644 index 000000000..121bb5f61 --- /dev/null +++ b/JS/wasm/crates/apis/src/http/types.rs @@ -0,0 +1,38 @@ +use serde::{Deserialize, Serialize}; +use std::collections::HashMap; + +#[derive(Serialize, Deserialize, Debug)] +pub struct Request { + url: String, + method: String, + headers: HashMap, + body: String, + params: HashMap, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct Response { + pub headers: HashMap, + pub status: u16, + #[serde(rename = "statusText")] + pub status_text: String, + pub body: Option, +} + +impl Request { + pub fn new( + url: String, + method: String, + headers: HashMap, + body: String, + params: HashMap, + ) -> Self { + Self { + url, + method, + headers, + body, + params, + } + } +} diff --git a/JS/wasm/crates/apis/src/jsonnet/mod.rs b/JS/wasm/crates/apis/src/jsonnet/mod.rs new file mode 100644 index 000000000..322df3e2a --- /dev/null +++ b/JS/wasm/crates/apis/src/jsonnet/mod.rs @@ -0,0 +1,57 @@ +use javy::quickjs::{JSContextRef, JSValue, JSValueRef}; + +use crate::{jsonnet_evaluate, jsonnet_output, jsonnet_output_len, JSApiSet}; + +pub(super) struct Jsonnet; + +impl JSApiSet for Jsonnet { + fn register(&self, runtime: &javy::Runtime, _config: &crate::APIConfig) -> anyhow::Result<()> { + let context = runtime.context(); + let global = context.global_object()?; + global.set_property( + "__jsonnet_evaluate_snippet", + context.wrap_callback(jsonnet_evaluate_snippet_callback())?, + )?; + + Ok(()) + } +} + +fn jsonnet_evaluate_snippet_callback( +) -> impl FnMut(&JSContextRef, JSValueRef, &[JSValueRef]) -> anyhow::Result { + move |_ctx, _this, args| { + // check the number of arguments + if args.len() != 2 { + return Err(anyhow::anyhow!("Expected 2 arguments, got {}", args.len())); + } + let var = args.get(0).unwrap().to_string(); + let code = args.get(1).unwrap().to_string(); + let var_len = var.len() as i32; + let path_len = code.len() as i32; + let var_ptr = var.as_ptr(); + let path_ptr = code.as_ptr(); + + unsafe { jsonnet_evaluate(var_ptr, var_len, path_ptr, path_len) } + let out_len = unsafe { jsonnet_output_len() }; + + let mut out_buffer = Vec::with_capacity(out_len as usize); + let out_ptr = out_buffer.as_mut_ptr(); + let out_buffer = unsafe { + jsonnet_output(out_ptr); + Vec::from_raw_parts(out_ptr, out_len as usize, out_len as usize) + }; + + let jsonnet_output: serde_json::Value = match serde_json::from_slice(&out_buffer) { + Ok(output) => output, + Err(e) => { + eprintln!("Failed to parse jsonnet output: {}", e); + return Err(anyhow::anyhow!( + "Failed to parse jsonnet output: {}", + e.to_string() + )); + } + }; + let jsonnet_output = jsonnet_output.to_string(); + Ok(jsonnet_output.into()) + } +} diff --git a/JS/wasm/crates/apis/src/lib.rs b/JS/wasm/crates/apis/src/lib.rs new file mode 100644 index 000000000..860a192c1 --- /dev/null +++ b/JS/wasm/crates/apis/src/lib.rs @@ -0,0 +1,106 @@ +//! JS APIs for Javy. +//! +//! This crate provides JS APIs you can add to Javy. +//! +//! Example usage: +//! ``` +//! # use anyhow::{anyhow, Error, Result}; +//! use javy::{quickjs::JSValue, Runtime}; +//! use javy_apis::RuntimeExt; +//! +//! let runtime = Runtime::new_with_defaults()?; +//! let context = runtime.context(); +//! context.global_object()?.set_property( +//! "print", +//! context.wrap_callback(move |_ctx, _this, args| { +//! let str = args +//! .first() +//! .ok_or(anyhow!("Need to pass an argument"))? +//! .to_string(); +//! println!("{str}"); +//! Ok(JSValue::Undefined) +//! })?, +//! )?; +//! context.eval_global("hello.js", "print('hello!');")?; +//! # Ok::<(), Error>(()) +//! ``` +//! +//! If you want to customize the runtime or the APIs, you can use the +//! [`Runtime::new_with_apis`] method instead to provide a [`javy::Config`] +//! for the underlying [`Runtime`] or an [`APIConfig`] for the APIs. +//! +//! ## Features +//! * `console` - Registers an implementation of the `console` API. +//! * `text_encoding` - Registers implementations of `TextEncoder` and `TextDecoder`. +//! * `random` - Overrides the implementation of `Math.random` to one that +//! seeds the RNG on first call to `Math.random`. This is helpful to enable +//! when using Wizer to snapshot a [`javy::Runtime`] so that the output of +//! `Math.random` relies on the WASI context used at runtime and not the +//! WASI context used when Wizening. Enabling this feature will increase the +//! size of the Wasm module that includes the Javy Runtime and will +//! introduce an additional hostcall invocation when `Math.random` is +//! invoked for the first time. +//! * `stream_io` - Registers implementations of `Javy.IO.readSync` and `Javy.IO.writeSync`. + +use anyhow::Result; +use javy::Runtime; + +pub use api_config::APIConfig; +#[cfg(feature = "console")] +pub use console::LogStream; +pub use runtime_ext::RuntimeExt; + +mod api_config; +#[cfg(feature = "console")] +mod console; +#[cfg(feature = "random")] +mod random; +mod runtime_ext; +#[cfg(feature = "stream_io")] +mod stream_io; +#[cfg(feature = "text_encoding")] +mod text_encoding; + +pub mod http; +mod jsonnet; + +#[link(wasm_import_module = "arakoo")] +extern "C" { + fn jsonnet_evaluate(var_ptr: *const u8, var_len: i32, code_ptr: *const u8, code_len: i32); + fn jsonnet_output_len() -> i32; + fn jsonnet_output(ptr: *mut u8); + fn fetch(request_pointer: *const u8, request_len: i32); + fn get_response_len() -> i32; + fn get_response(ptr: *mut u8); + +} + +pub(crate) trait JSApiSet { + fn register(&self, runtime: &Runtime, config: &APIConfig) -> Result<()>; +} + +/// Adds enabled JS APIs to the provided [`Runtime`]. +/// +/// ## Example +/// ``` +/// # use anyhow::Error; +/// # use javy::Runtime; +/// # use javy_apis::APIConfig; +/// let runtime = Runtime::default(); +/// javy_apis::add_to_runtime(&runtime, APIConfig::default())?; +/// # Ok::<(), Error>(()) +/// ``` +pub fn add_to_runtime(runtime: &Runtime, config: APIConfig) -> Result<()> { + #[cfg(feature = "console")] + console::Console::new().register(runtime, &config)?; + #[cfg(feature = "random")] + random::Random.register(runtime, &config)?; + #[cfg(feature = "stream_io")] + stream_io::StreamIO.register(runtime, &config)?; + #[cfg(feature = "text_encoding")] + text_encoding::TextEncoding.register(runtime, &config)?; + http::Http.register(runtime, &config)?; + jsonnet::Jsonnet.register(runtime, &config)?; + + Ok(()) +} diff --git a/JS/wasm/crates/apis/src/random/mod.rs b/JS/wasm/crates/apis/src/random/mod.rs new file mode 100644 index 000000000..e7bbb5708 --- /dev/null +++ b/JS/wasm/crates/apis/src/random/mod.rs @@ -0,0 +1,37 @@ +use anyhow::Result; +use javy::{quickjs::JSValue, Runtime}; + +use crate::{APIConfig, JSApiSet}; + +pub struct Random; + +impl JSApiSet for Random { + fn register(&self, runtime: &Runtime, _config: &APIConfig) -> Result<()> { + let ctx = runtime.context(); + ctx.global_object()?.get_property("Math")?.set_property( + "random", + // TODO figure out if we can lazily initialize the PRNG + ctx.wrap_callback(|_ctx, _this, _args| Ok(JSValue::Float(fastrand::f64())))?, + )?; + Ok(()) + } +} + +#[cfg(test)] +mod tests { + use crate::{random::Random, APIConfig, JSApiSet}; + use anyhow::Result; + use javy::Runtime; + + #[test] + fn test_random() -> Result<()> { + let runtime = Runtime::default(); + Random.register(&runtime, &APIConfig::default())?; + let ctx = runtime.context(); + ctx.eval_global("test.js", "result = Math.random()")?; + let result = ctx.global_object()?.get_property("result")?.as_f64()?; + assert!(result >= 0.0); + assert!(result < 1.0); + Ok(()) + } +} diff --git a/JS/wasm/crates/apis/src/runtime_ext.rs b/JS/wasm/crates/apis/src/runtime_ext.rs new file mode 100644 index 000000000..d64915741 --- /dev/null +++ b/JS/wasm/crates/apis/src/runtime_ext.rs @@ -0,0 +1,35 @@ +use anyhow::Result; +use javy::{Config, Runtime}; + +use crate::APIConfig; + +/// A extension trait for [`Runtime`] that creates a [`Runtime`] with APIs +/// provided in this crate. +/// +/// ## Example +/// ``` +/// # use anyhow::Error; +/// use javy::Runtime; +/// use javy_apis::RuntimeExt; +/// let runtime = Runtime::new_with_defaults()?; +/// # Ok::<(), Error>(()) +/// ``` +pub trait RuntimeExt { + /// Creates a [`Runtime`] configured by the provided [`Config`] with JS + /// APIs added configured according to the [`APIConfig`]. + fn new_with_apis(config: Config, api_config: APIConfig) -> Result; + /// Creates a [`Runtime`] with JS APIs added with a default configuration. + fn new_with_defaults() -> Result; +} + +impl RuntimeExt for Runtime { + fn new_with_apis(config: Config, api_config: APIConfig) -> Result { + let runtime = Runtime::new(config)?; + crate::add_to_runtime(&runtime, api_config)?; + Ok(runtime) + } + + fn new_with_defaults() -> Result { + Self::new_with_apis(Config::default(), APIConfig::default()) + } +} diff --git a/JS/wasm/crates/apis/src/stream_io/io.js b/JS/wasm/crates/apis/src/stream_io/io.js new file mode 100644 index 000000000..8777c80a4 --- /dev/null +++ b/JS/wasm/crates/apis/src/stream_io/io.js @@ -0,0 +1,31 @@ +(function () { + const __javy_io_readSync = globalThis.__javy_io_readSync; + const __javy_io_writeSync = globalThis.__javy_io_writeSync; + globalThis.Javy.IO = { + readSync(fd, data) { + if (!(data instanceof Uint8Array)) { + throw TypeError("Data needs to be an Uint8Array"); + } + return __javy_io_readSync( + fd, + data.buffer, + data.byteOffset, + data.byteLength + ); + }, + writeSync(fd, data) { + if (!(data instanceof Uint8Array)) { + throw TypeError("Data needs to be an Uint8Array"); + } + return __javy_io_writeSync( + fd, + data.buffer, + data.byteOffset, + data.byteLength + ); + }, + }; + + Reflect.deleteProperty(globalThis, "__javy_io_readSync"); + Reflect.deleteProperty(globalThis, "__javy_io_writeSync"); +})(); diff --git a/JS/wasm/crates/apis/src/stream_io/mod.rs b/JS/wasm/crates/apis/src/stream_io/mod.rs new file mode 100644 index 000000000..abdf12176 --- /dev/null +++ b/JS/wasm/crates/apis/src/stream_io/mod.rs @@ -0,0 +1,68 @@ +use anyhow::Result; +use std::io::{Read, Write}; + +use javy::Runtime; + +use crate::{APIConfig, JSApiSet}; + +pub(super) struct StreamIO; + +impl JSApiSet for StreamIO { + fn register(&self, runtime: &Runtime, _config: &APIConfig) -> Result<()> { + let context = runtime.context(); + let global = context.global_object()?; + + let mut javy_object = global.get_property("Javy")?; + if javy_object.is_undefined() { + javy_object = context.object_value()?; + global.set_property("Javy", javy_object)?; + } + + global.set_property( + "__javy_io_writeSync", + context.wrap_callback(|_, _this_arg, args| { + let [fd, data, offset, length, ..] = args else { + anyhow::bail!("Invalid number of parameters"); + }; + + let mut fd: Box = match fd.try_into()? { + 1 => Box::new(std::io::stdout()), + 2 => Box::new(std::io::stderr()), + _ => anyhow::bail!("Only stdout and stderr are supported"), + }; + let data: Vec = data.try_into()?; + let offset: usize = offset.try_into()?; + let length: usize = length.try_into()?; + let data = &data[offset..(offset + length)]; + let n = fd.write(data)?; + fd.flush()?; + Ok(n.into()) + })?, + )?; + + global.set_property( + "__javy_io_readSync", + context.wrap_callback(|_, _this_arg, args| { + let [fd, data, offset, length, ..] = args else { + anyhow::bail!("Invalid number of parameters"); + }; + let mut fd: Box = match fd.try_into()? { + 0 => Box::new(std::io::stdin()), + _ => anyhow::bail!("Only stdin is supported"), + }; + let offset: usize = offset.try_into()?; + let length: usize = length.try_into()?; + if !data.is_array_buffer() { + anyhow::bail!("Data needs to be an ArrayBuffer"); + } + let data = data.as_bytes_mut()?; + let data = &mut data[offset..(offset + length)]; + let n = fd.read(data)?; + Ok(n.into()) + })?, + )?; + + context.eval_global("io.js", include_str!("io.js"))?; + Ok(()) + } +} diff --git a/JS/wasm/crates/apis/src/text_encoding/mod.rs b/JS/wasm/crates/apis/src/text_encoding/mod.rs new file mode 100644 index 000000000..7d8007647 --- /dev/null +++ b/JS/wasm/crates/apis/src/text_encoding/mod.rs @@ -0,0 +1,102 @@ +use std::{borrow::Cow, str}; + +use anyhow::{anyhow, Result}; +use javy::{ + quickjs::{JSContextRef, JSError, JSValue, JSValueRef}, + Runtime, +}; + +use crate::{APIConfig, JSApiSet}; + +pub(super) struct TextEncoding; + +impl JSApiSet for TextEncoding { + fn register(&self, runtime: &Runtime, _config: &APIConfig) -> Result<()> { + let context = runtime.context(); + let global = context.global_object()?; + global.set_property( + "__javy_decodeUtf8BufferToString", + context.wrap_callback(decode_utf8_buffer_to_js_string())?, + )?; + global.set_property( + "__javy_encodeStringToUtf8Buffer", + context.wrap_callback(encode_js_string_to_utf8_buffer())?, + )?; + + context.eval_global("text-encoding.js", include_str!("./text-encoding.js"))?; + Ok(()) + } +} + +fn decode_utf8_buffer_to_js_string( +) -> impl FnMut(&JSContextRef, JSValueRef, &[JSValueRef]) -> anyhow::Result { + move |_ctx: &JSContextRef, _this: JSValueRef, args: &[JSValueRef]| { + if args.len() != 5 { + return Err(anyhow!("Expecting 5 arguments, received {}", args.len())); + } + + let buffer: Vec = args[0].try_into()?; + let byte_offset: usize = args[1].try_into()?; + let byte_length: usize = args[2].try_into()?; + let fatal: bool = args[3].try_into()?; + let ignore_bom: bool = args[4].try_into()?; + + let mut view = buffer + .get(byte_offset..(byte_offset + byte_length)) + .ok_or_else(|| { + anyhow!("Provided offset and length is not valid for provided buffer") + })?; + + if !ignore_bom { + view = match view { + // [0xEF, 0xBB, 0xBF] is the UTF-8 BOM which we want to strip + [0xEF, 0xBB, 0xBF, rest @ ..] => rest, + _ => view, + }; + } + + let str = + if fatal { + Cow::from(str::from_utf8(view).map_err(|_| { + JSError::Type("The encoded data was not valid utf-8".to_string()) + })?) + } else { + String::from_utf8_lossy(view) + }; + Ok(str.to_string().into()) + } +} + +fn encode_js_string_to_utf8_buffer( +) -> impl FnMut(&JSContextRef, JSValueRef, &[JSValueRef]) -> anyhow::Result { + move |_ctx: &JSContextRef, _this: JSValueRef, args: &[JSValueRef]| { + if args.len() != 1 { + return Err(anyhow!("Expecting 1 argument, got {}", args.len())); + } + + let js_string: String = args[0].try_into()?; + Ok(js_string.into_bytes().into()) + } +} + +#[cfg(test)] +mod tests { + use crate::{APIConfig, JSApiSet}; + use anyhow::Result; + use javy::Runtime; + + use super::TextEncoding; + + #[test] + fn test_text_encoder_decoder() -> Result<()> { + let runtime = Runtime::default(); + let context = runtime.context(); + TextEncoding.register(&runtime, &APIConfig::default())?; + let result = context.eval_global( + "main", + "let encoder = new TextEncoder(); let buffer = encoder.encode('hello'); let decoder = new TextDecoder(); decoder.decode(buffer) == 'hello';" + )?; + assert!(result.as_bool()?); + Ok(()) + } +} diff --git a/JS/wasm/crates/apis/src/text_encoding/text-encoding.js b/JS/wasm/crates/apis/src/text_encoding/text-encoding.js new file mode 100644 index 000000000..f8c834d92 --- /dev/null +++ b/JS/wasm/crates/apis/src/text_encoding/text-encoding.js @@ -0,0 +1,66 @@ +(function () { + const __javy_decodeUtf8BufferToString = globalThis.__javy_decodeUtf8BufferToString; + const __javy_encodeStringToUtf8Buffer = globalThis.__javy_encodeStringToUtf8Buffer; + + class TextDecoder { + constructor(label = "utf-8", options = {}) { + label = label.trim().toLowerCase(); + const acceptedLabels = ["utf-8", "utf8", "unicode-1-1-utf-8", "unicode11utf8", "unicode20utf8", "x-unicode20utf8"]; + if (!acceptedLabels.includes(label)) { + // Not spec-compliant behaviour + throw new RangeError("The encoding label provided must be utf-8"); + } + Object.defineProperties(this, { + encoding: { value: "utf-8", enumerable: true, writable: false }, + fatal: { value: !!options.fatal, enumerable: true, writable: false }, + ignoreBOM: { value: !!options.ignoreBOM, enumerable: true, writable: false }, + }) + } + + decode(input, options = {}) { + if (input === undefined) { + return ""; + } + + if (options.stream) { + throw new Error("Streaming decode is not supported"); + } + + // backing buffer would not have byteOffset and may have different byteLength + let byteOffset = input.byteOffset || 0; + let byteLength = input.byteLength; + if (ArrayBuffer.isView(input)) { + input = input.buffer; + } + + if (!(input instanceof ArrayBuffer)) { + throw new TypeError("The provided value is not of type '(ArrayBuffer or ArrayBufferView)'"); + } + + return __javy_decodeUtf8BufferToString(input, byteOffset, byteLength, this.fatal, this.ignoreBOM); + } + } + + class TextEncoder { + constructor() { + Object.defineProperties(this, { + encoding: { value: "utf-8", enumerable: true, writable: false }, + }); + } + + encode(input = "") { + input = input.toString(); // non-string inputs are converted to strings + return new Uint8Array(__javy_encodeStringToUtf8Buffer(input)); + } + + encodeInto(source, destination) { + throw new Error("encodeInto is not supported"); + } + } + + globalThis.TextDecoder = TextDecoder; + globalThis.TextEncoder = TextEncoder; + + Reflect.deleteProperty(globalThis, "__javy_decodeUtf8BufferToString"); + Reflect.deleteProperty(globalThis, "__javy_encodeStringToUtf8Buffer"); +})(); diff --git a/JS/wasm/crates/arakoo-core/Cargo.toml b/JS/wasm/crates/arakoo-core/Cargo.toml new file mode 100644 index 000000000..92dc76e1a --- /dev/null +++ b/JS/wasm/crates/arakoo-core/Cargo.toml @@ -0,0 +1,25 @@ +[package] +name = "arakoo-core" +edition.workspace = true +version.workspace = true + +[[bin]] +name = "arakoo-core" +path = "src/main.rs" +[lib] +name = "javy_quickjs_provider" +crate-type = ["cdylib"] + +[dependencies] +anyhow = { workspace = true } +javy = { workspace = true, features = ["export_alloc_fns", "json"] } +once_cell = { workspace = true } +apis = { path = "../apis", features = [ + "console", + "text_encoding", + "random", + "stream_io", +] } +serde_json = { workspace = true } +[features] +experimental_event_loop = [] diff --git a/JS/wasm/crates/arakoo-core/src/execution.rs b/JS/wasm/crates/arakoo-core/src/execution.rs new file mode 100644 index 000000000..d03da0752 --- /dev/null +++ b/JS/wasm/crates/arakoo-core/src/execution.rs @@ -0,0 +1,86 @@ +use std::process; + +use anyhow::{bail, Error, Result}; +use apis::http::types::Response; +use javy::{json, quickjs::JSContextRef, Runtime}; + +pub fn run_bytecode(runtime: &Runtime, bytecode: &[u8]) { + let context = runtime.context(); + + context + .eval_binary(bytecode) + .and_then(|_| process_event_loop(context)) + .unwrap_or_else(handle_error); +} + +#[allow(dead_code)] +pub fn invoke_entrypoint( + runtime: &Runtime, + bytecode: &[u8], + input: String, +) -> anyhow::Result { + let context = runtime.context(); + + match context.eval_binary(bytecode) { + Ok(_) => {} + Err(e) => { + eprintln!("error"); + eprintln!("Error while running bytecode: {e}"); + return Err(e); + } + } + let global = context.global_object().unwrap(); + let entry_point = global.get_property("entrypoint").unwrap(); + + let request = input; + let input_bytes = request.as_bytes(); + let input_value = json::transcode_input(context, input_bytes).unwrap_or_else(|e| { + eprintln!("Error when transcoding input: {e}"); + process::abort(); + }); + entry_point + .call(&global, &[input_value]) + .and_then(|_| process_event_loop(context)) + .unwrap_or_else(handle_error); + + let global = context.global_object().unwrap(); + + let error = global.get_property("error").unwrap(); + let output = global.get_property("result").unwrap(); + + if !error.is_null_or_undefined() { + let error = error.to_string(); + eprintln!("Error while running JS: {error}"); + process::abort(); + } + let output = json::transcode_output(output).unwrap(); + let response: Response = serde_json::from_slice(&output).unwrap(); + Ok(response) +} + +pub fn invoke_function(runtime: &Runtime, fn_module: &str, fn_name: &str) { + let context = runtime.context(); + let js = if fn_name == "default" { + format!("import {{ default as defaultFn }} from '{fn_module}'; defaultFn();") + } else { + format!("import {{ {fn_name} }} from '{fn_module}'; {fn_name}();") + }; + context + .eval_module("runtime.mjs", &js) + .and_then(|_| process_event_loop(context)) + .unwrap_or_else(handle_error); +} + +fn process_event_loop(context: &JSContextRef) -> Result<()> { + if cfg!(feature = "experimental_event_loop") { + context.execute_pending()?; + } else if context.is_pending() { + bail!("Adding tasks to the event queue is not supported"); + } + Ok(()) +} + +fn handle_error(e: Error) { + eprintln!("Error while running JS: {e}"); + process::abort(); +} diff --git a/JS/wasm/crates/arakoo-core/src/lib.rs b/JS/wasm/crates/arakoo-core/src/lib.rs new file mode 100644 index 000000000..567aed64d --- /dev/null +++ b/JS/wasm/crates/arakoo-core/src/lib.rs @@ -0,0 +1,83 @@ +use javy::Runtime; +use once_cell::sync::OnceCell; +use std::slice; +use std::str; + +mod execution; +mod runtime; + +const FUNCTION_MODULE_NAME: &str = "function.mjs"; + +static mut COMPILE_SRC_RET_AREA: [u32; 2] = [0; 2]; +static mut RUNTIME: OnceCell = OnceCell::new(); + +/// Used by Wizer to preinitialize the module +#[export_name = "wizer.initialize"] +pub extern "C" fn init() { + let runtime = runtime::new_runtime().unwrap(); + unsafe { RUNTIME.set(runtime).unwrap() }; +} + +/// Compiles JS source code to QuickJS bytecode. +/// +/// Returns a pointer to a buffer containing a 32-bit pointer to the bytecode byte array and the +/// u32 length of the bytecode byte array. +/// +/// # Arguments +/// +/// * `js_src_ptr` - A pointer to the start of a byte array containing UTF-8 JS source code +/// * `js_src_len` - The length of the byte array containing JS source code +/// +/// # Safety +/// +/// * `js_src_ptr` must reference a valid array of unsigned bytes of `js_src_len` length +#[export_name = "compile_src"] +pub unsafe extern "C" fn compile_src(js_src_ptr: *const u8, js_src_len: usize) -> *const u32 { + // Use fresh runtime to avoid depending on Wizened runtime + let runtime = runtime::new_runtime().unwrap(); + let js_src = str::from_utf8(slice::from_raw_parts(js_src_ptr, js_src_len)).unwrap(); + let bytecode = runtime + .context() + .compile_module(FUNCTION_MODULE_NAME, js_src) + .unwrap(); + let bytecode_len = bytecode.len(); + // We need the bytecode buffer to live longer than this function so it can be read from memory + let bytecode_ptr = Box::leak(bytecode.into_boxed_slice()).as_ptr(); + COMPILE_SRC_RET_AREA[0] = bytecode_ptr as u32; + COMPILE_SRC_RET_AREA[1] = bytecode_len.try_into().unwrap(); + COMPILE_SRC_RET_AREA.as_ptr() +} + +/// Evaluates QuickJS bytecode +/// +/// # Safety +/// +/// * `bytecode_ptr` must reference a valid array of unsigned bytes of `bytecode_len` length +#[export_name = "eval_bytecode"] +pub unsafe extern "C" fn eval_bytecode(bytecode_ptr: *const u8, bytecode_len: usize) { + let runtime = RUNTIME.get().unwrap(); + let bytecode = slice::from_raw_parts(bytecode_ptr, bytecode_len); + execution::run_bytecode(runtime, bytecode); +} + +/// Evaluates QuickJS bytecode and invokes the exported JS function name. +/// +/// # Safety +/// +/// * `bytecode_ptr` must reference a valid array of bytes of `bytecode_len` +/// length. +/// * `fn_name_ptr` must reference a UTF-8 string with `fn_name_len` byte +/// length. +#[export_name = "invoke"] +pub unsafe extern "C" fn invoke( + bytecode_ptr: *const u8, + bytecode_len: usize, + fn_name_ptr: *const u8, + fn_name_len: usize, +) { + let runtime = RUNTIME.get().unwrap(); + let bytecode = slice::from_raw_parts(bytecode_ptr, bytecode_len); + let fn_name = str::from_utf8_unchecked(slice::from_raw_parts(fn_name_ptr, fn_name_len)); + execution::run_bytecode(runtime, bytecode); + execution::invoke_function(runtime, FUNCTION_MODULE_NAME, fn_name); +} diff --git a/JS/wasm/crates/arakoo-core/src/main.rs b/JS/wasm/crates/arakoo-core/src/main.rs new file mode 100644 index 000000000..70bc1b337 --- /dev/null +++ b/JS/wasm/crates/arakoo-core/src/main.rs @@ -0,0 +1,122 @@ +use javy::Runtime; +use once_cell::sync::OnceCell; + +use std::io; +use std::io::Read; +use std::slice; +use std::str; +use std::string::String; + +mod execution; +mod runtime; +use apis::http::types::Request; +const FUNCTION_MODULE_NAME: &str = "function.mjs"; + +static mut RUNTIME: OnceCell = OnceCell::new(); +static mut BYTECODE: OnceCell> = OnceCell::new(); + +#[link(wasm_import_module = "arakoo")] +extern "C" { + fn set_output(ptr: *const u8, len: i32); + fn get_request_len() -> i32; + fn get_request(ptr: *mut u8); +} + +#[export_name = "wizer.initialize"] +pub extern "C" fn init() { + let _wasm_ctx = WasmCtx::new(); + let runtime = runtime::new_runtime().unwrap(); + + let mut contents = String::new(); + io::stdin().read_to_string(&mut contents).unwrap(); + let bytecode = runtime + .context() + .compile_module("function.mjs", &contents) + .unwrap(); + + unsafe { + RUNTIME.set(runtime).unwrap(); + BYTECODE.set(bytecode).unwrap(); + } +} + +fn main() { + let bytecode = unsafe { BYTECODE.take().unwrap() }; + let runtime = unsafe { RUNTIME.take().unwrap() }; + execution::run_bytecode(&runtime, &bytecode); +} + +#[export_name = "run_entrypoint"] +pub fn run_entrypoint() { + let runtime = unsafe { RUNTIME.take().unwrap() }; + let bytecode = unsafe { BYTECODE.take().unwrap() }; + + let input_len = unsafe { get_request_len() }; + let mut input_buffer = Vec::with_capacity(input_len as usize); + let input_ptr = input_buffer.as_mut_ptr(); + + let input_buffer = unsafe { + get_request(input_ptr); + Vec::from_raw_parts(input_ptr, input_len as usize, input_len as usize) + }; + let request: Request = serde_json::from_slice(&input_buffer).unwrap(); + let request_string = serde_json::to_string(&request).unwrap(); + let result = execution::invoke_entrypoint(&runtime, &bytecode, request_string).unwrap(); + + let result_string = serde_json::to_string(&result).unwrap(); + + let len = result_string.len() as i32; + let result_ptr = result_string.as_ptr(); + unsafe { + set_output(result_ptr, len); + }; +} + +// Removed in post-processing. +/// Evaluates QuickJS bytecode and invokes the exported JS function name. +/// +/// # Safety +/// +/// * `fn_name_ptr` must reference a UTF-8 string with `fn_name_size` byte +/// length. +#[export_name = "javy.invoke"] +pub unsafe extern "C" fn invoke(fn_name_ptr: *mut u8, fn_name_size: usize) { + let _wasm_ctx = WasmCtx::new(); + + let js_fn_name = str::from_utf8_unchecked(slice::from_raw_parts(fn_name_ptr, fn_name_size)); + let runtime = unsafe { RUNTIME.take().unwrap() }; + execution::invoke_function(&runtime, FUNCTION_MODULE_NAME, js_fn_name); +} + +// RAII abstraction for calling Wasm ctors and dtors for exported non-main functions. +struct WasmCtx; + +impl WasmCtx { + #[must_use = "Failing to assign the return value will result in the wasm dtors being run immediately"] + fn new() -> Self { + unsafe { __wasm_call_ctors() }; + Self + } +} + +impl Drop for WasmCtx { + fn drop(&mut self) { + unsafe { __wasm_call_dtors() }; + } +} + +extern "C" { + // `__wasm_call_ctors` is generated by `wasm-ld` and invokes all of the global constructors. + // In a Rust bin crate, the `_start` function will invoke this implicitly but no other exported + // Wasm functions will invoke this. + // If this is not invoked, access to environment variables and directory preopens will not be + // available. + // This should only be invoked at the start of exported Wasm functions that are not the `main` + // function. + // References: + // - [Rust 1.67.0 stopped initializing the WASI environment for exported functions](https://github.com/rust-lang/rust/issues/107635) + // - [Wizer header in Fastly's JS compute runtime](https://github.com/fastly/js-compute-runtime/blob/main/runtime/js-compute-runtime/third_party/wizer.h#L92) + fn __wasm_call_ctors(); + + fn __wasm_call_dtors(); +} diff --git a/JS/wasm/crates/arakoo-core/src/runtime.rs b/JS/wasm/crates/arakoo-core/src/runtime.rs new file mode 100644 index 000000000..51c7591c0 --- /dev/null +++ b/JS/wasm/crates/arakoo-core/src/runtime.rs @@ -0,0 +1,9 @@ +use anyhow::Result; +use apis::{APIConfig, LogStream, RuntimeExt}; +use javy::{Config, Runtime}; + +pub fn new_runtime() -> Result { + let mut api_config = APIConfig::default(); + api_config.log_stream(LogStream::StdErr); + Runtime::new_with_apis(Config::default(), api_config) +} diff --git a/JS/wasm/crates/cli/Cargo.toml b/JS/wasm/crates/cli/Cargo.toml new file mode 100644 index 000000000..8c53d4d51 --- /dev/null +++ b/JS/wasm/crates/cli/Cargo.toml @@ -0,0 +1,50 @@ +[package] +name = "cli" +edition.workspace = true +version.workspace = true + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[[bin]] +name = "arakoo" +path = "src/main.rs" + +[features] +dump_wat = ["dep:wasmprinter"] +experimental_event_loop = [] + +[dependencies] +wizer = { workspace = true } +structopt = "0.3" +anyhow = { workspace = true } +binaryen = { git = "https://github.com/pepyakin/binaryen-rs", rev = "00c98174843f957681ba0bc5cdcc9d15f5d0cb23" } +brotli = "3.4.0" +wasmprinter = { version = "0.2.75", optional = true } +wasmtime = { workspace = true } +wasmtime-wasi = { workspace = true } +wasi-common = { workspace = true } +walrus = "0.20.3" +swc_core = { version = "0.87.19", features = [ + "common_sourcemap", + "ecma_ast", + "ecma_parser", +] } +wit-parser = "0.13.0" +convert_case = "0.6.0" +wat = "1.0.85" +serve = { path = "../serve" } +tokio = { version = "1.0" } + +[dev-dependencies] +serde_json = "1.0" +uuid = { version = "1.6", features = ["v4"] } +lazy_static = "1.4" +serde = { version = "1.0", default-features = false, features = ["derive"] } +criterion = "0.5" +num-format = "0.4.4" +tempfile = "3.9.0" +wasmparser = "0.118.1" + +[build-dependencies] +anyhow = "1.0.79" +wizer = { workspace = true } diff --git a/JS/wasm/crates/cli/build.rs b/JS/wasm/crates/cli/build.rs new file mode 100644 index 000000000..3bd70e472 --- /dev/null +++ b/JS/wasm/crates/cli/build.rs @@ -0,0 +1,91 @@ +use std::env; +use std::fs; +use std::io::{Read, Write}; + +use std::path::{Path, PathBuf}; + +use anyhow::Result; + +fn main() -> Result<()> { + if let Ok("cargo-clippy") = env::var("CARGO_CFG_FEATURE").as_ref().map(String::as_str) { + stub_javy_core_for_clippy() + } else { + copy_javy_core() + } +} + +// When using clippy, we need to write stubbed engine.wasm and provider.wasm files to ensure +// compilation succeeds. This skips building the actual engine.wasm and provider.wasm that would +// be injected into the CLI binary. +fn stub_javy_core_for_clippy() -> Result<()> { + let out_dir = PathBuf::from(env::var("OUT_DIR")?); + let engine_path = out_dir.join("engine.wasm"); + let provider_path = out_dir.join("provider.wasm"); + + if !engine_path.exists() { + std::fs::write(engine_path, [])?; + println!("cargo:warning=using stubbed engine.wasm for static analysis purposes..."); + } + + if !provider_path.exists() { + std::fs::write(provider_path, [])?; + println!("cargo:warning=using stubbed provider.wasm for static analysis purposes..."); + } + Ok(()) +} + +fn read_file(path: impl AsRef) -> Result> { + let mut buf: Vec = vec![]; + fs::File::open(path.as_ref())?.read_to_end(&mut buf)?; + Ok(buf) +} + +// Copy the engine binary build from the `core` crate +fn copy_javy_core() -> Result<()> { + let cargo_manifest_dir = env::var("CARGO_MANIFEST_DIR")?; + // let if build mode is release or debug + + let module_path = if cfg!(debug_assertions) { + PathBuf::from(&cargo_manifest_dir) + .parent() + .unwrap() + .parent() + .unwrap() + .join("../../target/wasm32-wasi/debug/") + } else { + PathBuf::from(&cargo_manifest_dir) + .parent() + .unwrap() + .parent() + .unwrap() + .join("../../target/wasm32-wasi/release/") + }; + + let engine_path = module_path.join("arakoo-core.wasm"); + let quickjs_provider_path = module_path.join("javy_quickjs_provider.wasm"); + let quickjs_provider_wizened_path = module_path.join("javy_quickjs_provider_wizened.wasm"); + + let mut wizer = wizer::Wizer::new(); + let wizened = wizer + .allow_wasi(true)? + .wasm_bulk_memory(true) + .run(read_file(&quickjs_provider_path)?.as_slice())?; + fs::File::create(&quickjs_provider_wizened_path)?.write_all(&wizened)?; + + println!("cargo:rerun-if-changed={}", engine_path.to_str().unwrap()); + println!( + "cargo:rerun-if-changed={}", + quickjs_provider_path.to_str().unwrap() + ); + println!("cargo:rerun-if-changed=build.rs"); + + if engine_path.exists() { + let out_dir = env::var("OUT_DIR")?; + let copied_engine_path = Path::new(&out_dir).join("engine.wasm"); + let copied_provider_path = Path::new(&out_dir).join("provider.wasm"); + + fs::copy(&engine_path, copied_engine_path)?; + fs::copy(&quickjs_provider_wizened_path, copied_provider_path)?; + } + Ok(()) +} diff --git a/JS/wasm/crates/cli/src/bytecode.rs b/JS/wasm/crates/cli/src/bytecode.rs new file mode 100644 index 000000000..abe4ec4ee --- /dev/null +++ b/JS/wasm/crates/cli/src/bytecode.rs @@ -0,0 +1,79 @@ +use anyhow::{anyhow, Result}; +use wasmtime::{Engine, Instance, Linker, Memory, Module, Store}; +use wasmtime_wasi::{WasiCtx, WasiCtxBuilder}; + +pub const QUICKJS_PROVIDER_MODULE: &[u8] = + include_bytes!(concat!(env!("OUT_DIR"), "/provider.wasm")); + +pub fn compile_source(js_source_code: &[u8]) -> Result> { + let (mut store, instance, memory) = create_wasm_env()?; + let (js_src_ptr, js_src_len) = + copy_source_code_into_instance(js_source_code, &mut store, &instance, &memory)?; + let ret_ptr = call_compile(js_src_ptr, js_src_len, &mut store, &instance)?; + let bytecode = copy_bytecode_from_instance(ret_ptr, &mut store, &memory)?; + Ok(bytecode) +} + +fn create_wasm_env() -> Result<(Store, Instance, Memory)> { + let engine = Engine::default(); + let module = Module::new(&engine, QUICKJS_PROVIDER_MODULE)?; + let mut linker = Linker::new(&engine); + wasmtime_wasi::snapshots::preview_1::add_wasi_snapshot_preview1_to_linker(&mut linker, |s| s)?; + let wasi = WasiCtxBuilder::new().inherit_stderr().build(); + let mut store = Store::new(&engine, wasi); + let instance = linker.instantiate(&mut store, &module)?; + let memory = instance.get_memory(&mut store, "memory").unwrap(); + Ok((store, instance, memory)) +} + +fn copy_source_code_into_instance( + js_source_code: &[u8], + mut store: &mut Store, + instance: &Instance, + memory: &Memory, +) -> Result<(u32, u32)> { + let realloc_fn = instance + .get_typed_func::<(u32, u32, u32, u32), u32>(&mut store, "canonical_abi_realloc")?; + let js_src_len = js_source_code.len().try_into()?; + + let original_ptr = 0; + let original_size = 0; + let alignment = 1; + let size = js_src_len; + let js_source_ptr = + realloc_fn.call(&mut store, (original_ptr, original_size, alignment, size))?; + + memory.write(&mut store, js_source_ptr.try_into()?, js_source_code)?; + + Ok((js_source_ptr, js_src_len)) +} + +fn call_compile( + js_src_ptr: u32, + js_src_len: u32, + mut store: &mut Store, + instance: &Instance, +) -> Result { + let compile_src_fn = instance.get_typed_func::<(u32, u32), u32>(&mut store, "compile_src")?; + let ret_ptr = compile_src_fn + .call(&mut store, (js_src_ptr, js_src_len)) + .map_err(|_| anyhow!("JS compilation failed"))?; + Ok(ret_ptr) +} + +fn copy_bytecode_from_instance( + ret_ptr: u32, + mut store: &mut Store, + memory: &Memory, +) -> Result> { + let mut ret_buffer = [0; 8]; + memory.read(&mut store, ret_ptr.try_into()?, &mut ret_buffer)?; + + let bytecode_ptr = u32::from_le_bytes(ret_buffer[0..4].try_into()?); + let bytecode_len = u32::from_le_bytes(ret_buffer[4..8].try_into()?); + + let mut bytecode = vec![0; bytecode_len.try_into()?]; + memory.read(&mut store, bytecode_ptr.try_into()?, &mut bytecode)?; + + Ok(bytecode) +} diff --git a/JS/wasm/crates/cli/src/commands.rs b/JS/wasm/crates/cli/src/commands.rs new file mode 100644 index 000000000..5a665a693 --- /dev/null +++ b/JS/wasm/crates/cli/src/commands.rs @@ -0,0 +1,72 @@ +use std::path::PathBuf; +use structopt::StructOpt; + +#[derive(Debug, StructOpt)] +#[structopt(name = "javy", about = "JavaScript to WebAssembly toolchain")] +pub enum Command { + /// Compiles JavaScript to WebAssembly. + Compile(CompileCommandOpts), + /// Emits the provider binary that is required to run dynamically + /// linked WebAssembly modules. + EmitProvider(EmitProviderCommandOpts), + Serve(ServeCommandOpts), +} + +#[derive(Debug, StructOpt)] +pub struct CompileCommandOpts { + #[structopt(parse(from_os_str))] + /// Path of the JavaScript input file. + pub input: PathBuf, + + #[structopt(short = "o", parse(from_os_str), default_value = "index.wasm")] + /// Desired path of the WebAssembly output file. + pub output: PathBuf, + + #[structopt(short = "d")] + /// Creates a smaller module that requires a dynamically linked QuickJS provider Wasm + /// module to execute (see `emit-provider` command). + pub dynamic: bool, + + #[structopt(long = "wit")] + /// Optional path to WIT file describing exported functions. + /// Only supports function exports with no arguments and no return values. + pub wit: Option, + + #[structopt(short = "n")] + /// Optional WIT world name for WIT file. Must be specified if WIT is file path is specified. + pub wit_world: Option, + + #[structopt(long = "no-source-compression")] + /// Disable source code compression, which reduces compile time at the expense of generating larger WebAssembly files. + pub no_source_compression: bool, +} + +#[derive(Debug, StructOpt)] +pub struct EmitProviderCommandOpts { + #[structopt(long = "out", short = "o")] + /// Output path for the provider binary (default is stdout). + pub out: Option, +} + +#[derive(Debug, StructOpt)] +pub struct ServeCommandOpts { + input: PathBuf, + #[structopt(short, long, default_value = "127.0.0.1")] + hostname: String, + #[structopt(short, long, default_value = "8080")] + port: u16, +} + +impl ServeCommandOpts { + /// The path to the service's Wasm binary. + pub fn input(&self) -> PathBuf { + PathBuf::from(&self.input) + } + + /// The address to bind the server to. + pub fn addr(&self) -> std::net::SocketAddr { + format!("{}:{}", self.hostname, self.port) + .parse() + .expect("Invalid address") + } +} diff --git a/JS/wasm/crates/cli/src/exports.rs b/JS/wasm/crates/cli/src/exports.rs new file mode 100644 index 000000000..19e5eb52d --- /dev/null +++ b/JS/wasm/crates/cli/src/exports.rs @@ -0,0 +1,48 @@ +use anyhow::{anyhow, Result}; +use convert_case::{Case, Casing}; +use std::{env, path::Path}; + +use crate::{js::JS, wit}; + +pub struct Export { + pub wit: String, + pub js: String, +} + +pub fn process_exports(js: &JS, wit: &Path, wit_world: &str) -> Result> { + let js_exports = js.exports()?; + parse_wit_exports(wit, wit_world)? + .into_iter() + .map(|wit_export| { + let export = wit_export.from_case(Case::Kebab).to_case(Case::Camel); + if !js_exports.contains(&export) { + Err(anyhow!("JS module does not export {export}")) + } else { + Ok(Export { + wit: wit_export, + js: export, + }) + } + }) + .collect::>>() +} + +fn parse_wit_exports(wit: &Path, wit_world: &str) -> Result> { + // Configure wit-parser to not require semicolons but only if the relevant + // environment variable is not already set. + const SEMICOLONS_OPTIONAL_ENV_VAR: &str = "WIT_REQUIRE_SEMICOLONS"; + let semicolons_env_var_already_set = env::var(SEMICOLONS_OPTIONAL_ENV_VAR).is_ok(); + if !semicolons_env_var_already_set { + env::set_var(SEMICOLONS_OPTIONAL_ENV_VAR, "0"); + } + + let exports = wit::parse_exports(wit, wit_world); + + // If we set the environment variable to not require semicolons, remove + // that environment variable now that we no longer need it set. + if !semicolons_env_var_already_set { + env::remove_var(SEMICOLONS_OPTIONAL_ENV_VAR); + } + + exports +} diff --git a/JS/wasm/crates/cli/src/js.rs b/JS/wasm/crates/cli/src/js.rs new file mode 100644 index 000000000..c0f47fbfd --- /dev/null +++ b/JS/wasm/crates/cli/src/js.rs @@ -0,0 +1,317 @@ +/// Higher-level representation of JavaScript. +/// +/// This is intended to be used to derive different representations of source +/// code. For example, as a byte array, a string, QuickJS bytecode, compressed +/// bytes, or attributes of the source code like what it exports. +use std::{ + collections::HashMap, + fs::File, + io::{Cursor, Read}, + path::Path, + rc::Rc, +}; + +use anyhow::{anyhow, bail, Context, Result}; +use brotli::enc::{self, BrotliEncoderParams}; +use swc_core::{ + common::{FileName, SourceMap}, + ecma::{ + ast::{ + Decl, EsVersion, ExportDecl, ExportSpecifier, Module, ModuleDecl, ModuleExportName, + ModuleItem, Stmt, + }, + parser::{self, EsConfig, Syntax}, + }, +}; + +use crate::bytecode; + +#[derive(Clone, Debug)] +pub struct JS { + source_code: Rc, +} + +impl JS { + fn from_string(source_code: String) -> JS { + JS { + source_code: Rc::new(source_code), + } + } + + pub fn from_file(path: &Path) -> Result { + let mut input_file = File::open(path) + .with_context(|| format!("Failed to open input file {}", path.display()))?; + let mut contents: Vec = vec![]; + input_file.read_to_end(&mut contents)?; + Ok(Self::from_string(String::from_utf8(contents)?)) + } + + pub fn as_bytes(&self) -> &[u8] { + self.source_code.as_bytes() + } + + pub fn compile(&self) -> Result> { + bytecode::compile_source(self.source_code.as_bytes()) + } + + pub fn compress(&self) -> Result> { + let mut compressed_source_code: Vec = vec![]; + enc::BrotliCompress( + &mut Cursor::new(&self.source_code.as_bytes()), + &mut compressed_source_code, + &BrotliEncoderParams { + quality: 11, + ..Default::default() + }, + )?; + Ok(compressed_source_code) + } + + pub fn exports(&self) -> Result> { + let module = self.parse_module()?; + + // function foo() ... + let mut functions = HashMap::new(); + // export { foo, bar as baz } + let mut named_exports = vec![]; + // export function foo() ... + let mut exported_functions = vec![]; + for item in module.body { + match item { + ModuleItem::ModuleDecl(ModuleDecl::ExportDecl(ExportDecl { + decl: Decl::Fn(f), + .. + })) => { + if !f.function.params.is_empty() { + bail!("Exported functions with parameters are not supported"); + } + if f.function.is_generator { + bail!("Exported generators are not supported"); + } + exported_functions.push(f.ident.sym); + } + ModuleItem::ModuleDecl(ModuleDecl::ExportNamed(e)) => { + for specifier in e.specifiers { + if let ExportSpecifier::Named(n) = specifier { + let orig = match n.orig { + ModuleExportName::Ident(i) => i.sym, + ModuleExportName::Str(s) => s.value, + }; + let exported_name = n.exported.map(|e| match e { + ModuleExportName::Ident(i) => i.sym, + ModuleExportName::Str(s) => s.value, + }); + named_exports.push((orig, exported_name)); + } + } + } + ModuleItem::ModuleDecl(ModuleDecl::ExportDefaultDecl(e)) if e.decl.is_fn_expr() => { + exported_functions.push("default".into()) + } + ModuleItem::ModuleDecl(ModuleDecl::ExportDefaultExpr(e)) if e.expr.is_arrow() => { + exported_functions.push("default".into()) + } + ModuleItem::Stmt(Stmt::Decl(Decl::Fn(f))) => { + functions.insert( + f.ident.sym, + (f.function.params.is_empty(), f.function.is_generator), + ); + } + _ => continue, + } + } + + let mut named_exported_functions = named_exports + .into_iter() + .filter_map(|(orig, exported)| { + if let Some((no_params, is_generator)) = functions.get(&orig) { + if !no_params { + Some(Err(anyhow!( + "Exported functions with parameters are not supported" + ))) + } else if *is_generator { + Some(Err(anyhow!("Exported generators are not supported"))) + } else { + Some(Ok(exported.unwrap_or(orig))) + } + } else { + None + } + }) + .collect::, _>>()?; + exported_functions.append(&mut named_exported_functions); + Ok(exported_functions + .into_iter() + .map(|f| f.to_string()) + .collect()) + } + + fn parse_module(&self) -> Result { + let source_map: SourceMap = Default::default(); + let file = source_map.new_source_file_from(FileName::Anon, self.source_code.clone()); + let mut errors = vec![]; + parser::parse_file_as_module( + &file, + Syntax::Es(EsConfig::default()), + EsVersion::Es2020, + None, + &mut errors, + ) + .map_err(|e| anyhow!(e.into_kind().msg())) + .with_context(|| "Invalid JavaScript") + } +} + +#[cfg(test)] +mod tests { + use crate::js::JS; + + use anyhow::Result; + + #[test] + fn parse_no_exports() -> Result<()> { + let exports = parse("function foo() {}")?; + assert_eq!(Vec::<&str>::default(), exports); + Ok(()) + } + + #[test] + fn parse_invalid_js() -> Result<()> { + let res = parse("fun foo() {}"); + assert_eq!("Invalid JavaScript", res.err().unwrap().to_string()); + Ok(()) + } + + #[test] + fn parse_one_func_export() -> Result<()> { + let exports = parse("export function foo() {}")?; + assert_eq!(vec!["foo"], exports); + Ok(()) + } + + #[test] + fn parse_func_export_with_parameter() -> Result<()> { + let res = parse("export function foo(bar) {}"); + assert_eq!( + "Exported functions with parameters are not supported", + res.err().unwrap().to_string() + ); + Ok(()) + } + + #[test] + fn parse_generator_export() -> Result<()> { + let res = parse("export function *foo() {}"); + assert_eq!( + "Exported generators are not supported", + res.err().unwrap().to_string() + ); + Ok(()) + } + + #[test] + fn parse_two_func_exports() -> Result<()> { + let exports = parse("export function foo() {}; export function bar() {};")?; + assert_eq!(vec!["foo", "bar"], exports); + Ok(()) + } + + #[test] + fn parse_const_export() -> Result<()> { + let exports = parse("export const x = 1;")?; + let expected_exports: Vec<&str> = vec![]; + assert_eq!(expected_exports, exports); + Ok(()) + } + + #[test] + fn parse_const_export_and_func_export() -> Result<()> { + let exports = parse("export const x = 1; export function foo() {}")?; + assert_eq!(vec!["foo"], exports); + Ok(()) + } + + #[test] + fn parse_named_func_export() -> Result<()> { + let exports = parse("function foo() {}; export { foo };")?; + assert_eq!(vec!["foo"], exports); + Ok(()) + } + + #[test] + fn parse_named_func_export_with_arg() -> Result<()> { + let res = parse("function foo(bar) {}; export { foo };"); + assert_eq!( + "Exported functions with parameters are not supported", + res.err().unwrap().to_string() + ); + Ok(()) + } + + #[test] + fn parse_funcs_with_args() -> Result<()> { + let exports = parse("function foo(bar) {}")?; + assert_eq!(Vec::<&str>::default(), exports); + Ok(()) + } + + #[test] + fn parse_named_func_export_and_const_export() -> Result<()> { + let exports = parse("function foo() {}; const bar = 1; export { foo, bar };")?; + assert_eq!(vec!["foo"], exports); + Ok(()) + } + + #[test] + fn parse_func_export_and_named_func_export() -> Result<()> { + let exports = parse("export function foo() {}; function bar() {}; export { bar };")?; + assert_eq!(vec!["foo", "bar"], exports); + Ok(()) + } + + #[test] + fn parse_renamed_func_export() -> Result<()> { + let exports = parse("function foo() {}; export { foo as bar };")?; + assert_eq!(vec!["bar"], exports); + Ok(()) + } + + #[test] + fn parse_hoisted_func_export() -> Result<()> { + let exports = parse("export { foo }; function foo() {}")?; + assert_eq!(vec!["foo"], exports); + Ok(()) + } + + #[test] + fn parse_renamed_hosted_func_export() -> Result<()> { + let exports = parse("export { foo as bar }; function foo() {}")?; + assert_eq!(vec!["bar"], exports); + Ok(()) + } + + #[test] + fn parse_hoisted_exports_with_func_and_const() -> Result<()> { + let exports = parse("export { foo, bar }; function foo() {}; const bar = 1;")?; + assert_eq!(vec!["foo"], exports); + Ok(()) + } + + #[test] + fn parse_default_arrow_export() -> Result<()> { + let exports = parse("export default () => {}")?; + assert_eq!(vec!["default"], exports); + Ok(()) + } + + #[test] + fn parse_default_function_export() -> Result<()> { + let exports = parse("export default function() {}")?; + assert_eq!(vec!["default"], exports); + Ok(()) + } + + fn parse(js: &str) -> Result> { + JS::from_string(js.to_string()).exports() + } +} diff --git a/JS/wasm/crates/cli/src/main.rs b/JS/wasm/crates/cli/src/main.rs new file mode 100644 index 000000000..d06673fbb --- /dev/null +++ b/JS/wasm/crates/cli/src/main.rs @@ -0,0 +1,56 @@ +mod bytecode; +mod commands; +mod exports; +mod js; +mod wasm_generator; +mod wit; + +use crate::commands::{Command, EmitProviderCommandOpts}; +use crate::wasm_generator::r#static as static_generator; +use anyhow::{bail, Result}; +use js::JS; +use std::fs; +use std::fs::File; +use std::io::Write; +use structopt::StructOpt; +use wasm_generator::dynamic as dynamic_generator; + +#[tokio::main] +async fn main() -> Result<()> { + let cmd = Command::from_args(); + + match &cmd { + Command::EmitProvider(opts) => emit_provider(opts), + Command::Compile(opts) => { + let js = JS::from_file(&opts.input)?; + let exports = match (&opts.wit, &opts.wit_world) { + (None, None) => Ok(vec![]), + (None, Some(_)) => Ok(vec![]), + (Some(_), None) => bail!("Must provide WIT world when providing WIT file"), + (Some(wit), Some(world)) => exports::process_exports(&js, wit, world), + }?; + let wasm = if opts.dynamic { + dynamic_generator::generate(&js, exports, opts.no_source_compression)? + } else { + static_generator::generate(&js, exports, opts.no_source_compression)? + }; + fs::write(&opts.output, wasm)?; + Ok(()) + } + Command::Serve(opts) => { + serve::WorkerCtx::new(opts.input())? + .serve(opts.addr()) + .await?; + Ok(()) + } + } +} + +fn emit_provider(opts: &EmitProviderCommandOpts) -> Result<()> { + let mut file: Box = match opts.out.as_ref() { + Some(path) => Box::new(File::create(path)?), + _ => Box::new(std::io::stdout()), + }; + file.write_all(bytecode::QUICKJS_PROVIDER_MODULE)?; + Ok(()) +} diff --git a/JS/wasm/crates/cli/src/wasm_generator/dynamic.rs b/JS/wasm/crates/cli/src/wasm_generator/dynamic.rs new file mode 100644 index 000000000..a89455a1e --- /dev/null +++ b/JS/wasm/crates/cli/src/wasm_generator/dynamic.rs @@ -0,0 +1,193 @@ +use crate::{exports::Export, js::JS}; + +use super::transform::{self, SourceCodeSection}; +use anyhow::Result; +use walrus::{DataKind, FunctionBuilder, Module, ValType}; + +// Run the calling code with the `dump_wat` feature enabled to print the WAT to stdout +// +// For the example generated WAT, the `bytecode_len` is 137 +// (module +// (type (;0;) (func)) +// (type (;1;) (func (param i32 i32))) +// (type (;2;) (func (param i32 i32 i32 i32))) +// (type (;3;) (func (param i32 i32 i32 i32) (result i32))) +// (import "javy_quickjs_provider_v1" "canonical_abi_realloc" (func (;0;) (type 3))) +// (import "javy_quickjs_provider_v1" "eval_bytecode" (func (;1;) (type 1))) +// (import "javy_quickjs_provider_v1" "memory" (memory (;0;) 0)) +// (import "javy_quickjs_provider_v1" "invoke" (func (;2;) (type 2))) +// (func (;3;) (type 0) +// (local i32 i32) +// i32.const 0 +// i32.const 0 +// i32.const 1 +// i32.const 137 +// call 0 +// local.tee 0 +// i32.const 0 +// i32.const 137 +// memory.init 0 +// data.drop 0 +// i32.const 0 +// i32.const 0 +// i32.const 1 +// i32.const 3 +// call 0 +// local.tee 1 +// i32.const 0 +// i32.const 3 +// memory.init 1 +// data.drop 1 +// local.get 0 +// i32.const 137 +// local.get 1 +// i32.const 3 +// call 2 +// ) +// (func (;4;) (type 0) +// (local i32) +// i32.const 0 +// i32.const 0 +// i32.const 1 +// i32.const 137 +// call 0 +// local.tee 0 +// i32.const 0 +// i32.const 137 +// memory.init 0 +// local.get 0 +// i32.const 137 +// call 1 +// ) +// (export "_start" (func 4)) +// (export "foo" (func 3)) +// (data (;0;) "\02\05\18function.mjs\06foo\0econsole\06log\06bar\0f\bc\03\00\01\00\00\be\03\00\00\0e\00\06\01\a0\01\00\00\00\03\01\01\1a\00\be\03\00\01\08\ea\05\c0\00\e1)8\e0\00\00\00B\e1\00\00\00\04\e2\00\00\00$\01\00)\bc\03\01\04\01\00\07\0a\0eC\06\01\be\03\00\00\00\03\00\00\13\008\e0\00\00\00B\e1\00\00\00\04\df\00\00\00$\01\00)\bc\03\01\02\03]") +// (data (;1;) "foo") +// ) +pub fn generate( + js: &JS, + exported_functions: Vec, + no_source_compression: bool, +) -> Result> { + let mut module = Module::with_config(transform::module_config()); + + const IMPORT_NAMESPACE: &str = "javy_quickjs_provider_v1"; + + let canonical_abi_realloc_type = module.types.add( + &[ValType::I32, ValType::I32, ValType::I32, ValType::I32], + &[ValType::I32], + ); + let (canonical_abi_realloc_fn, _) = module.add_import_func( + IMPORT_NAMESPACE, + "canonical_abi_realloc", + canonical_abi_realloc_type, + ); + + let eval_bytecode_type = module.types.add(&[ValType::I32, ValType::I32], &[]); + let (eval_bytecode_fn, _) = + module.add_import_func(IMPORT_NAMESPACE, "eval_bytecode", eval_bytecode_type); + + let (memory, _) = module.add_import_memory(IMPORT_NAMESPACE, "memory", false, 0, None); + + transform::add_producers_section(&mut module.producers); + if no_source_compression { + module.customs.add(SourceCodeSection::uncompressed(js)?); + } else { + module.customs.add(SourceCodeSection::compressed(js)?); + } + + let bytecode = js.compile()?; + let bytecode_len: i32 = bytecode.len().try_into()?; + let bytecode_data = module.data.add(DataKind::Passive, bytecode); + + let mut main = FunctionBuilder::new(&mut module.types, &[], &[]); + let bytecode_ptr_local = module.locals.add(ValType::I32); + main.func_body() + // Allocate memory in javy_quickjs_provider for bytecode array. + .i32_const(0) // orig ptr + .i32_const(0) // orig size + .i32_const(1) // alignment + .i32_const(bytecode_len) // new size + .call(canonical_abi_realloc_fn) + // Copy bytecode array into allocated memory. + .local_tee(bytecode_ptr_local) // save returned address to local and set as dest addr for mem.init + .i32_const(0) // offset into data segment for mem.init + .i32_const(bytecode_len) // size to copy from data segment + // top-2: dest addr, top-1: offset into source, top-0: size of memory region in bytes. + .memory_init(memory, bytecode_data) + // Evaluate bytecode. + .local_get(bytecode_ptr_local) // ptr to bytecode + .i32_const(bytecode_len) + .call(eval_bytecode_fn); + let main = main.finish(vec![], &mut module.funcs); + + module.exports.add("_start", main); + + if !exported_functions.is_empty() { + let invoke_type = module.types.add( + &[ValType::I32, ValType::I32, ValType::I32, ValType::I32], + &[], + ); + let (invoke_fn, _) = module.add_import_func(IMPORT_NAMESPACE, "invoke", invoke_type); + + let fn_name_ptr_local = module.locals.add(ValType::I32); + for export in exported_functions { + // For each JS function export, add an export that copies the name of the function into memory and invokes it. + let js_export_bytes = export.js.as_bytes(); + let js_export_len: i32 = js_export_bytes.len().try_into().unwrap(); + let fn_name_data = module.data.add(DataKind::Passive, js_export_bytes.to_vec()); + + let mut export_fn = FunctionBuilder::new(&mut module.types, &[], &[]); + export_fn + .func_body() + // Copy bytecode. + .i32_const(0) // orig ptr + .i32_const(0) // orig len + .i32_const(1) // alignment + .i32_const(bytecode_len) // size to copy + .call(canonical_abi_realloc_fn) + .local_tee(bytecode_ptr_local) + .i32_const(0) // offset into data segment + .i32_const(bytecode_len) // size to copy + .memory_init(memory, bytecode_data) // copy bytecode into allocated memory + .data_drop(bytecode_data) + // Copy function name. + .i32_const(0) // orig ptr + .i32_const(0) // orig len + .i32_const(1) // alignment + .i32_const(js_export_len) // new size + .call(canonical_abi_realloc_fn) + .local_tee(fn_name_ptr_local) + .i32_const(0) // offset into data segment + .i32_const(js_export_len) // size to copy + .memory_init(memory, fn_name_data) // copy fn name into allocated memory + .data_drop(fn_name_data) + // Call invoke. + .local_get(bytecode_ptr_local) + .i32_const(bytecode_len) + .local_get(fn_name_ptr_local) + .i32_const(js_export_len) + .call(invoke_fn); + let export_fn = export_fn.finish(vec![], &mut module.funcs); + module.exports.add(&export.wit, export_fn); + } + } + + let wasm = module.emit_wasm(); + print_wat(&wasm)?; + Ok(wasm) +} + +#[cfg(feature = "dump_wat")] +fn print_wat(wasm_binary: &[u8]) -> Result<()> { + println!( + "Generated WAT: \n{}", + wasmprinter::print_bytes(&wasm_binary)? + ); + Ok(()) +} + +#[cfg(not(feature = "dump_wat"))] +fn print_wat(_wasm_binary: &[u8]) -> Result<()> { + Ok(()) +} diff --git a/JS/wasm/crates/cli/src/wasm_generator/mod.rs b/JS/wasm/crates/cli/src/wasm_generator/mod.rs new file mode 100644 index 000000000..186453527 --- /dev/null +++ b/JS/wasm/crates/cli/src/wasm_generator/mod.rs @@ -0,0 +1,3 @@ +pub mod dynamic; +pub mod r#static; +mod transform; diff --git a/JS/wasm/crates/cli/src/wasm_generator/static.rs b/JS/wasm/crates/cli/src/wasm_generator/static.rs new file mode 100644 index 000000000..14440b494 --- /dev/null +++ b/JS/wasm/crates/cli/src/wasm_generator/static.rs @@ -0,0 +1,143 @@ +use std::{collections::HashMap, rc::Rc, sync::OnceLock}; + +use anyhow::{anyhow, Result}; +use binaryen::{CodegenConfig, Module}; +use walrus::{DataKind, ExportItem, FunctionBuilder, FunctionId, MemoryId, ValType}; +use wasi_common::{pipe::ReadPipe, WasiCtx}; +use wasmtime::Linker; +use wasmtime_wasi::WasiCtxBuilder; +use wizer::Wizer; + +use crate::{exports::Export, js::JS}; + +use super::transform::{self, SourceCodeSection}; + +static mut WASI: OnceLock = OnceLock::new(); + +pub fn generate(js: &JS, exports: Vec, no_source_compression: bool) -> Result> { + let wasm = include_bytes!(concat!(env!("OUT_DIR"), "/engine.wasm")); + + let wasi = WasiCtxBuilder::new() + .stdin(Box::new(ReadPipe::from(js.as_bytes()))) + .inherit_stdout() + .inherit_stderr() + .build(); + // We can't move the WasiCtx into `make_linker` since WasiCtx doesn't implement the `Copy` trait. + // So we move the WasiCtx into a mutable static OnceLock instead. + // Setting the value in the `OnceLock` and getting the reference back from it should be safe given + // we're never executing this code concurrently. This code will also fail if `generate` is invoked + // more than once per execution. + if unsafe { WASI.set(wasi) }.is_err() { + panic!("Failed to set WASI static variable") + } + + let wasm = Wizer::new() + .make_linker(Some(Rc::new(|engine| { + let mut linker = Linker::new(engine); + wasmtime_wasi::add_to_linker(&mut linker, |_ctx: &mut Option| { + unsafe { WASI.get_mut() }.unwrap() + })?; + Ok(linker) + })))? + .wasm_bulk_memory(true) + .run(wasm) + .map_err(|_| anyhow!("JS compilation failed"))?; + + let mut module = transform::module_config().parse(&wasm)?; + + let (realloc, free, invoke, memory) = { + let mut exports = HashMap::new(); + for export in module.exports.iter() { + exports.insert(export.name.as_str(), export); + } + ( + *exports.get("canonical_abi_realloc").unwrap(), + *exports.get("canonical_abi_free").unwrap(), + *exports.get("javy.invoke").unwrap(), + *exports.get("memory").unwrap(), + ) + }; + + let realloc_export = realloc.id(); + let free_export = free.id(); + let invoke_export = invoke.id(); + + if !exports.is_empty() { + let ExportItem::Function(realloc_fn) = realloc.item else { + unreachable!() + }; + let ExportItem::Function(invoke_fn) = invoke.item else { + unreachable!() + }; + let ExportItem::Memory(memory) = memory.item else { + unreachable!() + }; + export_exported_js_functions(&mut module, realloc_fn, invoke_fn, memory, exports); + } + + // We no longer need these exports so remove them. + module.exports.delete(realloc_export); + module.exports.delete(free_export); + module.exports.delete(invoke_export); + + let wasm = module.emit_wasm(); + + let codegen_cfg = CodegenConfig { + optimization_level: 3, // Aggressively optimize for speed. + shrink_level: 0, // Don't optimize for size at the expense of performance. + debug_info: false, + }; + + let mut module = Module::read(&wasm) + .map_err(|_| anyhow!("Unable to read wasm binary for wasm-opt optimizations"))?; + module.optimize(&codegen_cfg); + module + .run_optimization_passes(vec!["strip"], &codegen_cfg) + .map_err(|_| anyhow!("Running wasm-opt optimization passes failed"))?; + let wasm = module.write(); + + let mut module = transform::module_config().parse(&wasm)?; + if no_source_compression { + module.customs.add(SourceCodeSection::uncompressed(js)?); + } else { + module.customs.add(SourceCodeSection::compressed(js)?); + } + transform::add_producers_section(&mut module.producers); + Ok(module.emit_wasm()) +} + +fn export_exported_js_functions( + module: &mut walrus::Module, + realloc_fn: FunctionId, + invoke_fn: FunctionId, + memory: MemoryId, + js_exports: Vec, +) { + let ptr_local = module.locals.add(ValType::I32); + for export in js_exports { + println!("Exporting JS function: {}", export.js); + // For each JS function export, add an export that copies the name of the function into memory and invokes it. + let js_export_bytes = export.js.as_bytes(); + let js_export_len: i32 = js_export_bytes.len().try_into().unwrap(); + let fn_name_data = module.data.add(DataKind::Passive, js_export_bytes.to_vec()); + + let mut export_fn = FunctionBuilder::new(&mut module.types, &[], &[]); + export_fn + .func_body() + .i32_const(0) // orig ptr + .i32_const(0) // orig len + .i32_const(1) // alignment + .i32_const(js_export_len) // new size + .call(realloc_fn) + .local_tee(ptr_local) + .i32_const(0) // offset into data segment + .i32_const(js_export_len) // size to copy + .memory_init(memory, fn_name_data) // copy fn name into allocated memory + .data_drop(fn_name_data) + .local_get(ptr_local) + .i32_const(js_export_len) + .call(invoke_fn); + let export_fn = export_fn.finish(vec![], &mut module.funcs); + module.exports.add(&export.wit, export_fn); + } +} diff --git a/JS/wasm/crates/cli/src/wasm_generator/transform.rs b/JS/wasm/crates/cli/src/wasm_generator/transform.rs new file mode 100644 index 000000000..68023dcbd --- /dev/null +++ b/JS/wasm/crates/cli/src/wasm_generator/transform.rs @@ -0,0 +1,47 @@ +use std::borrow::Cow; + +use anyhow::Result; +use walrus::{CustomSection, IdsToIndices, ModuleConfig, ModuleProducers}; + +use crate::js::JS; + +#[derive(Debug)] +pub struct SourceCodeSection { + source_code: Vec, +} + +impl SourceCodeSection { + pub fn compressed(js: &JS) -> Result { + Ok(SourceCodeSection { + source_code: js.compress()?, + }) + } + + pub fn uncompressed(js: &JS) -> Result { + Ok(SourceCodeSection { + source_code: js.as_bytes().to_vec(), + }) + } +} + +impl CustomSection for SourceCodeSection { + fn name(&self) -> &str { + "javy_source" + } + + fn data(&self, _ids_to_indices: &IdsToIndices) -> Cow<[u8]> { + (&self.source_code).into() + } +} + +pub fn module_config() -> ModuleConfig { + let mut config = ModuleConfig::new(); + config.generate_name_section(false); + config +} + +pub fn add_producers_section(producers: &mut ModuleProducers) { + producers.clear(); // removes Walrus and Rust + producers.add_language("JavaScript", "ES2020"); + producers.add_processed_by("Javy", env!("CARGO_PKG_VERSION")); +} diff --git a/JS/wasm/crates/cli/src/wit.rs b/JS/wasm/crates/cli/src/wit.rs new file mode 100644 index 000000000..027dc22da --- /dev/null +++ b/JS/wasm/crates/cli/src/wit.rs @@ -0,0 +1,35 @@ +use std::path::Path; + +use anyhow::{bail, Result}; + +use wit_parser::{Resolve, UnresolvedPackage, WorldItem}; + +pub fn parse_exports(wit: impl AsRef, world: &str) -> Result> { + let mut resolve = Resolve::default(); + let package = UnresolvedPackage::parse_path(wit.as_ref())?; + resolve.push(package)?; + let (_, package_id) = resolve.package_names.first().unwrap(); + let world_id = resolve.select_world(*package_id, Some(world))?; + let world = resolve.worlds.get(world_id).unwrap(); + + if !world.imports.is_empty() { + bail!("Imports in WIT file are not supported"); + } + let mut exported_functions = vec![]; + for (_, export) in &world.exports { + match export { + WorldItem::Interface(_) => bail!("Exported interfaces are not supported"), + WorldItem::Function(f) => { + if !f.params.is_empty() { + bail!("Exported functions with parameters are not supported") + } else if f.results.len() != 0 { + bail!("Exported functions with return values are not supported") + } else { + exported_functions.push(f.name.clone()) + } + } + WorldItem::Type(_) => bail!("Exported types are not supported"), + } + } + Ok(exported_functions) +} diff --git a/JS/wasm/crates/serve/Cargo.toml b/JS/wasm/crates/serve/Cargo.toml new file mode 100644 index 000000000..509102172 --- /dev/null +++ b/JS/wasm/crates/serve/Cargo.toml @@ -0,0 +1,22 @@ +[package] +name = "serve" +edition.workspace = true +version.workspace = true + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[dependencies] +wasi-common = { workspace = true } +wasmtime = { workspace = true } +wasmtime-wasi = { workspace = true } +anyhow = { workspace = true } +serde = { workspace = true } +serde_json = "1" +tokio = { version = "1.21.2", features = ["full"] } +tracing = "0.1.37" +hyper = { version = "0.14.26", features = ["full"] } +futures = "0.3.24" +tracing-subscriber = { version = "^0.3.18", features = ["env-filter", "fmt"] } +jrsonnet-evaluator = { version = "0.5.0-pre95" } +jrsonnet-parser = { version = "0.5.0-pre95" } +jrsonnet-stdlib = { version = "0.5.0-pre95" } +reqwest = { version = "0.11", features = ["json"] } diff --git a/JS/wasm/crates/serve/src/binding.rs b/JS/wasm/crates/serve/src/binding.rs new file mode 100644 index 000000000..0ed50769e --- /dev/null +++ b/JS/wasm/crates/serve/src/binding.rs @@ -0,0 +1,270 @@ +use std::sync::{Arc, Mutex}; + +use jrsonnet_evaluator::{ + apply_tla, + function::TlaArg, + gc::GcHashMap, + manifest::{JsonFormat, ManifestFormat}, + tb, + trace::{CompactFormat, PathResolver, TraceFormat}, + FileImportResolver, State, Val, +}; +use jrsonnet_parser::IStr; +use jrsonnet_stdlib::ContextInitializer; + +use tokio::runtime::Builder; +use tracing::error; +use wasi_common::WasiCtx; +use wasmtime::*; + +use crate::io::{WasmInput, WasmOutput}; + +pub struct VM { + state: State, + manifest_format: Box, + trace_format: Box, + tla_args: GcHashMap, +} +/// Adds exported functions to the Wasm linker. +/// +/// This function wraps the `jsonnet_evaluate`, `jsonnet_output_len`, and `jsonnet_output` +/// functions to be called from WebAssembly. It sets up the necessary state and +/// memory management for evaluating Jsonnet code and writing the output back to +/// WebAssembly memory. +pub fn add_jsonnet_to_linker(linker: &mut Linker) -> anyhow::Result<()> { + // Create a shared output buffer that will be used to store the result of the Jsonnet evaluation. + let output: Arc> = Arc::new(Mutex::new(String::new())); + let output_clone = output.clone(); + + // Wrap the `jsonnet_evaluate` function to be called from WebAssembly. + linker.func_wrap( + "arakoo", + "jsonnet_evaluate", + move |mut caller: Caller<'_, WasiCtx>, + var_ptr: i32, + var_len: i32, + path_ptr: i32, + code_len: i32| { + // Clone the output buffer for use within the closure. + let output = output_clone.clone(); + // Get the WebAssembly memory instance. + let mem = match caller.get_export("memory") { + Some(Extern::Memory(mem)) => mem, + _ => return Err(Trap::NullReference.into()), + }; + // Calculate the offsets for the variable and path buffers in WebAssembly memory. + let var_offset = var_ptr as u32 as usize; + let path_offset = path_ptr as u32 as usize; + // Create buffers to read the variable and path data from WebAssembly memory. + let mut var_buffer = vec![0; var_len as usize]; + let mut path_buffer = vec![0; code_len as usize]; + + // Read the path data from WebAssembly memory and convert it to a string. + let path = match mem.read(&caller, path_offset, &mut path_buffer) { + Ok(_) => match std::str::from_utf8(&path_buffer) { + Ok(s) => s, + Err(_) => return Err(Trap::BadSignature.into()), + }, + _ => return Err(Trap::MemoryOutOfBounds.into()), + }; + // Read the variable data from WebAssembly memory and convert it to a string. + let var = match mem.read(&caller, var_offset, &mut var_buffer) { + Ok(_) => match std::str::from_utf8(&var_buffer) { + Ok(s) => s, + Err(_) => return Err(Trap::BadSignature.into()), + }, + _ => return Err(Trap::MemoryOutOfBounds.into()), + }; + // Parse the variable data as JSON. + let var_json: serde_json::Value = match serde_json::from_str(var) { + Ok(v) => v, + Err(e) => { + error!("Error parsing var: {}", e); + return Err(Trap::BadSignature.into()); + } + }; + + // Initialize the Jsonnet VM state with default settings. + let state = State::default(); + state.settings_mut().import_resolver = tb!(FileImportResolver::default()); + state.settings_mut().context_initializer = tb!(ContextInitializer::new( + state.clone(), + PathResolver::new_cwd_fallback(), + )); + // Create the Jsonnet VM with the default settings. + let vm = VM { + state, + manifest_format: Box::new(JsonFormat::default()), + trace_format: Box::new(CompactFormat::default()), + tla_args: GcHashMap::default(), + }; + + // Evaluate the Jsonnet code snippet using the provided path and variables. + let code = path; + let any_initializer = vm.state.context_initializer(); + let context = any_initializer + .as_any() + .downcast_ref::() + .unwrap(); + for (key, value) in var_json.as_object().unwrap() { + context.add_ext_var(key.into(), Val::Str(value.as_str().unwrap().into())); + } + let out = match vm + .state + .evaluate_snippet("snippet", code) + .and_then(|val| apply_tla(vm.state.clone(), &vm.tla_args, val)) + .and_then(|val| val.manifest(&vm.manifest_format)) + { + Ok(v) => v, + Err(e) => { + error!("Error evaluating snippet: {}", e); + let mut out = String::new(); + vm.trace_format.write_trace(&mut out, &e).unwrap(); + out + } + }; + // Store the output of the Jsonnet evaluation in the shared output buffer. + let mut output = output.lock().unwrap(); + *output = out; + Ok(()) + }, + )?; + + // Wrap the `jsonnet_output_len` function to be called from WebAssembly. + // This function returns the length of the output string. + let output_clone = output.clone(); + linker.func_wrap("arakoo", "jsonnet_output_len", move || -> i32 { + let output_clone = output_clone.clone(); + let output = output_clone.lock().unwrap().clone(); + output.len() as i32 + })?; + + // Wrap the `jsonnet_output` function to be called from WebAssembly. + // This function writes the output string to the specified memory location. + linker.func_wrap( + "arakoo", + "jsonnet_output", + move |mut caller: Caller<'_, WasiCtx>, ptr: i32| { + let output_clone = output.clone(); + let mem = match caller.get_export("memory") { + Some(Extern::Memory(mem)) => mem, + _ => return Err(Trap::NullReference.into()), + }; + let offset = ptr as u32 as usize; + let out = output_clone.lock().unwrap().clone(); + match mem.write(&mut caller, offset, out.as_bytes()) { + Ok(_) => {} + _ => return Err(Trap::MemoryOutOfBounds.into()), + }; + Ok(()) + }, + )?; + + Ok(()) +} + +pub fn add_fetch_to_linker(linker: &mut Linker) -> anyhow::Result<()> { + let response: Arc> = Arc::new(Mutex::new(String::new())); + let error: Arc> = Arc::new(Mutex::new(String::new())); + + let response_clone = response.clone(); + let error_clone = error.clone(); + linker.func_wrap( + "arakoo", + "fetch", + move |mut caller: Caller<'_, WasiCtx>, request_ptr: i32, request_len: i32| { + let response_arc = response_clone.clone(); + let error = error_clone.clone(); + let mem = match caller.get_export("memory") { + Some(Extern::Memory(mem)) => mem, + _ => { + let mut error = error.lock().unwrap(); + *error = "Memory not found".to_string(); + return Err(Trap::NullReference.into()); + } + }; + let request_offset = request_ptr as u32 as usize; + let mut request_buffer = vec![0; request_len as usize]; + let request = match mem.read(&caller, request_offset, &mut request_buffer) { + Ok(_) => match std::str::from_utf8(&request_buffer) { + Ok(s) => s.to_string(), // Clone the string here + Err(_) => { + let mut error = error.lock().unwrap(); + *error = "Bad signature".to_string(); + return Err(Trap::BadSignature.into()); + } + }, + _ => { + let mut error = error.lock().unwrap(); + *error = "Memory out of bounds".to_string(); + return Err(Trap::MemoryOutOfBounds.into()); + } + }; + + let thread_result = std::thread::spawn(move || { + Builder::new_current_thread() + .enable_all() + .build() + .unwrap() + .block_on(async { + let request: WasmInput = match serde_json::from_str(&request) { + Ok(r) => r, + Err(e) => { + return Err(anyhow::anyhow!("Error parsing request: {}", e)); + } + }; + let method: reqwest::Method = match request.method().parse() { + Ok(m) => m, + Err(_) => { + return Err(anyhow::anyhow!( + "Invalid method: {}", + request.method() + )); + } + }; + let client = reqwest::Client::new(); + let mut builder = client.request(method, request.url()); + let header = request.headers(); + for (k, v) in header { + builder = builder.header(k, v); + } + builder = builder.body(request.body().to_string()); + match builder.send().await { + Ok(r) => { + let response = WasmOutput::from_reqwest_response(r).await?; + Ok(response) + } + Err(e) => { + error!("Error sending request: {}", e); + return Err(anyhow::anyhow!("Error sending request: {}", e)); + } + } + }) + }) + .join(); + let response = match thread_result { + Ok(Ok(r)) => r, + Ok(Err(e)) => { + let mut error = error.lock().unwrap(); + *error = format!("Error sending request: {}", e); + error!("Error sending request: {}", e); + return Err(Trap::BadSignature.into()); + } + Err(_) => { + let mut error = error.lock().unwrap(); + *error = "Error sending request: thread join error".to_string(); + error!("Error sending request: thread join error"); + return Err(Trap::BadSignature.into()); + } + }; + + let res = serde_json::to_string(&response).unwrap(); + let mut response = response_arc.lock().unwrap(); + *response = res; + Ok(()) + }, + )?; + // add the fetch_output_len and fetch_output functions here + // also add the fetch_error_len and fetch_error functions here + Ok(()) +} diff --git a/JS/wasm/crates/serve/src/io.rs b/JS/wasm/crates/serve/src/io.rs new file mode 100644 index 000000000..8aaad3f0d --- /dev/null +++ b/JS/wasm/crates/serve/src/io.rs @@ -0,0 +1,131 @@ +use std::collections::HashMap; + +use hyper::{header::HOST, http::request::Parts, HeaderMap, Uri}; +use serde::{Deserialize, Serialize}; + +#[derive(Serialize, Deserialize, Debug)] +pub struct WasmInput<'a> { + url: String, + method: &'a str, + headers: HashMap, + body: &'a str, + params: HashMap, +} + +#[derive(Deserialize, Debug, Clone, Serialize)] +pub struct WasmOutput { + pub headers: HashMap, + pub status: u16, + #[serde(rename = "statusText")] + pub status_text: String, + body: Option, +} + +impl<'a> WasmInput<'a> { + pub fn new(request: &'a Parts, body: &'a str) -> Self { + let mut params = HashMap::new(); + + if let Some(query) = request.uri.query() { + for pair in query.split('&') { + let mut parts = pair.split('='); + let key = parts.next().unwrap(); + let value = parts.next().unwrap(); + params.insert(key.to_string(), value.to_string()); + } + } + + let url = Self::build_url(request); + + Self { + url, + method: request.method.as_str(), + headers: Self::build_headers_hash(&request.headers), + body, + params, + } + } + + pub fn url(&self) -> &str { + &self.url + } + + pub fn method(&self) -> &str { + self.method + } + + pub fn headers(&self) -> &HashMap { + &self.headers + } + + pub fn body(&self) -> &str { + self.body + } + + pub fn params(&self) -> &HashMap { + &self.params + } + + fn build_url(request: &Parts) -> String { + Uri::builder() + .scheme("http") + .authority(request.headers.get(HOST).unwrap().to_str().unwrap()) + .path_and_query(request.uri.path_and_query().unwrap().clone()) + .build() + .unwrap() + .to_string() + } + + fn build_headers_hash(headers: &HeaderMap) -> HashMap { + let mut parsed_headers = HashMap::new(); + + for (key, value) in headers.iter() { + parsed_headers.insert( + String::from(key.as_str()), + String::from(value.to_str().unwrap()), + ); + } + + parsed_headers + } +} +impl WasmOutput { + pub fn body(&self) -> String { + self.body.clone().unwrap_or_default() + } + + pub(crate) fn new() -> Self { + Self { + headers: HashMap::new(), + status: 200, + status_text: "OK".to_string(), + body: Some(String::new()), + } + } + + pub async fn from_reqwest_response(response: reqwest::Response) -> anyhow::Result { + let headers = response.headers().clone(); + let status = response.status().as_u16(); + let status_text = response.status().to_string(); + let body = response.text().await?; + + Ok(Self { + headers: Self::build_headers_hash(&headers), + status, + status_text, + body: Some(body), + }) + } + + fn build_headers_hash(headers: &reqwest::header::HeaderMap) -> HashMap { + let mut parsed_headers = HashMap::new(); + + for (key, value) in headers.iter() { + parsed_headers.insert( + key.as_str().to_string(), + value.to_str().unwrap_or_default().to_string(), + ); + } + + parsed_headers + } +} diff --git a/JS/wasm/crates/serve/src/lib.rs b/JS/wasm/crates/serve/src/lib.rs new file mode 100644 index 000000000..805306d8e --- /dev/null +++ b/JS/wasm/crates/serve/src/lib.rs @@ -0,0 +1,315 @@ +// mod binding; +mod binding; +mod io; + +use std::{ + convert::Infallible, + env, + future::Future, + net::SocketAddr, + path::Path, + pin::Pin, + str::FromStr, + sync::{Arc, Mutex}, + task::{self, Poll}, +}; + +use binding::add_fetch_to_linker; +// use binding::add_exports_to_linker; +use futures::future::{self, Ready}; +use hyper::{ + header::{HeaderName, HeaderValue}, + http::request::Parts, + server::conn::AddrStream, + service::Service, + Body, Request, Response, +}; + +use tracing::{error, event, info, Level}; +use tracing_subscriber::{filter::EnvFilter, FmtSubscriber}; +use wasi_common::WasiCtx; +use wasmtime_wasi::WasiCtxBuilder; + +use wasmtime::{Caller, Config, Engine, Extern, Linker, Module, Store, Trap, WasmBacktraceDetails}; + +use crate::{ + binding::add_jsonnet_to_linker, + io::{WasmInput, WasmOutput}, +}; + +#[derive(Clone)] +pub struct RequestService { + worker_ctx: WorkerCtx, +} + +impl RequestService { + /// Create a new request service. + fn new(ctx: WorkerCtx) -> Self { + Self { worker_ctx: ctx } + } +} + +#[derive(Clone)] +pub struct WorkerCtx { + engine: Engine, + module: Module, +} + +impl WorkerCtx { + pub fn new(module_path: impl AsRef) -> anyhow::Result { + tracing_subscriber(); + info!("Loading module from {:?}", module_path.as_ref()); + let mut binding = Config::default(); + let config = binding.async_support(true); + // check if env has debug flag + if env::var("DEBUG").is_ok() { + config + .debug_info(true) + .wasm_backtrace(true) + .coredump_on_trap(true) // Enable core dumps on trap + .wasm_backtrace_details(WasmBacktraceDetails::Enable); + } + + let engine = Engine::new(&config)?; + let module = Module::from_file(&engine, module_path)?; + + Ok(Self { engine, module }) + } + + pub fn module(&self) -> &Module { + &self.module + } + + pub fn engine(&self) -> &Engine { + &self.engine + } + pub async fn serve(self, addr: SocketAddr) -> Result<(), hyper::Error> { + info!("Starting server ..."); + let server = hyper::Server::bind(&addr).serve(self); + event!(Level::INFO, "Listening on http://{}", server.local_addr()); + server.await?; + Ok(()) + } + + pub async fn handle_request( + &self, + request: hyper::Request, + ) -> anyhow::Result<(Response, Option)> { + let (parts, body) = request.into_parts(); + info!("Handling request: {:?} {:?}", parts.method, parts.uri); + let body = hyper::body::to_bytes(body).await.unwrap(); + let body_str = String::from_utf8_lossy(&body).to_string(); + let result = self.run(&parts, &body_str).await; + match result { + Ok(output) => { + let mut response = Response::builder(); + response = response.status(output.status); + + let headers = output.headers.clone(); + let headers_vec: Vec<(String, String)> = headers + .into_iter() + .map(|(k, v)| (k.to_owned(), v.to_owned())) + .collect(); + headers_vec.iter().for_each(|(key, value)| { + response.headers_mut().unwrap().insert( + HeaderName::from_str(key).unwrap(), + HeaderValue::from_str(value).unwrap(), + ); + }); + + let response = response.body(Body::from(output.body())).unwrap(); + Ok((response, None)) + } + + Err(e) => { + error!("Error: {}", e); + let response = Response::builder() + .status(500) + .body(Body::from("Internal Server Error")) + .unwrap(); + Ok((response, Some(e))) + } + } + } + + /// Runs the WebAssembly module with the provided request parts and body. + /// + /// This function sets up the necessary state and memory management for running the WebAssembly + /// module, including setting up the input and output buffers, and wrapping the necessary + /// functions to be called from WebAssembly. + async fn run(&self, parts: &Parts, body: &str) -> anyhow::Result { + // Serialize the request parts and body into a JSON input for the WebAssembly module. + let input = serde_json::to_vec(&WasmInput::new(parts, body)).unwrap(); + let mem_len = input.len() as i32; + + // Create a new linker with the WASI context. + let mut linker: Linker = Linker::new(self.engine()); + wasmtime_wasi::add_to_linker(&mut linker, |ctx| ctx)?; + + // Wrap the `get_request_len` function to be called from WebAssembly. + // This function returns the length of the input buffer. + linker.func_wrap("arakoo", "get_request_len", move || -> i32 { mem_len })?; + + // Wrap the `get_request` function to be called from WebAssembly. + // This function writes the input buffer to the specified memory location. + match linker.func_wrap( + "arakoo", + "get_request", + move |mut caller: Caller<'_, WasiCtx>, ptr: i32| { + let mem = match caller.get_export("memory") { + Some(Extern::Memory(mem)) => mem, + _ => return Err(Trap::NullReference.into()), + }; + let offset = ptr as u32 as usize; + match mem.write(&mut caller, offset, &input) { + Ok(_) => {} + _ => return Err(Trap::MemoryOutOfBounds.into()), + }; + Ok(()) + }, + ) { + Ok(_) => {} + Err(e) => { + println!("Error adding get_request: {}", e); + } + } + + // Create a shared output buffer that will be used to store the result of the WebAssembly execution. + let output: Arc> = Arc::new(Mutex::new(WasmOutput::new())); + let output_clone = output.clone(); + + // Wrap the `set_output` function to be called from WebAssembly. + // This function reads the output buffer from the specified memory location and updates the shared output buffer. + linker.func_wrap( + "arakoo", + "set_output", + move |mut caller: Caller<'_, WasiCtx>, ptr: i32, len: i32| { + let output = output_clone.clone(); + let mem = match caller.get_export("memory") { + Some(Extern::Memory(mem)) => mem, + _ => return Err(Trap::NullReference.into()), + }; + let offset = ptr as u32 as usize; + let mut buffer = vec![0; len as usize]; + match mem.read(&caller, offset, &mut buffer) { + Ok(_) => match serde_json::from_slice::(&buffer) { + Ok(parsed_output) => { + let mut output = output.lock().unwrap(); + *output = parsed_output; + Ok(()) + } + Err(_e) => Err(Trap::BadSignature.into()), + }, + _ => Err(Trap::MemoryOutOfBounds.into()), + } + }, + )?; + + // Add additional exports to the linker, such as Jsonnet evaluation functions. + add_jsonnet_to_linker(&mut linker)?; + add_fetch_to_linker(&mut linker)?; + + // Create a WASI context builder with inherited standard output and error streams. + let wasi_builder = WasiCtxBuilder::new() + .inherit_stdout() + .inherit_stderr() + .build(); + + // Create a new store with the WASI context. + let mut store = Store::new(self.engine(), wasi_builder); + + // Instantiate the WebAssembly module with the linker and store. + linker.module(&mut store, "", self.module())?; + + // Get the entrypoint function from the WebAssembly instance and call it. + let instance = linker + .instantiate_async(&mut store, self.module()) + .await + .map_err(anyhow::Error::msg)?; + let run_entrypoint_fn = instance.get_typed_func::<(), ()>(&mut store, "run_entrypoint")?; + run_entrypoint_fn + .call_async(&mut store, ()) + .await + .map_err(anyhow::Error::msg)?; + + // Drop the store to release resources. + drop(store); + + // Lock the output buffer and return a clone of the result. + let output = output.lock().unwrap().clone(); + Ok(output) + } + fn make_service(&self) -> RequestService { + RequestService::new(self.clone()) + } +} + +impl<'addr> Service<&'addr AddrStream> for WorkerCtx { + type Response = RequestService; + type Error = Infallible; + type Future = Ready>; + + fn poll_ready(&mut self, _cx: &mut task::Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, _addr: &'addr AddrStream) -> Self::Future { + future::ok(self.make_service()) + } +} + +impl Service> for RequestService { + type Response = Response; + type Error = anyhow::Error; + #[allow(clippy::type_complexity)] + type Future = Pin> + Send>>; + + fn poll_ready(&mut self, _cx: &mut task::Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, req: Request) -> Self::Future { + let ctx = self.worker_ctx.clone(); + + Box::pin(async move { ctx.handle_request(req).await.map(|result| result.0) }) + } +} + +fn tracing_subscriber() { + let verbosity = match env::var("RUST_LOG_VERBOSITY") { + Ok(s) => s.parse().unwrap_or(0), + Err(_) => 0, + }; + + if env::var("RUST_LOG").ok().is_none() { + match verbosity { + 0 => env::set_var("RUST_LOG", "info"), + 1 => env::set_var("RUST_LOG", "debug"), + _ => env::set_var("RUST_LOG", "trace"), + } + } + + // Build a subscriber, using the default `RUST_LOG` environment variable for our filter. + let builder = FmtSubscriber::builder() + .with_writer(std::io::stderr) + .with_env_filter(EnvFilter::from_default_env()) + .with_ansi(true) + .with_target(false); + + match env::var("RUST_LOG_PRETTY") { + // If the `RUST_LOG_PRETTY` environment variable is set to "true", we should emit logs in a + // pretty, human-readable output format. + Ok(s) if s == "true" => builder + .pretty() + // Show levels, because ANSI escape sequences are normally used to indicate this. + .with_level(true) + .init(), + // Otherwise, we should install the subscriber without any further additions. + _ => builder.with_ansi(false).init(), + } + event!( + Level::DEBUG, + "RUST_LOG set to '{}'", + env::var("RUST_LOG").unwrap_or_else(|_| String::from("")) + ); +} diff --git a/JS/wasm/crates/wasmjs-engine/.gitignore b/JS/wasm/crates/wasmjs-engine/.gitignore deleted file mode 100644 index a404254d7..000000000 --- a/JS/wasm/crates/wasmjs-engine/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -target/ -**/node_modules/ \ No newline at end of file diff --git a/JS/wasm/crates/wasmjs-engine/Cargo.lock b/JS/wasm/crates/wasmjs-engine/Cargo.lock deleted file mode 100644 index f950d0ccb..000000000 --- a/JS/wasm/crates/wasmjs-engine/Cargo.lock +++ /dev/null @@ -1,1205 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "aho-corasick" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" -dependencies = [ - "memchr", -] - -[[package]] -name = "anyhow" -version = "1.0.76" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59d2a3357dde987206219e78ecfbbb6e8dad06cbb65292758d3270e6254f7355" - -[[package]] -name = "async-trait" -version = "0.1.75" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdf6721fb0140e4f897002dd086c06f6c27775df19cfe1fccb21181a48fd2c98" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.42", -] - -[[package]] -name = "autocfg" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" - -[[package]] -name = "bindgen" -version = "0.64.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4243e6031260db77ede97ad86c27e501d646a27ab57b59a574f725d98ab1fb4" -dependencies = [ - "bitflags 1.3.2", - "cexpr", - "clang-sys", - "lazy_static", - "lazycell", - "log", - "peeking_take_while", - "proc-macro2", - "quote", - "regex", - "rustc-hash", - "shlex", - "syn 1.0.109", - "which", -] - -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "bitflags" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" - -[[package]] -name = "bytes" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" - -[[package]] -name = "cc" -version = "1.0.83" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" -dependencies = [ - "libc", -] - -[[package]] -name = "cexpr" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" -dependencies = [ - "nom", -] - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "clang-sys" -version = "1.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c688fc74432808e3eb684cae8830a86be1d66a2bd58e1f248ed0960a590baf6f" -dependencies = [ - "glob", - "libc", - "libloading", -] - -[[package]] -name = "core-foundation" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "core-foundation-sys" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" - -[[package]] -name = "either" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" - -[[package]] -name = "errno" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" -dependencies = [ - "libc", - "windows-sys 0.52.0", -] - -[[package]] -name = "fastrand" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" - -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - -[[package]] -name = "foreign-types" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -dependencies = [ - "foreign-types-shared", -] - -[[package]] -name = "foreign-types-shared" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" - -[[package]] -name = "futures-channel" -version = "0.3.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "164713a5a0dcc3e7b4b1ed7d3b433cabc18025386f9339346e8daf15963cf7ac" -dependencies = [ - "futures-core", -] - -[[package]] -name = "futures-core" -version = "0.3.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86d7a0c1aa76363dac491de0ee99faf6941128376f1cf96f07db7603b7de69dd" - -[[package]] -name = "futures-task" -version = "0.3.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd65540d33b37b16542a0438c12e6aeead10d4ac5d05bd3f805b8f35ab592879" - -[[package]] -name = "futures-util" -version = "0.3.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ef6b17e481503ec85211fed8f39d1970f128935ca1f814cd32ac4a6842e84ab" -dependencies = [ - "futures-core", - "futures-task", - "pin-project-lite", - "pin-utils", -] - -[[package]] -name = "glob" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" - -[[package]] -name = "heck" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" -dependencies = [ - "unicode-segmentation", -] - -[[package]] -name = "home" -version = "0.5.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" -dependencies = [ - "windows-sys 0.52.0", -] - -[[package]] -name = "http" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" -dependencies = [ - "bytes", - "fnv", - "itoa", -] - -[[package]] -name = "http-body" -version = "1.0.0-rc.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "951dfc2e32ac02d67c90c0d65bd27009a635dc9b381a2cc7d284ab01e3a0150d" -dependencies = [ - "bytes", - "http", -] - -[[package]] -name = "http-body-util" -version = "0.1.0-rc.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92445bc9cc14bfa0a3ce56817dc3b5bcc227a168781a356b702410789cec0d10" -dependencies = [ - "bytes", - "futures-util", - "http", - "http-body", - "pin-project-lite", -] - -[[package]] -name = "httparse" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" - -[[package]] -name = "httpdate" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" - -[[package]] -name = "hyper" -version = "1.0.0-rc.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b75264b2003a3913f118d35c586e535293b3e22e41f074930762929d071e092" -dependencies = [ - "bytes", - "futures-channel", - "futures-core", - "futures-util", - "http", - "http-body", - "httparse", - "httpdate", - "itoa", - "pin-project-lite", - "tokio", - "tracing", - "want", -] - -[[package]] -name = "id-arena" -version = "2.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25a2bc672d1148e28034f176e01fffebb08b35768468cc954630da77a1449005" - -[[package]] -name = "itoa" -version = "1.0.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" - -[[package]] -name = "javy" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82bea151527df24f765b795a87a80d144f8cc35ef99acaed99465f1206a4501e" -dependencies = [ - "anyhow", - "quickjs-wasm-rs", - "serde-transcode", - "serde_json", -] - -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - -[[package]] -name = "lazycell" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" - -[[package]] -name = "libc" -version = "0.2.151" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" - -[[package]] -name = "libloading" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" -dependencies = [ - "cfg-if", - "winapi", -] - -[[package]] -name = "linux-raw-sys" -version = "0.4.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" - -[[package]] -name = "log" -version = "0.4.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" - -[[package]] -name = "memchr" -version = "2.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" - -[[package]] -name = "minimal-lexical" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" - -[[package]] -name = "mio" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b9d9a46eff5b4ff64b45a9e316a6d1e0bc719ef429cbec4dc630684212bfdf9" -dependencies = [ - "libc", - "log", - "wasi", - "windows-sys 0.45.0", -] - -[[package]] -name = "native-tls" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" -dependencies = [ - "lazy_static", - "libc", - "log", - "openssl", - "openssl-probe", - "openssl-sys", - "schannel", - "security-framework", - "security-framework-sys", - "tempfile", -] - -[[package]] -name = "nom" -version = "7.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" -dependencies = [ - "memchr", - "minimal-lexical", -] - -[[package]] -name = "once_cell" -version = "1.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" - -[[package]] -name = "openssl" -version = "0.10.61" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b8419dc8cc6d866deb801274bba2e6f8f6108c1bb7fcc10ee5ab864931dbb45" -dependencies = [ - "bitflags 2.4.1", - "cfg-if", - "foreign-types", - "libc", - "once_cell", - "openssl-macros", - "openssl-sys", -] - -[[package]] -name = "openssl-macros" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "openssl-probe" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" - -[[package]] -name = "openssl-sys" -version = "0.9.97" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3eaad34cdd97d81de97964fc7f29e2d104f483840d906ef56daa1912338460b" -dependencies = [ - "cc", - "libc", - "pkg-config", - "vcpkg", -] - -[[package]] -name = "peeking_take_while" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" - -[[package]] -name = "pin-project-lite" -version = "0.2.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - -[[package]] -name = "pkg-config" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69d3587f8a9e599cc7ec2c00e331f71c4e69a5f9a4b8a6efd5b07466b9736f9a" - -[[package]] -name = "proc-macro2" -version = "1.0.70" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "pulldown-cmark" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffade02495f22453cd593159ea2f59827aae7f53fa8323f756799b670881dcf8" -dependencies = [ - "bitflags 1.3.2", - "memchr", - "unicase", -] - -[[package]] -name = "quickjs-wasm-rs" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "174a4fb51c14dcb82f1f98ec1ec3c2f26f2cd6e40f200d86c5f6eecacf40b409" -dependencies = [ - "anyhow", - "once_cell", - "quickjs-wasm-sys", - "serde", -] - -[[package]] -name = "quickjs-wasm-sys" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1af9a5eb35f2df97dc9816b711e681b0c3cc8f5c18fdd7df0021ec4f60bbcb4" -dependencies = [ - "anyhow", - "bindgen", - "bytes", - "cc", - "futures-core", - "futures-task", - "futures-util", - "http-body-util", - "hyper", - "mio", - "native-tls", - "openssl-macros", - "tokio", - "tokio-macros", - "tokio-native-tls", - "walkdir", -] - -[[package]] -name = "quote" -version = "1.0.33" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "redox_syscall" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" -dependencies = [ - "bitflags 1.3.2", -] - -[[package]] -name = "regex" -version = "1.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", -] - -[[package]] -name = "regex-automata" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" - -[[package]] -name = "rustc-hash" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" - -[[package]] -name = "rustix" -version = "0.38.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72e572a5e8ca657d7366229cdde4bd14c4eb5499a9573d4d366fe1b599daa316" -dependencies = [ - "bitflags 2.4.1", - "errno", - "libc", - "linux-raw-sys", - "windows-sys 0.52.0", -] - -[[package]] -name = "ryu" -version = "1.0.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" - -[[package]] -name = "same-file" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "schannel" -version = "0.1.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" -dependencies = [ - "windows-sys 0.48.0", -] - -[[package]] -name = "security-framework" -version = "2.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" -dependencies = [ - "bitflags 1.3.2", - "core-foundation", - "core-foundation-sys", - "libc", - "security-framework-sys", -] - -[[package]] -name = "security-framework-sys" -version = "2.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "serde" -version = "1.0.193" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde-transcode" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "590c0e25c2a5bb6e85bf5c1bce768ceb86b316e7a01bdf07d2cb4ec2271990e2" -dependencies = [ - "serde", -] - -[[package]] -name = "serde_derive" -version = "1.0.193" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.42", -] - -[[package]] -name = "serde_json" -version = "1.0.108" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" -dependencies = [ - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "shlex" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7cee0529a6d40f580e7a5e6c495c8fbfe21b7b52795ed4bb5e62cdf92bc6380" - -[[package]] -name = "socket2" -version = "0.4.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" -dependencies = [ - "libc", - "winapi", -] - -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.42" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b7d0a2c048d661a1a59fcd7355baa232f7ed34e0ee4df2eef3c1c1c0d3852d8" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "tempfile" -version = "3.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5" -dependencies = [ - "cfg-if", - "fastrand", - "redox_syscall", - "rustix", - "windows-sys 0.48.0", -] - -[[package]] -name = "tinyvec" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" - -[[package]] -name = "tokio" -version = "1.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03201d01c3c27a29c8a5cee5b55a93ddae1ccf6f08f65365c2c918f8c1b76f64" -dependencies = [ - "autocfg", - "libc", - "mio", - "pin-project-lite", - "socket2", - "tokio-macros", - "windows-sys 0.45.0", -] - -[[package]] -name = "tokio-macros" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b557f72f448c511a979e2564e55d74e6c4432fc96ff4f6241bc6bded342643b7" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "tokio-native-tls" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" -dependencies = [ - "native-tls", - "tokio", -] - -[[package]] -name = "tracing" -version = "0.1.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" -dependencies = [ - "pin-project-lite", - "tracing-core", -] - -[[package]] -name = "tracing-core" -version = "0.1.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" -dependencies = [ - "once_cell", -] - -[[package]] -name = "try-lock" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" - -[[package]] -name = "unicase" -version = "2.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" -dependencies = [ - "version_check", -] - -[[package]] -name = "unicode-ident" -version = "1.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" - -[[package]] -name = "unicode-normalization" -version = "0.1.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" -dependencies = [ - "tinyvec", -] - -[[package]] -name = "unicode-segmentation" -version = "1.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" - -[[package]] -name = "unicode-xid" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" - -[[package]] -name = "vcpkg" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" - -[[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "walkdir" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" -dependencies = [ - "same-file", - "winapi-util", -] - -[[package]] -name = "want" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" -dependencies = [ - "try-lock", -] - -[[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" - -[[package]] -name = "wasmjs-engine" -version = "0.1.0" -dependencies = [ - "anyhow", - "javy", - "regex", - "serde_json", - "wit-bindgen-rust", -] - -[[package]] -name = "which" -version = "4.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" -dependencies = [ - "either", - "home", - "once_cell", - "rustix", -] - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-util" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" -dependencies = [ - "winapi", -] - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "windows-sys" -version = "0.45.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" -dependencies = [ - "windows-targets 0.42.2", -] - -[[package]] -name = "windows-sys" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" -dependencies = [ - "windows-targets 0.48.5", -] - -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets 0.52.0", -] - -[[package]] -name = "windows-targets" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" -dependencies = [ - "windows_aarch64_gnullvm 0.42.2", - "windows_aarch64_msvc 0.42.2", - "windows_i686_gnu 0.42.2", - "windows_i686_msvc 0.42.2", - "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm 0.42.2", - "windows_x86_64_msvc 0.42.2", -] - -[[package]] -name = "windows-targets" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" -dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", -] - -[[package]] -name = "windows-targets" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" -dependencies = [ - "windows_aarch64_gnullvm 0.52.0", - "windows_aarch64_msvc 0.52.0", - "windows_i686_gnu 0.52.0", - "windows_i686_msvc 0.52.0", - "windows_x86_64_gnu 0.52.0", - "windows_x86_64_gnullvm 0.52.0", - "windows_x86_64_msvc 0.52.0", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" - -[[package]] -name = "windows_i686_gnu" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" - -[[package]] -name = "windows_i686_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" - -[[package]] -name = "windows_i686_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" - -[[package]] -name = "windows_i686_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" - -[[package]] -name = "wit-bindgen-gen-core" -version = "0.2.0" -source = "git+https://github.com/bytecodealliance/wit-bindgen?tag=v0.2.0#cb871cfa1ee460b51eb1d144b175b9aab9c50aba" -dependencies = [ - "anyhow", - "wit-parser", -] - -[[package]] -name = "wit-bindgen-gen-rust" -version = "0.2.0" -source = "git+https://github.com/bytecodealliance/wit-bindgen?tag=v0.2.0#cb871cfa1ee460b51eb1d144b175b9aab9c50aba" -dependencies = [ - "heck", - "wit-bindgen-gen-core", -] - -[[package]] -name = "wit-bindgen-gen-rust-wasm" -version = "0.2.0" -source = "git+https://github.com/bytecodealliance/wit-bindgen?tag=v0.2.0#cb871cfa1ee460b51eb1d144b175b9aab9c50aba" -dependencies = [ - "heck", - "wit-bindgen-gen-core", - "wit-bindgen-gen-rust", -] - -[[package]] -name = "wit-bindgen-rust" -version = "0.2.0" -source = "git+https://github.com/bytecodealliance/wit-bindgen?tag=v0.2.0#cb871cfa1ee460b51eb1d144b175b9aab9c50aba" -dependencies = [ - "async-trait", - "bitflags 1.3.2", - "wit-bindgen-rust-impl", -] - -[[package]] -name = "wit-bindgen-rust-impl" -version = "0.2.0" -source = "git+https://github.com/bytecodealliance/wit-bindgen?tag=v0.2.0#cb871cfa1ee460b51eb1d144b175b9aab9c50aba" -dependencies = [ - "proc-macro2", - "syn 1.0.109", - "wit-bindgen-gen-core", - "wit-bindgen-gen-rust-wasm", -] - -[[package]] -name = "wit-parser" -version = "0.2.0" -source = "git+https://github.com/bytecodealliance/wit-bindgen?tag=v0.2.0#cb871cfa1ee460b51eb1d144b175b9aab9c50aba" -dependencies = [ - "anyhow", - "id-arena", - "pulldown-cmark", - "unicode-normalization", - "unicode-xid", -] diff --git a/JS/wasm/crates/wasmjs-engine/Cargo.toml b/JS/wasm/crates/wasmjs-engine/Cargo.toml deleted file mode 100644 index 07bf9c246..000000000 --- a/JS/wasm/crates/wasmjs-engine/Cargo.toml +++ /dev/null @@ -1,17 +0,0 @@ -[package] -name = "wasmjs-engine" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -anyhow = "1" -javy = { version = "2.1.0", features = ["json"] } -regex = "1" -serde_json = "1.0.108" -# wit-bindgen-rust = "0.13.1" -wit-bindgen-rust = { git = "https://github.com/bytecodealliance/wit-bindgen", tag = "v0.2.0" } - -[profile.release] -lto = "thin" diff --git a/JS/wasm/crates/wasmjs-engine/build.rs b/JS/wasm/crates/wasmjs-engine/build.rs deleted file mode 100644 index 506027b3f..000000000 --- a/JS/wasm/crates/wasmjs-engine/build.rs +++ /dev/null @@ -1,19 +0,0 @@ -use std::process::Command; - -fn main() { - Command::new("npm") - .current_dir("shims") - .arg("install") - .status() - .unwrap(); - - Command::new("npm") - .current_dir("shims") - .args(["run", "build"]) - .status() - .unwrap(); - - println!("cargo:rerun-if-changed=shims/package.json"); - println!("cargo:rerun-if-changed=shims/build.js"); - println!("cargo:rerun-if-changed=shims/src/*.js"); -} diff --git a/JS/wasm/crates/wasmjs-engine/package-lock.json b/JS/wasm/crates/wasmjs-engine/package-lock.json deleted file mode 100644 index 42532ba21..000000000 --- a/JS/wasm/crates/wasmjs-engine/package-lock.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name": "wasmjs-engine", - "lockfileVersion": 3, - "requires": true, - "packages": {} -} diff --git a/JS/wasm/crates/wasmjs-engine/shims/.gitignore b/JS/wasm/crates/wasmjs-engine/shims/.gitignore deleted file mode 100644 index 77738287f..000000000 --- a/JS/wasm/crates/wasmjs-engine/shims/.gitignore +++ /dev/null @@ -1 +0,0 @@ -dist/ \ No newline at end of file diff --git a/JS/wasm/crates/wasmjs-engine/shims/build.js b/JS/wasm/crates/wasmjs-engine/shims/build.js deleted file mode 100644 index ebfb9d72e..000000000 --- a/JS/wasm/crates/wasmjs-engine/shims/build.js +++ /dev/null @@ -1,68 +0,0 @@ -import { build } from "esbuild"; - -// Build for index.js -build({ - entryPoints: ["src/index.js"], - bundle: true, - outfile: "dist/index.js", - format: "esm", - target: "esnext", - platform: "node", - treeShaking: false, -}).catch((error) => { - console.error(error); - process.exit(1); -}); - -// Build for buffer.js -build({ - entryPoints: ["src/buffer.js"], - bundle: true, - outfile: "dist/buffer.js", - format: "esm", - target: "esnext", - platform: "node", - treeShaking: false, -}).catch((error) => { - console.error(error); - process.exit(1); -}); - -build({ - entryPoints: ["src/path.js"], - bundle: true, - outfile: "dist/path.js", - format: "esm", - target: "esnext", - platform: "node", - treeShaking: false, -}).catch((error) => { - console.error(error); - process.exit(1); -}); - -build({ - entryPoints: ["src/crypto.ts"], - bundle: true, - outfile: "dist/crypto.js", - format: "esm", - target: "esnext", - platform: "node", - treeShaking: false, -}).catch((error) => { - console.error(error); - process.exit(1); -}); - -build({ - entryPoints: ["src/arakoo-jsonnet.js"], - bundle: true, - outfile: "dist/arakoo-jsonnet.js", - format: "esm", - target: "esnext", - platform: "node", - treeShaking: false, -}).catch((error) => { - console.error(error); - process.exit(1); -}); diff --git a/JS/wasm/crates/wasmjs-engine/shims/package-lock.json b/JS/wasm/crates/wasmjs-engine/shims/package-lock.json deleted file mode 100644 index 7bb9dc38c..000000000 --- a/JS/wasm/crates/wasmjs-engine/shims/package-lock.json +++ /dev/null @@ -1,567 +0,0 @@ -{ - "name": "shims", - "version": "1.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "shims", - "version": "1.0.0", - "dependencies": { - "@sinonjs/text-encoding": "^0.7", - "@types/node": "^20.10.3", - "@ungap/url-search-params": "^0.2", - "base64-js": "^1.5.1", - "buffer": "^6.0.3", - "esbuild": "^0.19", - "http-status": "^1.7", - "query-string": "^7.1.1", - "sjcl": "^1.0.8", - "url-parse": "^1.5.10" - }, - "devDependencies": { - "@types/sjcl": "^1.0.34" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.5.tgz", - "integrity": "sha512-bhvbzWFF3CwMs5tbjf3ObfGqbl/17ict2/uwOSfr3wmxDE6VdS2GqY/FuzIPe0q0bdhj65zQsvqfArI9MY6+AA==", - "cpu": [ - "arm" - ], - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.5.tgz", - "integrity": "sha512-5d1OkoJxnYQfmC+Zd8NBFjkhyCNYwM4n9ODrycTFY6Jk1IGiZ+tjVJDDSwDt77nK+tfpGP4T50iMtVi4dEGzhQ==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.5.tgz", - "integrity": "sha512-9t+28jHGL7uBdkBjL90QFxe7DVA+KGqWlHCF8ChTKyaKO//VLuoBricQCgwhOjA1/qOczsw843Fy4cbs4H3DVA==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.5.tgz", - "integrity": "sha512-mvXGcKqqIqyKoxq26qEDPHJuBYUA5KizJncKOAf9eJQez+L9O+KfvNFu6nl7SCZ/gFb2QPaRqqmG0doSWlgkqw==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.5.tgz", - "integrity": "sha512-Ly8cn6fGLNet19s0X4unjcniX24I0RqjPv+kurpXabZYSXGM4Pwpmf85WHJN3lAgB8GSth7s5A0r856S+4DyiA==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.5.tgz", - "integrity": "sha512-GGDNnPWTmWE+DMchq1W8Sd0mUkL+APvJg3b11klSGUDvRXh70JqLAO56tubmq1s2cgpVCSKYywEiKBfju8JztQ==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.5.tgz", - "integrity": "sha512-1CCwDHnSSoA0HNwdfoNY0jLfJpd7ygaLAp5EHFos3VWJCRX9DMwWODf96s9TSse39Br7oOTLryRVmBoFwXbuuQ==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.5.tgz", - "integrity": "sha512-lrWXLY/vJBzCPC51QN0HM71uWgIEpGSjSZZADQhq7DKhPcI6NH1IdzjfHkDQws2oNpJKpR13kv7/pFHBbDQDwQ==", - "cpu": [ - "arm" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.5.tgz", - "integrity": "sha512-o3vYippBmSrjjQUCEEiTZ2l+4yC0pVJD/Dl57WfPwwlvFkrxoSO7rmBZFii6kQB3Wrn/6GwJUPLU5t52eq2meA==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.5.tgz", - "integrity": "sha512-MkjHXS03AXAkNp1KKkhSKPOCYztRtK+KXDNkBa6P78F8Bw0ynknCSClO/ztGszILZtyO/lVKpa7MolbBZ6oJtQ==", - "cpu": [ - "ia32" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.5.tgz", - "integrity": "sha512-42GwZMm5oYOD/JHqHska3Jg0r+XFb/fdZRX+WjADm3nLWLcIsN27YKtqxzQmGNJgu0AyXg4HtcSK9HuOk3v1Dw==", - "cpu": [ - "loong64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.5.tgz", - "integrity": "sha512-kcjndCSMitUuPJobWCnwQ9lLjiLZUR3QLQmlgaBfMX23UEa7ZOrtufnRds+6WZtIS9HdTXqND4yH8NLoVVIkcg==", - "cpu": [ - "mips64el" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.5.tgz", - "integrity": "sha512-yJAxJfHVm0ZbsiljbtFFP1BQKLc8kUF6+17tjQ78QjqjAQDnhULWiTA6u0FCDmYT1oOKS9PzZ2z0aBI+Mcyj7Q==", - "cpu": [ - "ppc64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.5.tgz", - "integrity": "sha512-5u8cIR/t3gaD6ad3wNt1MNRstAZO+aNyBxu2We8X31bA8XUNyamTVQwLDA1SLoPCUehNCymhBhK3Qim1433Zag==", - "cpu": [ - "riscv64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.5.tgz", - "integrity": "sha512-Z6JrMyEw/EmZBD/OFEFpb+gao9xJ59ATsoTNlj39jVBbXqoZm4Xntu6wVmGPB/OATi1uk/DB+yeDPv2E8PqZGw==", - "cpu": [ - "s390x" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.5.tgz", - "integrity": "sha512-psagl+2RlK1z8zWZOmVdImisMtrUxvwereIdyJTmtmHahJTKb64pAcqoPlx6CewPdvGvUKe2Jw+0Z/0qhSbG1A==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.5.tgz", - "integrity": "sha512-kL2l+xScnAy/E/3119OggX8SrWyBEcqAh8aOY1gr4gPvw76la2GlD4Ymf832UCVbmuWeTf2adkZDK+h0Z/fB4g==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.5.tgz", - "integrity": "sha512-sPOfhtzFufQfTBgRnE1DIJjzsXukKSvZxloZbkJDG383q0awVAq600pc1nfqBcl0ice/WN9p4qLc39WhBShRTA==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.5.tgz", - "integrity": "sha512-dGZkBXaafuKLpDSjKcB0ax0FL36YXCvJNnztjKV+6CO82tTYVDSH2lifitJ29jxRMoUhgkg9a+VA/B03WK5lcg==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.5.tgz", - "integrity": "sha512-dWVjD9y03ilhdRQ6Xig1NWNgfLtf2o/STKTS+eZuF90fI2BhbwD6WlaiCGKptlqXlURVB5AUOxUj09LuwKGDTg==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.5.tgz", - "integrity": "sha512-4liggWIA4oDgUxqpZwrDhmEfAH4d0iljanDOK7AnVU89T6CzHon/ony8C5LeOdfgx60x5cnQJFZwEydVlYx4iw==", - "cpu": [ - "ia32" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.5.tgz", - "integrity": "sha512-czTrygUsB/jlM8qEW5MD8bgYU2Xg14lo6kBDXW6HdxKjh8M5PzETGiSHaz9MtbXBYDloHNUAUW2tMiKW4KM9Mw==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@sinonjs/text-encoding": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.2.tgz", - "integrity": "sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==" - }, - "node_modules/@types/node": { - "version": "20.10.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.3.tgz", - "integrity": "sha512-XJavIpZqiXID5Yxnxv3RUDKTN5b81ddNC3ecsA0SoFXz/QU8OGBwZGMomiq0zw+uuqbL/krztv/DINAQ/EV4gg==", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/@types/sjcl": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/@types/sjcl/-/sjcl-1.0.34.tgz", - "integrity": "sha512-bQHEeK5DTQRunIfQeUMgtpPsNNCcZyQ9MJuAfW1I7iN0LDunTc78Fu17STbLMd7KiEY/g2zHVApippa70h6HoQ==", - "dev": true - }, - "node_modules/@ungap/url-search-params": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/@ungap/url-search-params/-/url-search-params-0.2.2.tgz", - "integrity": "sha512-qQsguKXZVKdCixOHX9jqnX/K/1HekPDpGKyEcXHT+zR6EjGA7S4boSuelL4uuPv6YfhN0n8c4UxW+v/Z3gM2iw==" - }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, - "node_modules/decode-uri-component": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", - "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esbuild": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.5.tgz", - "integrity": "sha512-bUxalY7b1g8vNhQKdB24QDmHeY4V4tw/s6Ak5z+jJX9laP5MoQseTOMemAr0gxssjNcH0MCViG8ONI2kksvfFQ==", - "hasInstallScript": true, - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/android-arm": "0.19.5", - "@esbuild/android-arm64": "0.19.5", - "@esbuild/android-x64": "0.19.5", - "@esbuild/darwin-arm64": "0.19.5", - "@esbuild/darwin-x64": "0.19.5", - "@esbuild/freebsd-arm64": "0.19.5", - "@esbuild/freebsd-x64": "0.19.5", - "@esbuild/linux-arm": "0.19.5", - "@esbuild/linux-arm64": "0.19.5", - "@esbuild/linux-ia32": "0.19.5", - "@esbuild/linux-loong64": "0.19.5", - "@esbuild/linux-mips64el": "0.19.5", - "@esbuild/linux-ppc64": "0.19.5", - "@esbuild/linux-riscv64": "0.19.5", - "@esbuild/linux-s390x": "0.19.5", - "@esbuild/linux-x64": "0.19.5", - "@esbuild/netbsd-x64": "0.19.5", - "@esbuild/openbsd-x64": "0.19.5", - "@esbuild/sunos-x64": "0.19.5", - "@esbuild/win32-arm64": "0.19.5", - "@esbuild/win32-ia32": "0.19.5", - "@esbuild/win32-x64": "0.19.5" - } - }, - "node_modules/filter-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/filter-obj/-/filter-obj-1.1.0.tgz", - "integrity": "sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/http-status": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/http-status/-/http-status-1.7.3.tgz", - "integrity": "sha512-GS8tL1qHT2nBCMJDYMHGkkkKQLNkIAHz37vgO68XKvzv+XyqB4oh/DfmMHdtRzfqSJPj1xKG2TaELZtlCz6BEQ==", - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/query-string": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/query-string/-/query-string-7.1.3.tgz", - "integrity": "sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg==", - "dependencies": { - "decode-uri-component": "^0.2.2", - "filter-obj": "^1.1.0", - "split-on-first": "^1.0.0", - "strict-uri-encode": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/querystringify": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", - "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" - }, - "node_modules/requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" - }, - "node_modules/sjcl": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/sjcl/-/sjcl-1.0.8.tgz", - "integrity": "sha512-LzIjEQ0S0DpIgnxMEayM1rq9aGwGRG4OnZhCdjx7glTaJtf4zRfpg87ImfjSJjoW9vKpagd82McDOwbRT5kQKQ==", - "engines": { - "node": "*" - } - }, - "node_modules/split-on-first": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz", - "integrity": "sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==", - "engines": { - "node": ">=6" - } - }, - "node_modules/strict-uri-encode": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz", - "integrity": "sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ==", - "engines": { - "node": ">=4" - } - }, - "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" - }, - "node_modules/url-parse": { - "version": "1.5.10", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", - "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", - "dependencies": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" - } - } - } -} diff --git a/JS/wasm/crates/wasmjs-engine/shims/package.json b/JS/wasm/crates/wasmjs-engine/shims/package.json deleted file mode 100644 index da05da7b5..000000000 --- a/JS/wasm/crates/wasmjs-engine/shims/package.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "name": "shims", - "version": "1.0.0", - "type": "module", - "main": "bin/index.js", - "scripts": { - "build": "node ./build.js" - }, - "dependencies": { - "@sinonjs/text-encoding": "^0.7", - "@types/node": "^20.10.3", - "@ungap/url-search-params": "^0.2", - "base64-js": "^1.5.1", - "buffer": "^6.0.3", - "esbuild": "^0.19", - "http-status": "^1.7", - "query-string": "^7.1.1", - "sjcl": "^1.0.8", - "url-parse": "^1.5.10" - }, - "devDependencies": { - "@types/sjcl": "^1.0.34" - } -} diff --git a/JS/wasm/crates/wasmjs-engine/shims/src/arakoo-jsonnet.js b/JS/wasm/crates/wasmjs-engine/shims/src/arakoo-jsonnet.js deleted file mode 100644 index 30a29b98f..000000000 --- a/JS/wasm/crates/wasmjs-engine/shims/src/arakoo-jsonnet.js +++ /dev/null @@ -1,3 +0,0 @@ -const jsonnet = globalThis.jsonnet; -const jsonnetExtVars = globalThis.jsonnetExtVars; -export { jsonnet, jsonnetExtVars }; diff --git a/JS/wasm/crates/wasmjs-engine/shims/src/buffer.js b/JS/wasm/crates/wasmjs-engine/shims/src/buffer.js deleted file mode 100644 index 5d9131bf5..000000000 --- a/JS/wasm/crates/wasmjs-engine/shims/src/buffer.js +++ /dev/null @@ -1,17 +0,0 @@ -import { - constants, - kMaxLength, - kStringMaxLength, - Buffer, - SlowBuffer, -} from "./internal/internal_buffer"; - -export { constants, kMaxLength, kStringMaxLength, Buffer, SlowBuffer }; - -export default { - constants, - kMaxLength, - kStringMaxLength, - Buffer, - SlowBuffer, -}; diff --git a/JS/wasm/crates/wasmjs-engine/shims/src/crypto.ts b/JS/wasm/crates/wasmjs-engine/shims/src/crypto.ts deleted file mode 100644 index f176cf637..000000000 --- a/JS/wasm/crates/wasmjs-engine/shims/src/crypto.ts +++ /dev/null @@ -1,321 +0,0 @@ -import { ERR_METHOD_NOT_IMPLEMENTED } from "./internal/internal_errors"; - -// export const getRandomValues = crypto.getRandomValues; -// export const subtle = crypto.subtle; -// export const timingSafeEqual = (crypto as any).timingSafeEqual; -// export const webcrypto = crypto; - -import { - DiffieHellman, - DiffieHellmanGroup, - createDiffieHellman, - createDiffieHellmanGroup, - getDiffieHellman, -} from "./internal/crypto_dh"; - -import { - randomBytes, - randomFillSync, - randomFill, - randomInt, - randomUUID, - PrimeNum, - GeneratePrimeOptions, - CheckPrimeOptions, - generatePrime, - generatePrimeSync, - checkPrime, - checkPrimeSync, -} from "./internal/crypto_random"; - -import { createHash, createHmac, Hash, HashOptions, Hmac } from "./internal/crypto_hash"; - -import { hkdf, hkdfSync } from "./internal/crypto_hkdf"; - -import { pbkdf2, pbkdf2Sync, ArrayLike } from "./internal/crypto_pbkdf2"; - -import { - KeyObject, - PublicKeyObject, - PrivateKeyObject, - SecretKeyObject, - generateKey, - generateKeyPair, - generateKeyPairSync, - generateKeySync, - createPrivateKey, - createPublicKey, - createSecretKey, -} from "./internal/crypto_keys"; - -export { - // DH - DiffieHellman, - DiffieHellmanGroup, - createDiffieHellman, - createDiffieHellmanGroup, - getDiffieHellman, - // Random - randomBytes, - randomFillSync, - randomFill, - randomInt, - randomUUID, - // Primes - PrimeNum as primeNum, - GeneratePrimeOptions as generatePrimeOptions, - CheckPrimeOptions as checkPrimeOptions, - generatePrime, - generatePrimeSync, - checkPrime, - checkPrimeSync, - // Hash and Hmac - createHash, - createHmac, - Hash, - HashOptions, - Hmac, - // Hkdf - hkdf, - hkdfSync, - // Pbkdf2 - pbkdf2, - pbkdf2Sync, - ArrayLike as arrayLike, - // Keys - KeyObject, - PublicKeyObject, - PrivateKeyObject, - SecretKeyObject, - generateKey, - generateKeyPair, - generateKeyPairSync, - generateKeySync, - createPrivateKey, - createPublicKey, - createSecretKey, -}; - -export function getCiphers() { - return [ - "aes-128-cbc", - "aes-192-cbc", - "aes-256-cbc", - "aes-128-ctr", - "aes-192-ctr", - "aes-256-ctr", - "aes-128-ecb", - "aes-192-ecb", - "aes-256-ecb", - "aes-128-gcm", - "aes-192-gcm", - "aes-256-gcm", - "aes-128-ofb", - "aes-192-ofb", - "aes-256-ofb", - "des-ecb", - "des-ede", - "des-ede-cbc", - "rc2-cbc", - ]; -} - -export function getCurves() { - // Hardcoded list of supported curves. Note that prime256v1 is equivalent to secp256r1, we follow - // OpenSSL's and bssl's nomenclature here. - return ["secp224r1", "prime256v1", "secp384r1", "secp521r1"]; -} - -export function getHashes() { - // Hardcoded list of hashes supported in boringssl, node's approach looks pretty clunky. This is - // expected to change infrequently based of bssl's stability-focused approach. - return [ - "md4", - "md5", - "sha1", - "sha224", - "sha256", - "sha384", - "sha512", - "md5-sha1", - "RSA-MD5", - "RSA-SHA1", - "RSA-SHA224", - "RSA-SHA256", - "RSA-SHA384", - "RSA-SHA512", - "DSA-SHA", - "DSA-SHA1", - "ecdsa-with-SHA1", - ]; -} - -// We do not implement the openssl secure heap. -export function secureHeapUsed() { - return { - total: 0, - used: 0, - utilization: 0, - min: 0, - }; -} - -// We do not allow users to set the engine used. -export function setEngine(_1: string, _2?: number) { - throw new ERR_METHOD_NOT_IMPLEMENTED("setEngine"); -} - -// We do not allow users to modify the FIPS enablement. -export function setFips(_: boolean) { - throw new ERR_METHOD_NOT_IMPLEMENTED("setFips"); -} - -// We always run in FIPS mode. -export const fips = true; -export function getFips() { - return fips; -} - -export default { - // DH - DiffieHellman, - DiffieHellmanGroup, - createDiffieHellman, - createDiffieHellmanGroup, - getDiffieHellman, - // Keys, - KeyObject, - PublicKeyObject, - PrivateKeyObject, - SecretKeyObject, - generateKey, - generateKeyPair, - generateKeyPairSync, - generateKeySync, - createPrivateKey, - createPublicKey, - createSecretKey, - // Random - // getRandomValues, - randomBytes, - randomFillSync, - randomFill, - randomInt, - randomUUID, - generatePrime, - generatePrimeSync, - checkPrime, - checkPrimeSync, - // Hash and Hmac - Hash, - Hmac, - createHash, - createHmac, - getHashes, - // Hkdf - hkdf, - hkdfSync, - // Pbkdf2 - pbkdf2, - pbkdf2Sync, - // Misc - getCiphers, - getCurves, - secureHeapUsed, - setEngine, - // timingSafeEqual, - // Fips - getFips, - setFips, - get fips() { - return getFips(); - }, - set fips(_: boolean) { - setFips(_); - }, - // WebCrypto - // subtle, - // webcrypto, -}; - -// Classes -// * [ ] crypto.Certificate -// * [ ] crypto.Cipher -// * [ ] crypto.Decipher -// * [x] crypto.DiffieHellman -// * [x] crypto.DiffieHellmanGroup -// * [ ] crypto.ECDH -// * [x] crypto.Hash -// * [x] crypto.Hmac -// * [ ] crypto.KeyObject -// * [ ] crypto.Sign -// * [ ] crypto.Verify -// * [ ] crypto.X509Certificate -// * [ ] crypto.constants -// * [ ] crypto.DEFAULT_ENCODING -// * Primes -// * [x] crypto.checkPrime(candidate[, options], callback) -// * [x] crypto.checkPrimeSync(candidate[, options]) -// * [x] crypto.generatePrime(size[, options[, callback]]) -// * [x] crypto.generatePrimeSync(size[, options]) -// * Ciphers -// * [ ] crypto.createCipher(algorithm, password[, options]) -// * [ ] crypto.createCipheriv(algorithm, key, iv[, options]) -// * [ ] crypto.createDecipher(algorithm, password[, options]) -// * [ ] crypto.createDecipheriv(algorithm, key, iv[, options]) -// * [ ] crypto.privateDecrypt(privateKey, buffer) -// * [ ] crypto.privateEncrypt(privateKey, buffer) -// * [ ] crypto.publicDecrypt(key, buffer) -// * [ ] crypto.publicEncrypt(key, buffer) -// * DiffieHellman -// * [x] crypto.createDiffieHellman(prime[, primeEncoding][, generator][, generatorEncoding]) -// * [x] crypto.createDiffieHellman(primeLength[, generator]) -// * [x] crypto.createDiffieHellmanGroup(name) -// * [ ] crypto.createECDH(curveName) -// * [ ] crypto.diffieHellman(options) -// * [x] crypto.getDiffieHellman(groupName) -// * Hash -// * [x] crypto.createHash(algorithm[, options]) -// * [x] crypto.createHmac(algorithm, key[, options]) -// * [x] crypto.getHashes() -// * Keys -// * [ ] crypto.createPrivateKey(key) -// * [ ] crypto.createPublicKey(key) -// * [x] crypto.createSecretKey(key[, encoding]) -// * [x] crypto.generateKey(type, options, callback) -// * [x] crypto.generateKeyPair(type, options, callback) -// * [x] crypto.generateKeyPairSync(type, options) -// * [x] crypto.generateKeySync(type, options) -// * Sign/Verify -// * [ ] crypto.createSign(algorithm[, options]) -// * [ ] crypto.createVerify(algorithm[, options]) -// * [ ] crypto.sign(algorithm, data, key[, callback]) -// * [ ] crypto.verify(algorithm, data, key, signature[, callback]) -// * Misc -// * [ ] crypto.getCipherInfo(nameOrNid[, options]) -// * [x] crypto.getCiphers() -// * [x] crypto.getCurves() -// * [x] crypto.secureHeapUsed() -// * [x] crypto.setEngine(engine[, flags]) -// * [x] crypto.timingSafeEqual(a, b) -// * Fips -// * [x] crypto.getFips() -// * [x] crypto.fips -// * [x] crypto.setFips(bool) -// * Random -// * [x] crypto.getRandomValues(typedArray) -// * [x] crypto.randomBytes(size[, callback]) -// * [x] crypto.randomFillSync(buffer[, offset][, size]) -// * [x] crypto.randomFill(buffer[, offset][, size], callback) -// * [x] crypto.randomInt([min, ]max[, callback]) -// * [x] crypto.randomUUID([options]) -// * Key Derivation -// * [.] crypto.hkdf(digest, ikm, salt, info, keylen, callback) (* still needs KeyObject support) -// * [.] crypto.hkdfSync(digest, ikm, salt, info, keylen) (* still needs KeyObject support) -// * [x] crypto.pbkdf2(password, salt, iterations, keylen, digest, callback) -// * [x] crypto.pbkdf2Sync(password, salt, iterations, keylen, digest) -// * [ ] crypto.scrypt(password, salt, keylen[, options], callback) -// * [ ] crypto.scryptSync(password, salt, keylen[, options]) -// * WebCrypto -// * [x] crypto.subtle -// * [x] crypto.webcrypto diff --git a/JS/wasm/crates/wasmjs-engine/shims/src/events.ts b/JS/wasm/crates/wasmjs-engine/shims/src/events.ts deleted file mode 100644 index 77f7b3f46..000000000 --- a/JS/wasm/crates/wasmjs-engine/shims/src/events.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from "./internal/events"; -export { default } from "./internal/events"; diff --git a/JS/wasm/crates/wasmjs-engine/shims/src/index.js b/JS/wasm/crates/wasmjs-engine/shims/src/index.js deleted file mode 100644 index 2fa1129e0..000000000 --- a/JS/wasm/crates/wasmjs-engine/shims/src/index.js +++ /dev/null @@ -1,371 +0,0 @@ -// import { URLSearchParams } from "@ungap/url-search-params"; -import { TextEncoder, TextDecoder } from "@sinonjs/text-encoding"; -import httpStatus from "http-status"; -import Url from "url-parse"; -import _queryString from "query-string"; - -class URL { - constructor(urlStr, base = undefined) { - let url = Url(urlStr, base); - this.url = url; - this.protocol = url.protocol; - this.slashes = url.slashes; - this.auth = url.auth; - this.username = url.username; - this.password = url.password; - this.host = url.host; - this.port = url.port; - this.pathname = url.pathname; - this.search = url.query; - this.searchParams = new URLSearchParams(this.search); - this.hash = url.hash; - this.href = url.origin; - this.origin = url.origin; - } - - set(key, value) { - this.url.set(key, value); - } - - toString() { - return this.url.toString(); - } - - toJson() { - return this.url.toString(); - } -} - -class URLSearchParams { - queryParams = {}; - - constructor(val) { - this.queryParams = { - ..._queryString.parse(val), - }; - } - append(key, val) { - this.queryParams[key] = val; - } - delete(key) { - delete this.queryParams[key]; - } - entries() { - let arr = []; - Object.entries(this.queryParams).map((o) => { - if (Array.isArray(o[1])) { - o[1].map((k) => { - arr.push([o[0], k]); - }); - } else { - arr.push([o[0], o[1]]); - } - }); - let iterLength = arr.length; - let iterIndex = 0; - return { - next: function () { - return iterIndex < iterLength - ? { value: arr[iterIndex++], done: false } - : { done: true }; - }, - }; - } - get(key) { - let val = this.queryParams[key]; - if (val) { - if (typeof val == "object") { - return val[0]; - } - return val; - } - return null; - } - getAll(key) { - let val = this.queryParams[key]; - if (val) { - return val; - } - return null; - } - has(key) { - return this.queryParams[key] != undefined ? true : false; - } - keys() { - return Object.keys(this.queryParams); - } - set(key, val) { - this.queryParams[key] = val; - } - toString() { - return _queryString.stringify(this.queryParams); - } - values() { - return Object.keys(this.queryParams).map((k) => this.queryParams[k]); - } - [Symbol.iterator]() { - return this.entries(); - } -} - -globalThis.URL = URL; -globalThis.URLSearchParams = URLSearchParams; - -function atob(b64) { - return Buffer.from(b64, "base64").toString(); -} - -function btoa(data) { - return Buffer.from(data).toString("base64"); -} - -globalThis.btoa = btoa; -globalThis.atob = atob; - -function require(path) { - return globalThis[path]; -} - -globalThis.require = require; -class Headers { - constructor(initialHeaders) { - let headers = {}; - - for (const key in initialHeaders) { - let value = initialHeaders[key]; - - if (typeof value === "string") { - headers[key] = value; - } - } - - this.headers = headers; - } - - append(key, value) { - this.headers[key] = value; - return value; - } - - set(key, value) { - this.append(key, value); - return value; - } - - delete(key) { - let dropValue = delete this.headers[key]; - return dropValue; - } - - get(key) { - return this.headers[key]; - } - - toJSON() { - return this.headers; - } -} - -class Request { - constructor(input) { - this.url = input.url; - this.method = input.method; - this.headers = new Headers(input.headers || {}); - this.body = input.body; - this.params = input.params || {}; - this.geo = input.geo || {}; - } - - text() { - return this.body; - } -} - -class Response { - constructor(body, options = {}) { - if (body instanceof String) { - this.body = body.toString(); - } else { - this.body = body; - } - - if (options.headers instanceof Headers) { - this.headers = options.headers; - } else if (options.headers instanceof Object) { - this.headers = new Headers(options.headers); - } else { - this.headers = new Headers({}); - } - - this.status = options.status || 200; - this.statusText = options.statusText || httpStatus[this.status]; - } - - static redirect(url, status = 307) { - return new Response(`Redirecting to ${url}`, { - status, - headers: { - Location: url, - }, - }); - } - - get ok() { - return this.status >= 200 && this.status < 300; - } - - defaultEncoding() { - return "utf-8"; - } - - arrayBuffer() { - let parsedBody = this.body; - - if (typeof this.body === "string") { - try { - parsedBody = new TextEncoder().encode(this.body); - } catch (e) { - return Promise.reject(`err: ${e}`); - } - } - - return parsedBody; - } - - json() { - let parsedBody = this.body; - - if (typeof this.body !== "string") { - try { - parsedBody = new TextDecoder(this.defaultEncoding()).decode(this.body); - } catch (e) { - return Promise.reject(`err: ${e}`); - } - } - - try { - return Promise.resolve(JSON.parse(parsedBody)); - } catch (e) { - return Promise.reject(`err: ${e}`); - } - } - - text() { - let parsedBody = this.body; - - if (typeof this.body !== "string") { - try { - parsedBody = new TextDecoder(this.defaultEncoding()).decode(this.body); - } catch (e) { - return Promise.reject(`err: ${e}`); - } - } - - return parsedBody; - } - - toString() { - return this.body; - } -} - -(function () { - const __send_http_request = globalThis.__send_http_request; - const __console_log = globalThis.__console_log; - - globalThis.fetch = (uri, opts) => { - let optsWithDefault = { - method: "GET", - headers: {}, - body: null, - ...opts, - }; - - if (optsWithDefault.body !== null && typeof optsWithDefault.body !== "string") { - try { - optsWithDefault.body = new TextEncoder().encode(optsWithDefault.body); - } catch (e) { - return Promise.reject(`err: ${e}`); - } - } - - let result = __send_http_request(uri, optsWithDefault); - - if (result.error === true) { - return Promise.reject(new Error(`[${result.type}] ${result.message}`)); - } else { - let response = new Response(result.body, { - headers: result.headers, - status: result.status, - }); - - return Promise.resolve(response); - } - }; - - globalThis.console = { - error(msg) { - this.log(msg); - }, - log(msg) { - __console_log(msg); - }, - info(msg) { - this.log(msg); - }, - debug(msg) { - this.log(msg); - }, - warn(msg) { - this.log(msg); - }, - trace(msg) { - this.log(msg); - }, - }; - - Reflect.deleteProperty(globalThis, "__send_http_request"); - Reflect.deleteProperty(globalThis, "__console_log"); -})(); - -globalThis.TextEncoder = TextEncoder; -globalThis.TextDecoder = TextDecoder; - -let handlerFunction; - -globalThis.addEventListener = (_eventName, handler) => { - handlerFunction = handler; -}; - -const requestToHandler = (input) => { - const request = new Request(input); - const event = { - request, - response: {}, - respondWith(res) { - this.response = res; - }, - }; - - try { - handlerFunction(event); - - Promise.resolve(event.response) - .then((res) => { - result = { - data: res.body, - headers: res.headers.headers, - status: res.status, - }; - }) - .catch((err) => { - error = `err: \n${err}`; - }); - } catch (err) { - error = `err: ${err}\n${err.stack}`; - } -}; - -globalThis.entrypoint = requestToHandler; -globalThis.result = {}; -globalThis.error = null; diff --git a/JS/wasm/crates/wasmjs-engine/shims/src/internal/async_hooks.d.ts b/JS/wasm/crates/wasmjs-engine/shims/src/internal/async_hooks.d.ts deleted file mode 100644 index 6f02fb827..000000000 --- a/JS/wasm/crates/wasmjs-engine/shims/src/internal/async_hooks.d.ts +++ /dev/null @@ -1,26 +0,0 @@ -// Type definitions for c++ implementation. - -export interface AsyncResourceOptions { - triggerAsyncId?: number; -} - -export class AsyncResource { - public constructor(type: string, options?: AsyncResourceOptions); - public runInAsyncScope(fn: (...args: unknown[]) => R, ...args: unknown[]): R; - - public bind unknown>( - fn: Func - ): Func & { asyncResource: AsyncResource }; - - public static bind unknown, ThisArg>( - fn: Func, - type?: string, - thisArg?: ThisArg - ): Func & { asyncResource: AsyncResource }; -} - -export class AsyncLocalStorage { - public run(store: T, fn: (...args: unknown[]) => R, ...args: unknown[]): R; - public exit(fn: (...args: unknown[]) => R, ...args: unknown[]): R; - public getStore(): T; -} diff --git a/JS/wasm/crates/wasmjs-engine/shims/src/internal/async_hooks.ts b/JS/wasm/crates/wasmjs-engine/shims/src/internal/async_hooks.ts deleted file mode 100644 index 968aa2fc3..000000000 --- a/JS/wasm/crates/wasmjs-engine/shims/src/internal/async_hooks.ts +++ /dev/null @@ -1,30 +0,0 @@ -export interface AsyncResourceOptions { - triggerAsyncId?: number; -} - -export class AsyncResource { - // @ts-ignore - public constructor(type: string, options?: AsyncResourceOptions); - // @ts-ignore - public runInAsyncScope(fn: (...args: unknown[]) => R, ...args: unknown[]): R; - - public bind unknown>( - fn: Func - ): Func & { asyncResource: AsyncResource }; - - // @ts-ignore - public static bind unknown, ThisArg>( - fn: Func, - type?: string, - thisArg?: ThisArg - ): Func & { asyncResource: AsyncResource }; -} - -export class AsyncLocalStorage { - // @ts-ignore - public run(store: T, fn: (...args: unknown[]) => R, ...args: unknown[]): R; - // @ts-ignore - public exit(fn: (...args: unknown[]) => R, ...args: unknown[]): R; - // @ts-ignore - public getStore(): T; -} diff --git a/JS/wasm/crates/wasmjs-engine/shims/src/internal/buffer.d.ts b/JS/wasm/crates/wasmjs-engine/shims/src/internal/buffer.d.ts deleted file mode 100644 index 6ba318865..000000000 --- a/JS/wasm/crates/wasmjs-engine/shims/src/internal/buffer.d.ts +++ /dev/null @@ -1,38 +0,0 @@ -export interface CompareOptions { - aStart?: number; - aEnd?: number; - bStart?: number; - bEnd?: number; -} - -type BufferSource = ArrayBufferView | ArrayBuffer; - -export function byteLength(value: string): number; -export function compare(a: Uint8Array, b: Uint8Array, options?: CompareOptions): number; -export function concat(list: Uint8Array[], length: number): ArrayBuffer; -export function decodeString(value: string, encoding: string): ArrayBuffer; -export function fillImpl( - buffer: Uint8Array, - value: string | BufferSource, - start: number, - end: number, - encoding?: string -): void; -export function indexOf( - buffer: Uint8Array, - value: string | Uint8Array, - byteOffset?: number, - encoding?: string, - findLast?: boolean -): number | undefined; -export function swap(buffer: Uint8Array, size: 16 | 32 | 64): void; -export function toString(buffer: Uint8Array, start: number, end: number, encoding: string): string; -export function write( - buffer: Uint8Array, - value: string, - offset: number, - length: number, - encoding: string -): void; -export function decode(buffer: Uint8Array, state: Uint8Array): string; -export function flush(state: Uint8Array): string; diff --git a/JS/wasm/crates/wasmjs-engine/shims/src/internal/buffer.ts b/JS/wasm/crates/wasmjs-engine/shims/src/internal/buffer.ts deleted file mode 100644 index 21fde0761..000000000 --- a/JS/wasm/crates/wasmjs-engine/shims/src/internal/buffer.ts +++ /dev/null @@ -1,521 +0,0 @@ -import { isInstance } from "./internal_buffer"; -import * as base64 from "base64-js"; -import { TextEncoder, TextDecoder } from "@sinonjs/text-encoding"; - -const hexCharValueTable = { - "0": 0, - "1": 1, - "2": 2, - "3": 3, - "4": 4, - "5": 5, - "6": 6, - "7": 7, - "8": 8, - "9": 9, - a: 10, - b: 11, - c: 12, - d: 13, - e: 14, - f: 15, - A: 10, - B: 11, - C: 12, - D: 13, - E: 14, - F: 15, -}; - -export function byteLength(string, encoding) { - if (Buffer.isBuffer(string)) { - return string.length; - } - if (ArrayBuffer.isView(string) || isInstance(string, ArrayBuffer)) { - return string.byteLength; - } - if (typeof string !== "string") { - throw new TypeError( - 'The "string" argument must be one of type string, Buffer, or ArrayBuffer. ' + - "Received type " + - typeof string - ); - } - - const len = string.length; - const mustMatch = arguments.length > 2 && arguments[2] === true; - if (!mustMatch && len === 0) return 0; - - // Use a for loop to avoid recursion - let loweredCase = false; - for (;;) { - switch (encoding) { - case "ascii": - case "latin1": - case "binary": - return len; - case "utf8": - case "utf-8": - return utf8ToBytes(string).length; - case "ucs2": - case "ucs-2": - case "utf16le": - case "utf-16le": - return len * 2; - case "hex": - return len >>> 1; - case "base64": - return base64ToBytes(string).length; - default: - if (loweredCase) { - return mustMatch ? -1 : utf8ToBytes(string).length; // assume utf8 - } - encoding = ("" + encoding).toLowerCase(); - loweredCase = true; - } - } -} - -// @ts-ignore - -export function compare(a: Uint8Array, b: Uint8Array, options?): number { - const aStart = options?.aStart ?? 0; - const aEnd = options?.aEnd ?? a.length; - const bStart = options?.bStart ?? 0; - const bEnd = options?.bEnd ?? b.length; - - const sliceA = a.slice(aStart, aEnd); - const sliceB = b.slice(bStart, bEnd); - - let x = sliceA.length; - let y = sliceB.length; - - for (let i = 0, len = Math.min(x, y); i < len; ++i) { - if (sliceA[i] !== sliceB[i]) { - x = sliceA[i]; - y = sliceB[i]; - break; - } - } - - if (x < y) return -1; - if (y < x) return 1; - return 0; -} - -export function concat(list: Uint8Array[], length: number): ArrayBuffer { - const result = new Uint8Array(length); - let offset = 0; - for (let i = 0; i < list.length; i++) { - result.set(list[i], offset); - offset += list[i].length; - } - return result.buffer; -} - -export function toString(buffer: Uint8Array, start: number, end: number, encoding: string): string { - const slice = buffer.slice(start, end); - const decoder = new TextDecoder(encoding); - return decoder.decode(slice); -} - -export function swap(buffer: Uint8Array, size: 16 | 32 | 64): void { - const length = buffer.length; - if (length % size !== 0) { - throw new RangeError("Buffer size must be a multiple of " + size); - } - - for (let i = 0; i < length; i += size) { - let left = i; - let right = i + size - 1; - while (left < right) { - const temp = buffer[left]; - buffer[left] = buffer[right]; - buffer[right] = temp; - left++; - right--; - } - } -} - -export function decodeString(value: string, encoding: string): ArrayBuffer { - const encoder = new TextEncoder(); - return encoder.encode(value).buffer; -} - -export function write( - buffer: Uint8Array, - value: string, - offset: number, - length: number, - encoding: string -): void { - let loweredCase = false; - for (;;) { - switch (encoding) { - case "hex": - return hexWrite(buffer, value, offset, length); - - case "utf8": - case "utf-8": - return utf8Write(buffer, value, offset, length); - - case "ascii": - case "latin1": - case "binary": - return asciiWrite(buffer, value, offset, length); - - case "base64": - // Warning: maxLength not taken into account in base64Write - return base64Write(buffer, value, offset, length); - - case "ucs2": - case "ucs-2": - case "utf16le": - case "utf-16le": - return ucs2Write(buffer, value, offset, length); - - default: - if (loweredCase) throw new TypeError("Unknown encoding: " + encoding); - encoding = ("" + encoding).toLowerCase(); - loweredCase = true; - } - } -} - -export function fillImpl( - buffer: Uint8Array, - val: string | BufferSource | number | boolean, - start: number, - end: number, - encoding?: string -): void { - let i; - if (typeof val === "number") { - for (i = start; i < end; ++i) { - buffer[i] = val; - } - } else { - const bytes = Buffer.isBuffer(val) ? val : Buffer.from(val as string, encoding); - const len = bytes.length; - for (i = 0; i < end - start; ++i) { - buffer[i + start] = bytes[i % len]; - } - } -} - -export function indexOf(buffer, val, byteOffset, encoding, dir) { - // Empty buffer means no match - if (buffer.length === 0) return -1; - - // Normalize byteOffset - if (typeof byteOffset === "string") { - encoding = byteOffset; - byteOffset = 0; - } else if (byteOffset > 0x7fffffff) { - byteOffset = 0x7fffffff; - } else if (byteOffset < -0x80000000) { - byteOffset = -0x80000000; - } - byteOffset = +byteOffset; // Coerce to Number. - if (numberIsNaN(byteOffset)) { - // byteOffset: it it's undefined, null, NaN, "foo", etc, search whole buffer - byteOffset = dir ? 0 : buffer.length - 1; - } - - // Normalize byteOffset: negative offsets start from the end of the buffer - if (byteOffset < 0) byteOffset = buffer.length + byteOffset; - if (byteOffset >= buffer.length) { - if (dir) return -1; - else byteOffset = buffer.length - 1; - } else if (byteOffset < 0) { - if (dir) byteOffset = 0; - else return -1; - } - - // Normalize val - if (typeof val === "string") { - val = Buffer.from(val, encoding); - } - - // Finally, search either indexOf (if dir is true) or lastIndexOf - if (Buffer.isBuffer(val)) { - // Special case: looking for empty string/buffer always fails - if (val.length === 0) { - return -1; - } - return arrayIndexOf(buffer, val, byteOffset, encoding, dir); - } else if (typeof val === "number") { - val = val & 0xff; // Search for a byte value [0-255] - if (typeof Uint8Array.prototype.indexOf === "function") { - if (dir) { - return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset); - } else { - return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset); - } - } - return arrayIndexOf(buffer, [val], byteOffset, encoding, dir); - } - - throw new TypeError("val must be string, number or Buffer"); -} - -function arrayIndexOf(arr, val, byteOffset, encoding, dir) { - let indexSize = 1; - let arrLength = arr.length; - let valLength = val.length; - - if (encoding !== undefined) { - encoding = String(encoding).toLowerCase(); - if ( - encoding === "ucs2" || - encoding === "ucs-2" || - encoding === "utf16le" || - encoding === "utf-16le" - ) { - if (arr.length < 2 || val.length < 2) { - return -1; - } - indexSize = 2; - arrLength /= 2; - valLength /= 2; - byteOffset /= 2; - } - } - - function read(buf, i) { - if (indexSize === 1) { - return buf[i]; - } else { - return buf.readUInt16BE(i * indexSize); - } - } - - let i; - if (dir) { - let foundIndex = -1; - for (i = byteOffset; i < arrLength; i++) { - if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) { - if (foundIndex === -1) foundIndex = i; - if (i - foundIndex + 1 === valLength) return foundIndex * indexSize; - } else { - if (foundIndex !== -1) i -= i - foundIndex; - foundIndex = -1; - } - } - } else { - if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength; - for (i = byteOffset; i >= 0; i--) { - let found = true; - for (let j = 0; j < valLength; j++) { - if (read(arr, i + j) !== read(val, j)) { - found = false; - break; - } - } - if (found) return i; - } - } - - return -1; -} - -function utf8ToBytes(string, units?) { - units = units || Infinity; - let codePoint; - const length = string.length; - let leadSurrogate = null; - const bytes = []; - - for (let i = 0; i < length; ++i) { - codePoint = string.charCodeAt(i); - - // is surrogate component - if (codePoint > 0xd7ff && codePoint < 0xe000) { - // last char was a lead - if (!leadSurrogate) { - // no lead yet - if (codePoint > 0xdbff) { - // unexpected trail - if ((units -= 3) > -1) bytes.push(0xef, 0xbf, 0xbd); - continue; - } else if (i + 1 === length) { - // unpaired lead - if ((units -= 3) > -1) bytes.push(0xef, 0xbf, 0xbd); - continue; - } - - // valid lead - leadSurrogate = codePoint; - - continue; - } - - // 2 leads in a row - if (codePoint < 0xdc00) { - if ((units -= 3) > -1) bytes.push(0xef, 0xbf, 0xbd); - leadSurrogate = codePoint; - continue; - } - - // valid surrogate pair - codePoint = (((leadSurrogate - 0xd800) << 10) | (codePoint - 0xdc00)) + 0x10000; - } else if (leadSurrogate) { - // valid bmp char, but last char was a lead - if ((units -= 3) > -1) bytes.push(0xef, 0xbf, 0xbd); - } - - leadSurrogate = null; - - // encode utf8 - if (codePoint < 0x80) { - if ((units -= 1) < 0) break; - bytes.push(codePoint); - } else if (codePoint < 0x800) { - if ((units -= 2) < 0) break; - bytes.push((codePoint >> 0x6) | 0xc0, (codePoint & 0x3f) | 0x80); - } else if (codePoint < 0x10000) { - if ((units -= 3) < 0) break; - bytes.push( - (codePoint >> 0xc) | 0xe0, - ((codePoint >> 0x6) & 0x3f) | 0x80, - (codePoint & 0x3f) | 0x80 - ); - } else if (codePoint < 0x110000) { - if ((units -= 4) < 0) break; - bytes.push( - (codePoint >> 0x12) | 0xf0, - ((codePoint >> 0xc) & 0x3f) | 0x80, - ((codePoint >> 0x6) & 0x3f) | 0x80, - (codePoint & 0x3f) | 0x80 - ); - } else { - throw new Error("Invalid code point"); - } - } - - return bytes; -} - -function hexWrite(buf, string, offset, length) { - offset = Number(offset) || 0; - const remaining = buf.length - offset; - if (!length) { - length = remaining; - } else { - length = Number(length); - if (length > remaining) { - length = remaining; - } - } - - const strLen = string.length; - - if (length > strLen / 2) { - length = strLen / 2; - } - let i; - for (i = 0; i < length; ++i) { - const a = hexCharValueTable[string[i * 2]]; - const b = hexCharValueTable[string[i * 2 + 1]]; - if (a === undefined || b === undefined) { - return i; - } - buf[offset + i] = (a << 4) | b; - } - return i; -} - -function base64ToBytes(str) { - return base64.toByteArray(base64clean(str)); -} - -function utf8Write(buf, string, offset, length) { - return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length); -} - -function asciiWrite(buf, string, offset, length) { - return blitBuffer(asciiToBytes(string), buf, offset, length); -} - -function base64Write(buf, string, offset, length) { - return blitBuffer(base64ToBytes(string), buf, offset, length); -} - -function ucs2Write(buf, string, offset, length) { - return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length); -} - -function asciiToBytes(str) { - const byteArray = []; - for (let i = 0; i < str.length; ++i) { - // Node's code seems to be doing this and not & 0x7F.. - byteArray.push(str.charCodeAt(i) & 0xff); - } - return byteArray; -} - -function utf16leToBytes(str, units) { - let c, hi, lo; - const byteArray = []; - for (let i = 0; i < str.length; ++i) { - if ((units -= 2) < 0) break; - - c = str.charCodeAt(i); - hi = c >> 8; - lo = c % 256; - byteArray.push(lo); - byteArray.push(hi); - } - - return byteArray; -} - -const INVALID_BASE64_RE = /[^+/0-9A-Za-z-_]/g; - -function base64clean(str) { - // Node takes equal signs as end of the Base64 encoding - str = str.split("=")[0]; - // Node strips out invalid characters like \n and \t from the string, base64-js does not - str = str.trim().replace(INVALID_BASE64_RE, ""); - // Node converts strings with length < 2 to '' - if (str.length < 2) return ""; - // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not - while (str.length % 4 !== 0) { - str = str + "="; - } - return str; -} - -function blitBuffer(src, dst, offset, length) { - let i; - for (i = 0; i < length; ++i) { - if (i + offset >= dst.length || i >= src.length) break; - dst[i + offset] = src[i]; - } - return i; -} - -function numberIsNaN(obj) { - // For IE11 support - return obj !== obj; // eslint-disable-line no-self-compare -} - -export function flush(state: Uint8Array): string { - // Create a new Uint8Array object from the state. - const buffer = new Uint8Array(state); - return String.fromCharCode.apply(null, buffer); -} - -export function decode(buffer: Uint8Array, state: Uint8Array): string { - let result = ""; - for (let i = 0; i < buffer.length; i++) { - const byte = buffer[i]; - const char = state[byte]; - if (char === undefined) { - throw new Error("Invalid byte"); - } - result += char; - } - return result; -} diff --git a/JS/wasm/crates/wasmjs-engine/shims/src/internal/constants.ts b/JS/wasm/crates/wasmjs-engine/shims/src/internal/constants.ts deleted file mode 100644 index 2013d207f..000000000 --- a/JS/wasm/crates/wasmjs-engine/shims/src/internal/constants.ts +++ /dev/null @@ -1,44 +0,0 @@ -export const CHAR_UPPERCASE_A = 65; /* A */ -export const CHAR_LOWERCASE_A = 97; /* a */ -export const CHAR_UPPERCASE_Z = 90; /* Z */ -export const CHAR_LOWERCASE_Z = 122; /* z */ -export const CHAR_UPPERCASE_C = 67; /* C */ -export const CHAR_LOWERCASE_B = 98; /* b */ -export const CHAR_LOWERCASE_E = 101; /* e */ -export const CHAR_LOWERCASE_N = 110; /* n */ -export const CHAR_DOT = 46; /* . */ -export const CHAR_FORWARD_SLASH = 47; /* / */ -export const CHAR_BACKWARD_SLASH = 92; /* \ */ -export const CHAR_VERTICAL_LINE = 124; /* | */ -export const CHAR_COLON = 58; /* : */ -export const CHAR_QUESTION_MARK = 63; /* ? */ -export const CHAR_UNDERSCORE = 95; /* _ */ -export const CHAR_LINE_FEED = 10; /* \n */ -export const CHAR_CARRIAGE_RETURN = 13; /* \r */ -export const CHAR_TAB = 9; /* \t */ -export const CHAR_FORM_FEED = 12; /* \f */ -export const CHAR_EXCLAMATION_MARK = 33; /* ! */ -export const CHAR_HASH = 35; /* # */ -export const CHAR_SPACE = 32; /* */ -export const CHAR_NO_BREAK_SPACE = 160; /* \u00A0 */ -export const CHAR_ZERO_WIDTH_NOBREAK_SPACE = 65279; /* \uFEFF */ -export const CHAR_LEFT_SQUARE_BRACKET = 91; /* [ */ -export const CHAR_RIGHT_SQUARE_BRACKET = 93; /* ] */ -export const CHAR_LEFT_ANGLE_BRACKET = 60; /* < */ -export const CHAR_RIGHT_ANGLE_BRACKET = 62; /* > */ -export const CHAR_LEFT_CURLY_BRACKET = 123; /* { */ -export const CHAR_RIGHT_CURLY_BRACKET = 125; /* } */ -export const CHAR_HYPHEN_MINUS = 45; /* - */ -export const CHAR_PLUS = 43; /* + */ -export const CHAR_DOUBLE_QUOTE = 34; /* " */ -export const CHAR_SINGLE_QUOTE = 39; /* ' */ -export const CHAR_PERCENT = 37; /* % */ -export const CHAR_SEMICOLON = 59; /* ; */ -export const CHAR_CIRCUMFLEX_ACCENT = 94; /* ^ */ -export const CHAR_GRAVE_ACCENT = 96; /* ` */ -export const CHAR_AT = 64; /* @ */ -export const CHAR_AMPERSAND = 38; /* & */ -export const CHAR_EQUAL = 61; /* = */ -export const CHAR_0 = 48; /* 0 */ -export const CHAR_9 = 57; /* 9 */ -export const EOL = ";"; diff --git a/JS/wasm/crates/wasmjs-engine/shims/src/internal/crypto.d.ts b/JS/wasm/crates/wasmjs-engine/shims/src/internal/crypto.d.ts deleted file mode 100644 index afab20186..000000000 --- a/JS/wasm/crates/wasmjs-engine/shims/src/internal/crypto.d.ts +++ /dev/null @@ -1,246 +0,0 @@ -import { Buffer } from "./internal_buffer"; - -// random -export function checkPrimeSync(candidate: ArrayBufferView, num_checks: number): boolean; -export function randomPrime( - size: number, - safe: boolean, - add?: ArrayBufferView | undefined, - rem?: ArrayBufferView | undefined -): ArrayBuffer; - -// Hash and Hmac -export class HashHandle { - public constructor(algorithm: string, xofLen: number); - public update(data: Buffer | ArrayBufferView): number; - public digest(): ArrayBuffer; - public copy(xofLen: number): HashHandle; -} - -export type ArrayLike = ArrayBuffer | string | Buffer | ArrayBufferView; - -export class HmacHandle { - public constructor(algorithm: string, key: ArrayLike | CryptoKey); - public update(data: Buffer | ArrayBufferView): number; - public digest(): ArrayBuffer; -} - -// hkdf -export function getHkdf( - hash: string, - key: ArrayLike, - salt: ArrayLike, - info: ArrayLike, - length: number -): ArrayBuffer; - -// pbkdf2 -export function getPbkdf( - password: ArrayLike, - salt: ArrayLike, - iterations: number, - keylen: number, - digest: string -): ArrayBuffer; - -// Keys -export function exportKey(key: CryptoKey, options?: InnerExportOptions): KeyExportResult; -export function equals(key: CryptoKey, otherKey: CryptoKey): boolean; -export function getAsymmetricKeyDetail(key: CryptoKey): AsymmetricKeyDetails; -export function getAsymmetricKeyType(key: CryptoKey): AsymmetricKeyType; -export function createSecretKey(key: ArrayBuffer | ArrayBufferView): CryptoKey; -export function createPrivateKey(key: InnerCreateAsymmetricKeyOptions): CryptoKey; -export function createPublicKey(key: InnerCreateAsymmetricKeyOptions): CryptoKey; - -export type KeyData = string | ArrayBuffer | ArrayBufferView; -// -// export interface RsaKeyAlgorithm { -// name: 'rsa' | 'rsa-pss'; -// modulusLength: number; -// publicExponent: Uint8Array; -// hash?: string; -// } -// -// export interface EcKeyAlgorithm { -// name: 'ec'; -// namedCurve: string; -// } -// -// export interface DhKeyAlgorithm { -// name: 'dh'; -// prime: Uint8Array; -// generator: Uint8Array; -// } -// -// export interface DsaKeyAlgorithm { -// name: 'dsa'; -// prime: Uint8Array; -// divisorLength: number; -// } -// -// export interface HmacKeyAlgorithm { -// name: 'hmac'; -// hash: string; -// } -// -// export interface AesKeyAlgorithm { -// name: 'aes'; -// length: number; -// } -// -// export type KeyAlgorithm = RsaKeyAlgorithm | -// EcKeyAlgorithm | -// DhKeyAlgorithm | -// DsaKeyAlgorithm | -// HmacKeyAlgorithm | -// AesKeyAlgorithm; -// -// export interface CryptoKey { -// algorithm: KeyAlgorithm; -// extractable: boolean; -// type: KeyObjectType; -// usages: string[]; -// } -// -// export interface RsaOtherPrimesInfo { -// d?: string; -// r?: string; -// t?: string; -// } -// -// export interface JsonWebKey { -// alg?: string; -// crv?: string; -// d?: string; -// dp?: string; -// dq?: string; -// e?: string; -// ext?: boolean; -// k?: string; -// key_ops?: string[]; -// kty?: string; -// n?: string; -// oth?: Array; -// p?: string; -// q?: string; -// qi?: string; -// use?: string; -// x?: string; -// y?: string; -// } -// -// export interface CryptoKeyPair { -// privateKey: CryptoKey; -// publicKey: CryptoKey; -// } -// -// export type KeyObjectType = 'secret' | 'public' | 'private'; -// -// export type KeyExportResult = string | Buffer | JsonWebKey; -// -// export type SecretKeyFormat = 'buffer' | 'jwk'; -// export type AsymmetricKeyFormat = 'pem' | 'der' | 'jwk'; -// export type PublicKeyEncoding = 'pkcs1' | 'spki'; -// export type PrivateKeyEncoding = 'pkcs1' | 'pkcs8' | 'sec1'; -// export type AsymmetricKeyType = 'rsa' | 'rsa-pss' | 'dsa' | 'ec' | 'x25519' | 'ed25519' | 'dh'; -// export type SecretKeyType = 'hmac' | 'aes'; -// export type ParamEncoding = 'named' | 'explicit'; -// -// export interface SecretKeyExportOptions { -// format?: SecretKeyFormat; -// } -// -// export interface PublicKeyExportOptions { -// type?: PublicKeyEncoding; -// format?: AsymmetricKeyFormat; -// } -// -// export interface PrivateKeyExportOptions { -// type?: PrivateKeyEncoding; -// format?: AsymmetricKeyFormat; -// cipher?: string; -// passphrase?: string | Uint8Array; -// encoding?: string; -// } -// -// export interface InnerPrivateKeyExportOptions { -// type?: PrivateKeyEncoding; -// format?: AsymmetricKeyFormat; -// cipher?: string; -// passphrase?: Uint8Array; -// } -// -// export type ExportOptions = SecretKeyExportOptions | -// PublicKeyExportOptions | -// PrivateKeyExportOptions; -// -// export type InnerExportOptions = SecretKeyExportOptions | -// PublicKeyExportOptions | -// InnerPrivateKeyExportOptions; -// -// export interface AsymmetricKeyDetails { -// modulusLength?: number; -// publicExponent?: bigint; -// hashAlgorithm?: string; -// mgf1HashAlgorithm?: string; -// saltLength?: number; -// divisorLength?: number; -// namedCurve?: string; -// } -// -// export interface CreateAsymmetricKeyOptions { -// key: string | ArrayBuffer | ArrayBufferView | JsonWebKey; -// format?: AsymmetricKeyFormat; -// type?: PublicKeyEncoding | PrivateKeyEncoding; -// passphrase?: string | Uint8Array; -// encoding?: string; -// } -// -// export interface InnerCreateAsymmetricKeyOptions { -// key?: ArrayBuffer | ArrayBufferView | JsonWebKey | CryptoKey; -// format?: AsymmetricKeyFormat; -// type?: PublicKeyEncoding | PrivateKeyEncoding; -// passphrase?: Uint8Array; -// } -// -// export interface GenerateKeyOptions { -// length: number; -// } -// -// export interface GenerateKeyPairOptions { -// modulusLength?: number; -// publicExponent?: number|bigint; -// hashAlgorithm?: string; -// mgf1HashAlgorithm?: string; -// saltLength?: number; -// divisorLength?: number; -// namedCurve?: string; -// prime?: Uint8Array; -// primeLength?: number; -// generator?: number; -// groupName?: string; -// paramEncoding?: ParamEncoding; -// publicKeyEncoding?: PublicKeyExportOptions; -// privateKeyEncoding?: PrivateKeyExportOptions; -// } - -// DiffieHellman -export class DiffieHellmanHandle { - public constructor( - sizeOrKey: number | ArrayBuffer | ArrayBufferView, - generator: number | ArrayBuffer | ArrayBufferView - ); - public setPublicKey(data: ArrayBuffer | ArrayBufferView | Buffer): void; - public setPrivateKey(data: ArrayBuffer | ArrayBufferView | Buffer): void; - public getPublicKey(): ArrayBuffer; - public getPrivateKey(): ArrayBuffer; - public getGenerator(): ArrayBuffer; - public getPrime(): ArrayBuffer; - - public computeSecret(key: ArrayBuffer | ArrayBufferView): ArrayBuffer; - public generateKeys(): ArrayBuffer; - - public getVerifyError(): number; -} - -export function DiffieHellmanGroupHandle(name: string): DiffieHellmanHandle; diff --git a/JS/wasm/crates/wasmjs-engine/shims/src/internal/crypto.ts b/JS/wasm/crates/wasmjs-engine/shims/src/internal/crypto.ts deleted file mode 100644 index 12248fd6e..000000000 --- a/JS/wasm/crates/wasmjs-engine/shims/src/internal/crypto.ts +++ /dev/null @@ -1,502 +0,0 @@ -import * as sjcl from "sjcl"; -import { Buffer } from "./internal_buffer"; - -export type ArrayLike = ArrayBuffer | string | Buffer | ArrayBufferView; -export type KeyData = string | ArrayBuffer | ArrayBufferView; - -/** - * Checks if a number represented by an ArrayBufferView is prime. - * - * @param {ArrayBufferView} candidate - The ArrayBufferView representing the number to check. - * @param {number} num_checks - The number of checks to perform. - * @returns {boolean} - Returns true if the number is prime, false otherwise. - */ -export function checkPrimeSync(candidate: ArrayBufferView, num_checks: number): boolean { - // Convert ArrayBufferView to number - let num = new Uint32Array(candidate.buffer)[0]; - - // Check if num is less than 2 (not a prime number) - if (num < 2) return false; - - // Check if num is divisible by any number up to its square root - for (let i = 2, sqrt = Math.sqrt(num); i <= sqrt; i++) { - if (num % i === 0) return false; - } - - // If no factors found, num is a prime number - return true; -} - -/** - * Generates a random prime number of a given size. - * - * @param {number} size - The size of the prime number to generate. - * @param {boolean} safe - If true, generates a safe prime (a prime number that is 2 less than another prime number). - * @param {ArrayBufferView} [add] - An ArrayBufferView representing a number to add to the generated prime number. - * @param {ArrayBufferView} [rem] - An ArrayBufferView representing a number to take the remainder of the generated prime number. - * @returns {ArrayBuffer} - Returns an ArrayBuffer representing the generated prime number. - */ -export function randomPrime( - size: number, - safe: boolean, - add?: ArrayBufferView, - rem?: ArrayBufferView -): ArrayBuffer { - let prime: number; - do { - prime = sjcl.random.randomWords(1, 0)[0]; - prime = Math.abs(prime) % 2 ** size; - if (safe) { - prime = 2 * prime + 1; - } - if (add) { - prime += new Uint32Array(add.buffer)[0]; - } - if (rem) { - prime %= new Uint32Array(rem.buffer)[0]; - } - } while (!checkPrimeSync(new Uint32Array([prime]), 10)); - - return new Uint32Array([prime]).buffer; -} - -// hkdf -export function getHkdf( - hash: string, - key: ArrayLike, - salt: ArrayLike, - info: ArrayLike, - length: number -): ArrayBuffer { - // Convert key, salt, and info to bitArrays - let keyBits = sjcl.codec.utf8String.toBits(key.toString()); - let saltBits = sjcl.codec.utf8String.toBits(salt.toString()); - let infoBits = sjcl.codec.utf8String.toBits(info.toString()); - - // Use sjcl.misc.hkdf to generate the key - // @ts-ignore - let derivedKeyBits = sjcl.misc.hkdf(keyBits, length, saltBits, hash, infoBits); - - // Convert the derived key to an ArrayBuffer and return it - return sjcl.codec.arrayBuffer.fromBits(derivedKeyBits); -} - -// pbkdf2 -export function getPbkdf( - password: ArrayLike, - salt: ArrayLike, - iterations: number, - keylen: number, - digest: string -): ArrayBuffer { - // Convert password and salt to bitArrays - let passwordBits = sjcl.codec.utf8String.toBits(password.toString()); - let saltBits = sjcl.codec.utf8String.toBits(salt.toString()); - - // Use sjcl.misc.pbkdf2 to generate the key - // @ts-ignore - let derivedKeyBits = sjcl.misc.pbkdf2(passwordBits, saltBits, iterations, keylen * 8, digest); - - // Convert the derived key to an ArrayBuffer and return it - return sjcl.codec.arrayBuffer.fromBits(derivedKeyBits); -} - -export class HashHandle { - private hash: sjcl.SjclHash; - - public constructor(algorithm: string, xofLen: number) { - switch (algorithm) { - case "sha1": - this.hash = new sjcl.hash.sha1(); - break; - case "sha256": - this.hash = new sjcl.hash.sha256(); - break; - case "sha512": - this.hash = new sjcl.hash.sha512(); - break; - default: - throw new Error(`Unsupported hash algorithm: ${algorithm}`); - } - - if (xofLen !== 0) { - throw new Error(`Unsupported xofLen: ${xofLen}`); - } - } - - public update(data: Buffer | ArrayBufferView): number { - let dataBits = sjcl.codec.utf8String.toBits(data.toString()); - this.hash.update(dataBits); - return this.hash.finalize().length; - } - - public digest(): ArrayBuffer { - let digestBits = this.hash.finalize(); - return sjcl.codec.arrayBuffer.fromBits(digestBits); - } - - public copy(xofLen: number): HashHandle { - let algo = ""; - let hash = this.hash; - switch (true) { - case hash instanceof sjcl.hash.sha1: - algo = "sha1"; - break; - case hash instanceof sjcl.hash.sha256: - algo = "sha256"; - break; - case hash instanceof sjcl.hash.sha512: - algo = "sha512"; - break; - default: - throw new Error(`Unsupported hash algorithm: ${algo}`); - } - let copy = new HashHandle(algo, xofLen); // Replace 'sha256' with the actual algorithm - copy.hash = this.hash; - return copy; - } -} - -export class HmacHandle { - private hmac: sjcl.SjclHMAC; - - public constructor(algorithm: string, key: ArrayLike | CryptoKey) { - let keyBits = sjcl.codec.utf8String.toBits(key.toString()); - switch (algorithm) { - case "sha1": - this.hmac = new sjcl.misc.hmac(keyBits, sjcl.hash.sha1); - break; - case "sha256": - this.hmac = new sjcl.misc.hmac(keyBits, sjcl.hash.sha256); - break; - case "sha512": - this.hmac = new sjcl.misc.hmac(keyBits, sjcl.hash.sha512); - break; - default: - throw new Error(`Unsupported hash algorithm: ${algorithm}`); - } - } - - public update(data: Buffer | ArrayBufferView): number { - let dataBits = sjcl.codec.utf8String.toBits(data.toString()); - this.hmac.update(dataBits); - return this.hmac.digest().length; - } - - public digest(): ArrayBuffer { - let digestBits = this.hmac.digest(); - return sjcl.codec.arrayBuffer.fromBits(digestBits); - } -} - -export interface RsaKeyAlgorithm { - name: "rsa" | "rsa-pss"; - modulusLength: number; - publicExponent: Uint8Array; - hash?: string; -} - -export interface EcKeyAlgorithm { - name: "ec"; - namedCurve: string; -} - -export interface DhKeyAlgorithm { - name: "dh"; - prime: Uint8Array; - generator: Uint8Array; -} - -export interface DsaKeyAlgorithm { - name: "dsa"; - prime: Uint8Array; - divisorLength: number; -} - -export interface HmacKeyAlgorithm { - name: "hmac"; - hash: string; -} - -export interface AesKeyAlgorithm { - name: "aes"; - length: number; -} - -export type KeyAlgorithm = - | RsaKeyAlgorithm - | EcKeyAlgorithm - | DhKeyAlgorithm - | DsaKeyAlgorithm - | HmacKeyAlgorithm - | AesKeyAlgorithm; - -export interface CryptoKey { - algorithm: KeyAlgorithm; - extractable: boolean; - type: KeyObjectType; - usages: string[]; -} - -export interface RsaOtherPrimesInfo { - d?: string; - r?: string; - t?: string; -} - -export interface JsonWebKey { - alg?: string; - crv?: string; - d?: string; - dp?: string; - dq?: string; - e?: string; - ext?: boolean; - k?: string; - key_ops?: string[]; - kty?: string; - n?: string; - oth?: Array; - p?: string; - q?: string; - qi?: string; - use?: string; - x?: string; - y?: string; -} - -export interface CryptoKeyPair { - privateKey: CryptoKey; - publicKey: CryptoKey; -} - -export type KeyObjectType = "secret" | "public" | "private"; - -export type KeyExportResult = string | Buffer | JsonWebKey; - -export type SecretKeyFormat = "buffer" | "jwk"; -export type AsymmetricKeyFormat = "pem" | "der" | "jwk"; -export type PublicKeyEncoding = "pkcs1" | "spki"; -export type PrivateKeyEncoding = "pkcs1" | "pkcs8" | "sec1"; -export type AsymmetricKeyType = "rsa" | "rsa-pss" | "dsa" | "ec" | "x25519" | "ed25519" | "dh"; -export type SecretKeyType = "hmac" | "aes"; -export type ParamEncoding = "named" | "explicit"; - -export interface SecretKeyExportOptions { - format?: SecretKeyFormat; -} - -export interface PublicKeyExportOptions { - type?: PublicKeyEncoding; - format?: AsymmetricKeyFormat; -} - -export interface PrivateKeyExportOptions { - type?: PrivateKeyEncoding; - format?: AsymmetricKeyFormat; - cipher?: string; - passphrase?: string | Uint8Array; - encoding?: string; -} - -export interface InnerPrivateKeyExportOptions { - type?: PrivateKeyEncoding; - format?: AsymmetricKeyFormat; - cipher?: string; - passphrase?: Uint8Array; -} - -export type ExportOptions = - | SecretKeyExportOptions - | PublicKeyExportOptions - | PrivateKeyExportOptions; - -export type InnerExportOptions = - | SecretKeyExportOptions - | PublicKeyExportOptions - | InnerPrivateKeyExportOptions; - -export interface AsymmetricKeyDetails { - modulusLength?: number; - publicExponent?: bigint; - hashAlgorithm?: string; - mgf1HashAlgorithm?: string; - saltLength?: number; - divisorLength?: number; - namedCurve?: string; -} - -export interface CreateAsymmetricKeyOptions { - key: string | ArrayBuffer | ArrayBufferView | JsonWebKey; - format?: AsymmetricKeyFormat; - type?: PublicKeyEncoding | PrivateKeyEncoding; - passphrase?: string | Uint8Array; - encoding?: string; -} - -export interface InnerCreateAsymmetricKeyOptions { - key?: ArrayBuffer | ArrayBufferView | JsonWebKey | CryptoKey; - format?: AsymmetricKeyFormat; - type?: PublicKeyEncoding | PrivateKeyEncoding; - passphrase?: Uint8Array; -} - -export interface GenerateKeyOptions { - length: number; -} - -export interface GenerateKeyPairOptions { - modulusLength?: number; - publicExponent?: number | bigint; - hashAlgorithm?: string; - mgf1HashAlgorithm?: string; - saltLength?: number; - divisorLength?: number; - namedCurve?: string; - prime?: Uint8Array; - primeLength?: number; - generator?: number; - groupName?: string; - paramEncoding?: ParamEncoding; - publicKeyEncoding?: PublicKeyExportOptions; - privateKeyEncoding?: PrivateKeyExportOptions; -} - -export function exportKey(key: CryptoKey, options?: InnerExportOptions): KeyExportResult { - // SJCL does not provide a direct method to export keys. - throw new Error("Function exportKey is not implemented yet"); -} - -export function equals(key: CryptoKey, otherKey: CryptoKey): boolean { - // SJCL does not provide a direct method to compare keys. - throw new Error("Function equals is not implemented yet"); -} - -export function getAsymmetricKeyDetail(key: CryptoKey): AsymmetricKeyDetails { - // SJCL does not provide a direct method to get asymmetric key details. - throw new Error("Function getAsymmetricKeyDetail is not implemented yet"); -} - -export function getAsymmetricKeyType(key: CryptoKey): AsymmetricKeyType { - // SJCL does not provide a direct method to get asymmetric key type. - throw new Error("Function getAsymmetricKeyType is not implemented yet"); -} - -export function createSecretKey(key: ArrayBuffer | ArrayBufferView): CryptoKey { - let keyArray: Uint8Array; - if (key instanceof ArrayBuffer) { - keyArray = new Uint8Array(key); - } else { - keyArray = new Uint8Array(key.buffer, key.byteOffset, key.byteLength); - } - - let keyBits = sjcl.codec.bytes.toBits(Array.from(keyArray)); - - let cipher = new sjcl.cipher.aes(keyBits); - - return { - algorithm: { - name: "aes", - length: key.byteLength * 8, - }, - extractable: true, - type: "secret", - usages: ["encrypt", "decrypt"], - }; -} - -export function createPrivateKey(key: InnerCreateAsymmetricKeyOptions): CryptoKey { - // SJCL does not provide a direct method to create private keys. - throw new Error("Function createPrivateKey is not implemented yet"); -} - -export function createPublicKey(key: InnerCreateAsymmetricKeyOptions): CryptoKey { - // SJCL does not provide a direct method to create public keys. - throw new Error("Function createPublicKey is not implemented yet"); -} - -export class DiffieHellmanHandle { - private prime: sjcl.BigNumber; - private generator: sjcl.BigNumber; - private privateKey: sjcl.BigNumber; - private publicKey: sjcl.BigNumber; - - public constructor( - sizeOrKey: number | ArrayBuffer | ArrayBufferView, - generator: number | ArrayBuffer | ArrayBufferView - ) { - // Convert sizeOrKey and generator to sjcl.bn - this.prime = new sjcl.bn(sizeOrKey.toString()); - this.generator = new sjcl.bn(generator.toString()); - - // Generate a random private key - this.privateKey = sjcl.bn.random(this.prime.sub(2), 10).add(1); - - // Calculate the public key - this.publicKey = this.generator.powermod(this.privateKey, this.prime); - } - - public setPublicKey(data: ArrayBuffer | ArrayBufferView | Buffer): void { - this.publicKey = new sjcl.bn(data.toString()); - } - - public setPrivateKey(data: ArrayBuffer | ArrayBufferView | Buffer): void { - this.privateKey = new sjcl.bn(data.toString()); - } - - public getPublicKey(): ArrayBuffer { - return sjcl.codec.arrayBuffer.fromBits(this.publicKey.toBits()); - } - - public getPrivateKey(): ArrayBuffer { - return sjcl.codec.arrayBuffer.fromBits(this.privateKey.toBits()); - } - - public getGenerator(): ArrayBuffer { - return sjcl.codec.arrayBuffer.fromBits(this.generator.toBits()); - } - - public getPrime(): ArrayBuffer { - return sjcl.codec.arrayBuffer.fromBits(this.prime.toBits()); - } - - public computeSecret(key: ArrayBuffer | ArrayBufferView): ArrayBuffer { - let otherPublicKey = new sjcl.bn(key.toString()); - let secret = otherPublicKey.powermod(this.privateKey, this.prime); - return sjcl.codec.arrayBuffer.fromBits(secret.toBits()); - } - - public generateKeys(): ArrayBuffer { - // Generate a new private key - this.privateKey = sjcl.bn.random(this.prime.sub(2), 10).add(1); - - // Calculate the new public key - this.publicKey = this.generator.powermod(this.privateKey, this.prime); - - return this.getPublicKey(); - } - - public getVerifyError(): number { - // This method is not applicable to the Diffie-Hellman protocol - throw new Error("Method getVerifyError is not applicable to the Diffie-Hellman protocol"); - } -} - -export function DiffieHellmanGroupHandle(name: string): DiffieHellmanHandle { - // Define some named groups with their prime and generator values - const groups: { [name: string]: { prime: number; generator: number } } = { - modp1: { prime: 2, generator: 2 }, - modp2: { prime: 3, generator: 2 }, - modp5: { prime: 5, generator: 2 }, - // Add more named groups here - }; - - // Get the named group - const group = groups[name]; - if (!group) { - throw new Error(`Unknown group name: ${name}`); - } - - // Create a DiffieHellmanHandle with the prime and generator of the named group - return new DiffieHellmanHandle(group.prime, group.generator); -} diff --git a/JS/wasm/crates/wasmjs-engine/shims/src/internal/crypto_dh.ts b/JS/wasm/crates/wasmjs-engine/shims/src/internal/crypto_dh.ts deleted file mode 100644 index 762f512f9..000000000 --- a/JS/wasm/crates/wasmjs-engine/shims/src/internal/crypto_dh.ts +++ /dev/null @@ -1,198 +0,0 @@ -/* eslint-disable */ - -"use strict"; - -import { Buffer } from "./internal_buffer"; - -import * as cryptoImpl from "./crypto"; -type ArrayLike = cryptoImpl.ArrayLike; - -import { ERR_CRYPTO_ECDH_INVALID_PUBLIC_KEY, ERR_INVALID_ARG_TYPE } from "./internal_errors"; - -import { validateInt32 } from "./validators"; - -import { isArrayBufferView, isAnyArrayBuffer } from "./internal_types"; - -import { getArrayBufferOrView, toBuf, kHandle } from "./crypto_util"; - -const DH_GENERATOR = 2; - -interface DiffieHellman { - [kHandle]: cryptoImpl.DiffieHellmanHandle; -} - -let DiffieHellman = function ( - this: DiffieHellman, - sizeOrKey: number | ArrayLike, - keyEncoding?: number | string, - generator?: number | ArrayLike, - genEncoding?: string -): DiffieHellman { - if (!(this instanceof DiffieHellman)) - return new DiffieHellman(sizeOrKey, keyEncoding, generator, genEncoding); - if ( - typeof sizeOrKey !== "number" && - typeof sizeOrKey !== "string" && - !isArrayBufferView(sizeOrKey) && - !isAnyArrayBuffer(sizeOrKey) - ) { - throw new ERR_INVALID_ARG_TYPE( - "sizeOrKey", - ["number", "string", "ArrayBuffer", "Buffer", "TypedArray", "DataView"], - sizeOrKey - ); - } - - // Sizes < 0 don't make sense but they _are_ accepted (and subsequently - // rejected with ERR_OSSL_BN_BITS_TOO_SMALL) by OpenSSL. The glue code - // in node_crypto.cc accepts values that are IsInt32() for that reason - // and that's why we do that here too. - if (typeof sizeOrKey === "number") validateInt32(sizeOrKey, "sizeOrKey"); - - if (keyEncoding && !Buffer.isEncoding(keyEncoding) && keyEncoding !== "buffer") { - genEncoding = generator as any; - generator = keyEncoding; - keyEncoding = "utf-8"; // default encoding - } - - keyEncoding ??= "utf-8"; - genEncoding ??= "utf-8"; - - if (typeof sizeOrKey !== "number") sizeOrKey = toBuf(sizeOrKey, keyEncoding as string); - - if (!generator) { - generator = DH_GENERATOR; - } else if (typeof generator === "number") { - validateInt32(generator, "generator"); - } else if (typeof generator === "string") { - generator = toBuf(generator, genEncoding); - } else if (!isArrayBufferView(generator) && !isAnyArrayBuffer(generator)) { - throw new ERR_INVALID_ARG_TYPE( - "generator", - ["number", "string", "ArrayBuffer", "Buffer", "TypedArray", "DataView"], - generator - ); - } - - this[kHandle] = new cryptoImpl.DiffieHellmanHandle(sizeOrKey as any, generator as any); - Object.defineProperty(DiffieHellman.prototype, "verifyError", { - get: function () { - return this[kHandle].getVerifyError(); - }, - configurable: true, - enumerable: true, - }); - return this; -} as any as { - new ( - sizeOrKey: number | ArrayLike, - keyEncoding?: number | string, - generator?: number | ArrayLike, - genEncoding?: string - ): DiffieHellman; -}; - -interface DiffieHellmanGroup { - [kHandle]: cryptoImpl.DiffieHellmanHandle; -} - -let DiffieHellmanGroup = function (this: DiffieHellmanGroup, name: string): DiffieHellmanGroup { - if (!(this instanceof DiffieHellmanGroup)) return new DiffieHellmanGroup(name); - - // The C++-based handle is shared between both classes, so DiffieHellmanGroupHandle() is merely - // a different constructor for a DiffieHellmanHandle. - this[kHandle] = cryptoImpl.DiffieHellmanGroupHandle(name); - Object.defineProperty(DiffieHellmanGroup.prototype, "verifyError", { - get: function () { - return this[kHandle].getVerifyError(); - }, - configurable: true, - enumerable: true, - }); - return this; -} as any as { new (name: string): DiffieHellmanGroup }; - -DiffieHellmanGroup.prototype.generateKeys = DiffieHellman.prototype.generateKeys = dhGenerateKeys; -DiffieHellmanGroup.prototype.computeSecret = DiffieHellman.prototype.computeSecret = - dhComputeSecret; -DiffieHellmanGroup.prototype.getPrime = DiffieHellman.prototype.getPrime = dhGetPrime; -DiffieHellmanGroup.prototype.getGenerator = DiffieHellman.prototype.getGenerator = dhGetGenerator; -DiffieHellmanGroup.prototype.getPublicKey = DiffieHellman.prototype.getPublicKey = dhGetPublicKey; -DiffieHellmanGroup.prototype.getPrivateKey = DiffieHellman.prototype.getPrivateKey = - dhGetPrivateKey; -DiffieHellman.prototype.setPublicKey = dhSetPublicKey; -DiffieHellman.prototype.setPrivateKey = dhSetPrivateKey; - -export { DiffieHellman, DiffieHellmanGroup }; - -type DHLike = DiffieHellman | DiffieHellmanGroup; -function dhGenerateKeys(this: DHLike, encoding?: string): Buffer | string { - const keys = this[kHandle].generateKeys(); - return encode(keys, encoding); -} - -function dhComputeSecret( - this: DHLike, - key: ArrayLike, - inEnc?: string, - outEnc?: string -): Buffer | string { - key = getArrayBufferOrView(key, "key", inEnc); - const ret = this[kHandle].computeSecret(key); - if (typeof ret === "string") throw new ERR_CRYPTO_ECDH_INVALID_PUBLIC_KEY(); - return encode(ret, outEnc); -} - -function dhGetPrime(this: DHLike, encoding?: string): Buffer | string { - const prime = this[kHandle].getPrime(); - return encode(prime, encoding); -} - -function dhGetGenerator(this: DHLike, encoding?: string): Buffer | string { - const generator = this[kHandle].getGenerator(); - return encode(generator, encoding); -} - -function dhGetPublicKey(this: DHLike, encoding?: string): Buffer | string { - const key = this[kHandle].getPublicKey(); - return encode(key, encoding); -} - -function dhGetPrivateKey(this: DHLike, encoding?: string): Buffer | string { - const key = this[kHandle].getPrivateKey(); - return encode(key, encoding); -} - -function dhSetPublicKey(this: DiffieHellman, key: ArrayLike, encoding?: string): DiffieHellman { - key = getArrayBufferOrView(key, "key", encoding); - this[kHandle].setPublicKey(key); - return this; -} - -function dhSetPrivateKey(this: DiffieHellman, key: ArrayLike, encoding?: string): DiffieHellman { - key = getArrayBufferOrView(key, "key", encoding); - this[kHandle].setPrivateKey(key); - return this; -} - -function encode(buffer: ArrayBuffer, encoding?: string): Buffer | string { - if (encoding && encoding !== "buffer") return Buffer.from(buffer).toString(encoding); - return Buffer.from(buffer); -} - -export function createDiffieHellman( - sizeOrKey: number | ArrayLike, - keyEncoding?: number | string, - generator?: number | ArrayLike, - genEncoding?: string -): DiffieHellman { - return new DiffieHellman(sizeOrKey, keyEncoding, generator, genEncoding); -} - -export function createDiffieHellmanGroup(name: string): DiffieHellmanGroup { - return new DiffieHellmanGroup(name); -} - -export function getDiffieHellman(name: string): DiffieHellmanGroup { - return createDiffieHellmanGroup(name); -} diff --git a/JS/wasm/crates/wasmjs-engine/shims/src/internal/crypto_hash.ts b/JS/wasm/crates/wasmjs-engine/shims/src/internal/crypto_hash.ts deleted file mode 100644 index 296bd2013..000000000 --- a/JS/wasm/crates/wasmjs-engine/shims/src/internal/crypto_hash.ts +++ /dev/null @@ -1,230 +0,0 @@ -/* eslint-disable */ - -import * as cryptoImpl from "./crypto"; -type ArrayLike = cryptoImpl.ArrayLike; - -import { kFinalized, kHandle, kState, getArrayBufferOrView, getStringOption } from "./crypto_util"; - -import { Buffer } from "./internal_buffer"; - -import { - ERR_CRYPTO_HASH_FINALIZED, - ERR_CRYPTO_HASH_UPDATE_FAILED, - ERR_CRYPTO_INVALID_KEY_OBJECT_TYPE, - ERR_INVALID_ARG_TYPE, -} from "./internal_errors"; - -import { validateEncoding, validateString, validateUint32 } from "./validators"; - -import { normalizeEncoding } from "./internal_utils"; - -import { isArrayBufferView, isCryptoKey, isAnyArrayBuffer } from "./internal_types"; - -import { Transform, TransformOptions, TransformCallback } from "./streams_transform"; - -import { KeyObject } from "./crypto_keys"; - -export interface HashOptions extends TransformOptions { - outputLength?: number; -} - -interface _kState { - [kFinalized]: boolean; -} - -interface Hash extends Transform { - [kHandle]: cryptoImpl.HashHandle; - [kState]: _kState; -} - -// These helper functions are needed because the constructors can -// use new, in which case V8 cannot inline the recursive constructor call -export function createHash(algorithm: string, options?: HashOptions): Hash { - return new Hash(algorithm, options); -} - -let Hash = function ( - this: Hash, - algorithm: string | cryptoImpl.HashHandle, - options?: HashOptions -): Hash { - if (!(this instanceof Hash)) return new Hash(algorithm, options); - - const xofLen = typeof options === "object" ? options.outputLength : undefined; - if (xofLen !== undefined) validateUint32(xofLen, "options.outputLength"); - if (algorithm instanceof cryptoImpl.HashHandle) { - this[kHandle] = algorithm.copy(xofLen as number); - } else { - validateString(algorithm, "algorithm"); - this[kHandle] = new cryptoImpl.HashHandle(algorithm, xofLen as number); - } - this[kState] = { - [kFinalized]: false, - }; - - Transform.call(this, options); - return this; -} as any as { new (algorithm: string | cryptoImpl.HashHandle, options?: HashOptions): Hash }; - -Object.setPrototypeOf(Hash.prototype, Transform.prototype); -Object.setPrototypeOf(Hash, Transform); - -Hash.prototype.copy = function (this: Hash, options?: HashOptions): Hash { - const state = this[kState]; - if (state[kFinalized]) throw new ERR_CRYPTO_HASH_FINALIZED(); - - return new Hash(this[kHandle], options); -}; - -Hash.prototype._transform = function ( - this: Hash | Hmac, - chunk: string | Buffer | ArrayBufferView, - encoding: string, - callback: TransformCallback -): void { - if (typeof chunk === "string") { - encoding ??= "utf-8"; - validateEncoding(chunk, encoding); - encoding = normalizeEncoding(encoding)!; - chunk = Buffer.from(chunk, encoding); - } - this[kHandle].update(chunk); - callback(); -}; - -Hash.prototype._flush = function (this: Hash | Hmac, callback: TransformCallback): void { - this.push(Buffer.from(this[kHandle].digest())); - callback(); -}; - -Hash.prototype.update = function ( - this: Hash | Hmac, - data: string | Buffer | ArrayBufferView, - encoding?: string -): Hash | Hmac { - encoding ??= "utf8"; - if (encoding === "buffer") { - encoding = undefined; - } - - const state = this[kState]; - if (state[kFinalized]) throw new ERR_CRYPTO_HASH_FINALIZED(); - - if (typeof data === "string") { - validateEncoding(data, encoding!); - encoding = normalizeEncoding(encoding); - data = Buffer.from(data, encoding); - } else if (!isArrayBufferView(data)) { - throw new ERR_INVALID_ARG_TYPE( - "data", - ["string", "Buffer", "TypedArray", "DataView"], - data - ); - } - - if (!this[kHandle].update(data)) throw new ERR_CRYPTO_HASH_UPDATE_FAILED(); - return this; -}; - -Hash.prototype.digest = function (this: Hash, outputEncoding?: string): Buffer | string { - const state = this[kState]; - if (state[kFinalized]) throw new ERR_CRYPTO_HASH_FINALIZED(); - - // Explicit conversion for backward compatibility. - const ret = Buffer.from(this[kHandle].digest()); - state[kFinalized] = true; - if (outputEncoding !== undefined && outputEncoding !== "buffer") { - return ret.toString(outputEncoding); - } else { - return ret; - } -}; - -/////////////////////////// - -interface Hmac extends Transform { - [kHandle]: cryptoImpl.HmacHandle; - [kState]: _kState; -} - -export function createHmac( - hmac: string, - key: ArrayLike | KeyObject | CryptoKey, - options?: TransformOptions -): Hmac { - return new Hmac(hmac, key, options); -} - -let Hmac = function ( - this: Hmac, - hmac: string, - key: ArrayLike | KeyObject | cryptoImpl.CryptoKey, - options?: TransformOptions -): Hmac { - if (!(this instanceof Hmac)) { - return new Hmac(hmac, key, options); - } - validateString(hmac, "hmac"); - const encoding = getStringOption(options, "encoding"); - - if (key instanceof KeyObject) { - if (key.type !== "secret") { - throw new ERR_CRYPTO_INVALID_KEY_OBJECT_TYPE(key.type, "secret"); - } - this[kHandle] = new cryptoImpl.HmacHandle(hmac, key[kHandle]); - } else if (isCryptoKey(key)) { - if ((key as cryptoImpl.CryptoKey).type !== "secret") { - throw new ERR_CRYPTO_INVALID_KEY_OBJECT_TYPE( - (key as cryptoImpl.CryptoKey).type, - "secret" - ); - } - this[kHandle] = new cryptoImpl.HmacHandle(hmac, key); - } else if (typeof key !== "string" && !isArrayBufferView(key) && !isAnyArrayBuffer(key)) { - throw new ERR_INVALID_ARG_TYPE( - "key", - ["ArrayBuffer", "Buffer", "ArrayBufferView", "string", "KeyObject", "CryptoKey"], - key - ); - } else { - this[kHandle] = new cryptoImpl.HmacHandle( - hmac, - getArrayBufferOrView(key as ArrayLike, "key", encoding) - ); - } - - this[kState] = { - [kFinalized]: false, - }; - Transform.call(this, options); - return this; -} as any as { - new (hmac: string, key: ArrayLike | KeyObject | CryptoKey, options?: TransformOptions): Hmac; -}; - -Object.setPrototypeOf(Hmac.prototype, Transform.prototype); -Object.setPrototypeOf(Hmac, Transform); - -Hmac.prototype.update = Hash.prototype.update; - -Hmac.prototype.digest = function (this: Hmac, outputEncoding?: string): Buffer | string { - const state = this[kState]; - if (state[kFinalized]) { - const buf = Buffer.from(""); - return outputEncoding === "buffer" ? buf : buf.toString(outputEncoding); - } - - // Explicit conversion for backward compatibility. - const ret = Buffer.from(this[kHandle].digest()); - state[kFinalized] = true; - if (outputEncoding !== undefined && outputEncoding !== "buffer") { - return ret.toString(outputEncoding); - } else { - return ret; - } -}; - -Hmac.prototype._flush = Hash.prototype._flush; -Hmac.prototype._transform = Hash.prototype._transform; - -export { Hash, Hmac }; diff --git a/JS/wasm/crates/wasmjs-engine/shims/src/internal/crypto_hkdf.ts b/JS/wasm/crates/wasmjs-engine/shims/src/internal/crypto_hkdf.ts deleted file mode 100644 index 7196bea89..000000000 --- a/JS/wasm/crates/wasmjs-engine/shims/src/internal/crypto_hkdf.ts +++ /dev/null @@ -1,110 +0,0 @@ -/* eslint-disable */ - -"use strict"; - -import * as cryptoImpl from "./crypto"; - -import { validateFunction, validateInteger, validateString } from "./validators"; - -import { KeyObject } from "./crypto_keys"; - -type ArrayLike = cryptoImpl.ArrayLike; - -import { kMaxLength } from "./internal_buffer"; - -import { toBuf, validateByteSource } from "./crypto_util"; - -import { isAnyArrayBuffer, isArrayBufferView } from "./internal_types"; - -import { NodeError, ERR_INVALID_ARG_TYPE, ERR_OUT_OF_RANGE } from "./internal_errors"; - -function validateParameters( - hash: string, - key: ArrayLike | KeyObject, - salt: ArrayLike, - info: ArrayLike, - length: number -) { - // TODO(soon): Add support for KeyObject input. - if (key instanceof KeyObject) { - throw new NodeError( - "ERR_METHOD_NOT_IMPLEMENTED", - "KeyObject support for hkdf() and " + - "hkdfSync() is not yet implemented. Use ArrayBuffer, TypedArray, " + - "DataView, or Buffer instead." - ); - } - - validateString(hash, "digest"); - key = prepareKey(key as unknown as ArrayLike); - salt = validateByteSource(salt, "salt"); - info = validateByteSource(info, "info"); - - validateInteger(length, "length", 0, kMaxLength); - - if (info.byteLength > 1024) { - throw new ERR_OUT_OF_RANGE( - "info", - "must not contain more than 1024 bytes", - info.byteLength - ); - } - - return { - hash, - key, - salt, - info, - length, - }; -} - -function prepareKey(key: ArrayLike): ArrayLike { - key = toBuf(key); - - if (!isAnyArrayBuffer(key) && !isArrayBufferView(key)) { - throw new ERR_INVALID_ARG_TYPE( - "ikm", - ["string", "SecretKeyObject", "ArrayBuffer", "TypedArray", "DataView", "Buffer"], - key - ); - } - - return key; -} - -export function hkdf( - hash: string, - key: ArrayLike | KeyObject, - salt: ArrayLike, - info: ArrayLike, - length: number, - callback: (err: Error | null, derivedKey?: ArrayBuffer) => void -): void { - ({ hash, key, salt, info, length } = validateParameters(hash, key, salt, info, length)); - - validateFunction(callback, "callback"); - - new Promise((res, rej) => { - try { - res(cryptoImpl.getHkdf(hash, key as ArrayLike, salt, info, length)); - } catch (err) { - rej(err); - } - }).then( - (val: ArrayBuffer) => callback(null, val), - (err) => callback(err) - ); -} - -export function hkdfSync( - hash: string, - key: ArrayLike | KeyObject, - salt: ArrayLike, - info: ArrayLike, - length: number -): ArrayBuffer { - ({ hash, key, salt, info, length } = validateParameters(hash, key, salt, info, length)); - - return cryptoImpl.getHkdf(hash, key, salt, info, length); -} diff --git a/JS/wasm/crates/wasmjs-engine/shims/src/internal/crypto_keys.ts b/JS/wasm/crates/wasmjs-engine/shims/src/internal/crypto_keys.ts deleted file mode 100644 index 488d7b8d6..000000000 --- a/JS/wasm/crates/wasmjs-engine/shims/src/internal/crypto_keys.ts +++ /dev/null @@ -1,406 +0,0 @@ -/* eslint-disable */ - -import { Buffer } from "./internal_buffer"; - -import * as cryptoImpl from "./crypto"; - -const { - CryptoKey, - KeyData, - KeyObjectType, - KeyExportResult, - SecretKeyType, - SecretKeyExportOptions, - PublicKeyExportOptions, - PrivateKeyExportOptions, - ExportOptions, - AsymmetricKeyDetails, - AsymmetricKeyType, - CreateAsymmetricKeyOptions, - GenerateKeyOptions, - GenerateKeyPairOptions, - InnerExportOptions, - // TODO(soon): Uncomment these once createPrivateKey/createPublicKey are implemented. - // JsonWebKey, - // InnerCreateAsymmetricKeyOptions, -} = cryptoImpl; - -import { arrayBufferToUnsignedBigInt, kHandle } from "./crypto_util"; - -import { - isAnyArrayBuffer, - isArrayBuffer, - isArrayBufferView, - isUint8Array, - // TODO(soon): Uncomment these once createPrivateKey/createPublicKey are implemented. - // isSharedArrayBuffer, -} from "./internal_types"; - -import { - ERR_INVALID_ARG_TYPE, - ERR_METHOD_NOT_IMPLEMENTED, - // TODO(soon): Uncomment these once createPrivateKey/createPublicKey are implemented. - // ERR_INVALID_ARG_VALUE, -} from "./internal_errors"; - -import { validateObject, validateString } from "./validators"; - -export abstract class KeyObject { - [kHandle]: CryptoKey; - - constructor() { - // KeyObjects cannot be created with new ... use one of the - // create or generate methods, or use from to get from a - // CryptoKey. - throw new Error("Illegal constructor"); - } - - static from(key: CryptoKey): KeyObject { - if (!(key instanceof CryptoKey)) { - throw new ERR_INVALID_ARG_TYPE("key", "CryptoKey", key); - } - switch (key.type) { - case "secret": - return Reflect.construct( - function (this: SecretKeyObject) { - this[kHandle] = key; - }, - [], - SecretKeyObject - ); - case "private": - return Reflect.construct( - function (this: PrivateKeyObject) { - this[kHandle] = key; - }, - [], - PrivateKeyObject - ); - case "public": - return Reflect.construct( - function (this: PublicKeyObject) { - this[kHandle] = key; - }, - [], - PublicKeyObject - ); - } - } - - export(options: ExportOptions = {}): KeyExportResult { - validateObject(options, "options", {}); - - // Yes, converting to any is a bit of a cheat, but it allows us to check - // each option individually without having to do a bunch of type guards. - const opts = options as any; - if (opts.format !== undefined) validateString(opts.format, "options.format"); - if (opts.type !== undefined) validateString(opts.type, "options.type"); - if (this.type === "private") { - if (opts.cipher !== undefined) { - validateString(opts.cipher, "options.cipher"); - if (typeof opts.passphrase === "string") { - opts.passphrase = Buffer.from(opts.passphrase, opts.encoding); - } - if (!isUint8Array(opts.passphrase)) { - throw new ERR_INVALID_ARG_TYPE( - "options.passphrase", - ["string", "Uint8Array"], - opts.passphrase - ); - } - } - } - - const ret = cryptoImpl.exportKey(this[kHandle], options as InnerExportOptions); - if (typeof ret === "string") return ret; - if (isUint8Array(ret)) { - return Buffer.from( - (ret as Uint8Array).buffer, - ret.byteOffset, - ret.byteLength - ) as KeyExportResult; - } else if (isArrayBuffer(ret)) { - return Buffer.from(ret as ArrayBuffer, 0, (ret as ArrayBuffer).byteLength); - } - return ret; - } - - equals(otherKeyObject: KeyObject): boolean { - if (this === otherKeyObject || this[kHandle] === otherKeyObject[kHandle]) return true; - if (this.type !== otherKeyObject.type) return false; - if (!(otherKeyObject[kHandle] instanceof CryptoKey)) { - throw new ERR_INVALID_ARG_TYPE("otherKeyObject", "KeyObject", otherKeyObject); - } - return cryptoImpl.equals(this[kHandle], otherKeyObject[kHandle]); - } - - abstract get type(): KeyObjectType; -} - -abstract class AsymmetricKeyObject extends KeyObject { - get asymmetricKeyDetails(): AsymmetricKeyDetails { - let detail = cryptoImpl.getAsymmetricKeyDetail(this[kHandle]); - if (isArrayBuffer(detail.publicExponent)) { - detail.publicExponent = arrayBufferToUnsignedBigInt(detail.publicExponent as any); - } - return detail; - } - - get asymmetricKeyType(): AsymmetricKeyType { - return cryptoImpl.getAsymmetricKeyType(this[kHandle]); - } -} - -export class PublicKeyObject extends AsymmetricKeyObject { - override export(options?: PublicKeyExportOptions): KeyExportResult { - return super.export(options); - } - - get type(): KeyObjectType { - return "public"; - } -} - -export class PrivateKeyObject extends AsymmetricKeyObject { - override export(options?: PrivateKeyExportOptions): KeyExportResult { - return super.export(options); - } - - get type(): KeyObjectType { - return "private"; - } -} - -export class SecretKeyObject extends KeyObject { - get symmetricKeySize(): number { - return (this[kHandle].algorithm as any).length | 0; - } - - override export(options?: SecretKeyExportOptions): KeyExportResult { - return super.export(options); - } - - get type(): KeyObjectType { - return "secret"; - } -} - -type ValidateKeyDataOptions = { - allowObject?: boolean; -}; -function validateKeyData( - key: unknown, - name: string, - options: ValidateKeyDataOptions = { - allowObject: false, - } -) { - if ( - key == null || - (typeof key !== "string" && - options.allowObject && - typeof key !== "object" && - !isArrayBufferView(key) && - !isAnyArrayBuffer(key)) - ) { - const expected = ["string", "ArrayBuffer", "TypedArray", "DataView"]; - if (options.allowObject) expected.push("object"); - throw new ERR_INVALID_ARG_TYPE(name, expected, key); - } -} - -export function createSecretKey(key: string, encoding?: string): SecretKeyObject; -export function createSecretKey(key: ArrayBuffer | ArrayBufferView): SecretKeyObject; -export function createSecretKey(key: KeyData, encoding?: string): SecretKeyObject { - validateKeyData(key, "key"); - if (typeof key === "string") key = Buffer.from(key as string, encoding); - return KeyObject.from(cryptoImpl.createSecretKey(key)) as SecretKeyObject; -} - -// TODO(soon): Fully implement createPrivateKey/createPublicKey. These are the -// equivalent of the WebCrypto API's importKey() method but operate synchronously -// and support a range of options not currently supported by WebCrypto. Implementing -// these will require either duplicating or significantly refactoring the current -// import key logic that supports Web Crypto now as the import logic is spread out -// over several locations and makes a number of assumptions that Web Crypto is being -// used. -// -// For now, users can use Web Crypto to import a CryptoKey then convert that into -// a KeyObject using KeyObject.from(). -// -// const kPrivateKey = Symbol('privateKey'); -// const kPublicKey = Symbol('publicKey'); - -// function validateAsymmetricKeyOptions( -// key: CreateAsymmetricKeyOptions | KeyData | CryptoKey | KeyObject, -// type: Symbol) { -// validateKeyData(key, 'key', { allowObject: true }); -// let inner : InnerCreateAsymmetricKeyOptions = {}; -// inner.format = 'pem'; -// if (typeof key === 'string') { -// inner.key = Buffer.from(key as string); -// } else if (isArrayBufferView(key)) { -// inner.key = key as ArrayBufferView; -// } else if (isArrayBuffer(key)) { -// inner.key = key as ArrayBuffer; -// } else if (isSharedArrayBuffer(key)) { -// inner.key = key as SharedArrayBuffer; -// } else if (type === kPublicKey && key instanceof KeyObject) { -// // Covers deriving public key from a private key. -// if (key.type !== 'private') { -// throw new ERR_INVALID_ARG_VALUE('key', key, 'must be a private key'); -// } -// inner.key = (key as KeyObject)[kHandle]; -// } else if (type === kPublicKey && key instanceof CryptoKey) { -// // Covers deriving public key from a private key. -// if ((key as CryptoKey).type !== 'private') { -// throw new ERR_INVALID_ARG_VALUE('key', key, 'must be a private key'); -// } -// inner.key = key as CryptoKey; -// } else { -// const options = key as CreateAsymmetricKeyOptions; -// if (typeof options.key === 'string') { -// inner.key = Buffer.from(options.key as string, options.encoding); -// } else if (isArrayBufferView(options.key)) { -// inner.key = options.key as ArrayBufferView; -// } else if (isArrayBuffer(options.key)) { -// inner.key = options.key as ArrayBuffer; -// } else if (isSharedArrayBuffer(options.key)) { -// inner.key = options.key as SharedArrayBuffer; -// } else if (type === kPublicKey && key instanceof KeyObject) { -// if ((options.key as KeyObject).type !== 'private') { -// throw new ERR_INVALID_ARG_VALUE('options.key', options.key, 'must be a private key'); -// } -// inner.key = (options.key as KeyObject)[kHandle]; -// } else if (type === kPublicKey && key instanceof CryptoKey) { -// if ((options.key as CryptoKey).type !== 'private') { -// throw new ERR_INVALID_ARG_VALUE('options.key', options.key, 'must be a private key'); -// } -// inner.key = options.key as CryptoKey; -// } else { -// inner.key = key as JsonWebKey; -// } -// validateKeyData(inner.key, 'options.key', { allowObject: true }); - -// if (options.format !== undefined) { -// validateString(options.format, 'options.format'); -// inner.format = options.format; -// } -// if (options.type !== undefined) { -// validateString(options.type, 'options.type'); -// inner.type = options.type; -// } -// if (options.passphrase !== undefined) { -// if (typeof options.passphrase === 'string') { -// inner.passphrase = Buffer.from(options.passphrase, options.encoding); -// } else { -// if (!isUint8Array(options.passphrase)) { -// throw new ERR_INVALID_ARG_TYPE('options.passphrase', [ -// 'string', 'Uint8Array' -// ], options.passphrase); -// } -// inner.passphrase = options.passphrase; -// } -// if (inner.passphrase.byteLength > 1024) { -// throw new ERR_INVALID_ARG_VALUE('options.passphrase', options.passphrase.length, '<= 1024'); -// } -// } -// } -// return inner; -// } - -export function createPrivateKey(key: string): PrivateKeyObject; -export function createPrivateKey(key: ArrayBuffer | ArrayBufferView): PrivateKeyObject; -export function createPrivateKey(key: CreateAsymmetricKeyOptions): PrivateKeyObject; -export function createPrivateKey(_key: CreateAsymmetricKeyOptions | KeyData): PrivateKeyObject { - // The options here are fairly complex. The key data can be a string, - // ArrayBuffer, or ArrayBufferView. The first argument can be one of - // these or an object with a key property that is one of these. If the - // key data is a string, then it will be decoded using an encoding - // (defaults to UTF8). - throw new ERR_METHOD_NOT_IMPLEMENTED("crypto.createPrivateKey"); - // return KeyObject.from(cryptoImpl.createPrivateKey( - // validateAsymmetricKeyOptions(key, kPrivateKey))) as PrivateKeyObject; -} - -export function createPublicKey(key: string): PublicKeyObject; -export function createPublicKey(key: ArrayBuffer): PublicKeyObject; -export function createPublicKey(key: ArrayBufferView): PublicKeyObject; - -export function createPublicKey(key: KeyObject): PublicKeyObject; -export function createPublicKey(key: CryptoKey): PublicKeyObject; -export function createPublicKey(key: CreateAsymmetricKeyOptions): PublicKeyObject; -export function createPublicKey( - _key: CreateAsymmetricKeyOptions | KeyData | CryptoKey | KeyObject -): PublicKeyObject { - // The options here are a bit complicated. The key material itself can - // either be a string, ArrayBuffer, or ArrayBufferView. It is also - // possible to pass a private key in the form of either a CryptoKey - // or KeyObject. The first argument can be one of these, or an object - // whose key value is one of these. If the key data is a string, then - // it will be decoded using an encoding (defaults to UTF8). If a - // CryptoKey or KeyObject is passed, it will be used to derived the - // public key. - throw new ERR_METHOD_NOT_IMPLEMENTED("crypto.createPublicKey"); - // return KeyObject.from(cryptoImpl.createPublicKey( - // validateAsymmetricKeyOptions(key, kPublicKey))) as PublicKeyObject; -} - -// ====================================================================================== - -export type PublicKeyResult = KeyExportResult | PublicKeyObject; -export type PrivateKeyResult = KeyExportResult | PrivateKeyObject; -export type GenerateKeyCallback = (err?: any, key?: KeyObject) => void; -export type GenerateKeyPairCallback = ( - err?: any, - publicKey?: PublicKeyResult, - privateKey?: PrivateKeyResult -) => void; - -export interface KeyObjectPair { - publicKey: PublicKeyResult; - privateKey: PrivateKeyResult; -} - -export function generateKey( - _type: SecretKeyType, - _options: GenerateKeyOptions, - callback: GenerateKeyCallback -) { - // We intentionally have not implemented key generation up to this point. - // The reason is that generation of cryptographically safe keys is a CPU - // intensive operation that can often exceed limits on the amount of CPU - // time a worker is allowed. - callback(new ERR_METHOD_NOT_IMPLEMENTED("crypto.generateKeySync")); -} - -export function generateKeySync(_type: SecretKeyType, _options: GenerateKeyOptions) { - // We intentionally have not implemented key generation up to this point. - // The reason is that generation of cryptographically safe keys is a CPU - // intensive operation that can often exceed limits on the amount of CPU - // time a worker is allowed. - throw new ERR_METHOD_NOT_IMPLEMENTED("crypto.generateKeySync"); -} - -export function generateKeyPair( - _type: AsymmetricKeyType, - _options: GenerateKeyPairOptions, - callback: GenerateKeyPairCallback -) { - // We intentionally have not implemented key generation up to this point. - // The reason is that generation of cryptographically safe keys is a CPU - // intensive operation that can often exceed limits on the amount of CPU - // time a worker is allowed. - callback(new ERR_METHOD_NOT_IMPLEMENTED("crypto.generateKeyPair")); -} - -export function generateKeyPairSync( - _type: AsymmetricKeyType, - _options: GenerateKeyPairOptions -): KeyObjectPair { - // We intentionally have not implemented key generation up to this point. - // The reason is that generation of cryptographically safe keys is a CPU - // intensive operation that can often exceed limits on the amount of CPU - // time a worker is allowed. - throw new ERR_METHOD_NOT_IMPLEMENTED("crypto.generateKeyPairSync"); -} diff --git a/JS/wasm/crates/wasmjs-engine/shims/src/internal/crypto_pbkdf2.ts b/JS/wasm/crates/wasmjs-engine/shims/src/internal/crypto_pbkdf2.ts deleted file mode 100644 index 3d575b53a..000000000 --- a/JS/wasm/crates/wasmjs-engine/shims/src/internal/crypto_pbkdf2.ts +++ /dev/null @@ -1,85 +0,0 @@ -/* eslint-disable */ - -"use strict"; - -import * as cryptoImpl from "./crypto"; -type ArrayLike = cryptoImpl.ArrayLike; -export { ArrayLike }; - -import { Buffer } from "./internal_buffer"; - -import { validateInt32, validateFunction, validateString } from "./validators"; - -import { getArrayBufferOrView } from "./crypto_util"; - -export function pbkdf2Sync( - password: ArrayLike, - salt: ArrayLike, - iterations: number, - keylen: number, - digest: string -): Buffer { - ({ password, salt, iterations, keylen, digest } = check( - password, - salt, - iterations, - keylen, - digest - )); - - const result = cryptoImpl.getPbkdf(password, salt, iterations, keylen, digest); - return Buffer.from(result); -} - -export type Pbkdf2Callback = (err?: Error | null, result?: Buffer) => void; -export function pbkdf2( - password: ArrayLike, - salt: ArrayLike, - iterations: number, - keylen: number, - digest: string, - callback: Pbkdf2Callback -): void { - if (typeof digest === "function") { - // Appease node test cases - validateString(undefined, "digest"); - } - validateFunction(callback, "callback"); - ({ password, salt, iterations, keylen, digest } = check( - password, - salt, - iterations, - keylen, - digest - )); - - new Promise((res, rej) => { - try { - res(cryptoImpl.getPbkdf(password, salt, iterations, keylen, digest)); - } catch (err) { - rej(err); - } - }).then( - (val) => callback(null, Buffer.from(val)), - (err) => callback(err) - ); -} - -function check( - password: ArrayLike | ArrayBufferView, - salt: ArrayLike | ArrayBufferView, - iterations: number, - keylen: number, - digest: string -): any { - validateString(digest, "digest"); - - password = getArrayBufferOrView(password, "password"); - salt = getArrayBufferOrView(salt, "salt"); - // OpenSSL uses a signed int to represent these values, so we are restricted - // to the 31-bit range here (which is plenty). - validateInt32(iterations, "iterations", 1); - validateInt32(keylen, "keylen", 0); - - return { password, salt, iterations, keylen, digest }; -} diff --git a/JS/wasm/crates/wasmjs-engine/shims/src/internal/crypto_random.ts b/JS/wasm/crates/wasmjs-engine/shims/src/internal/crypto_random.ts deleted file mode 100644 index ac49474c8..000000000 --- a/JS/wasm/crates/wasmjs-engine/shims/src/internal/crypto_random.ts +++ /dev/null @@ -1,393 +0,0 @@ -/* eslint-disable */ - -import * as cryptoImpl from "./crypto"; - -import { - validateObject, - validateBoolean, - validateFunction, - validateInt32, - validateInteger, -} from "./validators"; - -import { isAnyArrayBuffer, isArrayBufferView } from "./internal_types"; - -import { ERR_INVALID_ARG_TYPE, ERR_OUT_OF_RANGE } from "./internal_errors"; - -import { Buffer, kMaxLength } from "./internal_buffer"; - -import { arrayBufferToUnsignedBigInt } from "./crypto_util"; - -export type RandomBytesCallback = (err: any | null, buffer: Uint8Array) => void; -export function randomBytes(size: number, callback: RandomBytesCallback): void; -export function randomBytes(size: number): Uint8Array; -export function randomBytes(size: number, callback?: RandomBytesCallback): Uint8Array | void { - validateInteger(size, "size", 0, kMaxLength); - const buf = Buffer.alloc(size); - if (callback !== undefined) { - randomFill(buf, callback as RandomFillCallback); - } else { - randomFillSync(buf); - return buf; - } -} - -export function randomFillSync( - buffer: ArrayBufferView | ArrayBuffer, - offset?: number, - size?: number -) { - if (!isAnyArrayBuffer(buffer) && !isArrayBufferView(buffer)) { - throw new ERR_INVALID_ARG_TYPE( - "buffer", - ["TypedArray", "DataView", "ArrayBuffer", "SharedArrayBuffer"], - buffer - ); - } - const maxLength = (buffer as Uint8Array).length; - if (offset !== undefined) { - validateInteger(offset!, "offset", 0, kMaxLength); - } else offset = 0; - if (size !== undefined) { - validateInteger(size!, "size", 0, maxLength - offset); - } else size = maxLength; - if (isAnyArrayBuffer(buffer)) { - buffer = Buffer.from(buffer as ArrayBuffer); - } - buffer = (buffer as Buffer).subarray(offset, offset + size); - return crypto.getRandomValues(buffer as ArrayBufferView); -} - -export type RandomFillCallback = (err: any | null, buf?: ArrayBufferView | ArrayBuffer) => void; -export function randomFill( - buffer: ArrayBufferView | ArrayBuffer, - callback?: RandomFillCallback -): void; -export function randomFill( - buffer: ArrayBufferView | ArrayBuffer, - offset: number, - callback?: RandomFillCallback -): void; -export function randomFill( - buffer: ArrayBufferView | ArrayBuffer, - offset: number, - size: number, - callback?: RandomFillCallback -): void; -export function randomFill( - buffer: ArrayBufferView | ArrayBuffer, - offsetOrCallback?: number | RandomFillCallback, - sizeOrCallback?: number | RandomFillCallback, - callback?: RandomFillCallback -) { - if (!isAnyArrayBuffer(buffer) && !isArrayBufferView(buffer)) { - throw new ERR_INVALID_ARG_TYPE( - "buffer", - ["TypedArray", "DataView", "ArrayBuffer", "SharedArrayBuffer"], - buffer - ); - } - - let offset = 0; - let size = 0; - const maxLength = (buffer as Uint8Array).length; - if (typeof callback === "function") { - validateInteger(offsetOrCallback, "offset", 0, maxLength); - offset = offsetOrCallback as number; - - validateInteger(sizeOrCallback, "size", 0, maxLength - offset); - size = sizeOrCallback as number; - } else if (typeof sizeOrCallback === "function") { - validateInteger(offsetOrCallback, "offset", 0, maxLength); - offset = offsetOrCallback as number; - size = maxLength - offset; - callback = sizeOrCallback as RandomFillCallback; - } else if (typeof offsetOrCallback === "function") { - offset = 0; - size = maxLength; - callback = offsetOrCallback as RandomFillCallback; - } - validateFunction(callback, "callback"); - - // We're currently not actually implementing the fill itself asynchronously, - // so we defer to randomFillSync here, but we invoke the callback asynchronously. - new Promise((res) => { - randomFillSync(buffer, offset, size); - res(); - }).then( - () => callback!(null, buffer), - (err: any) => callback!(err) - ); -} - -const RAND_MAX = 0xffff_ffff_ffff; -// Cache random data to use in randomInt. The cache size must be evenly -// divisible by 6 because each attempt to obtain a random int uses 6 bytes. -const randomCache = Buffer.alloc(6 * 1024); -let randomCacheOffset = 0; -let initialized = false; - -function getRandomInt(min: number, max: number) { - if (!initialized) { - randomFillSync(randomCache); - initialized = true; - } - // First we generate a random int between [0..range) - const range = max - min; - - if (!(range <= RAND_MAX)) { - throw new ERR_OUT_OF_RANGE(`max${max ? "" : " - min"}`, `<= ${RAND_MAX}`, range); - } - - // For (x % range) to produce an unbiased value greater than or equal to 0 and - // less than range, x must be drawn randomly from the set of integers greater - // than or equal to 0 and less than randLimit. - const randLimit = RAND_MAX - (RAND_MAX % range); - - // If we don't have a callback, or if there is still data in the cache, we can - // do this synchronously, which is super fast. - while (randomCacheOffset <= randomCache.length) { - if (randomCacheOffset === randomCache.length) { - // This might block the thread for a bit, but we are in sync mode. - randomFillSync(randomCache); - randomCacheOffset = 0; - } - - const x = randomCache.readUIntBE(randomCacheOffset, 6); - randomCacheOffset += 6; - if (x < randLimit) { - const n = (x % range) + min; - return n; - } - } - return 0; // Should be unreachable. -} - -export type RandomIntCallback = (err: any | null, n?: number) => void; -export function randomInt(max: number): number; -export function randomInt(min: number, max: number): number; -export function randomInt(max: number, callback: RandomIntCallback): void; -export function randomInt(min: number, max: number, callback: RandomIntCallback): void; -export function randomInt( - minOrMax: number, - maxOrCallback?: number | RandomIntCallback, - callback?: RandomIntCallback -) { - let min = 0; - let max = 0; - if (typeof callback === "function") { - validateInteger(minOrMax, "min"); - validateInteger(maxOrCallback, "max"); - min = minOrMax as number; - max = maxOrCallback as number; - } else if (typeof maxOrCallback === "function") { - min = 0; - validateInteger(minOrMax, "max"); - max = minOrMax as number; - callback = maxOrCallback as RandomIntCallback; - } else if (arguments.length === 2) { - validateInteger(minOrMax, "min"); - validateInteger(maxOrCallback, "max"); - min = minOrMax as number; - max = maxOrCallback as number; - } else { - min = 0; - validateInteger(minOrMax, "max"); - max = minOrMax; - } - - if (min > max) { - throw new ERR_OUT_OF_RANGE("min", "min <= max", min); - } - - if (callback !== undefined) { - new Promise((res) => { - res(getRandomInt(min, max)); - }).then( - (n: number) => callback!(null, n), - (err: any) => callback!(err) - ); - return; - } else { - return getRandomInt(min, max); - } -} - -export function randomUUID(options?: any) { - // While we do not actually use the entropy cache, we go ahead and validate - // the input parameters as Node.js does. - if (options !== undefined) { - validateObject(options, "options", options); - if (options.disableEntropyCache !== undefined) { - validateBoolean(options.disableEntropyCache, "options.disableEntropyCache"); - } - } - return crypto.randomUUID(); -} - -export type PrimeNum = ArrayBuffer | ArrayBufferView | Buffer | bigint; -export interface GeneratePrimeOptions { - add?: PrimeNum; - rem?: PrimeNum; - safe?: boolean; - bigint?: boolean; -} - -export interface CheckPrimeOptions { - checks?: number; -} - -export type GeneratePrimeCallback = (err?: any, prime?: bigint | ArrayBuffer) => void; -export type CheckPrimeCallback = (err?: any, prime?: boolean) => void; - -function processGeneratePrimeOptions(options: GeneratePrimeOptions): { - add: ArrayBufferView; - rem: ArrayBufferView; - safe: boolean; - bigint: boolean; -} { - validateObject(options, "options", {}); - const { safe = false, bigint = false } = options; - let { add, rem } = options; - validateBoolean(safe, "options.safe"); - validateBoolean(bigint, "options.bigint"); - - if (add !== undefined) { - if (typeof add === "bigint") { - add = unsignedBigIntToBuffer(add, "options.add"); - } else if (!isAnyArrayBuffer(add) && !isArrayBufferView(add)) { - throw new ERR_INVALID_ARG_TYPE( - "options.add", - ["ArrayBuffer", "TypedArray", "Buffer", "DataView", "bigint"], - add - ); - } - } - - if (rem !== undefined) { - if (typeof rem === "bigint") { - rem = unsignedBigIntToBuffer(rem, "options.rem"); - } else if (!isAnyArrayBuffer(rem) && !isArrayBufferView(rem)) { - throw new ERR_INVALID_ARG_TYPE( - "options.rem", - ["ArrayBuffer", "TypedArray", "Buffer", "DataView", "bigint"], - rem - ); - } - } - - return { - safe, - bigint, - add: add as ArrayBufferView, - rem: rem as ArrayBufferView, - }; -} - -export function generatePrimeSync(size: number, options: GeneratePrimeOptions = {}) { - validateInt32(size, "size", 1); - const { safe, bigint, add, rem } = processGeneratePrimeOptions(options); - - let primeBuf = cryptoImpl.randomPrime(size, safe, add, rem); - return bigint ? arrayBufferToUnsignedBigInt(primeBuf) : primeBuf; -} - -export function generatePrime( - size: number, - options: GeneratePrimeOptions, - callback: GeneratePrimeCallback -): void; -export function generatePrime(size: number, callback: GeneratePrimeCallback): void; -export function generatePrime( - size: number, - options: GeneratePrimeOptions | GeneratePrimeCallback, - callback?: GeneratePrimeCallback -): void { - validateInt32(size, "size", 1); - if (typeof options === "function") { - callback = options; - options = {}; - } - validateFunction(callback, "callback"); - - const { safe, bigint, add, rem } = processGeneratePrimeOptions(options as GeneratePrimeOptions); - - new Promise((res, rej) => { - try { - const primeBuf = cryptoImpl.randomPrime(size, safe, add, rem); - res(bigint ? arrayBufferToUnsignedBigInt(primeBuf) : primeBuf); - } catch (err) { - rej(err); - } - }).then( - (val) => callback!(null, val), - (err) => callback!(err) - ); -} - -function unsignedBigIntToBuffer(bigint: bigint, name: string) { - if (bigint < 0) { - throw new ERR_OUT_OF_RANGE(name, ">= 0", bigint); - } - - const hex = bigint.toString(16); - const padded = hex.padStart(hex.length + (hex.length % 2), "0"); - return Buffer.from(padded, "hex"); -} - -function validateCandidate(candidate: PrimeNum): Buffer { - if (typeof candidate === "bigint") candidate = unsignedBigIntToBuffer(candidate, "candidate"); - if (!isAnyArrayBuffer(candidate) && !isArrayBufferView(candidate)) { - throw new ERR_INVALID_ARG_TYPE( - "candidate", - ["ArrayBuffer", "TypedArray", "Buffer", "DataView", "bigint"], - candidate - ); - } - return candidate as Buffer; -} - -function validateChecks(options: CheckPrimeOptions): number { - const { checks = 0 } = options; - // The checks option is unsigned but must fit into a signed 32-bit integer for OpenSSL. - validateInt32(checks, "options.checks", 0); - return checks; -} - -export function checkPrimeSync(candidate: PrimeNum, options: CheckPrimeOptions = {}) { - candidate = validateCandidate(candidate); - validateObject(options, "options", {}); - const checks = validateChecks(options); - return cryptoImpl.checkPrimeSync(candidate as ArrayBufferView, checks); -} - -export function checkPrime( - candidate: PrimeNum, - options: CheckPrimeOptions, - callback: CheckPrimeCallback -): void; -export function checkPrime(candidate: PrimeNum, callback: CheckPrimeCallback): void; -export function checkPrime( - candidate: PrimeNum, - options: CheckPrimeOptions | CheckPrimeCallback, - callback?: CheckPrimeCallback -): void { - candidate = validateCandidate(candidate); - if (typeof options === "function") { - callback = options; - options = {}; - } - validateObject(options, "options", {}); - validateFunction(callback, "callback"); - const checks = validateChecks(options); - new Promise((res, rej) => { - try { - res(cryptoImpl.checkPrimeSync(candidate as ArrayBufferView, checks)); - } catch (err) { - rej(err); - } - }).then( - (val) => callback!(null, val), - (err) => callback!(err) - ); -} diff --git a/JS/wasm/crates/wasmjs-engine/shims/src/internal/crypto_util.ts b/JS/wasm/crates/wasmjs-engine/shims/src/internal/crypto_util.ts deleted file mode 100644 index 9b268df0b..000000000 --- a/JS/wasm/crates/wasmjs-engine/shims/src/internal/crypto_util.ts +++ /dev/null @@ -1,102 +0,0 @@ -/* eslint-disable */ - -"use strict"; - -import { Buffer } from "./internal_buffer"; - -import { isAnyArrayBuffer, isArrayBufferView } from "./internal_types"; - -import { ERR_INVALID_ARG_TYPE } from "./internal_errors"; - -import { validateString } from "./validators"; - -import * as cryptoImpl from "./crypto"; -type ArrayLike = cryptoImpl.ArrayLike; - -export const kHandle = Symbol("kHandle"); -export const kFinalized = Symbol("kFinalized"); -export const kState = Symbol("kFinalized"); - -export function getStringOption(options: any, key: string) { - let value; - if (options && (value = options[key]) != null) validateString(value, `options.${key}`); - return value; -} - -export function getArrayBufferOrView( - buffer: Buffer | ArrayBuffer | ArrayBufferView | string, - name: string, - encoding?: string -): Buffer | ArrayBuffer | ArrayBufferView { - if (isAnyArrayBuffer(buffer)) return buffer as ArrayBuffer; - if (typeof buffer === "string") { - if (encoding === undefined || encoding === "buffer") { - encoding = "utf8"; - } - return Buffer.from(buffer, encoding); - } - if (!isArrayBufferView(buffer)) { - throw new ERR_INVALID_ARG_TYPE( - name, - ["string", "ArrayBuffer", "Buffer", "TypedArray", "DataView"], - buffer - ); - } - return buffer; -} - -/** - * 48 is the ASCII code for '0', 97 is the ASCII code for 'a'. - * @param {number} number An integer between 0 and 15. - * @returns {number} corresponding to the ASCII code of the hex representation - * of the parameter. - */ -export const numberToHexCharCode = (number: number): number => (number < 10 ? 48 : 87) + number; - -/** - * @param {ArrayBuffer} buf An ArrayBuffer. - * @return {bigint} - */ -export function arrayBufferToUnsignedBigInt(buf: ArrayBuffer): bigint { - const length = buf.byteLength; - const chars = Array(length * 2); - const view = new DataView(buf); - - for (let i = 0; i < length; i++) { - const val = view.getUint8(i); - chars[2 * i] = numberToHexCharCode(val >> 4); - chars[2 * i + 1] = numberToHexCharCode(val & 0xf); - } - - return BigInt(`0x${String.fromCharCode.apply(null, chars)}`); -} - -// This is here because many functions accepted binary strings without -// any explicit encoding in older versions of node, and we don't want -// to break them unnecessarily. -export function toBuf(val: ArrayLike, encoding?: string): Buffer | ArrayBuffer | ArrayBufferView { - if (typeof val === "string") { - if (encoding === "buffer") { - encoding = "utf8"; - } - return Buffer.from(val, encoding); - } - return val; -} - -export function validateByteSource( - val: ArrayLike, - name: string -): Buffer | ArrayBuffer | ArrayBufferView { - val = toBuf(val); - - if (isAnyArrayBuffer(val) || isArrayBufferView(val)) { - return val; - } - - throw new ERR_INVALID_ARG_TYPE( - name, - ["string", "ArrayBuffer", "TypedArray", "DataView", "Buffer"], - val - ); -} diff --git a/JS/wasm/crates/wasmjs-engine/shims/src/internal/events.ts b/JS/wasm/crates/wasmjs-engine/shims/src/internal/events.ts deleted file mode 100644 index 83f86114d..000000000 --- a/JS/wasm/crates/wasmjs-engine/shims/src/internal/events.ts +++ /dev/null @@ -1,888 +0,0 @@ -import { - AbortError, - ERR_INVALID_ARG_TYPE, - ERR_INVALID_THIS, - ERR_OUT_OF_RANGE, - ERR_UNHANDLED_ERROR, -} from "./internal_errors"; - -import { validateAbortSignal, validateBoolean, validateFunction } from "./validators"; - -import * as process from "./process"; - -import { spliceOne } from "./internal_utils"; - -import * as async_hooks from "./async_hooks"; -const { AsyncResource } = async_hooks; - -import { inspect } from "./internal_inspect"; - -const kRejection = Symbol.for("nodejs.rejection"); -const kCapture = Symbol("kCapture"); -const kErrorMonitor = Symbol("events.errorMonitor"); -const kMaxEventTargetListeners = Symbol("events.maxEventTargetListeners"); -const kMaxEventTargetListenersWarned = Symbol("events.maxEventTargetListenersWarned"); - -export interface EventEmitterOptions { - captureRejections?: boolean; -} - -export type EventName = string | symbol; -export type EventCallback = (...args: any[]) => unknown; -export interface EventEmitter { - addListener(eventName: EventName, listener: EventCallback): EventEmitter; - emit(eventName: EventName, ...args: unknown[]): void; - eventNames(): EventName[]; - getMaxListeners(): number; - listenerCount(eventName: EventName): number; - listeners(eventName: EventName): EventCallback[]; - off(eventName: EventName, listener: EventCallback): EventEmitter; - on(eventName: EventName, listener: EventCallback): EventEmitter; - once(eventName: EventName, listener: EventCallback): EventEmitter; - prependListener(eventName: EventName, listener: EventCallback): EventEmitter; - prependOnceListener(eventName: EventName, listener: EventCallback): EventEmitter; - removeAllListeners(eventName?: EventName): EventEmitter; - removeListener(eventName: EventName, listener: EventCallback): EventEmitter; - setMaxListeners(n: number): EventEmitter; - rawListeners(eventName: EventName): EventCallback[]; - [kRejection](err: unknown, eventName: EventName, ...args: unknown[]): void; -} - -type AsyncResource = typeof AsyncResource; - -declare var EventTarget: Function; - -export function EventEmitter(this: EventEmitter, opts?: EventEmitterOptions) { - EventEmitter.init.call(this, opts); -} - -class EventEmitterReferencingAsyncResource extends AsyncResource { - #eventEmitter: EventEmitter; - constructor(emitter: EventEmitter) { - super(""); - this.#eventEmitter = emitter; - } - - get eventEmitter() { - if (this.#eventEmitter === undefined) - throw new ERR_INVALID_THIS("EventEmitterReferencingAsyncResource"); - return this.#eventEmitter; - } -} - -// @ts-ignore -- TODO(soon) Properly handle the extends EventEmitter here -export class EventEmitterAsyncResource extends EventEmitter { - #asyncResource: EventEmitterReferencingAsyncResource; - - constructor(options?: EventEmitterOptions) { - super(options); - // @ts-ignore - this.#asyncResource = new EventEmitterReferencingAsyncResource(this); - } - - get asyncResource(): AsyncResource { - if (this.#asyncResource === undefined) - throw new ERR_INVALID_THIS("EventEmitterAsyncResource"); - // @ts-ignore - return this.#asyncResource; - } - - emit(event: string | symbol, ...args: any[]): void { - if (this.#asyncResource === undefined) - throw new ERR_INVALID_THIS("EventEmitterAsyncResource"); - args.unshift(super.emit, this, event); - Reflect.apply(this.#asyncResource.runInAsyncScope, this.#asyncResource, args); - } -} - -export default EventEmitter; -EventEmitter.on = on; -EventEmitter.once = once; -EventEmitter.getEventListeners = getEventListeners; -EventEmitter.setMaxListeners = setMaxListeners; -EventEmitter.listenerCount = listenerCount; -EventEmitter.EventEmitter = EventEmitter; -EventEmitter.usingDomains = false; -EventEmitter.captureRejectionSymbol = kRejection; -EventEmitter.errorMonitor = kErrorMonitor; -EventEmitter.EventEmitterAsyncResource = EventEmitterAsyncResource; - -export const captureRejectionSymbol = EventEmitter.captureRejectionSymbol; -export const errorMonitor = EventEmitter.errorMonitor; -export let defaultMaxListeners = 10; - -Object.defineProperties(EventEmitter, { - captureRejections: { - get() { - return EventEmitter.prototype[kCapture]; - }, - set(value) { - validateBoolean(value, "EventEmitter.captureRejections"); - - EventEmitter.prototype[kCapture] = value; - }, - enumerable: true, - }, - defaultMaxListeners: { - enumerable: true, - get: function () { - return defaultMaxListeners; - }, - set: function (arg) { - if (typeof arg !== "number" || arg < 0 || Number.isNaN(arg)) { - throw new ERR_OUT_OF_RANGE("defaultMaxListeners", "a non-negative number", arg); - } - defaultMaxListeners = arg; - }, - }, - kMaxEventTargetListeners: { - value: kMaxEventTargetListeners, - enumerable: false, - configurable: false, - writable: false, - }, - kMaxEventTargetListenersWarned: { - value: kMaxEventTargetListenersWarned, - enumerable: false, - configurable: false, - writable: false, - }, -}); - -// The default for captureRejections is false -Object.defineProperty(EventEmitter.prototype, kCapture, { - value: false, - writable: true, - enumerable: false, -}); - -EventEmitter.init = function (this: any, opts?: EventEmitterOptions) { - if (this._events === undefined || this._events === Object.getPrototypeOf(this)._events) { - this._events = Object.create(null); - this._eventsCount = 0; - } - - (this as any)._maxListeners ??= undefined; - - if (opts?.captureRejections) { - validateBoolean(opts.captureRejections, "options.captureRejections"); - (this as any)[kCapture] = Boolean(opts.captureRejections); - } else { - // Assigning the kCapture property directly saves an expensive - // prototype lookup in a very sensitive hot path. - (this as any)[kCapture] = EventEmitter.prototype[kCapture]; - } -}; - -export function setMaxListeners(n = defaultMaxListeners, ...eventTargets: any[]) { - if (typeof n !== "number" || n < 0 || Number.isNaN(n)) { - throw new ERR_OUT_OF_RANGE("n", "a non-negative number", n); - } - if (eventTargets.length === 0) { - defaultMaxListeners = n; - } else { - for (let i = 0; i < eventTargets.length; i++) { - const target = eventTargets[i]; - if (target instanceof EventTarget) { - (target as any)[kMaxEventTargetListeners] = n; - (target as any)[kMaxEventTargetListenersWarned] = false; - } else if (typeof target.setMaxListeners === "function") { - target.setMaxListeners(n); - } else { - throw new ERR_INVALID_ARG_TYPE( - "eventTargets", - ["EventEmitter", "EventTarget"], - target - ); - } - } - } -} - -EventEmitter.prototype._events = undefined; -EventEmitter.prototype._eventsCount = 0; -EventEmitter.prototype._maxListeners = undefined; - -function addCatch(that: any, promise: Promise, type: string | symbol, args: any[]) { - if (!that[kCapture]) { - return; - } - - // Handle Promises/A+ spec, then could be a getter - // that throws on second use. - try { - const then = promise.then; - - if (typeof then === "function") { - then.call(promise, undefined, function (err) { - // The callback is called with nextTick to avoid a follow-up - // rejection from this promise. - process.nextTick(emitUnhandledRejectionOrErr, that, err, type, args); - }); - } - } catch (err) { - that.emit("error", err); - } -} - -function emitUnhandledRejectionOrErr(ee: any, err: any, type: string | symbol, args: any[]) { - if (typeof ee[kRejection] === "function") { - ee[kRejection](err, type, ...args); - } else { - // We have to disable the capture rejections mechanism, otherwise - // we might end up in an infinite loop. - const prev = ee[kCapture]; - - // If the error handler throws, it is not catcheable and it - // will end up in 'uncaughtException'. We restore the previous - // value of kCapture in case the uncaughtException is present - // and the exception is handled. - try { - ee[kCapture] = false; - ee.emit("error", err); - } finally { - ee[kCapture] = prev; - } - } -} - -EventEmitter.prototype.setMaxListeners = function setMaxListeners(n: number) { - if (typeof n !== "number" || n < 0 || Number.isNaN(n)) { - throw new ERR_OUT_OF_RANGE("n", "a non-negative number", n); - } - this._maxListeners = n; - return this; -}; - -function _getMaxListeners(that: any) { - if (that._maxListeners === undefined) { - return (EventEmitter as any).defaultMaxListeners; - } - return that._maxListeners; -} - -EventEmitter.prototype.getMaxListeners = function getMaxListeners() { - return _getMaxListeners(this); -}; - -EventEmitter.prototype.emit = function emit(type: string | symbol, ...args: any[]) { - let doError = type === "error"; - - const events = this._events; - if (events !== undefined) { - if (doError && events[kErrorMonitor] !== undefined) { - this.emit(kErrorMonitor, ...args); - } - doError = doError && events.error === undefined; - } else if (!doError) { - return false; - } - - // If there is no 'error' event listener then throw. - if (doError) { - let er; - if (args.length > 0) { - er = args[0]; - } - if (er instanceof Error) { - try { - const capture = {}; - (Error as any).captureStackTrace(capture, EventEmitter.prototype.emit); - } catch { - // pass - } - - // Note: The comments on the `throw` lines are intentional, they show - // up in Node's output if this results in an unhandled exception. - throw er; // Unhandled 'error' event - } - - let stringifiedEr; - try { - stringifiedEr = inspect(er); - } catch { - stringifiedEr = er; - } - - // At least give some kind of context to the user - const err = new ERR_UNHANDLED_ERROR(stringifiedEr); - (err as any).context = er; - throw err; // Unhandled 'error' event - } - - const handler = events[type]; - - if (handler === undefined) { - return false; - } - - if (typeof handler === "function") { - const result = handler.apply(this, args); - - // We check if result is undefined first because that - // is the most common case so we do not pay any perf - // penalty - if (result !== undefined && result !== null) { - addCatch(this, result, type, args); - } - } else { - const len = handler.length; - const listeners = arrayClone(handler); - for (let i = 0; i < len; ++i) { - const result = listeners[i].apply(this, args); - - // We check if result is undefined first because that - // is the most common case so we do not pay any perf - // penalty. - // This code is duplicated because extracting it away - // would make it non-inlineable. - if (result !== undefined && result !== null) { - addCatch(this, result, type, args); - } - } - } - - return true; -}; - -function _addListener(target: any, type: string | symbol, listener: unknown, prepend: boolean) { - let m; - let events; - let existing; - - validateFunction(listener, "listener"); - - events = target._events; - if (events === undefined) { - events = target._events = Object.create(null); - target._eventsCount = 0; - } else { - // To avoid recursion in the case that type === "newListener"! Before - // adding it to the listeners, first emit "newListener". - if (events.newListener !== undefined) { - target.emit("newListener", type, (listener as any).listener ?? listener); - - // Re-assign `events` because a newListener handler could have caused the - // this._events to be assigned to a new object - events = target._events; - } - existing = events[type]; - } - - if (existing === undefined) { - // Optimize the case of one listener. Don't need the extra array object. - events[type] = listener; - ++target._eventsCount; - } else { - if (typeof existing === "function") { - // Adding the second element, need to change to array. - existing = events[type] = prepend ? [listener, existing] : [existing, listener]; - // If we've already got an array, just append. - } else if (prepend) { - existing.unshift(listener); - } else { - existing.push(listener); - } - - // Check for listener leak - m = _getMaxListeners(target); - if (m > 0 && existing.length > m && !existing.warned) { - existing.warned = true; - console.log( - "Possible EventEmitter memory leak detected. " + - `${existing.length} ${String(type)} listeners ` + - `added to an EventEmitter. Use ` + - "emitter.setMaxListeners() to increase limit" - ); - // TODO(soon): Implement process.emitWarning and inspect - // // No error code for this since it is a Warning - // // eslint-disable-next-line no-restricted-syntax - // const w = new Error( - // "Possible EventEmitter memory leak detected. " + - // `${existing.length} ${String(type)} listeners ` + - // `added to ${inspect(target, { depth: -1 })}. Use ` + - // "emitter.setMaxListeners() to increase limit", - // ); - // w.name = "MaxListenersExceededWarning"; - // w.emitter = target; - // w.type = type; - // w.count = existing.length; - // process.emitWarning(w); - } - } - - return target; -} - -EventEmitter.prototype.addListener = function addListener( - type: string | symbol, - listener: unknown -) { - return _addListener(this, type, listener, false); -}; - -EventEmitter.prototype.on = EventEmitter.prototype.addListener; - -EventEmitter.prototype.prependListener = function prependListener( - type: string | symbol, - listener: unknown -) { - return _addListener(this, type, listener, true); -}; - -function onceWrapper(this: any) { - if (!this.fired) { - this.target.removeListener(this.type, this.wrapFn); - this.fired = true; - if (arguments.length === 0) { - return this.listener.call(this.target); - } - return this.listener.apply(this.target, arguments); - } -} - -function _onceWrap(target: any, type: string | symbol, listener: unknown) { - const state = { fired: false, wrapFn: undefined, target, type, listener }; - const wrapped = onceWrapper.bind(state); - (wrapped as any).listener = listener; - (state as any).wrapFn = wrapped; - return wrapped; -} - -EventEmitter.prototype.once = function once(type: string | symbol, listener: unknown) { - validateFunction(listener, "listener"); - - this.on(type, _onceWrap(this, type, listener)); - return this; -}; - -EventEmitter.prototype.prependOnceListener = function prependOnceListener( - type: string | symbol, - listener: unknown -) { - validateFunction(listener, "listener"); - - this.prependListener(type, _onceWrap(this, type, listener)); - return this; -}; - -EventEmitter.prototype.removeListener = function removeListener( - type: string | symbol, - listener: unknown -) { - validateFunction(listener, "listener"); - - const events = this._events; - if (events === undefined) { - return this; - } - - const list = events[type]; - if (list === undefined) { - return this; - } - - if (list === listener || list.listener === listener) { - if (--this._eventsCount === 0) { - this._events = Object.create(null); - } else { - delete events[type]; - if (events.removeListener) { - this.emit("removeListener", type, list.listener || listener); - } - } - } else if (typeof list !== "function") { - let position = -1; - - for (let i = list.length - 1; i >= 0; i--) { - if (list[i] === listener || list[i].listener === listener) { - position = i; - break; - } - } - - if (position < 0) { - return this; - } - - if (position === 0) { - list.shift(); - } else { - spliceOne(list, position); - } - - if (list.length === 1) { - events[type] = list[0]; - } - - if (events.removeListener !== undefined) { - this.emit("removeListener", type, listener); - } - } - - return this; -}; - -EventEmitter.prototype.off = EventEmitter.prototype.removeListener; - -EventEmitter.prototype.removeAllListeners = function removeAllListeners(type: string | symbol) { - const events = this._events; - if (events === undefined) { - return this; - } - - // Not listening for removeListener, no need to emit - if (events.removeListener === undefined) { - if (arguments.length === 0) { - this._events = Object.create(null); - this._eventsCount = 0; - } else if (events[type] !== undefined) { - if (--this._eventsCount === 0) { - this._events = Object.create(null); - } else { - delete events[type]; - } - } - return this; - } - - // Emit removeListener for all listeners on all events - if (arguments.length === 0) { - for (const key of Reflect.ownKeys(events)) { - if (key === "removeListener") continue; - this.removeAllListeners(key); - } - this.removeAllListeners("removeListener"); - this._events = Object.create(null); - this._eventsCount = 0; - return this; - } - - const listeners = events[type]; - - if (typeof listeners === "function") { - this.removeListener(type, listeners); - } else if (listeners !== undefined) { - // LIFO order - for (let i = listeners.length - 1; i >= 0; i--) { - this.removeListener(type, listeners[i]); - } - } - - return this; -}; - -function _listeners(target: any, type: string | symbol, unwrap: boolean) { - const events = target._events; - - if (events === undefined) { - return []; - } - - const evlistener = events[type]; - if (evlistener === undefined) { - return []; - } - - if (typeof evlistener === "function") { - return unwrap ? [evlistener.listener || evlistener] : [evlistener]; - } - - return unwrap ? unwrapListeners(evlistener) : arrayClone(evlistener); -} - -EventEmitter.prototype.listeners = function listeners(type: string | symbol) { - return _listeners(this, type, true); -}; - -EventEmitter.prototype.rawListeners = function rawListeners(type: string | symbol) { - return _listeners(this, type, false); -}; - -const _listenerCount = function listenerCount(this: any, type: string | symbol) { - const events = this._events; - - if (events !== undefined) { - const evlistener = events[type]; - - if (typeof evlistener === "function") { - return 1; - } else if (evlistener !== undefined) { - return evlistener.length; - } - } - - return 0; -}; - -EventEmitter.prototype.listenerCount = _listenerCount; - -export function listenerCount(emitter: any, type: string | symbol) { - if (typeof emitter.listenerCount === "function") { - return emitter.listenerCount(type); - } - return _listenerCount.call(emitter, type); -} - -EventEmitter.prototype.eventNames = function eventNames() { - return this._eventsCount > 0 ? Reflect.ownKeys(this._events) : []; -}; - -function arrayClone(arr: any[]) { - // At least since V8 8.3, this implementation is faster than the previous - // which always used a simple for-loop - switch (arr.length) { - case 2: - return [arr[0], arr[1]]; - case 3: - return [arr[0], arr[1], arr[2]]; - case 4: - return [arr[0], arr[1], arr[2], arr[3]]; - case 5: - return [arr[0], arr[1], arr[2], arr[3], arr[4]]; - case 6: - return [arr[0], arr[1], arr[2], arr[3], arr[4], arr[5]]; - } - return arr.slice(); -} - -function unwrapListeners(arr: any[]) { - const ret = arrayClone(arr); - for (let i = 0; i < ret.length; ++i) { - const orig = ret[i].listener; - if (typeof orig === "function") { - ret[i] = orig; - } - } - return ret; -} - -export function getEventListeners(emitterOrTarget: any, type: string | symbol) { - // First check if EventEmitter - if (typeof emitterOrTarget.listeners === "function") { - return emitterOrTarget.listeners(type); - } - if (emitterOrTarget instanceof EventTarget) { - // Workers does not implement the ability to get the event listeners on an - // EventTarget the way that Node.js does. We simply return empty here. - return []; - } - throw new ERR_INVALID_ARG_TYPE("emitter", ["EventEmitter", "EventTarget"], emitterOrTarget); -} - -export interface OnceOptions { - signal?: AbortSignal; -} - -export async function once(emitter: any, name: string | symbol, options: OnceOptions = {}) { - const signal = options?.signal; - validateAbortSignal(signal, "options.signal"); - if (signal?.aborted) { - throw new AbortError(); - } - return new Promise((resolve, reject) => { - const errorListener = (err: any) => { - emitter.removeListener(name, resolver); - if (signal != null) { - eventTargetAgnosticRemoveListener(signal, "abort", abortListener); - } - reject(err); - }; - const resolver = (...args: any[]) => { - if (typeof emitter.removeListener === "function") { - emitter.removeListener("error", errorListener); - } - if (signal != null) { - eventTargetAgnosticRemoveListener(signal, "abort", abortListener); - } - resolve(args); - }; - eventTargetAgnosticAddListener(emitter, name, resolver, { once: true }); - if (name !== "error" && typeof emitter.once === "function") { - emitter.once("error", errorListener); - } - function abortListener() { - eventTargetAgnosticRemoveListener(emitter, name, resolver); - eventTargetAgnosticRemoveListener(emitter, "error", errorListener); - reject(new AbortError()); - } - if (signal != null) { - eventTargetAgnosticAddListener(signal, "abort", abortListener, { once: true }); - } - }); -} - -const AsyncIteratorPrototype = Object.getPrototypeOf( - Object.getPrototypeOf(async function* () {}).prototype -); - -function createIterResult(value: any, done: boolean) { - return { value, done }; -} - -function eventTargetAgnosticRemoveListener( - emitter: any, - name: string | symbol, - listener: unknown, - flags: unknown = undefined -) { - if (typeof emitter.removeListener === "function") { - emitter.removeListener(name, listener); - } else if (typeof emitter.removeEventListener === "function") { - emitter.removeEventListener(name, listener, flags); - } else { - throw new ERR_INVALID_ARG_TYPE("emitter", "EventEmitter", emitter); - } -} - -interface AddListenerFlags { - once?: boolean; -} - -function eventTargetAgnosticAddListener( - emitter: any, - name: string | symbol, - listener: unknown, - flags: AddListenerFlags = {} -) { - if (typeof emitter.on === "function") { - if (flags?.once) { - emitter.once(name, listener); - } else { - emitter.on(name, listener); - } - } else if (typeof emitter.addEventListener === "function") { - // EventTarget does not have `error` event semantics like Node - // EventEmitters, we do not listen to `error` events here. - emitter.addEventListener( - name, - (arg: unknown) => { - (listener as any)(arg); - }, - flags - ); - } else { - throw new ERR_INVALID_ARG_TYPE("emitter", "EventEmitter", emitter); - } -} - -interface OnOptions { - signal?: AbortSignal; -} - -export function on(emitter: any, event: string | symbol, options: OnOptions = {}) { - const signal = options?.signal; - validateAbortSignal(signal, "options.signal"); - if (signal?.aborted) { - throw new AbortError(); - } - - const unconsumedEvents: any[] = []; - const unconsumedPromises: any[] = []; - let error: any = null; - let finished = false; - - const iterator = Object.setPrototypeOf( - { - next() { - // First, we consume all unread events - const value = unconsumedEvents.shift(); - if (value) { - return Promise.resolve(createIterResult(value, false)); - } - - // Then we error, if an error happened - // This happens one time if at all, because after 'error' - // we stop listening - if (error) { - const p = Promise.reject(error); - // Only the first element errors - error = null; - return p; - } - - // If the iterator is finished, resolve to done - if (finished) { - return Promise.resolve(createIterResult(undefined, true)); - } - - // Wait until an event happens - return new Promise(function (resolve, reject) { - unconsumedPromises.push({ resolve, reject }); - }); - }, - - return() { - eventTargetAgnosticRemoveListener(emitter, event, eventHandler); - eventTargetAgnosticRemoveListener(emitter, "error", errorHandler); - - if (signal) { - eventTargetAgnosticRemoveListener(signal, "abort", abortListener, { - once: true, - }); - } - - finished = true; - - for (const promise of unconsumedPromises) { - promise.resolve(createIterResult(undefined, true)); - } - - return Promise.resolve(createIterResult(undefined, true)); - }, - - throw(err: any) { - if (!err || !(err instanceof Error)) { - throw new ERR_INVALID_ARG_TYPE("EventEmitter.AsyncIterator", "Error", err); - } - error = err; - eventTargetAgnosticRemoveListener(emitter, event, eventHandler); - eventTargetAgnosticRemoveListener(emitter, "error", errorHandler); - }, - - [Symbol.asyncIterator]() { - return this; - }, - }, - AsyncIteratorPrototype - ); - - eventTargetAgnosticAddListener(emitter, event, eventHandler); - if (event !== "error" && typeof emitter.on === "function") { - emitter.on("error", errorHandler); - } - - if (signal) { - eventTargetAgnosticAddListener(signal, "abort", abortListener, { once: true }); - } - - return iterator; - - function abortListener() { - errorHandler(new AbortError()); - } - - function eventHandler(...args: any[]) { - const promise = unconsumedPromises.shift(); - if (promise) { - promise.resolve(createIterResult(args, false)); - } else { - unconsumedEvents.push(args); - } - } - - function errorHandler(err: any) { - finished = true; - - const toError = unconsumedPromises.shift(); - - if (toError) { - toError.reject(err); - } else { - // The next time we call next() - error = err; - } - - iterator.return(); - } -} diff --git a/JS/wasm/crates/wasmjs-engine/shims/src/internal/internal_buffer.ts b/JS/wasm/crates/wasmjs-engine/shims/src/internal/internal_buffer.ts deleted file mode 100644 index e2487edc5..000000000 --- a/JS/wasm/crates/wasmjs-engine/shims/src/internal/internal_buffer.ts +++ /dev/null @@ -1,2274 +0,0 @@ -import { - ERR_BUFFER_OUT_OF_BOUNDS, - ERR_OUT_OF_RANGE, - ERR_INVALID_ARG_TYPE, - ERR_INVALID_ARG_VALUE, - ERR_INVALID_BUFFER_SIZE, - ERR_UNKNOWN_ENCODING, -} from "./internal_errors"; - -import * as bufferUtil from "./buffer"; - -import { isAnyArrayBuffer, isArrayBufferView, isUint8Array } from "./internal_types"; - -import { normalizeEncoding } from "./internal_utils"; - -import { validateString } from "./validators"; - -import * as internalUtil from "./util"; -import { InspectOptionsStylized, inspect as utilInspect } from "./internal_inspect"; - -// Temporary buffers to convert numbers. -const float32Array = new Float32Array(1); -const uInt8Float32Array = new Uint8Array(float32Array.buffer); -const float64Array = new Float64Array(1); -const uInt8Float64Array = new Uint8Array(float64Array.buffer); - -// Check endianness. -float32Array[0] = -1; // 0xBF800000 -// Either it is [0, 0, 128, 191] or [191, 128, 0, 0]. It is not possible to -// check this with `os.endianness()` because that is determined at compile time. -export const bigEndian = uInt8Float32Array[3] === 0; - -// Node.js caps it's max length at uint32_t max, we are very intentionally more -// conservative here, capping at int32_t max. -export const kMaxLength = 2147483647; -export const kStringMaxLength = 536870888; -const MAX_UINT32 = 2 ** 32; -const kIsBuffer = Symbol("kIsBuffer"); - -const customInspectSymbol = - typeof Symbol === "function" && typeof Symbol["for"] === "function" - ? Symbol["for"]("nodejs.util.inspect.custom") - : null; - -const INSPECT_MAX_BYTES = 50; - -export const constants = { - MAX_LENGTH: kMaxLength, - MAX_STRING_LENGTH: kStringMaxLength, -}; - -function createBuffer(length: number): Buffer { - if (length > kMaxLength) { - throw new ERR_OUT_OF_RANGE("The given length is invalid", `0 to ${kMaxLength}`, length); - } - const buf = new Uint8Array(length); - Object.setPrototypeOf(buf, Buffer.prototype); - return buf as Buffer; -} - -type WithImplicitCoercion = T | { valueOf(): T }; -type StringLike = WithImplicitCoercion | { [Symbol.toPrimitive](hint: "string"): string }; -type ArrayBufferLike = WithImplicitCoercion; -type BufferSource = StringLike | ArrayBufferLike | Uint8Array | ReadonlyArray; - -export interface Buffer extends Uint8Array { - readonly buffer: ArrayBuffer; - readonly parent: ArrayBuffer; - readonly byteOffset: number; - readonly length: number; - compare( - target: Uint8Array, - targetStart?: number, - targetEnd?: number, - sourceStart?: number, - sourceEnd?: number - ): number; - copy( - target: Uint8Array, - targetStart?: number, - sourceStart?: number, - sourceEnd?: number - ): number; - equals(other: Uint8Array): boolean; - fill(value: number, offset?: number, end?: number): this; - fill(value: string, encoding?: string): this; - fill(value: string, offset?: number, end?: number, encoding?: string): this; - fill(value: Uint8Array, offset?: number, end?: number): this; - includes(value: number, byteOffset?: number): boolean; - includes(value: string, encoding?: string): boolean; - includes(value: string, byteOffset?: number, encoding?: string): boolean; - includes(value: Uint8Array, byteOffset?: number): boolean; - indexOf(value: number, byteOffset?: number): number; - indexOf(value: string, encoding?: string): number; - indexOf(value: string, byteOffset?: number, encoding?: string): number; - indexOf(value: Uint8Array, byteOffset?: number): number; - lastIndexOf(value: number, byteOffset?: number): number; - lastIndexOf(value: string, encoding?: string): number; - lastIndexOf(value: string, byteOffset?: number, encoding?: string): number; - lastIndexOf(value: Uint8Array, byteOffset?: number): number; - readBigInt64BE(offset?: number): bigint; - readBigInt64LE(offset?: number): bigint; - readBigUInt64BE(offset?: number): bigint; - readBigUInt64LE(offset?: number): bigint; - readDoubleBE(offset?: number): number; - readDoubleLE(offset?: number): number; - readFloatBE(offset?: number): number; - readFloatLE(offset?: number): number; - readInt8(offset?: number): number; - readInt16BE(offset?: number): number; - readInt16LE(offset?: number): number; - readInt32BE(offset?: number): number; - readInt32LE(offset?: number): number; - readIntBE(offset?: number, byteLength?: number): number; - readIntLE(offset?: number, byteLength?: number): number; - readUInt8(offset?: number): number; - readUInt16BE(offset?: number): number; - readUInt16LE(offset?: number): number; - readUInt32BE(offset?: number): number; - readUInt32LE(offset?: number): number; - readUIntBE(offset?: number, byteLength?: number): number; - readUIntLE(offset?: number, byteLength?: number): number; - swap16(): this; - swap32(): this; - swap64(): this; - toJSON(): { type: "Buffer"; data: number[] }; - toString(encoding?: string, start?: number, end?: number): string; - write(string: string, encoding?: string): number; - write(string: string, offset?: number, encoding?: string): number; - write(string: string, offset?: number, length?: number, encoding?: string): number; - writeBigInt64BE(value: bigint, offset?: number): number; - writeBigInt64LE(value: bigint, offset?: number): number; - writeBigUInt64BE(value: bigint, offset?: number): number; - writeBigUInt64LE(value: bigint, offset?: number): number; - writeDoubleBE(value: number, offset?: number): number; - writeDoubleLE(value: number, offset?: number): number; - writeFloatBE(value: number, offset?: number): number; - writeFloatLE(value: number, offset?: number): number; - writeInt8(value: number, offset?: number): number; - writeInt16BE(value: number, offset?: number): number; - writeInt16LE(value: number, offset?: number): number; - writeInt32BE(value: number, offset?: number): number; - writeInt32LE(value: number, offset?: number): number; - writeIntBE(value: number, offset?: number, byteLength?: number): number; - writeIntLE(value: number, offset?: number, byteLength?: number): number; - writeUInt8(value: number, offset?: number): number; - writeUInt16BE(value: number, offset?: number): number; - writeUInt16LE(value: number, offset?: number): number; - writeUInt32BE(value: number, offset?: number): number; - writeUInt32LE(value: number, offset?: number): number; - writeUIntBE(value: number, offset?: number, byteLength?: number): number; - writeUIntLE(value: number, offset?: number, byteLength?: number): number; - new (array: Iterable): Buffer; - new (arrayBuffer: ArrayBufferLike, byteOffset?: number, length?: number): Buffer; - new (buffer: ArrayBufferView): Buffer; - new (size: number): Buffer; - new (string: string, encoding?: string): Buffer; -} - -type FillValue = string | number | ArrayBufferView; - -export function Buffer(value: number): Buffer; -export function Buffer(value: StringLike, encoding?: string): Buffer; -export function Buffer(value: ArrayBufferLike, byteOffset?: number, length?: number): Buffer; -export function Buffer( - value: Uint8Array | ReadonlyArray, - byteOffset?: number, - length?: number -): Buffer; -export function Buffer(value: StringLike, encoding?: string): Buffer; -export function Buffer( - value: number | BufferSource, - encodingOrOffset?: string | number, - length?: number -): Buffer { - if (typeof value === "number") { - if (typeof encodingOrOffset === "string") { - throw new ERR_INVALID_ARG_TYPE("string", "string", value); - } - return allocUnsafe(value); - } - - return _from(value, encodingOrOffset, length); -} - -Object.setPrototypeOf(Buffer.prototype, Uint8Array.prototype); -Object.setPrototypeOf(Buffer, Uint8Array); - -Object.defineProperties(Buffer, { - // By default, Node.js allocates Buffers from a shared slab allocation - // as a performance optimization. While this is fast, it's not ideal - // in our environment as it could potentially be used to leak buffer - // data across multiple requests. We always want our Buffer instances - // to be distinct allocations. To signal this, we keep our poolSize - // always set to 0. - poolSize: { - enumerable: true, - value: 0, - writable: false, - }, -}); - -Object.defineProperties(Buffer.prototype, { - parent: { - enumerable: true, - get() { - if (!Buffer.isBuffer(this)) { - return void 0; - } - return this.buffer; - }, - }, - offset: { - enumerable: true, - get() { - if (!Buffer.isBuffer(this)) { - return void 0; - } - return this.byteOffset; - }, - }, - [kIsBuffer]: { - enumerable: false, - configurable: false, - value: true, - }, -}); - -function _from(value: BufferSource, encodingOrOffset?: string | number, length?: number): Buffer { - if (typeof value === "string") { - return fromString(value, encodingOrOffset as string | undefined) as Buffer; - } - - if (typeof value === "object" && value != null) { - if (isAnyArrayBuffer(value)) { - return fromArrayBuffer( - value as ArrayBufferLike, - encodingOrOffset as number, - length - ) as Buffer; - } - - const valueOf = value?.valueOf(); - if ( - valueOf != null && - valueOf !== value && - (typeof valueOf === "string" || typeof valueOf === "object") - ) { - return _from(valueOf as BufferSource, encodingOrOffset, length); - } - - if ((value as any).length !== undefined || isAnyArrayBuffer((value as any).buffer)) { - if (typeof (value as any).length !== "number") { - return createBuffer(0); - } - - return fromArrayLike(value as any) as Buffer; - } - - if ((value as any).type === "Buffer" && Array.isArray((value as any).data)) { - return fromArrayLike((value as any).data) as Buffer; - } - - const toPrimitive = (value as any)[Symbol.toPrimitive]; - if (typeof toPrimitive === "function") { - const primitive = toPrimitive("string"); - if (typeof primitive === "string") { - return fromString(primitive, encodingOrOffset as string | undefined) as Buffer; - } - } - } - - throw new ERR_INVALID_ARG_TYPE( - "first argument", - [ - "string", - "Buffer", - "TypedArray", - "ArrayBuffer", - "SharedArrayBuffer", - "Array", - "Array-like Object", - ], - value - ); -} - -function from(value: StringLike, encoding?: string): Buffer; -function from(value: ArrayBufferLike, byteOffset?: number, length?: number): Buffer; -function from( - value: Uint8Array | ReadonlyArray, - byteOffset?: number, - length?: number -): Buffer; -function from(value: BufferSource, encodingOrOffset?: string | number, length?: number) { - return _from(value, encodingOrOffset, length); -} - -function fromString(string: StringLike, encoding?: string) { - if (typeof encoding !== "string" || encoding === "") { - encoding = "utf8"; - } - const normalizedEncoding = normalizeEncoding(encoding); - if (!Buffer.isEncoding(normalizedEncoding)) { - throw new ERR_UNKNOWN_ENCODING(encoding); - } - - const ab = bufferUtil.decodeString(`${string}`, normalizedEncoding as string); - if (ab === undefined) { - throw new ERR_INVALID_ARG_VALUE( - "string", - string, - `Unable to decode string using encoding ${encoding}` - ); - } - return fromArrayBuffer(ab, 0, ab.byteLength); -} - -function fromArrayLike(array: Uint8Array | ReadonlyArray) { - const u8 = Uint8Array.from(array); - return fromArrayBuffer(u8.buffer, u8.byteOffset, u8.byteLength); -} - -function fromArrayBuffer(obj: ArrayBufferLike, byteOffset: number, length?: number) { - // Convert byteOffset to integer - if (byteOffset === undefined) { - byteOffset = 0; - } else { - byteOffset = +byteOffset; - if (Number.isNaN(byteOffset)) { - byteOffset = 0; - } - } - - const maxLength = (obj as ArrayBuffer).byteLength - byteOffset; - - if (maxLength < 0) { - throw new ERR_BUFFER_OUT_OF_BOUNDS("offset"); - } - - if (length === undefined) { - length = maxLength; - } else { - // Convert length to non-negative integer. - length = +length; - if (length > 0) { - if (length > maxLength) { - throw new ERR_BUFFER_OUT_OF_BOUNDS("length"); - } - } else { - length = 0; - } - } - - const buffer = new Uint8Array(obj as ArrayBuffer, byteOffset, length); - Object.setPrototypeOf(buffer, Buffer.prototype); - return buffer; -} - -Buffer.from = from; - -function of(...args: number[]) { - const buf = Buffer.alloc(args.length); - for (let k = 0; k < args.length; k++) buf[k] = args[k]!; - return buf; -} - -Buffer.of = of; - -function alloc(size: number, fill?: FillValue, encoding?: string): Buffer { - validateNumber(size, "size"); - if (Number.isNaN(size)) { - throw new ERR_INVALID_ARG_VALUE.RangeError("size", size); - } - if (size >= kMaxLength) { - throw new ERR_OUT_OF_RANGE("size", `0 to ${kMaxLength}`, size); - } - - const buffer = createBuffer(size); - if (fill !== undefined) { - if (encoding !== undefined) { - validateString(encoding, "encoding"); - } - return buffer.fill(fill as any, encoding); - } - return buffer; -} - -Buffer.alloc = alloc; - -function allocUnsafe(size: number): Buffer { - return alloc(size); -} - -Buffer.allocUnsafe = allocUnsafe; -Buffer.allocUnsafeSlow = allocUnsafe; - -export function SlowBuffer(length: number) { - return alloc(+length); -} - -Object.setPrototypeOf(SlowBuffer.prototype, Uint8Array.prototype); -Object.setPrototypeOf(SlowBuffer, Uint8Array); - -Buffer.isBuffer = function isBuffer(b: unknown) { - return b != null && (b as any)[kIsBuffer] && b !== Buffer.prototype; -}; - -export function compare(a: Buffer | Uint8Array, b: Buffer | Uint8Array) { - if (isInstance(a, Uint8Array)) { - const buf = a as Uint8Array; - a = fromArrayBuffer(buf.buffer, buf.byteOffset, buf.byteLength); - } - if (isInstance(b, Uint8Array)) { - const buf = b as Uint8Array; - b = fromArrayBuffer(buf.buffer, buf.byteOffset, buf.byteLength); - } - if (!Buffer.isBuffer(a)) { - throw new ERR_INVALID_ARG_TYPE("a", ["Buffer", "Uint8Array"], typeof a); - } - if (!Buffer.isBuffer(b)) { - throw new ERR_INVALID_ARG_TYPE("b", ["Buffer", "Uint8Array"], typeof b); - } - if (a === b) return 0; - - return bufferUtil.compare(a, b); -} - -Buffer.compare = compare; - -export function isEncoding(encoding: unknown) { - return ( - typeof encoding === "string" && - encoding.length !== 0 && - normalizeEncoding(encoding) !== undefined - ); -} - -Buffer.isEncoding = isEncoding; - -Buffer.concat = function concat(list: (Buffer | Uint8Array)[], length?: number) { - if (!Array.isArray(list)) { - throw new ERR_INVALID_ARG_TYPE("list", "(Buffer|Uint8Array)[]", list); - } - - if (list.length === 0) return alloc(0); - - if (length === undefined) { - length = 0; - for (let i = 0; i < list.length; i++) { - if (list[i]!.length !== undefined) { - length += list[i]!.length; - } else { - throw new ERR_INVALID_ARG_TYPE("list", "(Buffer|Uint8Array)[]", list[i]); - } - } - } - validateOffset(length, "length"); - - const ab = bufferUtil.concat(list, length as number); - return fromArrayBuffer(ab, 0, length); -}; - -function base64ByteLength(str: string) { - let len = str.length; - if (str.charCodeAt(len - 1) === 0x3d) { - len--; - } - if (len > 1 && str.charCodeAt(len - 1) === 0x3d) len--; - - // Base64 ratio: 3/4 - return (len * 3) >>> 2; -} - -function byteLength( - string: string | ArrayBufferView | ArrayBuffer | SharedArrayBuffer, - encoding?: string -) { - if (typeof string !== "string") { - if (isArrayBufferView(string) || isAnyArrayBuffer(string)) { - return string.byteLength; - } - - throw new ERR_INVALID_ARG_TYPE("string", ["string", "Buffer", "ArrayBuffer"], string); - } - - string = `${string}`; - let normalizedEncoding = normalizeEncoding(encoding); - if (!Buffer.isEncoding(normalizedEncoding)) { - normalizedEncoding = "utf8"; - } - - switch (normalizedEncoding) { - case "ascii": - // Fall through - case "latin1": - return (string as string).length; - case "utf16le": - return (string as string).length * 2; - case "base64": - // Fall through - case "base64url": - return base64ByteLength(string as string); - case "hex": - return (string as string).length >>> 1; - case "utf8": - // Fall-through - default: - return bufferUtil.byteLength(string as string, normalizedEncoding as string); - } -} - -Buffer.byteLength = byteLength; - -Buffer.prototype.swap16 = function swap16() { - const len = this.length; - if (len % 2 !== 0) { - throw new ERR_INVALID_BUFFER_SIZE(16); - } - bufferUtil.swap(this, 16); - return this; -}; - -Buffer.prototype.swap32 = function swap32() { - const len = this.length; - if (len % 4 !== 0) { - throw new ERR_INVALID_BUFFER_SIZE(32); - } - bufferUtil.swap(this, 32); - return this; -}; - -Buffer.prototype.swap64 = function swap64() { - const len = this.length; - if (len % 8 !== 0) { - throw new ERR_INVALID_BUFFER_SIZE(64); - } - bufferUtil.swap(this, 64); - return this; -}; - -Buffer.prototype.toString = function toString(encoding?: string, start?: number, end?: number) { - if (arguments.length === 0) { - return bufferUtil.toString(this, 0, this.length, "utf8"); - } - - const len = this.length; - - if (start === undefined || start <= 0) { - start = 0; - } else if (start >= len) { - return ""; - } else { - start |= 0; - } - - if (end === undefined || end > len) { - end = len; - } else { - end |= 0; - } - - if ((end as number) <= start) { - return ""; - } - - const normalizedEncoding = normalizeEncoding(`${encoding}`); - if (!Buffer.isEncoding(normalizedEncoding)) { - throw new ERR_UNKNOWN_ENCODING(encoding as string); - } - - return bufferUtil.toString(this, start as number, end as number, normalizedEncoding as string); -}; - -Buffer.prototype.toLocaleString = Buffer.prototype.toString; - -Buffer.prototype.equals = function equals(b: Buffer | Uint8Array) { - return compare(this, b) === 0; -}; - -Buffer.prototype.inspect = function inspect(_recurseTimes: number, ctx: InspectOptionsStylized) { - let str = ""; - const max = INSPECT_MAX_BYTES; - str = this.toString("hex", 0, max) - .replace(/(.{2})/g, "$1 ") - .trim(); - const remaining = this.length - max; - if (remaining > 0) { - str += ` ... ${remaining} more byte${remaining > 1 ? "s" : ""}`; - } - // Inspect special properties as well, if possible. - if (ctx) { - let extras = false; - const filter = ctx.showHidden ? internalUtil.ALL_PROPERTIES : internalUtil.ONLY_ENUMERABLE; - const obj: Record = { __proto__: null }; - internalUtil.getOwnNonIndexProperties(this, filter).forEach((key) => { - extras = true; - obj[key] = this[key]; - }); - if (extras) { - if (this.length !== 0) str += ", "; - // '[Object: null prototype] {'.length === 26 - // This is guarded with a test. - str += utilInspect(obj, { - ...ctx, - breakLength: Infinity, - compact: true, - }).slice(27, -2); - } - } - return ""; -}; - -if (customInspectSymbol) { - Buffer.prototype[customInspectSymbol] = Buffer.prototype.inspect; -} - -Buffer.prototype.compare = function compare( - target: Buffer | Uint8Array, - start?: number, - end?: number, - thisStart?: number, - thisEnd?: number -) { - if (isInstance(target, Uint8Array)) { - target = fromArrayBuffer(target.buffer, target.byteOffset, target.byteLength); - } - if (!Buffer.isBuffer(target)) { - throw new ERR_INVALID_ARG_TYPE("target", ["Buffer", "Uint8Array"], target); - } - - if (start === undefined) { - start = 0; - } else { - validateOffset(start, "targetStart", 0, kMaxLength); - } - - if (end === undefined) { - end = target.length; - } else { - validateOffset(end, "targetEnd", 0, target.length); - } - - if (thisStart === undefined) { - thisStart = 0; - } else { - validateOffset(thisStart as number, "sourceStart", 0, kMaxLength); - } - - if (thisEnd === undefined) { - thisEnd = this.length; - } else { - validateOffset(thisEnd as number, "sourceEnd", 0, this.length); - } - - return bufferUtil.compare(this, target, { - aStart: thisStart as number, - aEnd: thisEnd as number, - bStart: start as number, - bEnd: end as number, - }); -}; - -function includes( - this: Buffer, - val: string | number | Buffer | Uint8Array, - byteOffset?: number, - encoding?: string -) { - return this.indexOf(val as any, byteOffset, encoding) !== -1; -} - -Buffer.prototype.includes = includes; - -// Finds either the first index of `val` in `buffer` at offset >= `byteOffset`, -// OR the last index of `val` in `buffer` at offset <= `byteOffset`. -// -// Arguments: -// - buffer - a Buffer to search -// - val - a string, Buffer, or number -// - byteOffset - an index into `buffer`; will be clamped to an int32 -// - encoding - an optional encoding, relevant if val is a string -// - dir - true for indexOf, false for lastIndexOf -function bidirectionalIndexOf( - buffer: Uint8Array, - val: string | number | Buffer | Uint8Array, - byteOffset: number | string | undefined, - encoding: string | undefined, - dir: boolean | undefined -) { - if (Buffer.isBuffer(val) && !isUint8Array(val)) { - throw new ERR_INVALID_ARG_TYPE("val", ["string", "number", "Buffer", "Uint8Array"], val); - } - - if (typeof byteOffset === "string") { - encoding = byteOffset; - byteOffset = undefined; - } else if ((byteOffset as number) > 0x7fffffff) { - byteOffset = 0x7fffffff; - } else if ((byteOffset as number) < -0x80000000) { - byteOffset = -0x80000000; - } - // Coerce to Number. Values like null and [] become 0. - byteOffset = +(byteOffset as number); - // If the offset is undefined, "foo", {}, coerces to NaN, search whole buffer. - if (Number.isNaN(byteOffset)) { - byteOffset = dir ? 0 : buffer.length || buffer.byteLength; - } - dir = !!dir; // Cast to bool. - - if (typeof val === "number") { - val = (val >>> 0) & 0xff; - if (dir) { - return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset); - } else { - return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset); - } - } - - if (typeof val !== "string" && !isUint8Array(val) && !Buffer.isBuffer(val)) { - throw new ERR_INVALID_ARG_TYPE("value", ["number", "string", "Buffer", "Uint8Array"], val); - } - - let normalizedEncoding = normalizeEncoding(encoding); - if (!Buffer.isEncoding(normalizedEncoding)) { - throw new ERR_UNKNOWN_ENCODING(encoding as string); - } - - const result = bufferUtil.indexOf(buffer, val, byteOffset, normalizedEncoding, dir); - return result == null ? -1 : result; -} - -Buffer.prototype.indexOf = function indexOf( - val: string | number | Buffer | Uint8Array, - byteOffset?: number | string, - encoding?: string -) { - return bidirectionalIndexOf(this, val, byteOffset, encoding, true); -}; - -Buffer.prototype.lastIndexOf = function lastIndexOf( - val: string | number | Buffer | Uint8Array, - byteOffset?: number | string, - encoding?: string -) { - return bidirectionalIndexOf(this, val, byteOffset, encoding, false); -}; - -Buffer.prototype.asciiSlice = function asciiSlice(offset: number, length: number) { - validateOffset(offset, "offset", 0, this.length); - validateOffset(length, "length", 0, this.length - offset); - return bufferUtil.toString(this, offset, offset + length, "ascii"); -}; - -Buffer.prototype.base64Slice = function base64Slice(offset: number, length: number) { - validateOffset(offset, "offset", 0, this.length); - validateOffset(length, "length", 0, this.length - offset); - return bufferUtil.toString(this, offset, offset + length, "base64"); -}; - -Buffer.prototype.base64urlSlice = function base64urlSlice(offset: number, length: number) { - validateOffset(offset, "offset", 0, this.length); - validateOffset(length, "length", 0, this.length - offset); - return bufferUtil.toString(this, offset, offset + length, "base64url"); -}; - -Buffer.prototype.hexSlice = function hexSlice(offset: number, length: number) { - validateOffset(offset, "offset", 0, this.length); - validateOffset(length, "length", 0, this.length - offset); - return bufferUtil.toString(this, offset, offset + length, "hex"); -}; - -Buffer.prototype.latin1Slice = function latin1Slice(offset: number, length: number) { - validateOffset(offset, "offset", 0, this.length); - validateOffset(length, "length", 0, this.length - offset); - return bufferUtil.toString(this, offset, offset + length, "latin1"); -}; - -Buffer.prototype.ucs2Slice = function ucs2Slice(offset: number, length: number) { - validateOffset(offset, "offset", 0, this.length); - validateOffset(length, "length", 0, this.length - offset); - return bufferUtil.toString(this, offset, offset + length, "utf16le"); -}; - -Buffer.prototype.utf8Slice = function utf8Slice(offset: number, length: number) { - validateOffset(offset, "offset", 0, this.length); - validateOffset(length, "length", 0, this.length - offset); - return bufferUtil.toString(this, offset, offset + length, "utf8"); -}; - -Buffer.prototype.asciiWrite = function asciiWrite( - string: StringLike, - offset?: number, - length?: number -) { - offset ??= 0; - length ??= this.length; - validateOffset(offset as number, "offset", 0, this.length); - validateOffset(length as number, "length", 0, this.length - offset); - return bufferUtil.write(this, `${string}`, offset as number, length as number, "ascii"); -}; - -Buffer.prototype.base64Write = function base64Write( - string: StringLike, - offset?: number, - length?: number -) { - offset ??= 0; - length ??= this.length; - validateOffset(offset as number, "offset", 0, this.length); - validateOffset(length as number, "length", 0, this.length - offset); - return bufferUtil.write(this, `${string}`, offset as number, length as number, "base64"); -}; - -Buffer.prototype.base64urlWrite = function base64urlWrite( - string: StringLike, - offset?: number, - length?: number -) { - offset ??= 0; - length ??= this.length; - validateOffset(offset as number, "offset", 0, this.length); - validateOffset(length as number, "length", 0, this.length - offset); - return bufferUtil.write(this, `${string}`, offset as number, length as number, "base64url"); -}; - -Buffer.prototype.hexWrite = function hexWrite(string: StringLike, offset: number, length: number) { - offset ??= 0; - length ??= this.length; - validateOffset(offset as number, "offset", 0, this.length); - validateOffset(length as number, "length", 0, this.length - offset); - return bufferUtil.write(this, `${string}`, offset as number, length as number, "hex"); -}; - -Buffer.prototype.latin1Write = function latin1Write( - string: StringLike, - offset: number, - length: number -) { - offset ??= 0; - length ??= this.length; - validateOffset(offset as number, "offset", 0, this.length); - validateOffset(length as number, "length", 0, this.length - offset); - return bufferUtil.write(this, `${string}`, offset as number, length as number, "latin1"); -}; - -Buffer.prototype.ucs2Write = function ucs2Write( - string: StringLike, - offset: number, - length: number -) { - offset ??= 0; - length ??= this.length; - validateOffset(offset as number, "offset", 0, this.length); - validateOffset(length as number, "length", 0, this.length - offset); - return bufferUtil.write(this, `${string}`, offset as number, length as number, "utf16le"); -}; - -Buffer.prototype.utf8Write = function utf8Write( - string: StringLike, - offset: number, - length: number -) { - offset ??= 0; - length ??= this.length; - validateOffset(offset as number, "offset", 0, this.length); - validateOffset(length as number, "length", 0, this.length - offset); - return bufferUtil.write(this, `${string}`, offset as number, length as number, "utf8"); -}; - -Buffer.prototype.write = function write( - string: StringLike, - offset?: number | string, - length?: number | string, - encoding?: string -) { - string = `${string}`; - if (offset === undefined) { - // Buffer#write(string) - return bufferUtil.write(this, string as string, 0, this.length, "utf8"); - } - - if (length === undefined && typeof offset === "string") { - // Buffer#write(string, encoding) - encoding = offset; - length = this.length; - offset = 0; - } else { - // Buffer#write(string, offset[, length][, encoding]) - validateOffset(offset as number, "offset", 0, this.length); - - const remaining = this.length - (offset as number); - - if (length === undefined) { - length = remaining; - } else if (typeof length === "string") { - encoding = length; - length = remaining; - } else { - validateOffset(length, "length", 0, this.length); - if (length > remaining) { - length = remaining; - } - } - } - - if (!encoding) { - return bufferUtil.write(this, string as string, offset as number, length as number, "utf8"); - } - - const normalizedEncoding = normalizeEncoding(encoding); - if (!Buffer.isEncoding(normalizedEncoding)) { - throw new ERR_UNKNOWN_ENCODING(encoding as string); - } - - return bufferUtil.write( - this, - string as string, - offset as number, - length as number, - normalizedEncoding as string - ); -}; - -Buffer.prototype.toJSON = function toJSON() { - return { - type: "Buffer", - data: Array.prototype.slice.call(this._arr || this, 0), - }; -}; - -Buffer.prototype.slice = function slice(start: number, end?: number) { - const len = this.length; - start = ~~start; - end = end === void 0 ? len : ~~end; - if (start < 0) { - start += len; - if (start < 0) { - start = 0; - } - } else if (start > len) { - start = len; - } - if (end === undefined) { - end = this.byteLength; - } else if (end < 0) { - end += len; - if (end < 0) { - end = 0; - } - } else if (end > len) { - end = len; - } - if ((end as number) < start) { - end = start; - } - const newBuf = this.subarray(start, end); - Object.setPrototypeOf(newBuf, Buffer.prototype); - return newBuf; -}; - -Buffer.prototype.readUintLE = Buffer.prototype.readUIntLE = function readUIntLE( - offset: number, - byteLength: number -) { - if (offset === undefined) { - throw new ERR_INVALID_ARG_TYPE("offset", "number", offset); - } - switch (byteLength) { - case 1: - return this.readUInt8(offset); - case 2: - return this.readUInt16LE(offset); - case 3: - return readUInt24LE(this, offset); - case 4: - return this.readUInt32LE(offset); - case 5: - return readUInt40LE(this, offset); - case 6: - return readUInt48LE(this, offset); - default: - boundsError(byteLength, 6, "byteLength"); - } -}; - -Buffer.prototype.readUintBE = Buffer.prototype.readUIntBE = function readUIntBE( - offset: number, - byteLength: number -) { - if (offset === undefined) { - throw new ERR_INVALID_ARG_TYPE("offset", "number", offset); - } - switch (byteLength) { - case 1: - return this.readUInt8(offset); - case 2: - return this.readUInt16BE(offset); - case 3: - return readUInt24BE(this, offset); - case 4: - return this.readUInt32BE(offset); - case 5: - return readUInt40BE(this, offset); - case 6: - return readUInt48BE(this, offset); - default: - boundsError(byteLength, 6, "byteLength"); - } -}; - -Buffer.prototype.readUint8 = Buffer.prototype.readUInt8 = function readUInt8(offset: number = 0) { - validateOffset(offset, "offset", 0, this.length); - const val = this[offset]; - if (val === undefined) { - boundsError(offset, this.length - 1); - } - - return val; -}; - -Buffer.prototype.readUint16BE = Buffer.prototype.readUInt16BE = readUInt16BE; - -Buffer.prototype.readUint16LE = Buffer.prototype.readUInt16LE = function readUInt16LE( - offset: number = 0 -) { - validateOffset(offset, "offset", 0, this.length); - const first = this[offset]; - const last = this[offset + 1]; - if (first === undefined || last === undefined) { - boundsError(offset, this.length - 2); - } - - return first + last * 2 ** 8; -}; - -Buffer.prototype.readUint32LE = Buffer.prototype.readUInt32LE = function readUInt32LE( - this: Buffer, - offset: number = 0 -) { - validateOffset(offset, "offset", 0, this.length); - const first = this[offset]; - const last = this[offset + 3]; - if (first === undefined || last === undefined) { - boundsError(offset, this.length - 4); - } - - return first + this[++offset]! * 2 ** 8 + this[++offset]! * 2 ** 16 + last * 2 ** 24; -}; - -Buffer.prototype.readUint32BE = Buffer.prototype.readUInt32BE = readUInt32BE; - -Buffer.prototype.readBigUint64LE = Buffer.prototype.readBigUInt64LE = function readBigUInt64LE( - this: Buffer, - offset: number = 0 -) { - offset = offset >>> 0; - validateOffset(offset, "offset", 0, this.length); - const first = this[offset]; - const last = this[offset + 7]; - if (first === undefined || last === undefined) { - boundsError(offset, this.length - 8); - } - const lo = - first + this[++offset]! * 2 ** 8 + this[++offset]! * 2 ** 16 + this[++offset]! * 2 ** 24; - const hi = - this[++offset]! + this[++offset]! * 2 ** 8 + this[++offset]! * 2 ** 16 + last * 2 ** 24; - return BigInt(lo) + (BigInt(hi) << BigInt(32)); -}; - -Buffer.prototype.readBigUint64BE = Buffer.prototype.readBigUInt64BE = function readBigUInt64BE( - this: Buffer, - offset: number = 0 -) { - offset = offset >>> 0; - validateOffset(offset, "offset", 0, this.length); - const first = this[offset]; - const last = this[offset + 7]; - if (first === undefined || last === undefined) { - boundsError(offset, this.length - 8); - } - const hi = - first * 2 ** 24 + this[++offset]! * 2 ** 16 + this[++offset]! * 2 ** 8 + this[++offset]!; - const lo = - this[++offset]! * 2 ** 24 + this[++offset]! * 2 ** 16 + this[++offset]! * 2 ** 8 + last; - return (BigInt(hi) << BigInt(32)) + BigInt(lo); -}; - -Buffer.prototype.readIntLE = function readIntLE(offset: number, byteLength: number) { - if (offset === undefined) { - throw new ERR_INVALID_ARG_TYPE("offset", "number", offset); - } - switch (byteLength) { - case 1: - return this.readInt8(offset); - case 2: - return this.readInt16LE(offset); - case 3: - return readInt24LE(this, offset); - case 4: - return this.readInt32LE(offset); - case 5: - return readInt40LE(this, offset); - case 6: - return readInt48LE(this, offset); - default: - boundsError(byteLength, 6, "byteLength"); - } -}; - -Buffer.prototype.readIntBE = function readIntBE(offset: number, byteLength: number) { - if (offset === undefined) { - throw new ERR_INVALID_ARG_TYPE("offset", "number", offset); - } - switch (byteLength) { - case 1: - return this.readInt8(offset); - case 2: - return this.readInt16BE(offset); - case 3: - return readInt24BE(this, offset); - case 4: - return this.readInt32BE(offset); - case 5: - return readInt40BE(this, offset); - case 6: - return readInt48BE(this, offset); - default: - boundsError(byteLength, 6, "byteLength"); - } -}; - -Buffer.prototype.readInt8 = function readInt8(offset: number = 0) { - validateOffset(offset, "offset", 0, this.length); - const val = this[offset]; - if (val === undefined) { - boundsError(offset, this.length - 1); - } - - return val | ((val & (2 ** 7)) * 0x1fffffe); -}; - -Buffer.prototype.readInt16LE = function readInt16LE(offset: number = 0) { - validateOffset(offset, "offset", 0, this.length); - const first = this[offset]; - const last = this[offset + 1]; - if (first === undefined || last === undefined) { - boundsError(offset, this.length - 2); - } - - const val = first + last * 2 ** 8; - return val | ((val & (2 ** 15)) * 0x1fffe); -}; - -Buffer.prototype.readInt16BE = function readInt16BE(offset: number = 0) { - validateOffset(offset, "offset", 0, this.length); - const first = this[offset]; - const last = this[offset + 1]; - if (first === undefined || last === undefined) { - boundsError(offset, this.length - 2); - } - - const val = first * 2 ** 8 + last; - return val | ((val & (2 ** 15)) * 0x1fffe); -}; - -Buffer.prototype.readInt32LE = function readInt32LE(offset: number = 0) { - validateOffset(offset, "offset", 0, this.length); - const first = this[offset]; - const last = this[offset + 3]; - if (first === undefined || last === undefined) { - boundsError(offset, this.length - 4); - } - - return first + this[++offset] * 2 ** 8 + this[++offset] * 2 ** 16 + (last << 24); // Overflow -}; - -Buffer.prototype.readInt32BE = function readInt32BE(offset: number = 0) { - validateOffset(offset, "offset", 0, this.length); - const first = this[offset]; - const last = this[offset + 3]; - if (first === undefined || last === undefined) { - boundsError(offset, this.length - 4); - } - - return ( - (first << 24) + // Overflow - this[++offset] * 2 ** 16 + - this[++offset] * 2 ** 8 + - last - ); -}; - -Buffer.prototype.readBigInt64LE = function readBigInt64LE(this: Buffer, offset: number = 0) { - offset = offset >>> 0; - validateOffset(offset, "offset", 0, this.length); - const first = this[offset]; - const last = this[offset + 7]; - if (first === undefined || last === undefined) { - boundsError(offset, this.length - 8); - } - const val = - this[offset + 4]! + this[offset + 5]! * 2 ** 8 + this[offset + 6]! * 2 ** 16 + (last << 24); - return ( - (BigInt(val) << BigInt(32)) + - BigInt( - first + this[++offset]! * 2 ** 8 + this[++offset]! * 2 ** 16 + this[++offset]! * 2 ** 24 - ) - ); -}; - -Buffer.prototype.readBigInt64BE = function readBigInt64BE(this: Buffer, offset: number = 0) { - offset = offset >>> 0; - validateOffset(offset, "offset", 0, this.length); - const first = this[offset]; - const last = this[offset + 7]; - if (first === undefined || last === undefined) { - boundsError(offset, this.length - 8); - } - const val = - (first << 24) + this[++offset]! * 2 ** 16 + this[++offset]! * 2 ** 8 + this[++offset]!; - return ( - (BigInt(val) << BigInt(32)) + - BigInt( - this[++offset]! * 2 ** 24 + this[++offset]! * 2 ** 16 + this[++offset]! * 2 ** 8 + last - ) - ); -}; - -Buffer.prototype.readFloatLE = function readFloatLE(offset: number = 0) { - return bigEndian ? readFloatBackwards(this, offset) : readFloatForwards(this, offset); -}; - -Buffer.prototype.readFloatBE = function readFloatBE(offset: number = 0) { - return bigEndian ? readFloatForwards(this, offset) : readFloatBackwards(this, offset); -}; - -Buffer.prototype.readDoubleLE = function readDoubleLE(offset: number = 0) { - return bigEndian ? readDoubleBackwards(this, offset) : readDoubleForwards(this, offset); -}; - -Buffer.prototype.readDoubleBE = function readDoubleBE(offset: number = 0) { - return bigEndian ? readDoubleForwards(this, offset) : readDoubleBackwards(this, offset); -}; - -Buffer.prototype.writeUintLE = Buffer.prototype.writeUIntLE = function writeUIntLE( - value: number, - offset: number, - byteLength: number -) { - switch (byteLength) { - case 1: - return writeU_Int8(this, value, offset, 0, 0xff); - case 2: - return writeU_Int16LE(this, value, offset, 0, 0xffff); - case 3: - return writeU_Int24LE(this, value, offset, 0, 0xffffff); - case 4: - return writeU_Int32LE(this, value, offset, 0, 0xffffffff); - case 5: - return writeU_Int40LE(this, value, offset, 0, 0xffffffffff); - case 6: - return writeU_Int48LE(this, value, offset, 0, 0xffffffffffff); - default: - boundsError(byteLength, 6, "byteLength"); - } -}; - -Buffer.prototype.writeUintBE = Buffer.prototype.writeUIntBE = function writeUIntBE( - value: number, - offset: number, - byteLength: number -) { - switch (byteLength) { - case 1: - return writeU_Int8(this, value, offset, 0, 0xff); - case 2: - return writeU_Int16BE(this, value, offset, 0, 0xffff); - case 3: - return writeU_Int24BE(this, value, offset, 0, 0xffffff); - case 4: - return writeU_Int32BE(this, value, offset, 0, 0xffffffff); - case 5: - return writeU_Int40BE(this, value, offset, 0, 0xffffffffff); - case 6: - return writeU_Int48BE(this, value, offset, 0, 0xffffffffffff); - default: - boundsError(byteLength, 6, "byteLength"); - } -}; - -Buffer.prototype.writeUint8 = Buffer.prototype.writeUInt8 = function writeUInt8( - value: number, - offset: number = 0 -) { - return writeU_Int8(this, value, offset, 0, 0xff); -}; - -Buffer.prototype.writeUint16LE = Buffer.prototype.writeUInt16LE = function writeUInt16LE( - value: number, - offset: number = 0 -) { - return writeU_Int16LE(this, value, offset, 0, 0xffff); -}; - -Buffer.prototype.writeUint16BE = Buffer.prototype.writeUInt16BE = function writeUInt16BE( - value: number, - offset: number = 0 -) { - return writeU_Int16BE(this, value, offset, 0, 0xffff); -}; - -Buffer.prototype.writeUint32LE = Buffer.prototype.writeUInt32LE = function writeUInt32LE( - value: number, - offset: number = 0 -) { - return _writeUInt32LE(this, value, offset, 0, 0xffffffff); -}; - -Buffer.prototype.writeUint32BE = Buffer.prototype.writeUInt32BE = function writeUInt32BE( - value: number, - offset: number = 0 -) { - return _writeUInt32BE(this, value, offset, 0, 0xffffffff); -}; - -function wrtBigUInt64LE(buf: Buffer, value: bigint, offset: number, min: bigint, max: bigint) { - checkIntBI(value, min, max, buf, offset, 7); - let lo = Number(value & BigInt(4294967295)); - buf[offset++] = lo; - lo = lo >> 8; - buf[offset++] = lo; - lo = lo >> 8; - buf[offset++] = lo; - lo = lo >> 8; - buf[offset++] = lo; - let hi = Number((value >> BigInt(32)) & BigInt(4294967295)); - buf[offset++] = hi; - hi = hi >> 8; - buf[offset++] = hi; - hi = hi >> 8; - buf[offset++] = hi; - hi = hi >> 8; - buf[offset++] = hi; - return offset; -} - -function wrtBigUInt64BE(buf: Buffer, value: bigint, offset: number, min: bigint, max: bigint) { - checkIntBI(value, min, max, buf, offset, 7); - let lo = Number(value & BigInt(4294967295)); - buf[offset + 7] = lo; - lo = lo >> 8; - buf[offset + 6] = lo; - lo = lo >> 8; - buf[offset + 5] = lo; - lo = lo >> 8; - buf[offset + 4] = lo; - let hi = Number((value >> BigInt(32)) & BigInt(4294967295)); - buf[offset + 3] = hi; - hi = hi >> 8; - buf[offset + 2] = hi; - hi = hi >> 8; - buf[offset + 1] = hi; - hi = hi >> 8; - buf[offset] = hi; - return offset + 8; -} - -Buffer.prototype.writeBigUint64LE = Buffer.prototype.writeBigUInt64LE = function writeBigUInt64LE( - this: Buffer, - value: bigint, - offset: number = 0 -) { - return wrtBigUInt64LE(this, value, offset, 0n, 0xffffffffffffffffn); -}; - -Buffer.prototype.writeBigUint64BE = Buffer.prototype.writeBigUInt64BE = function writeBigUInt64BE( - this: Buffer, - value: bigint, - offset: number = 0 -) { - return wrtBigUInt64BE(this, value, offset, 0n, 0xffffffffffffffffn); -}; - -Buffer.prototype.writeIntLE = function writeIntLE( - value: number, - offset: number, - byteLength: number -) { - switch (byteLength) { - case 1: - return writeU_Int8(this, value, offset, -0x80, 0x7f); - case 2: - return writeU_Int16LE(this, value, offset, -0x8000, 0x7fff); - case 3: - return writeU_Int24LE(this, value, offset, -0x800000, 0x7fffff); - case 4: - return writeU_Int32LE(this, value, offset, -0x80000000, 0x7fffffff); - case 5: - return writeU_Int40LE(this, value, offset, -0x8000000000, 0x7fffffffff); - case 6: - return writeU_Int48LE(this, value, offset, -0x800000000000, 0x7fffffffffff); - default: - boundsError(byteLength, 6, "byteLength"); - } -}; - -Buffer.prototype.writeIntBE = function writeIntBE( - value: number, - offset: number, - byteLength: number -) { - switch (byteLength) { - case 1: - return writeU_Int8(this, value, offset, -0x80, 0x7f); - case 2: - return writeU_Int16BE(this, value, offset, -0x8000, 0x7fff); - case 3: - return writeU_Int24BE(this, value, offset, -0x800000, 0x7fffff); - case 4: - return writeU_Int32BE(this, value, offset, -0x80000000, 0x7fffffff); - case 5: - return writeU_Int40BE(this, value, offset, -0x8000000000, 0x7fffffffff); - case 6: - return writeU_Int48BE(this, value, offset, -0x800000000000, 0x7fffffffffff); - default: - boundsError(byteLength, 6, "byteLength"); - } -}; - -Buffer.prototype.writeInt8 = function writeInt8(value: number, offset: number = 0) { - return writeU_Int8(this, value, offset, -0x80, 0x7f); -}; - -Buffer.prototype.writeInt16LE = function writeInt16LE(value: number, offset: number = 0) { - return writeU_Int16LE(this, value, offset, -0x8000, 0x7fff); -}; - -Buffer.prototype.writeInt16BE = function writeInt16BE(value: number, offset: number = 0) { - return writeU_Int16BE(this, value, offset, -0x8000, 0x7fff); -}; - -Buffer.prototype.writeInt32LE = function writeInt32LE(value: number, offset: number = 0) { - return writeU_Int32LE(this, value, offset, -0x80000000, 0x7fffffff); -}; - -Buffer.prototype.writeInt32BE = function writeInt32BE(value: number, offset: number = 0) { - return writeU_Int32BE(this, value, offset, -0x80000000, 0x7fffffff); -}; - -Buffer.prototype.writeBigInt64LE = function writeBigInt64LE( - this: Buffer, - value: bigint, - offset: number = 0 -) { - return wrtBigUInt64LE(this, value, offset, -0x8000000000000000n, 0x7fffffffffffffffn); -}; - -Buffer.prototype.writeBigInt64BE = function writeBigInt64BE( - this: Buffer, - value: bigint, - offset: number = 0 -) { - return wrtBigUInt64BE(this, value, offset, -0x8000000000000000n, 0x7fffffffffffffffn); -}; - -Buffer.prototype.writeFloatLE = function writeFloatLE(value: number, offset: number) { - return bigEndian - ? writeFloatBackwards(this, value, offset) - : writeFloatForwards(this, value, offset); -}; - -Buffer.prototype.writeFloatBE = function writeFloatBE(value: number, offset: number) { - return bigEndian - ? writeFloatForwards(this, value, offset) - : writeFloatBackwards(this, value, offset); -}; - -Buffer.prototype.writeDoubleLE = function writeDoubleLE(value: number, offset: number) { - return bigEndian - ? writeDoubleBackwards(this, value, offset) - : writeDoubleForwards(this, value, offset); -}; - -Buffer.prototype.writeDoubleBE = function writeDoubleBE(value: number, offset: number) { - return bigEndian - ? writeDoubleForwards(this, value, offset) - : writeDoubleBackwards(this, value, offset); -}; - -Buffer.prototype.copy = function copy( - target: Buffer | Uint8Array, - targetStart?: number, - sourceStart?: number, - sourceEnd?: number -) { - if (!isUint8Array(target)) { - throw new ERR_INVALID_ARG_TYPE("target", ["Buffer", "Uint8Array"], target); - } - - targetStart = toInteger(targetStart, 0); - if ((targetStart as number) < 0) { - throw new ERR_OUT_OF_RANGE("targetStart", ">= 0", targetStart); - } - - sourceStart = toInteger(sourceStart, 0); - if ((sourceStart as number) < 0) { - throw new ERR_OUT_OF_RANGE("sourceStart", ">= 0", sourceStart); - } - if ((sourceStart as number) >= MAX_UINT32) { - throw new ERR_OUT_OF_RANGE("sourceStart", `< ${MAX_UINT32}`, sourceStart); - } - - sourceEnd ??= this.length; - sourceEnd = toInteger(sourceEnd, 0); - if ((sourceEnd as number) < 0) { - throw new ERR_OUT_OF_RANGE("sourceEnd", ">= 0", sourceEnd); - } - if ((sourceEnd as number) >= MAX_UINT32) { - throw new ERR_OUT_OF_RANGE("sourceEnd", `< ${MAX_UINT32}`, sourceEnd); - } - - if ((targetStart as number) >= target.length) { - return 0; - } - - if ((sourceEnd as number) > 0 && (sourceEnd as number) < (sourceStart as number)) { - sourceEnd = sourceStart; - } - if (sourceEnd === sourceStart) { - return 0; - } - if (target.length === 0 || this.length === 0) { - return 0; - } - - if ((sourceEnd as number) > this.length) { - sourceEnd = this.length; - } - - if (target.length - (targetStart as number) < (sourceEnd as number) - (sourceStart as number)) { - sourceEnd = target.length - (targetStart as number) + (sourceStart as number); - } - - const len = (sourceEnd as number) - (sourceStart as number); - if (this === target) { - this.copyWithin(targetStart as number, sourceStart as number, sourceEnd as number); - } else { - const sub = this.subarray(sourceStart, sourceEnd); - target.set(sub, targetStart); - } - - return len; -}; - -Buffer.prototype.fill = function fill( - val: string | number | Buffer | Uint8Array, - start?: number | string, - end?: number, - encoding?: string -) { - let normalizedEncoding: string | undefined; - if (typeof val === "string") { - if (typeof start === "string") { - encoding = start; - start = 0; - end = this.length; - } else if (typeof end === "string") { - encoding = end; - end = this.length; - } - normalizedEncoding = normalizeEncoding(encoding); - if (!Buffer.isEncoding(normalizedEncoding)) { - throw new ERR_UNKNOWN_ENCODING(encoding as string); - } - if (val.length === 1) { - const code = val.charCodeAt(0); - if ((encoding === "utf8" && code < 128) || encoding === "latin1") { - val = code; - } - } - } - - if (start !== undefined) { - validateNumber(start, "start"); - } - if (end !== undefined) { - validateNumber(end, "end"); - } - - if ((end as number) < 0 || (end as number) > this.length) { - throw new ERR_OUT_OF_RANGE("end", `0 to ${this.length}`, end); - } - if ((start as number) < 0 || this.length < (start as number) || this.length < (end as number)) { - throw new ERR_OUT_OF_RANGE("start", "0 to end", start); - } - if ((end as number) <= (start as number)) { - return this; - } - start = (start as number) >>> 0; - end = end === void 0 ? this.length : end >>> 0; - - if (typeof val === "string") { - bufferUtil.fillImpl( - this, - val as string, - start as number, - end as number, - normalizedEncoding - ); - return this; - } - - if (isArrayBufferView(val)) { - if ((val as ArrayBufferView).byteLength === 0) { - throw new ERR_INVALID_ARG_VALUE("value", "zero-length"); - } - bufferUtil.fillImpl(this, val as ArrayBufferView, start as number, end as number); - return this; - } - - if (typeof val === "number") { - val = val & 255; - } else if (typeof val === "boolean") { - val = Number(val); - } - val ??= 0; - - Uint8Array.prototype.fill.call(this, val as number, start, end); - - return this; -}; - -function checkBounds(buf: Buffer, offset: number, byteLength2: number) { - validateOffset(offset, "offset", 0, buf.length); - if (buf[offset] === undefined || buf[offset + byteLength2] === undefined) { - boundsError(offset, buf.length - (byteLength2 + 1)); - } -} - -function checkIntBI( - value: bigint | number, - min: bigint | number, - max: bigint | number, - buf: Buffer, - offset: number, - byteLength2: number -) { - if (value > max || value < min) { - const n = typeof min === "bigint" ? "n" : ""; - let range; - if (byteLength2 > 3) { - if (min === 0 || min === BigInt(0)) { - range = `>= 0${n} and < 2${n} ** ${(byteLength2 + 1) * 8}${n}`; - } else { - range = `>= -(2${n} ** ${(byteLength2 + 1) * 8 - 1}${n}) and < 2 ** ${ - (byteLength2 + 1) * 8 - 1 - }${n}`; - } - } else { - range = `>= ${min}${n} and <= ${max}${n}`; - } - throw new ERR_OUT_OF_RANGE("value", range, value); - } - checkBounds(buf, offset, byteLength2); -} - -export function isInstance(obj: unknown, type: Function) { - return ( - obj instanceof type || - (obj != null && - obj.constructor != null && - obj.constructor.name != null && - obj.constructor.name === type.name) - ); -} - -function readUInt48LE(buf: Buffer | Uint8Array, offset: number = 0) { - validateOffset(offset, "offset", 0, buf.length); - const first = buf[offset]; - const last = buf[offset + 5]; - if (first === undefined || last === undefined) { - boundsError(offset, buf.length - 6); - } - - return ( - first + - buf[++offset]! * 2 ** 8 + - buf[++offset]! * 2 ** 16 + - buf[++offset]! * 2 ** 24 + - (buf[++offset]! + last * 2 ** 8) * 2 ** 32 - ); -} - -function readUInt40LE(buf: Buffer | Uint8Array, offset: number = 0) { - validateOffset(offset, "offset", 0, buf.length); - const first = buf[offset]; - const last = buf[offset + 4]; - if (first === undefined || last === undefined) { - boundsError(offset, buf.length - 5); - } - - return ( - first + - buf[++offset]! * 2 ** 8 + - buf[++offset]! * 2 ** 16 + - buf[++offset]! * 2 ** 24 + - last * 2 ** 32 - ); -} - -function readUInt24LE(buf: Buffer | Uint8Array, offset: number = 0) { - validateOffset(offset, "offset", 0, buf.length); - const first = buf[offset]; - const last = buf[offset + 2]; - if (first === undefined || last === undefined) { - boundsError(offset, buf.length - 3); - } - - return first + buf[++offset]! * 2 ** 8 + last * 2 ** 16; -} - -function readUInt48BE(buf: Buffer | Uint8Array, offset: number = 0) { - validateOffset(offset, "offset", 0, buf.length); - const first = buf[offset]; - const last = buf[offset + 5]; - if (first === undefined || last === undefined) { - boundsError(offset, buf.length - 6); - } - - return ( - (first * 2 ** 8 + buf[++offset]!) * 2 ** 32 + - buf[++offset]! * 2 ** 24 + - buf[++offset]! * 2 ** 16 + - buf[++offset]! * 2 ** 8 + - last - ); -} - -function readUInt40BE(buf: Buffer | Uint8Array, offset: number = 0) { - validateOffset(offset, "offset", 0, buf.length); - const first = buf[offset]; - const last = buf[offset + 4]; - if (first === undefined || last === undefined) { - boundsError(offset, buf.length - 5); - } - - return ( - first * 2 ** 32 + - buf[++offset]! * 2 ** 24 + - buf[++offset]! * 2 ** 16 + - buf[++offset]! * 2 ** 8 + - last - ); -} - -function readUInt24BE(buf: Buffer | Uint8Array, offset: number = 0) { - validateOffset(offset, "offset", 0, buf.length); - const first = buf[offset]; - const last = buf[offset + 2]; - if (first === undefined || last === undefined) { - boundsError(offset, buf.length - 3); - } - - return first * 2 ** 16 + buf[++offset]! * 2 ** 8 + last; -} - -function readUInt16BE(this: Buffer, offset: number = 0) { - validateOffset(offset, "offset", 0, this.length); - const first = this[offset]; - const last = this[offset + 1]; - if (first === undefined || last === undefined) { - boundsError(offset, this.length - 2); - } - - return first * 2 ** 8 + last; -} - -function readUInt32BE(this: Buffer, offset: number = 0) { - validateOffset(offset, "offset", 0, this.length); - const first = this[offset]; - const last = this[offset + 3]; - if (first === undefined || last === undefined) { - boundsError(offset, this.length - 4); - } - - return first * 2 ** 24 + this[++offset]! * 2 ** 16 + this[++offset]! * 2 ** 8 + last; -} - -function readDoubleBackwards(buffer: Buffer | Uint8Array, offset: number = 0) { - validateOffset(offset, "offset", 0, buffer.length); - const first = buffer[offset]; - const last = buffer[offset + 7]; - if (first === undefined || last === undefined) { - boundsError(offset, buffer.length - 8); - } - - uInt8Float64Array[7] = first; - uInt8Float64Array[6] = buffer[++offset]!; - uInt8Float64Array[5] = buffer[++offset]!; - uInt8Float64Array[4] = buffer[++offset]!; - uInt8Float64Array[3] = buffer[++offset]!; - uInt8Float64Array[2] = buffer[++offset]!; - uInt8Float64Array[1] = buffer[++offset]!; - uInt8Float64Array[0] = last; - return float64Array[0]; -} - -function readDoubleForwards(buffer: Buffer | Uint8Array, offset: number = 0) { - validateOffset(offset, "offset", 0, buffer.length); - const first = buffer[offset]; - const last = buffer[offset + 7]; - if (first === undefined || last === undefined) { - boundsError(offset, buffer.length - 8); - } - - uInt8Float64Array[0] = first; - uInt8Float64Array[1] = buffer[++offset]!; - uInt8Float64Array[2] = buffer[++offset]!; - uInt8Float64Array[3] = buffer[++offset]!; - uInt8Float64Array[4] = buffer[++offset]!; - uInt8Float64Array[5] = buffer[++offset]!; - uInt8Float64Array[6] = buffer[++offset]!; - uInt8Float64Array[7] = last; - return float64Array[0]; -} - -function writeDoubleForwards(buffer: Buffer | Uint8Array, val: number, offset: number = 0) { - val = +val; - checkBounds(buffer as any, offset, 7); - - float64Array[0] = val; - buffer[offset++] = uInt8Float64Array[0]!; - buffer[offset++] = uInt8Float64Array[1]!; - buffer[offset++] = uInt8Float64Array[2]!; - buffer[offset++] = uInt8Float64Array[3]!; - buffer[offset++] = uInt8Float64Array[4]!; - buffer[offset++] = uInt8Float64Array[5]!; - buffer[offset++] = uInt8Float64Array[6]!; - buffer[offset++] = uInt8Float64Array[7]!; - return offset; -} - -function writeDoubleBackwards(buffer: Buffer | Uint8Array, val: number, offset: number = 0) { - val = +val; - checkBounds(buffer as any, offset, 7); - - float64Array[0] = val; - buffer[offset++] = uInt8Float64Array[7]!; - buffer[offset++] = uInt8Float64Array[6]!; - buffer[offset++] = uInt8Float64Array[5]!; - buffer[offset++] = uInt8Float64Array[4]!; - buffer[offset++] = uInt8Float64Array[3]!; - buffer[offset++] = uInt8Float64Array[2]!; - buffer[offset++] = uInt8Float64Array[1]!; - buffer[offset++] = uInt8Float64Array[0]!; - return offset; -} - -function readFloatBackwards(buffer: Buffer | Uint8Array, offset: number = 0) { - validateOffset(offset, "offset", 0, buffer.length); - const first = buffer[offset]; - const last = buffer[offset + 3]; - if (first === undefined || last === undefined) { - boundsError(offset, buffer.length - 4); - } - - uInt8Float32Array[3] = first; - uInt8Float32Array[2] = buffer[++offset]!; - uInt8Float32Array[1] = buffer[++offset]!; - uInt8Float32Array[0] = last; - return float32Array[0]; -} - -function readFloatForwards(buffer: Buffer | Uint8Array, offset: number = 0) { - validateOffset(offset, "offset", 0, buffer.length); - const first = buffer[offset]; - const last = buffer[offset + 3]; - if (first === undefined || last === undefined) { - boundsError(offset, buffer.length - 4); - } - - uInt8Float32Array[0] = first; - uInt8Float32Array[1] = buffer[++offset]!; - uInt8Float32Array[2] = buffer[++offset]!; - uInt8Float32Array[3] = last; - return float32Array[0]; -} - -function writeFloatForwards(buffer: Buffer | Uint8Array, val: number, offset: number = 0) { - val = +val; - checkBounds(buffer as any, offset, 3); - - float32Array[0] = val; - buffer[offset++] = uInt8Float32Array[0]!; - buffer[offset++] = uInt8Float32Array[1]!; - buffer[offset++] = uInt8Float32Array[2]!; - buffer[offset++] = uInt8Float32Array[3]!; - return offset; -} - -function writeFloatBackwards(buffer: Buffer | Uint8Array, val: number, offset: number = 0) { - val = +val; - checkBounds(buffer as any, offset, 3); - - float32Array[0] = val; - buffer[offset++] = uInt8Float32Array[3]!; - buffer[offset++] = uInt8Float32Array[2]!; - buffer[offset++] = uInt8Float32Array[1]!; - buffer[offset++] = uInt8Float32Array[0]!; - return offset; -} - -function readInt24LE(buf: Buffer | Uint8Array, offset: number = 0) { - validateOffset(offset, "offset", 0, buf.length); - const first = buf[offset]; - const last = buf[offset + 2]; - if (first === undefined || last === undefined) { - boundsError(offset, buf.length - 3); - } - - const val = first + buf[++offset]! * 2 ** 8 + last * 2 ** 16; - return val | ((val & (2 ** 23)) * 0x1fe); -} - -function readInt40LE(buf: Buffer | Uint8Array, offset: number = 0) { - validateOffset(offset, "offset", 0, buf.length); - const first = buf[offset]; - const last = buf[offset + 4]; - if (first === undefined || last === undefined) { - boundsError(offset, buf.length - 5); - } - - return ( - (last | ((last & (2 ** 7)) * 0x1fffffe)) * 2 ** 32 + - first + - buf[++offset]! * 2 ** 8 + - buf[++offset]! * 2 ** 16 + - buf[++offset]! * 2 ** 24 - ); -} - -function readInt48LE(buf: Buffer | Uint8Array, offset: number = 0) { - validateOffset(offset, "offset", 0, buf.length); - const first = buf[offset]; - const last = buf[offset + 5]; - if (first === undefined || last === undefined) { - boundsError(offset, buf.length - 6); - } - - const val = buf[offset + 4]! + last * 2 ** 8; - return ( - (val | ((val & (2 ** 15)) * 0x1fffe)) * 2 ** 32 + - first + - buf[++offset]! * 2 ** 8 + - buf[++offset]! * 2 ** 16 + - buf[++offset]! * 2 ** 24 - ); -} - -function readInt24BE(buf: Buffer | Uint8Array, offset: number = 0) { - validateOffset(offset, "offset", 0, buf.length); - const first = buf[offset]; - const last = buf[offset + 2]; - if (first === undefined || last === undefined) { - boundsError(offset, buf.length - 3); - } - - const val = first * 2 ** 16 + buf[++offset]! * 2 ** 8 + last; - return val | ((val & (2 ** 23)) * 0x1fe); -} - -function readInt48BE(buf: Buffer | Uint8Array, offset: number = 0) { - validateOffset(offset, "offset", 0, buf.length); - const first = buf[offset]; - const last = buf[offset + 5]; - if (first === undefined || last === undefined) { - boundsError(offset, buf.length - 6); - } - - const val = buf[++offset]! + first * 2 ** 8; - return ( - (val | ((val & (2 ** 15)) * 0x1fffe)) * 2 ** 32 + - buf[++offset]! * 2 ** 24 + - buf[++offset]! * 2 ** 16 + - buf[++offset]! * 2 ** 8 + - last - ); -} - -function readInt40BE(buf: Buffer | Uint8Array, offset: number = 0) { - validateOffset(offset, "offset", 0, buf.length); - const first = buf[offset]; - const last = buf[offset + 4]; - if (first === undefined || last === undefined) { - boundsError(offset, buf.length - 5); - } - - return ( - (first | ((first & (2 ** 7)) * 0x1fffffe)) * 2 ** 32 + - buf[++offset]! * 2 ** 24 + - buf[++offset]! * 2 ** 16 + - buf[++offset]! * 2 ** 8 + - last - ); -} - -function boundsError(value: number, length: number, type?: string): never { - if (Math.floor(value) !== value) { - throw new ERR_OUT_OF_RANGE(type || "offset", "an integer", value); - } - - if (length < 0) { - throw new ERR_BUFFER_OUT_OF_BOUNDS(); - } - - throw new ERR_OUT_OF_RANGE(type || "offset", `>= ${type ? 1 : 0} and <= ${length}`, value); -} - -function validateNumber(value: unknown, name: string) { - if (typeof value !== "number") { - throw new ERR_INVALID_ARG_TYPE(name, "number", value); - } -} - -function checkInt( - value: number | bigint, - min: number | bigint, - max: number | bigint, - buf: Buffer, - offset: number, - byteLength: number -) { - if (value > max || value < min) { - const n = typeof min === "bigint" ? "n" : ""; - let range; - if (byteLength > 3) { - if (min === 0 || min === 0n) { - range = `>= 0${n} and < 2${n} ** ${(byteLength + 1) * 8}${n}`; - } else { - range = - `>= -(2${n} ** ${(byteLength + 1) * 8 - 1}${n}) and ` + - `< 2${n} ** ${(byteLength + 1) * 8 - 1}${n}`; - } - } else { - range = `>= ${min}${n} and <= ${max}${n}`; - } - throw new ERR_OUT_OF_RANGE("value", range, value); - } - checkBounds(buf, offset, byteLength); -} - -function toInteger(n: number | undefined, defaultVal: number) { - if (n === undefined) n = 0; - n = +(n as number); - if (!Number.isNaN(n) && n >= Number.MIN_SAFE_INTEGER && n <= Number.MAX_SAFE_INTEGER) { - return n % 1 === 0 ? n : Math.floor(n); - } - return defaultVal; -} - -function writeU_Int8(buf: Buffer, value: number, offset: number, min: number, max: number) { - value = +value; - validateOffset(offset, "offset", 0, buf.length); - if (value > max || value < min) { - throw new ERR_OUT_OF_RANGE("value", `>= ${min} and <= ${max}`, value); - } - if (buf[offset] === undefined) { - boundsError(offset, buf.length - 1); - } - - buf[offset] = value; - return offset + 1; -} - -function writeU_Int16BE(buf: Buffer, value: number, offset: number, min: number, max: number) { - value = +value; - validateOffset(offset, "offset", 0, buf.length); - checkInt(value, min, max, buf, offset, 1); - - buf[offset++] = value >>> 8; - buf[offset++] = value; - return offset; -} - -function _writeUInt32LE(buf: Buffer, value: number, offset: number, min: number, max: number) { - value = +value; - validateOffset(offset, "offset", 0, buf.length); - checkInt(value, min, max, buf, offset, 3); - - buf[offset++] = value; - value = value >>> 8; - buf[offset++] = value; - value = value >>> 8; - buf[offset++] = value; - value = value >>> 8; - buf[offset++] = value; - return offset; -} - -function writeU_Int16LE(buf: Buffer, value: number, offset: number, min: number, max: number) { - value = +value; - validateOffset(offset, "offset", 0, buf.length); - checkInt(value, min, max, buf, offset, 1); - - buf[offset++] = value; - buf[offset++] = value >>> 8; - return offset; -} - -function _writeUInt32BE(buf: Buffer, value: number, offset: number, min: number, max: number) { - value = +value; - validateOffset(offset, "offset", 0, buf.length); - checkInt(value, min, max, buf, offset, 3); - - buf[offset + 3] = value; - value = value >>> 8; - buf[offset + 2] = value; - value = value >>> 8; - buf[offset + 1] = value; - value = value >>> 8; - buf[offset] = value; - return offset + 4; -} - -function writeU_Int48BE(buf: Buffer, value: number, offset: number, min: number, max: number) { - value = +value; - validateOffset(offset, "offset", 0, buf.length); - checkInt(value, min, max, buf, offset, 5); - - const newVal = Math.floor(value * 2 ** -32); - buf[offset++] = newVal >>> 8; - buf[offset++] = newVal; - buf[offset + 3] = value; - value = value >>> 8; - buf[offset + 2] = value; - value = value >>> 8; - buf[offset + 1] = value; - value = value >>> 8; - buf[offset] = value; - return offset + 4; -} - -function writeU_Int40BE(buf: Buffer, value: number, offset: number, min: number, max: number) { - value = +value; - validateOffset(offset, "offset", 0, buf.length); - checkInt(value, min, max, buf, offset, 4); - - buf[offset++] = Math.floor(value * 2 ** -32); - buf[offset + 3] = value; - value = value >>> 8; - buf[offset + 2] = value; - value = value >>> 8; - buf[offset + 1] = value; - value = value >>> 8; - buf[offset] = value; - return offset + 4; -} - -function writeU_Int32BE(buf: Buffer, value: number, offset: number, min: number, max: number) { - value = +value; - validateOffset(offset, "offset", 0, buf.length); - checkInt(value, min, max, buf, offset, 3); - - buf[offset + 3] = value; - value = value >>> 8; - buf[offset + 2] = value; - value = value >>> 8; - buf[offset + 1] = value; - value = value >>> 8; - buf[offset] = value; - return offset + 4; -} - -function writeU_Int24BE(buf: Buffer, value: number, offset: number, min: number, max: number) { - value = +value; - validateOffset(offset, "offset", 0, buf.length); - checkInt(value, min, max, buf, offset, 2); - - buf[offset + 2] = value; - value = value >>> 8; - buf[offset + 1] = value; - value = value >>> 8; - buf[offset] = value; - return offset + 3; -} - -function validateOffset( - value: number, - name: string, - min: number = 0, - max: number = Number.MAX_SAFE_INTEGER -) { - if (typeof value !== "number") { - throw new ERR_INVALID_ARG_TYPE(name, "number", value); - } - if (!Number.isInteger(value)) { - throw new ERR_OUT_OF_RANGE(name, "an integer", value); - } - if (value < min || value > max) { - throw new ERR_OUT_OF_RANGE(name, `>= ${min} && <= ${max}`, value); - } -} - -function writeU_Int48LE(buf: Buffer, value: number, offset: number, min: number, max: number) { - value = +value; - validateOffset(offset, "offset", 0, buf.length); - checkInt(value, min, max, buf, offset, 5); - - const newVal = Math.floor(value * 2 ** -32); - buf[offset++] = value; - value = value >>> 8; - buf[offset++] = value; - value = value >>> 8; - buf[offset++] = value; - value = value >>> 8; - buf[offset++] = value; - buf[offset++] = newVal; - buf[offset++] = newVal >>> 8; - return offset; -} - -function writeU_Int40LE(buf: Buffer, value: number, offset: number, min: number, max: number) { - value = +value; - validateOffset(offset, "offset", 0, buf.length); - checkInt(value, min, max, buf, offset, 4); - - const newVal = value; - buf[offset++] = value; - value = value >>> 8; - buf[offset++] = value; - value = value >>> 8; - buf[offset++] = value; - value = value >>> 8; - buf[offset++] = value; - buf[offset++] = Math.floor(newVal * 2 ** -32); - return offset; -} - -function writeU_Int32LE(buf: Buffer, value: number, offset: number, min: number, max: number) { - value = +value; - validateOffset(offset, "offset", 0, buf.length); - checkInt(value, min, max, buf, offset, 3); - - buf[offset++] = value; - value = value >>> 8; - buf[offset++] = value; - value = value >>> 8; - buf[offset++] = value; - value = value >>> 8; - buf[offset++] = value; - return offset; -} - -function writeU_Int24LE(buf: Buffer, value: number, offset: number, min: number, max: number) { - value = +value; - validateOffset(offset, "offset", 0, buf.length); - checkInt(value, min, max, buf, offset, 2); - - buf[offset++] = value; - value = value >>> 8; - buf[offset++] = value; - value = value >>> 8; - buf[offset++] = value; - return offset; -} - -export default { - Buffer, - constants, - kMaxLength, - kStringMaxLength, - SlowBuffer, -}; diff --git a/JS/wasm/crates/wasmjs-engine/shims/src/internal/internal_errors.ts b/JS/wasm/crates/wasmjs-engine/shims/src/internal/internal_errors.ts deleted file mode 100644 index ab8e66830..000000000 --- a/JS/wasm/crates/wasmjs-engine/shims/src/internal/internal_errors.ts +++ /dev/null @@ -1,473 +0,0 @@ -import { inspect } from "./internal_inspect"; - -const classRegExp = /^([A-Z][a-z0-9]*)+$/; - -const kTypes = [ - "string", - "function", - "number", - "object", - "Function", - "Object", - "boolean", - "bigint", - "symbol", -]; - -export class NodeErrorAbstraction extends Error { - code: string; - - constructor(name: string, code: string, message: string) { - super(message); - this.code = code; - this.name = name; - //This number changes depending on the name of this class - //20 characters as of now - (this as any).stack = this.stack && `${name} [${this.code}]${this.stack.slice(20)}`; - } - - override toString() { - return `${this.name} [${this.code}]: ${this.message}`; - } -} - -export class NodeError extends NodeErrorAbstraction { - constructor(code: string, message: string) { - super(Error.prototype.name, code, message); - } -} - -export class NodeRangeError extends NodeErrorAbstraction { - constructor(code: string, message: string) { - super(RangeError.prototype.name, code, message); - Object.setPrototypeOf(this, RangeError.prototype); - this.toString = function () { - return `${this.name} [${this.code}]: ${this.message}`; - }; - } -} - -export class NodeTypeError extends NodeErrorAbstraction implements TypeError { - constructor(code: string, message: string) { - super(TypeError.prototype.name, code, message); - Object.setPrototypeOf(this, TypeError.prototype); - this.toString = function () { - return `${this.name} [${this.code}]: ${this.message}`; - }; - } -} - -function createInvalidArgType(name: string, expected: string | string[]): string { - // https://github.com/nodejs/node/blob/f3eb224/lib/internal/errors.js#L1037-L1087 - expected = Array.isArray(expected) ? expected : [expected]; - let msg = "The "; - if (name.endsWith(" argument")) { - // For cases like 'first argument' - msg += `${name} `; - } else { - const type = name.includes(".") ? "property" : "argument"; - msg += `"${name}" ${type} `; - } - msg += "must be "; - - const types = []; - const instances = []; - const other = []; - for (const value of expected) { - if (kTypes.includes(value)) { - types.push(value.toLocaleLowerCase()); - } else if (classRegExp.test(value)) { - instances.push(value); - } else { - other.push(value); - } - } - - // Special handle `object` in case other instances are allowed to outline - // the differences between each other. - if (instances.length > 0) { - const pos = types.indexOf("object"); - if (pos !== -1) { - types.splice(pos, 1); - instances.push("Object"); - } - } - - if (types.length > 0) { - if (types.length > 2) { - const last = types.pop(); - msg += `one of type ${types.join(", ")}, or ${last}`; - } else if (types.length === 2) { - msg += `one of type ${types[0]} or ${types[1]}`; - } else { - msg += `of type ${types[0]}`; - } - if (instances.length > 0 || other.length > 0) { - msg += " or "; - } - } - - if (instances.length > 0) { - if (instances.length > 2) { - const last = instances.pop(); - msg += `an instance of ${instances.join(", ")}, or ${last}`; - } else { - msg += `an instance of ${instances[0]}`; - if (instances.length === 2) { - msg += ` or ${instances[1]}`; - } - } - if (other.length > 0) { - msg += " or "; - } - } - - if (other.length > 0) { - if (other.length > 2) { - const last = other.pop(); - msg += `one of ${other.join(", ")}, or ${last}`; - } else if (other.length === 2) { - msg += `one of ${other[0]} or ${other[1]}`; - } else { - // @ts-ignore - if (other[0].toLowerCase() !== other[0]) { - msg += "an "; - } - msg += `${other[0]}`; - } - } - - return msg; -} - -function invalidArgTypeHelper(input: any) { - if (input == null) { - return ` Received ${input}`; - } - if (typeof input === "function" && input.name) { - return ` Received function ${input.name}`; - } - if (typeof input === "object") { - if (input.constructor && input.constructor.name) { - return ` Received an instance of ${input.constructor.name}`; - } - return ` Received ${inspect(input, { depth: -1 })}`; - } - let inspected = inspect(input, { colors: false }); - if (inspected.length > 25) { - inspected = `${inspected.slice(0, 25)}...`; - } - return ` Received type ${typeof input} (${inspected})`; -} - -function addNumericalSeparator(val: string) { - let res = ""; - let i = val.length; - const start = val[0] === "-" ? 1 : 0; - for (; i >= start + 4; i -= 3) { - res = `_${val.slice(i - 3, i)}${res}`; - } - return `${val.slice(0, i)}${res}`; -} - -export class ERR_CRYPTO_ECDH_INVALID_PUBLIC_KEY extends NodeError { - constructor() { - super("ERR_CRYPTO_ECDH_INVALID_PUBLIC_KEY", "Public key is not valid for specified curve"); - } -} - -export class ERR_CRYPTO_HASH_FINALIZED extends NodeError { - constructor() { - super("ERR_CRYPTO_HASH_FINALIZED", "Digest already called"); - } -} - -export class ERR_CRYPTO_HASH_UPDATE_FAILED extends NodeError { - constructor() { - super("ERR_CRYPTO_HASH_UPDATE_FAILED", "Hash update failed"); - } -} - -export class ERR_CRYPTO_INCOMPATIBLE_KEY extends NodeError { - constructor(name: string, msg: string) { - super("ERR_CRYPTO_INCOMPATIBLE_KEY", `Incompatible ${name}: ${msg}`); - } -} - -export class ERR_CRYPTO_INVALID_KEY_OBJECT_TYPE extends NodeError { - constructor(actual: string, expected: string) { - super( - "ERR_CRYPTO_INVALID_KEY_OBJECT_TYPE", - `Invalid key object type ${actual}, expected ${expected}.` - ); - } -} - -export class ERR_INVALID_ARG_TYPE_RANGE extends NodeRangeError { - constructor(name: string, expected: string | string[], actual: unknown) { - const msg = createInvalidArgType(name, expected); - - super("ERR_INVALID_ARG_TYPE", `${msg}.${invalidArgTypeHelper(actual)}`); - } -} - -export class ERR_INVALID_ARG_TYPE extends NodeTypeError { - constructor(name: string, expected: string | string[], actual: unknown) { - const msg = createInvalidArgType(name, expected); - - super("ERR_INVALID_ARG_TYPE", `${msg}.${invalidArgTypeHelper(actual)}`); - } - - static RangeError = ERR_INVALID_ARG_TYPE_RANGE; -} - -export class ERR_INVALID_ARG_VALUE_RANGE extends NodeRangeError { - constructor(name: string, value: unknown, reason: string = "is invalid") { - const type = name.includes(".") ? "property" : "argument"; - const inspected = inspect(value); - - super("ERR_INVALID_ARG_VALUE", `The ${type} '${name}' ${reason}. Received ${inspected}`); - } -} - -export class ERR_INVALID_ARG_VALUE extends NodeTypeError { - constructor(name: string, value: unknown, reason: string = "is invalid") { - const type = name.includes(".") ? "property" : "argument"; - const inspected = inspect(value); - - super("ERR_INVALID_ARG_VALUE", `The ${type} '${name}' ${reason}. Received ${inspected}`); - } - - static RangeError = ERR_INVALID_ARG_VALUE_RANGE; -} - -export class ERR_OUT_OF_RANGE extends RangeError { - code = "ERR_OUT_OF_RANGE"; - - constructor(str: string, range: string, input: unknown, replaceDefaultBoolean = false) { - // TODO(later): Implement internal assert? - // assert(range, 'Missing "range" argument'); - let msg = replaceDefaultBoolean ? str : `The value of "${str}" is out of range.`; - let received; - if (Number.isInteger(input) && Math.abs(input as number) > 2 ** 32) { - received = addNumericalSeparator(String(input)); - } else if (typeof input === "bigint") { - received = String(input); - if (input > 2n ** 32n || input < -(2n ** 32n)) { - received = addNumericalSeparator(received); - } - received += "n"; - } else { - received = inspect(input); - } - msg += ` It must be ${range}. Received ${received}`; - - super(msg); - - const { name } = this; - // Add the error code to the name to include it in the stack trace. - this.name = `${name} [${this.code}]`; - // Access the stack to generate the error message including the error code from the name. - this.stack; - // Reset the name to the actual name. - this.name = name; - } -} - -export class ERR_UNHANDLED_ERROR extends NodeError { - constructor(x: string) { - super("ERR_UNHANDLED_ERROR", `Unhandled error. (${x})`); - } -} - -export class ERR_INVALID_THIS extends NodeTypeError { - constructor(x: string) { - super("ERR_INVALID_THIS", `Value of "this" must be of type ${x}`); - } -} - -export class ERR_BUFFER_OUT_OF_BOUNDS extends NodeRangeError { - constructor(name?: string) { - super( - "ERR_BUFFER_OUT_OF_BOUNDS", - name - ? `"${name}" is outside of buffer bounds` - : "Attempt to access memory outside buffer bounds" - ); - } -} - -export class ERR_INVALID_BUFFER_SIZE extends NodeRangeError { - constructor(size: number) { - super("ERR_INVALID_BUFFER_SIZE", `Buffer size must be a multiple of ${size}-bits`); - } -} - -export class ERR_UNKNOWN_ENCODING extends NodeTypeError { - constructor(x: string) { - super("ERR_UNKNOWN_ENCODING", `Unknown encoding: ${x}`); - } -} - -export class ERR_STREAM_PREMATURE_CLOSE extends NodeTypeError { - constructor() { - super("ERR_STREAM_PREMATURE_CLOSE", "Premature close"); - } -} - -export class AbortError extends Error { - code: string; - - constructor(message = "The operation was aborted", options?: ErrorOptions) { - if (options !== undefined && typeof options !== "object") { - throw new ERR_INVALID_ARG_TYPE("options", "Object", options); - } - super(message, options); - this.code = "ABORT_ERR"; - this.name = "AbortError"; - } -} - -function determineSpecificType(value: any) { - if (value == null) { - return "" + value; - } - if (typeof value === "function" && value.name) { - return `function ${value.name}`; - } - if (typeof value === "object") { - if (value.constructor?.name) { - return `an instance of ${value.constructor.name}`; - } - return `${inspect(value, { depth: -1 })}`; - } - let inspected = inspect(value, { colors: false }); - if (inspected.length > 28) inspected = `${inspected.slice(0, 25)}...`; - - return `type ${typeof value} (${inspected})`; -} - -export class ERR_AMBIGUOUS_ARGUMENT extends NodeTypeError { - constructor(x: string, y: string) { - super("ERR_AMBIGUOUS_ARGUMENT", `The "${x}" argument is ambiguous. ${y}`); - } -} - -export class ERR_INVALID_RETURN_VALUE extends NodeTypeError { - constructor(input: string, name: string, value: unknown) { - super( - "ERR_INVALID_RETURN_VALUE", - `Expected ${input} to be returned from the "${name}" function but got ${determineSpecificType( - value - )}.` - ); - } -} - -export class ERR_MULTIPLE_CALLBACK extends NodeError { - constructor() { - super("ERR_MULTIPLE_CALLBACK", "Callback called multiple times"); - } -} - -export class ERR_MISSING_ARGS extends NodeTypeError { - constructor(...args: (string | string[])[]) { - let msg = "The "; - - const len = args.length; - - const wrap = (a: unknown) => `"${a}"`; - - args = args.map((a) => (Array.isArray(a) ? a.map(wrap).join(" or ") : wrap(a))); - - switch (len) { - case 1: - msg += `${args[0]} argument`; - break; - case 2: - msg += `${args[0]} and ${args[1]} arguments`; - break; - default: - msg += args.slice(0, len - 1).join(", "); - msg += `, and ${args[len - 1]} arguments`; - break; - } - - super("ERR_MISSING_ARGS", `${msg} must be specified`); - } -} - -export class ERR_FALSY_VALUE_REJECTION extends NodeError { - reason: string; - constructor(reason: string) { - super("ERR_FALSY_VALUE_REJECTION", "Promise was rejected with falsy value"); - this.reason = reason; - } -} - -export class ERR_METHOD_NOT_IMPLEMENTED extends NodeError { - constructor(name: string | symbol) { - if (typeof name === "symbol") { - name = (name as symbol).description!; - } - super("ERR_METHOD_NOT_IMPLEMENTED", `The ${name} method is not implemented`); - } -} - -export class ERR_STREAM_CANNOT_PIPE extends NodeError { - constructor() { - super("ERR_STREAM_CANNOT_PIPE", "Cannot pipe, not readable"); - } -} -export class ERR_STREAM_DESTROYED extends NodeError { - constructor(name: string | symbol) { - if (typeof name === "symbol") { - name = (name as symbol).description!; - } - super("ERR_STREAM_DESTROYED", `Cannot call ${name} after a stream was destroyed`); - } -} -export class ERR_STREAM_ALREADY_FINISHED extends NodeError { - constructor(name: string | symbol) { - if (typeof name === "symbol") { - name = (name as symbol).description!; - } - super("ERR_STREAM_ALREADY_FINISHED", `Cannot call ${name} after a stream was finished`); - } -} -export class ERR_STREAM_NULL_VALUES extends NodeTypeError { - constructor() { - super("ERR_STREAM_NULL_VALUES", "May not write null values to stream"); - } -} -export class ERR_STREAM_WRITE_AFTER_END extends NodeError { - constructor() { - super("ERR_STREAM_WRITE_AFTER_END", "write after end"); - } -} - -export class ERR_STREAM_PUSH_AFTER_EOF extends NodeError { - constructor() { - super("ERR_STREAM_PUSH_AFTER_EOF", "stream.push() after EOF"); - } -} - -export class ERR_STREAM_UNSHIFT_AFTER_END_EVENT extends NodeError { - constructor() { - super("ERR_STREAM_UNSHIFT_AFTER_END_EVENT", "stream.unshift() after end event"); - } -} - -export function aggregateTwoErrors(innerError: any, outerError: any) { - if (innerError && outerError && innerError !== outerError) { - if (Array.isArray(outerError.errors)) { - // If `outerError` is already an `AggregateError`. - outerError.errors.push(innerError); - return outerError; - } - const err = new AggregateError([outerError, innerError], outerError.message); - (err as any).code = outerError.code; - return err; - } - return innerError || outerError; -} diff --git a/JS/wasm/crates/wasmjs-engine/shims/src/internal/internal_inspect.ts b/JS/wasm/crates/wasmjs-engine/shims/src/internal/internal_inspect.ts deleted file mode 100644 index 4e5c8c797..000000000 --- a/JS/wasm/crates/wasmjs-engine/shims/src/internal/internal_inspect.ts +++ /dev/null @@ -1,2772 +0,0 @@ -import * as internal from "./util"; - -import { Buffer } from "./internal_buffer"; -import { - isAsyncFunction, - isGeneratorFunction, - isAnyArrayBuffer, - isArrayBuffer, - isArgumentsObject, - isBoxedPrimitive, - isDataView, - isMap, - isMapIterator, - isModuleNamespaceObject, - isNativeError, - isPromise, - isSet, - isSetIterator, - isWeakMap, - isWeakSet, - isRegExp, - isDate, - isTypedArray, - isStringObject, - isNumberObject, - isBooleanObject, - isBigIntObject, -} from "./internal_types"; -// import { ALL_PROPERTIES, ONLY_ENUMERABLE, getOwnNonIndexProperties } from "node-internal:internal_utils"; -import { validateObject, validateString } from "./validators"; - -// // Simplified assertions to avoid `Assertions require every name in the call target to be -// declared with an explicit type` TypeScript error -function assert(value: boolean, message = "Assertion failed"): asserts value { - if (!value) throw new Error(message); -} -assert.fail = function (message = "Assertion failed"): never { - throw new Error(message); -}; - -function isError(e: unknown): e is Error { - // An error could be an instance of Error while not being a native error - // or could be from a different realm and not be instance of Error but still - // be a native error. - return isNativeError(e) || e instanceof Error; -} - -const typedArrayPrototype = Object.getPrototypeOf(Uint8Array).prototype; -const typedArrayPrototypeLength: (this: internal.TypedArray) => number = - Object.getOwnPropertyDescriptor(typedArrayPrototype, "length")!.get!; -const typedArrayPrototypeToStringTag: (this: internal.TypedArray) => string = - Object.getOwnPropertyDescriptor(typedArrayPrototype, Symbol.toStringTag)!.get!; - -const setPrototypeSize: (this: Set) => number = Object.getOwnPropertyDescriptor( - Set.prototype, - "size" -)!.get!; -const mapPrototypeSize: (this: Map) => number = Object.getOwnPropertyDescriptor( - Map.prototype, - "size" -)!.get!; - -let maxStack_ErrorName: string; -let maxStack_ErrorMessage: string; -function isStackOverflowError(err: Error): boolean { - if (maxStack_ErrorMessage === undefined) { - try { - function overflowStack() { - overflowStack(); - } - overflowStack(); - } catch (err) { - assert(isError(err)); - maxStack_ErrorMessage = err.message; - maxStack_ErrorName = err.name; - } - } - - return err && err.name === maxStack_ErrorName && err.message === maxStack_ErrorMessage; -} - -export const customInspectSymbol = Symbol.for("nodejs.util.inspect.custom"); - -const colorRegExp = /\u001b\[\d\d?m/g; - -function removeColors(str: string): string { - return str.replace(colorRegExp, ""); -} - -export interface InspectOptions { - /** - * If `true`, object's non-enumerable symbols and properties are included in the formatted result. - * `WeakMap` and `WeakSet` entries are also included as well as user defined prototype properties (excluding method properties). - * @default false - */ - showHidden?: boolean; - /** - * Specifies the number of times to recurse while formatting object. - * This is useful for inspecting large objects. - * To recurse up to the maximum call stack size pass `Infinity` or `null`. - * @default 2 - */ - depth?: number | null; - /** - * If `true`, the output is styled with ANSI color codes. Colors are customizable. - */ - colors?: boolean; - /** - * If `false`, `[util.inspect.custom](depth, opts, inspect)` functions are not invoked. - * @default true - */ - customInspect?: boolean; - /** - * If `true`, `Proxy` inspection includes the target and handler objects. - * @default false - */ - showProxy?: boolean; - /** - * Specifies the maximum number of `Array`, `TypedArray`, `WeakMap`, and `WeakSet` elements - * to include when formatting. Set to `null` or `Infinity` to show all elements. - * Set to `0` or negative to show no elements. - * @default 100 - */ - maxArrayLength?: number | null; - /** - * Specifies the maximum number of characters to - * include when formatting. Set to `null` or `Infinity` to show all elements. - * Set to `0` or negative to show no characters. - * @default 10000 - */ - maxStringLength?: number | null; - /** - * The length at which input values are split across multiple lines. - * Set to `Infinity` to format the input as a single line - * (in combination with `compact` set to `true` or any number >= `1`). - * @default 80 - */ - breakLength?: number; - /** - * Setting this to `false` causes each object key - * to be displayed on a new line. It will also add new lines to text that is - * longer than `breakLength`. If set to a number, the most `n` inner elements - * are united on a single line as long as all properties fit into - * `breakLength`. Short array elements are also grouped together. Note that no - * text will be reduced below 16 characters, no matter the `breakLength` size. - * For more information, see the example below. - * @default true - */ - compact?: boolean | number; - /** - * If set to `true` or a function, all properties of an object, and `Set` and `Map` - * entries are sorted in the resulting string. - * If set to `true` the default sort is used. - * If set to a function, it is used as a compare function. - */ - sorted?: boolean | ((a: string, b: string) => number); - /** - * If set to `true`, getters are going to be - * inspected as well. If set to `'get'` only getters without setter are going - * to be inspected. If set to `'set'` only getters having a corresponding - * setter are going to be inspected. This might cause side effects depending on - * the getter function. - * @default false - */ - getters?: "get" | "set" | boolean; - /** - * If set to `true`, an underscore is used to separate every three digits in all bigints and numbers. - * @default false - */ - numericSeparator?: boolean; -} -export type Style = - | "special" - | "number" - | "bigint" - | "boolean" - | "undefined" - | "null" - | "string" - | "symbol" - | "date" - | "regexp" - | "module" - | "name"; -export type CustomInspectFunction = (depth: number, options: InspectOptionsStylized) => any; // TODO: , inspect: inspect -export interface InspectOptionsStylized extends InspectOptions { - stylize(text: string, styleType: Style): string; -} - -const builtInObjects = new Set( - Object.getOwnPropertyNames(globalThis).filter((e) => /^[A-Z][a-zA-Z0-9]+$/.exec(e) !== null) -); - -// https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot -const isUndetectableObject = (v: unknown): boolean => typeof v === "undefined" && v !== undefined; - -// These options must stay in sync with `getUserOptions`. So if any option will -// be added or removed, `getUserOptions` must also be updated accordingly. -export const inspectDefaultOptions = Object.seal({ - showHidden: false, - depth: 2, - colors: false, - customInspect: true, - showProxy: false, - maxArrayLength: 100, - maxStringLength: 10000, - breakLength: 80, - compact: 3, - sorted: false, - getters: false, - numericSeparator: false, -} as const); - -const kObjectType = 0; -const kArrayType = 1; -const kArrayExtrasType = 2; - -const strEscapeSequencesRegExp = - /[\x00-\x1f\x27\x5c\x7f-\x9f]|[\ud800-\udbff](?![\udc00-\udfff])|(?<~]))"; -const ansi = new RegExp(ansiPattern, "g"); - -interface Context extends Required { - maxArrayLength: number; - maxStringLength: number; - budget: Record; - indentationLvl: number; - seen: unknown[]; - currentDepth: number; - userOptions?: InspectOptions; - circular?: Map; -} - -function getUserOptions(ctx: Context, isCrossContext: boolean): InspectOptionsStylized { - const ret: InspectOptionsStylized = { - stylize: ctx.stylize, - showHidden: ctx.showHidden, - depth: ctx.depth, - colors: ctx.colors, - customInspect: ctx.customInspect, - showProxy: ctx.showProxy, - maxArrayLength: ctx.maxArrayLength, - maxStringLength: ctx.maxStringLength, - breakLength: ctx.breakLength, - compact: ctx.compact, - sorted: ctx.sorted, - getters: ctx.getters, - numericSeparator: ctx.numericSeparator, - ...ctx.userOptions, - }; - - // Typically, the target value will be an instance of `Object`. If that is - // *not* the case, the object may come from another vm.Context, and we want - // to avoid passing it objects from this Context in that case, so we remove - // the prototype from the returned object itself + the `stylize()` function, - // and remove all other non-primitives, including non-primitive user options. - if (isCrossContext) { - Object.setPrototypeOf(ret, null); - for (const key of Object.keys(ret) as (keyof InspectOptionsStylized)[]) { - if ( - (typeof ret[key] === "object" || typeof ret[key] === "function") && - ret[key] !== null - ) { - delete ret[key]; - } - } - ret.stylize = Object.setPrototypeOf((value: string, flavour: Style) => { - let stylized; - try { - stylized = `${ctx.stylize(value, flavour)}`; - } catch { - // Continue regardless of error. - } - - if (typeof stylized !== "string") return value; - // `stylized` is a string as it should be, which is safe to pass along. - return stylized; - }, null); - } - - return ret; -} - -/** - * Echos the value of any input. Tries to print the value out - * in the best way possible given the different types. - * @param {any} value The value to print out. - * @param {object} opts Optional options object that alters the output. - */ -/* Legacy: value, showHidden, depth, colors */ -export function inspect( - value: unknown, - showHidden?: boolean, - depth?: number | null, - color?: boolean -): string; -export function inspect(value: unknown, opts?: InspectOptions): string; -export function inspect(value: unknown, opts?: Partial | boolean): string { - // Default options - const ctx: Context = { - budget: {}, - indentationLvl: 0, - seen: [], - currentDepth: 0, - stylize: stylizeNoColor, - showHidden: inspectDefaultOptions.showHidden, - depth: inspectDefaultOptions.depth, - colors: inspectDefaultOptions.colors, - customInspect: inspectDefaultOptions.customInspect, - showProxy: inspectDefaultOptions.showProxy, - maxArrayLength: inspectDefaultOptions.maxArrayLength, - maxStringLength: inspectDefaultOptions.maxStringLength, - breakLength: inspectDefaultOptions.breakLength, - compact: inspectDefaultOptions.compact, - sorted: inspectDefaultOptions.sorted, - getters: inspectDefaultOptions.getters, - numericSeparator: inspectDefaultOptions.numericSeparator, - }; - if (arguments.length > 1) { - // Legacy... - if (arguments.length > 2) { - if (arguments[2] !== undefined) { - ctx.depth = arguments[2]; - } - if (arguments.length > 3 && arguments[3] !== undefined) { - ctx.colors = arguments[3]; - } - } - // Set user-specified options - if (typeof opts === "boolean") { - ctx.showHidden = opts; - } else if (opts) { - const optKeys = Object.keys(opts) as (keyof InspectOptionsStylized)[]; - for (let i = 0; i < optKeys.length; ++i) { - const key = optKeys[i]!; - // TODO(BridgeAR): Find a solution what to do about stylize. Either make - // this function public or add a new API with a similar or better - // functionality. - if ( - Object.prototype.hasOwnProperty.call(inspectDefaultOptions, key) || - key === "stylize" - ) { - (ctx as Record)[key] = opts[key]; - } else if (ctx.userOptions === undefined) { - // This is required to pass through the actual user input. - ctx.userOptions = opts; - } - } - } - } - if (ctx.colors) ctx.stylize = stylizeWithColor; - if (ctx.maxArrayLength === null) ctx.maxArrayLength = Infinity; - if (ctx.maxStringLength === null) ctx.maxStringLength = Infinity; - return formatValue(ctx, value, 0); -} -inspect.custom = customInspectSymbol; - -Object.defineProperty(inspect, "defaultOptions", { - get() { - return inspectDefaultOptions; - }, - set(options) { - validateObject(options, "options"); - return Object.assign(inspectDefaultOptions, options); - }, -}); - -// Set Graphics Rendition https://en.wikipedia.org/wiki/ANSI_escape_code#graphics -// Each color consists of an array with the color code as first entry and the -// reset code as second entry. -const defaultFG = 39; -const defaultBG = 49; -inspect.colors = { - __proto__: null, - reset: [0, 0], - bold: [1, 22], - dim: [2, 22], // Alias: faint - italic: [3, 23], - underline: [4, 24], - blink: [5, 25], - // Swap foreground and background colors - inverse: [7, 27], // Alias: swapcolors, swapColors - hidden: [8, 28], // Alias: conceal - strikethrough: [9, 29], // Alias: strikeThrough, crossedout, crossedOut - doubleunderline: [21, 24], // Alias: doubleUnderline - black: [30, defaultFG], - red: [31, defaultFG], - green: [32, defaultFG], - yellow: [33, defaultFG], - blue: [34, defaultFG], - magenta: [35, defaultFG], - cyan: [36, defaultFG], - white: [37, defaultFG], - bgBlack: [40, defaultBG], - bgRed: [41, defaultBG], - bgGreen: [42, defaultBG], - bgYellow: [43, defaultBG], - bgBlue: [44, defaultBG], - bgMagenta: [45, defaultBG], - bgCyan: [46, defaultBG], - bgWhite: [47, defaultBG], - framed: [51, 54], - overlined: [53, 55], - gray: [90, defaultFG], // Alias: grey, blackBright - redBright: [91, defaultFG], - greenBright: [92, defaultFG], - yellowBright: [93, defaultFG], - blueBright: [94, defaultFG], - magentaBright: [95, defaultFG], - cyanBright: [96, defaultFG], - whiteBright: [97, defaultFG], - bgGray: [100, defaultBG], // Alias: bgGrey, bgBlackBright - bgRedBright: [101, defaultBG], - bgGreenBright: [102, defaultBG], - bgYellowBright: [103, defaultBG], - bgBlueBright: [104, defaultBG], - bgMagentaBright: [105, defaultBG], - bgCyanBright: [106, defaultBG], - bgWhiteBright: [107, defaultBG], -}; - -function defineColorAlias(target: string, alias: string) { - Object.defineProperty(inspect.colors, alias, { - get() { - return this[target]; - }, - set(value) { - this[target] = value; - }, - configurable: true, - enumerable: false, - }); -} - -defineColorAlias("gray", "grey"); -defineColorAlias("gray", "blackBright"); -defineColorAlias("bgGray", "bgGrey"); -defineColorAlias("bgGray", "bgBlackBright"); -defineColorAlias("dim", "faint"); -defineColorAlias("strikethrough", "crossedout"); -defineColorAlias("strikethrough", "strikeThrough"); -defineColorAlias("strikethrough", "crossedOut"); -defineColorAlias("hidden", "conceal"); -defineColorAlias("inverse", "swapColors"); -defineColorAlias("inverse", "swapcolors"); -defineColorAlias("doubleunderline", "doubleUnderline"); - -// TODO(BridgeAR): Add function style support for more complex styles. -// Don't use 'blue' not visible on cmd.exe -inspect.styles = { - __proto__: null, - special: "cyan", - number: "yellow", - bigint: "yellow", - boolean: "yellow", - undefined: "grey", - null: "bold", - string: "green", - symbol: "green", - date: "magenta", - name: undefined, - // TODO(BridgeAR): Highlight regular expressions properly. - regexp: "red", - module: "underline", -}; - -function addQuotes(str: string, quotes: number): string { - if (quotes === -1) { - return `"${str}"`; - } - if (quotes === -2) { - return `\`${str}\``; - } - return `'${str}'`; -} - -function escapeFn(str: string): string { - const charCode = str.charCodeAt(0); - return meta.length > charCode ? meta[charCode]! : `\\u${charCode.toString(16)}`; -} - -// Escape control characters, single quotes and the backslash. -// This is similar to JSON stringify escaping. -function strEscape(str: string): string { - let escapeTest = strEscapeSequencesRegExp; - let escapeReplace = strEscapeSequencesReplacer; - let singleQuote = 39; - - // Check for double quotes. If not present, do not escape single quotes and - // instead wrap the text in double quotes. If double quotes exist, check for - // backticks. If they do not exist, use those as fallback instead of the - // double quotes. - if (str.includes("'")) { - // This invalidates the charCode and therefore can not be matched for - // anymore. - if (!str.includes('"')) { - singleQuote = -1; - } else if (!str.includes("`") && !str.includes("${")) { - singleQuote = -2; - } - if (singleQuote !== 39) { - escapeTest = strEscapeSequencesRegExpSingle; - escapeReplace = strEscapeSequencesReplacerSingle; - } - } - - // Some magic numbers that worked out fine while benchmarking with v8 6.0 - if (str.length < 5000 && escapeTest.exec(str) === null) return addQuotes(str, singleQuote); - if (str.length > 100) { - str = str.replace(escapeReplace, escapeFn); - return addQuotes(str, singleQuote); - } - - let result = ""; - let last = 0; - for (let i = 0; i < str.length; i++) { - const point = str.charCodeAt(i); - if (point === singleQuote || point === 92 || point < 32 || (point > 126 && point < 160)) { - if (last === i) { - result += meta[point]; - } else { - result += `${str.slice(last, i)}${meta[point]}`; - } - last = i + 1; - } else if (point >= 0xd800 && point <= 0xdfff) { - if (point <= 0xdbff && i + 1 < str.length) { - const point = str.charCodeAt(i + 1); - if (point >= 0xdc00 && point <= 0xdfff) { - i++; - continue; - } - } - result += `${str.slice(last, i)}\\u${point.toString(16)}`; - last = i + 1; - } - } - - if (last !== str.length) { - result += str.slice(last); - } - return addQuotes(result, singleQuote); -} - -function stylizeWithColor(str: string, styleType: Style): string { - const style = inspect.styles[styleType]; - if (style !== undefined) { - const color = (inspect.colors as unknown as Record)[style]; - if (color !== undefined) return `\u001b[${color[0]}m${str}\u001b[${color[1]}m`; - } - return str; -} - -function stylizeNoColor(str: string): string { - return str; -} - -// Return a new empty array to push in the results of the default formatter. -function getEmptyFormatArray(): string[] { - return []; -} - -function isInstanceof(object: unknown, proto: Function): boolean { - try { - return object instanceof proto; - } catch { - return false; - } -} - -function getConstructorName( - obj: object, - ctx: Context, - recurseTimes: number, - protoProps?: string[] -): string | null { - let firstProto: unknown; - const tmp = obj; - while (obj || isUndetectableObject(obj)) { - const descriptor = Object.getOwnPropertyDescriptor(obj, "constructor"); - if ( - descriptor !== undefined && - typeof descriptor.value === "function" && - descriptor.value.name !== "" && - isInstanceof(tmp, descriptor.value) - ) { - if ( - protoProps !== undefined && - (firstProto !== obj || !builtInObjects.has(descriptor.value.name)) - ) { - addPrototypeProperties(ctx, tmp, firstProto || tmp, recurseTimes, protoProps); - } - return String(descriptor.value.name); - } - - obj = Object.getPrototypeOf(obj); - if (firstProto === undefined) { - firstProto = obj; - } - } - - if (firstProto === null) { - return null; - } - - const res = internal.getConstructorName(tmp); - - if (ctx.depth !== null && recurseTimes > ctx.depth) { - return `${res} `; - } - - const protoConstr = getConstructorName(firstProto!, ctx, recurseTimes + 1, protoProps); - - if (protoConstr === null) { - return `${res} <${inspect(firstProto, { - ...ctx, - customInspect: false, - depth: -1, - })}>`; - } - - return `${res} <${protoConstr}>`; -} - -// This function has the side effect of adding prototype properties to the -// `output` argument (which is an array). This is intended to highlight user -// defined prototype properties. -function addPrototypeProperties( - ctx: Context, - main: object, - obj: Object, - recurseTimes: number, - output: string[] -): void { - let depth = 0; - let keys: PropertyKey[] | undefined; - let keySet: Set | undefined; - do { - if (depth !== 0 || main === obj) { - obj = Object.getPrototypeOf(obj); - // Stop as soon as a null prototype is encountered. - if (obj === null) { - return; - } - // Stop as soon as a built-in object type is detected. - const descriptor = Object.getOwnPropertyDescriptor(obj, "constructor"); - if ( - descriptor !== undefined && - typeof descriptor.value === "function" && - builtInObjects.has(descriptor.value.name) - ) { - return; - } - } - - if (depth === 0) { - keySet = new Set(); - } else { - keys!.forEach((key) => keySet!.add(key)); - } - // Get all own property names and symbols. - keys = Reflect.ownKeys(obj); - ctx.seen.push(main); - for (const key of keys) { - // Ignore the `constructor` property and keys that exist on layers above. - if ( - key === "constructor" || - Object.prototype.hasOwnProperty.call(main, key) || - (depth !== 0 && keySet!.has(key)) - ) { - continue; - } - const desc = Object.getOwnPropertyDescriptor(obj, key); - if (typeof desc?.value === "function") { - continue; - } - const value = formatProperty(ctx, obj, recurseTimes, key, kObjectType, desc, main); - if (ctx.colors) { - // Faint! - output.push(`\u001b[2m${value}\u001b[22m`); - } else { - output.push(value); - } - } - ctx.seen.pop(); - // Limit the inspection to up to three prototype layers. Using `recurseTimes` - // is not a good choice here, because it's as if the properties are declared - // on the current object from the users perspective. - } while (++depth !== 3); -} - -function getPrefix(constructor: string | null, tag: string, fallback: string, size = ""): string { - if (constructor === null) { - if (tag !== "" && fallback !== tag) { - return `[${fallback}${size}: null prototype] [${tag}] `; - } - return `[${fallback}${size}: null prototype] `; - } - - if (tag !== "" && constructor !== tag) { - return `${constructor}${size} [${tag}] `; - } - return `${constructor}${size} `; -} - -// Look up the keys of the object. -function getKeys(value: object, showHidden: boolean): PropertyKey[] { - let keys: PropertyKey[]; - const symbols = Object.getOwnPropertySymbols(value); - if (showHidden) { - keys = Object.getOwnPropertyNames(value); - if (symbols.length !== 0) keys.push(...symbols); - } else { - // This might throw if `value` is a Module Namespace Object from an - // unevaluated module, but we don't want to perform the actual type - // check because it's expensive. - // TODO(devsnek): track https://github.com/tc39/ecma262/issues/1209 - // and modify this logic as needed. - try { - keys = Object.keys(value); - } catch (err: any) { - assert( - isNativeError(err) && - err.name === "ReferenceError" && - isModuleNamespaceObject(value) - ); - keys = Object.getOwnPropertyNames(value); - } - if (symbols.length !== 0) { - const filter = (key: PropertyKey) => - Object.prototype.propertyIsEnumerable.call(value, key); - keys.push(...symbols.filter(filter)); - } - } - return keys; -} - -function getCtxStyle(value: unknown, constructor: string | null, tag: string): string { - let fallback = ""; - if (constructor === null) { - fallback = internal.getConstructorName(value); - if (fallback === tag) { - fallback = "Object"; - } - } - return getPrefix(constructor, tag, fallback); -} - -function formatProxy(ctx: Context, proxy: internal.ProxyDetails, recurseTimes: number): string { - if (ctx.depth !== null && recurseTimes > ctx.depth) { - return ctx.stylize("Proxy [Array]", "special"); - } - recurseTimes += 1; - ctx.indentationLvl += 2; - const res: string[] = [ - formatValue(ctx, proxy.target, recurseTimes), - formatValue(ctx, proxy.handler, recurseTimes), - ]; - ctx.indentationLvl -= 2; - return reduceToSingleString(ctx, res, "", ["Proxy [", "]"], kArrayExtrasType, recurseTimes); -} - -// Note: using `formatValue` directly requires the indentation level to be -// corrected by setting `ctx.indentationLvL += diff` and then to decrease the -// value afterwards again. -function formatValue( - ctx: Context, - value: unknown, - recurseTimes: number, - typedArray?: unknown -): string { - // Primitive types cannot have properties. - if (typeof value !== "object" && typeof value !== "function" && !isUndetectableObject(value)) { - return formatPrimitive(ctx.stylize, value as Primitive, ctx); - } - if (value === null) { - return ctx.stylize("null", "null"); - } - - // Memorize the context for custom inspection on proxies. - const context = value; - // Always check for proxies to prevent side effects and to prevent triggering - // any proxy handlers. - const proxy = internal.getProxyDetails(value); - if (proxy !== undefined) { - if (proxy === null || proxy.target === null) { - return ctx.stylize("", "special"); - } - if (ctx.showProxy) { - return formatProxy(ctx, proxy, recurseTimes); - } - value = proxy.target; - } - - // Provide a hook for user-specified inspect functions. - // Check that value is an object with an inspect function on it. - if (ctx.customInspect) { - let maybeCustom = (value as Record)[customInspectSymbol]; - - // WORKERD SPECIFIC PATCH: if `value` is a JSG resource type, use a well-known custom inspect - const maybeResourceTypeInspect = (value as Record)[ - internal.kResourceTypeInspect - ]; - if (typeof maybeResourceTypeInspect === "object") { - maybeCustom = formatJsgResourceType.bind( - context as Record, - maybeResourceTypeInspect as Record - ); - } - - if ( - typeof maybeCustom === "function" && - // Filter out the util module, its inspect function is special. - maybeCustom !== inspect && - // Also filter out any prototype objects using the circular check. - !((value as object).constructor && (value as object).constructor.prototype === value) - ) { - // This makes sure the recurseTimes are reported as before while using - // a counter internally. - const depth = ctx.depth === null ? null : ctx.depth - recurseTimes; - const isCrossContext = proxy !== undefined || !(context instanceof Object); - const ret = Function.prototype.call.call( - maybeCustom, - context, - depth, - getUserOptions(ctx, isCrossContext), - inspect - ); - // If the custom inspection method returned `this`, don't go into - // infinite recursion. - if (ret !== context) { - if (typeof ret !== "string") { - return formatValue(ctx, ret, recurseTimes); - } - return ret.replaceAll("\n", `\n${" ".repeat(ctx.indentationLvl)}`); - } - } - } - - // Using an array here is actually better for the average case than using - // a Set. `seen` will only check for the depth and will never grow too large. - if (ctx.seen.includes(value)) { - let index: number | undefined = 1; - if (ctx.circular === undefined) { - ctx.circular = new Map(); - ctx.circular.set(value, index); - } else { - index = ctx.circular.get(value); - if (index === undefined) { - index = ctx.circular.size + 1; - ctx.circular.set(value, index); - } - } - return ctx.stylize(`[Circular *${index}]`, "special"); - } - - return formatRaw(ctx, value, recurseTimes, typedArray); -} - -function formatRaw( - ctx: Context, - value: unknown, - recurseTimes: number, - typedArray: unknown -): string { - let keys: PropertyKey[] | undefined; - let protoProps: string[] | undefined; - if (ctx.showHidden && (ctx.depth === null || recurseTimes <= ctx.depth)) { - protoProps = []; - } - - const constructor = getConstructorName(value as object, ctx, recurseTimes, protoProps); - // Reset the variable to check for this later on. - if (protoProps !== undefined && protoProps.length === 0) { - protoProps = undefined; - } - - let tag = (value as { [Symbol.toStringTag]?: string })[Symbol.toStringTag]; - // Only list the tag in case it's non-enumerable / not an own property. - // Otherwise we'd print this twice. - if ( - typeof tag !== "string" || - (tag !== "" && - (ctx.showHidden - ? Object.prototype.hasOwnProperty - : Object.prototype.propertyIsEnumerable - ).call(value, Symbol.toStringTag)) - ) { - tag = ""; - } - let base = ""; - let formatter: (ctx: Context, value: any, recurseTimes: number) => string[] = - getEmptyFormatArray; - let braces: [string, string] | undefined; - let noIterator = true; - let i = 0; - const filter = ctx.showHidden ? internal.ALL_PROPERTIES : internal.ONLY_ENUMERABLE; - - let extrasType = kObjectType; - - // Iterators and the rest are split to reduce checks. - // We have to check all values in case the constructor is set to null. - // Otherwise it would not possible to identify all types properly. - - const isEntriesObject = hasEntries(value); - if (Symbol.iterator in (value as object) || constructor === null || isEntriesObject) { - noIterator = false; - if (isEntriesObject) { - // WORKERD SPECIFIC PATCH: if `value` is an object with entries, format them like a map - const size = value[kEntries].length; - const prefix = getPrefix(constructor, tag, "Object", `(${size})`); - keys = getKeys(value, ctx.showHidden); - - // Remove `kEntries` and `size` from keys - keys.splice(keys.indexOf(kEntries), 1); - const sizeIndex = keys.indexOf("size"); - if (sizeIndex !== -1) keys.splice(sizeIndex, 1); - - formatter = formatMap.bind(null, value[kEntries][Symbol.iterator]()); - if (size === 0 && keys.length === 0 && protoProps === undefined) return `${prefix}{}`; - braces = [`${prefix}{`, "}"]; - } else if (Array.isArray(value)) { - // Only set the constructor for non ordinary ("Array [...]") arrays. - const prefix = - constructor !== "Array" || tag !== "" - ? getPrefix(constructor, tag, "Array", `(${value.length})`) - : ""; - keys = internal.getOwnNonIndexProperties(value, filter); - braces = [`${prefix}[`, "]"]; - if (value.length === 0 && keys.length === 0 && protoProps === undefined) - return `${braces[0]}]`; - extrasType = kArrayExtrasType; - formatter = formatArray; - } else if (isSet(value)) { - const size = setPrototypeSize.call(value); - const prefix = getPrefix(constructor, tag, "Set", `(${size})`); - keys = getKeys(value, ctx.showHidden); - formatter = - constructor !== null - ? formatSet.bind(null, value) - : formatSet.bind(null, Set.prototype.values.call(value)); - if (size === 0 && keys.length === 0 && protoProps === undefined) return `${prefix}{}`; - braces = [`${prefix}{`, "}"]; - } else if (isMap(value)) { - const size = mapPrototypeSize.call(value); - const prefix = getPrefix(constructor, tag, "Map", `(${size})`); - keys = getKeys(value, ctx.showHidden); - formatter = - constructor !== null - ? formatMap.bind(null, value) - : formatMap.bind(null, Map.prototype.entries.call(value)); - if (size === 0 && keys.length === 0 && protoProps === undefined) return `${prefix}{}`; - braces = [`${prefix}{`, "}"]; - } else if (isTypedArray(value)) { - keys = internal.getOwnNonIndexProperties(value, filter); - let bound = value; - let fallback = ""; - if (constructor === null) { - fallback = typedArrayPrototypeToStringTag.call(value); - // Reconstruct the array information. - bound = new ( - globalThis as unknown as Record< - string, - { new (value: NodeJS.TypedArray): NodeJS.TypedArray } - > - )[fallback]!(value); - } - const size = typedArrayPrototypeLength.call(value); - const prefix = getPrefix(constructor, tag, fallback, `(${size})`); - braces = [`${prefix}[`, "]"]; - if (value.length === 0 && keys.length === 0 && !ctx.showHidden) return `${braces[0]}]`; - // Special handle the value. The original value is required below. The - // bound function is required to reconstruct missing information. - formatter = formatTypedArray.bind(null, bound, size); - extrasType = kArrayExtrasType; - } else if (isMapIterator(value)) { - keys = getKeys(value, ctx.showHidden); - braces = getIteratorBraces("Map", tag); - // Add braces to the formatter parameters. - formatter = formatIterator.bind(null, braces); - } else if (isSetIterator(value)) { - keys = getKeys(value, ctx.showHidden); - braces = getIteratorBraces("Set", tag); - // Add braces to the formatter parameters. - formatter = formatIterator.bind(null, braces); - } else { - noIterator = true; - } - } - if (noIterator) { - keys = getKeys(value as object, ctx.showHidden); - braces = ["{", "}"]; - if (constructor === "Object") { - if (isArgumentsObject(value)) { - braces[0] = "[Arguments] {"; - } else if (tag !== "") { - braces[0] = `${getPrefix(constructor, tag, "Object")}{`; - } - if (keys.length === 0 && protoProps === undefined) { - return `${braces[0]}}`; - } - } else if (typeof value === "function") { - base = getFunctionBase(value, constructor, tag); - if (keys.length === 0 && protoProps === undefined) return ctx.stylize(base, "special"); - } else if (isRegExp(value)) { - // Make RegExps say that they are RegExps - base = RegExp.prototype.toString.call(constructor !== null ? value : new RegExp(value)); - const prefix = getPrefix(constructor, tag, "RegExp"); - if (prefix !== "RegExp ") base = `${prefix}${base}`; - if ( - (keys.length === 0 && protoProps === undefined) || - (ctx.depth !== null && recurseTimes > ctx.depth) - ) { - return ctx.stylize(base, "regexp"); - } - } else if (isDate(value)) { - // Make dates with properties first say the date - base = Number.isNaN(Date.prototype.getTime.call(value)) - ? Date.prototype.toString.call(value) - : Date.prototype.toISOString.call(value); - const prefix = getPrefix(constructor, tag, "Date"); - if (prefix !== "Date ") base = `${prefix}${base}`; - if (keys.length === 0 && protoProps === undefined) { - return ctx.stylize(base, "date"); - } - } else if (isError(value)) { - base = formatError(value, constructor, tag, ctx, keys); - if (keys.length === 0 && protoProps === undefined) return base; - } else if (isAnyArrayBuffer(value)) { - // Fast path for ArrayBuffer and SharedArrayBuffer. - // Can't do the same for DataView because it has a non-primitive - // .buffer property that we need to recurse for. - const arrayType = isArrayBuffer(value) ? "ArrayBuffer" : "SharedArrayBuffer"; - const prefix = getPrefix(constructor, tag, arrayType); - if (typedArray === undefined) { - formatter = formatArrayBuffer; - } else if (keys.length === 0 && protoProps === undefined) { - return ( - prefix + `{ byteLength: ${formatNumber(ctx.stylize, value.byteLength, false)} }` - ); - } - braces[0] = `${prefix}{`; - keys.unshift("byteLength"); - } else if (isDataView(value)) { - braces[0] = `${getPrefix(constructor, tag, "DataView")}{`; - // .buffer goes last, it's not a primitive like the others. - keys.unshift("byteLength", "byteOffset", "buffer"); - } else if (isPromise(value)) { - braces[0] = `${getPrefix(constructor, tag, "Promise")}{`; - formatter = formatPromise; - } else if (isWeakSet(value)) { - braces[0] = `${getPrefix(constructor, tag, "WeakSet")}{`; - formatter = ctx.showHidden ? formatWeakSet : formatWeakCollection; - } else if (isWeakMap(value)) { - braces[0] = `${getPrefix(constructor, tag, "WeakMap")}{`; - formatter = ctx.showHidden ? formatWeakMap : formatWeakCollection; - } else if (isModuleNamespaceObject(value)) { - braces[0] = `${getPrefix(constructor, tag, "Module")}{`; - // Special handle keys for namespace objects. - formatter = formatNamespaceObject.bind(null, keys); - } else if (isBoxedPrimitive(value)) { - base = getBoxedBase(value, ctx, keys, constructor, tag); - if (keys.length === 0 && protoProps === undefined) { - return base; - } - } else { - if (keys.length === 0 && protoProps === undefined) { - return `${getCtxStyle(value, constructor, tag)}{}`; - } - braces[0] = `${getCtxStyle(value, constructor, tag)}{`; - } - } - - if (ctx.depth !== null && recurseTimes > ctx.depth) { - let constructorName = getCtxStyle(value, constructor, tag).slice(0, -1); - if (constructor !== null) constructorName = `[${constructorName}]`; - return ctx.stylize(constructorName, "special"); - } - recurseTimes += 1; - - ctx.seen.push(value); - ctx.currentDepth = recurseTimes; - let output; - const indentationLvl = ctx.indentationLvl; - try { - output = formatter(ctx, value, recurseTimes); - for (i = 0; i < keys!.length; i++) { - output.push(formatProperty(ctx, value as object, recurseTimes, keys![i]!, extrasType)); - } - if (protoProps !== undefined) { - output.push(...protoProps); - } - } catch (err) { - const constructorName = getCtxStyle(value, constructor, tag).slice(0, -1); - return handleMaxCallStackSize(ctx, err as Error, constructorName, indentationLvl); - } - if (ctx.circular !== undefined) { - const index = ctx.circular.get(value); - if (index !== undefined) { - const reference = ctx.stylize(``, "special"); - // Add reference always to the very beginning of the output. - if (ctx.compact !== true) { - base = base === "" ? reference : `${reference} ${base}`; - } else { - braces![0] = `${reference} ${braces![0]}`; - } - } - } - ctx.seen.pop(); - - if (ctx.sorted) { - const comparator = ctx.sorted === true ? undefined : ctx.sorted; - if (extrasType === kObjectType) { - output.sort(comparator); - } else if (keys!.length > 1) { - const sorted = output.slice(output.length - keys!.length).sort(comparator); - output.splice(output.length - keys!.length, keys!.length, ...sorted); - } - } - - const res = reduceToSingleString(ctx, output, base, braces!, extrasType, recurseTimes, value); - const budget = ctx.budget[ctx.indentationLvl] || 0; - const newLength = budget + res.length; - ctx.budget[ctx.indentationLvl] = newLength; - // If any indentationLvl exceeds this limit, limit further inspecting to the - // minimum. Otherwise the recursive algorithm might continue inspecting the - // object even though the maximum string size (~2 ** 28 on 32 bit systems and - // ~2 ** 30 on 64 bit systems) exceeded. The actual output is not limited at - // exactly 2 ** 27 but a bit higher. This depends on the object shape. - // This limit also makes sure that huge objects don't block the event loop - // significantly. - if (newLength > 2 ** 27) { - ctx.depth = -1; - } - return res; -} - -function getIteratorBraces(type: string, tag: string): [string, string] { - if (tag !== `${type} Iterator`) { - if (tag !== "") tag += "] ["; - tag += `${type} Iterator`; - } - return [`[${tag}] {`, "}"]; -} - -function getBoxedBase( - value: unknown, - ctx: Context, - keys: PropertyKey[], - constructor: string | null, - tag: string -): string { - let fn: (this: unknown) => Primitive; - let type: Capitalize> | "BigInt"; - if (isNumberObject(value)) { - fn = Number.prototype.valueOf; - type = "Number"; - } else if (isStringObject(value)) { - fn = String.prototype.valueOf; - type = "String"; - // For boxed Strings, we have to remove the 0-n indexed entries, - // since they just noisy up the output and are redundant - // Make boxed primitive Strings look like such - keys.splice(0, value.length); - } else if (isBooleanObject(value)) { - fn = Boolean.prototype.valueOf; - type = "Boolean"; - } else if (isBigIntObject(value)) { - fn = BigInt.prototype.valueOf; - type = "BigInt"; - } else { - fn = Symbol.prototype.valueOf; - type = "Symbol"; - } - let base = `[${type}`; - if (type !== constructor) { - if (constructor === null) { - base += " (null prototype)"; - } else { - base += ` (${constructor})`; - } - } - base += `: ${formatPrimitive(stylizeNoColor, fn.call(value), ctx)}]`; - if (tag !== "" && tag !== constructor) { - base += ` [${tag}]`; - } - if (keys.length !== 0 || ctx.stylize === stylizeNoColor) return base; - return ctx.stylize(base, type.toLowerCase() as Style); -} - -function getClassBase(value: any, constructor: string | null, tag: string): string { - const hasName = Object.prototype.hasOwnProperty.call(value, "name"); - const name = (hasName && value.name) || "(anonymous)"; - let base = `class ${name}`; - if (constructor !== "Function" && constructor !== null) { - base += ` [${constructor}]`; - } - if (tag !== "" && constructor !== tag) { - base += ` [${tag}]`; - } - if (constructor !== null) { - const superName = Object.getPrototypeOf(value).name; - if (superName) { - base += ` extends ${superName}`; - } - } else { - base += " extends [null prototype]"; - } - return `[${base}]`; -} - -function getFunctionBase(value: Function, constructor: string | null, tag: string): string { - const stringified = Function.prototype.toString.call(value); - if (stringified.startsWith("class") && stringified.endsWith("}")) { - const slice = stringified.slice(5, -1); - const bracketIndex = slice.indexOf("{"); - if ( - bracketIndex !== -1 && - (!slice.slice(0, bracketIndex).includes("(") || - // Slow path to guarantee that it's indeed a class. - classRegExp.exec(slice.replace(stripCommentsRegExp, "")) !== null) - ) { - return getClassBase(value, constructor, tag); - } - } - let type = "Function"; - if (isGeneratorFunction(value)) { - type = `Generator${type}`; - } - if (isAsyncFunction(value)) { - type = `Async${type}`; - } - let base = `[${type}`; - if (constructor === null) { - base += " (null prototype)"; - } - if (value.name === "") { - base += " (anonymous)"; - } else { - base += `: ${value.name}`; - } - base += "]"; - if (constructor !== type && constructor !== null) { - base += ` ${constructor}`; - } - if (tag !== "" && constructor !== tag) { - base += ` [${tag}]`; - } - return base; -} - -export function identicalSequenceRange( - a: unknown[], - b: unknown[] -): { len: number; offset: number } { - for (let i = 0; i < a.length - 3; i++) { - // Find the first entry of b that matches the current entry of a. - const pos = b.indexOf(a[i]); - if (pos !== -1) { - const rest = b.length - pos; - if (rest > 3) { - let len = 1; - const maxLen = Math.min(a.length - i, rest); - // Count the number of consecutive entries. - while (maxLen > len && a[i + len] === b[pos + len]) { - len++; - } - if (len > 3) { - return { len, offset: i }; - } - } - } - } - - return { len: 0, offset: 0 }; -} - -function getStackString(error: Error): string { - return error.stack ? String(error.stack) : Error.prototype.toString.call(error); -} - -function getStackFrames(ctx: Context, err: Error, stack: string): string[] { - const frames = stack.split("\n"); - - let cause; - try { - ({ cause } = err); - } catch { - // If 'cause' is a getter that throws, ignore it. - } - - // Remove stack frames identical to frames in cause. - if (cause != null && isError(cause)) { - const causeStack = getStackString(cause); - const causeStackStart = causeStack.indexOf("\n at"); - if (causeStackStart !== -1) { - const causeFrames = causeStack.slice(causeStackStart + 1).split("\n"); - const { len, offset } = identicalSequenceRange(frames, causeFrames); - if (len > 0) { - const skipped = len - 2; - const msg = ` ... ${skipped} lines matching cause stack trace ...`; - frames.splice(offset + 1, skipped, ctx.stylize(msg, "undefined")); - } - } - } - return frames; -} - -function improveStack( - stack: string, - constructor: string | null, - name: string, - tag: string -): string { - // A stack trace may contain arbitrary data. Only manipulate the output - // for "regular errors" (errors that "look normal") for now. - let len = name.length; - - if ( - constructor === null || - (name.endsWith("Error") && - stack.startsWith(name) && - (stack.length === len || stack[len] === ":" || stack[len] === "\n")) - ) { - let fallback = "Error"; - if (constructor === null) { - const start = - /^([A-Z][a-z_ A-Z0-9[\]()-]+)(?::|\n {4}at)/.exec(stack) || - /^([a-z_A-Z0-9-]*Error)$/.exec(stack); - fallback = (start && start[1]) || ""; - len = fallback.length; - fallback = fallback || "Error"; - } - const prefix = getPrefix(constructor, tag, fallback).slice(0, -1); - if (name !== prefix) { - if (prefix.includes(name)) { - if (len === 0) { - stack = `${prefix}: ${stack}`; - } else { - stack = `${prefix}${stack.slice(len)}`; - } - } else { - stack = `${prefix} [${name}]${stack.slice(len)}`; - } - } - } - return stack; -} - -function removeDuplicateErrorKeys( - ctx: Context, - keys: PropertyKey[], - err: Error, - stack: string -): void { - if (!ctx.showHidden && keys.length !== 0) { - for (const name of ["name", "message", "stack"] as const) { - const index = keys.indexOf(name); - // Only hide the property in case it's part of the original stack - if (index !== -1 && stack.includes(err[name]!)) { - keys.splice(index, 1); - } - } - } -} - -function markNodeModules(ctx: Context, line: string): string { - let tempLine = ""; - let nodeModule; - let pos = 0; - while ((nodeModule = nodeModulesRegExp.exec(line)) !== null) { - // '/node_modules/'.length === 14 - tempLine += line.slice(pos, nodeModule.index + 14); - tempLine += ctx.stylize(nodeModule[1]!, "module"); - pos = nodeModule.index + nodeModule[0].length; - } - if (pos !== 0) { - line = tempLine + line.slice(pos); - } - return line; -} - -function formatError( - err: Error, - constructor: string | null, - tag: string, - ctx: Context, - keys: PropertyKey[] -): string { - const name = err.name != null ? String(err.name) : "Error"; - let stack = getStackString(err); - - removeDuplicateErrorKeys(ctx, keys, err, stack); - - if ("cause" in err && (keys.length === 0 || !keys.includes("cause"))) { - keys.push("cause"); - } - - // Print errors aggregated into AggregateError - if ( - Array.isArray((err as { errors?: unknown }).errors) && - (keys.length === 0 || !keys.includes("errors")) - ) { - keys.push("errors"); - } - - stack = improveStack(stack, constructor, name, tag); - - // Ignore the error message if it's contained in the stack. - let pos = (err.message && stack.indexOf(err.message)) || -1; - if (pos !== -1) pos += err.message.length; - // Wrap the error in brackets in case it has no stack trace. - const stackStart = stack.indexOf("\n at", pos); - if (stackStart === -1) { - stack = `[${stack}]`; - } else { - let newStack = stack.slice(0, stackStart); - const stackFramePart = stack.slice(stackStart + 1); - const lines = getStackFrames(ctx, err, stackFramePart); - if (ctx.colors) { - // Highlight userland code and node modules. - for (let line of lines) { - newStack += "\n"; - - line = markNodeModules(ctx, line); - - newStack += line; - } - } else { - newStack += `\n${lines.join("\n")}`; - } - stack = newStack; - } - // The message and the stack have to be indented as well! - if (ctx.indentationLvl !== 0) { - const indentation = " ".repeat(ctx.indentationLvl); - stack = stack.replaceAll("\n", `\n${indentation}`); - } - return stack; -} - -function groupArrayElements( - ctx: Context, - output: string[], - value: unknown[] | undefined -): string[] { - let totalLength = 0; - let maxLength = 0; - let i = 0; - let outputLength = output.length; - if (ctx.maxArrayLength !== null && ctx.maxArrayLength < output.length) { - // This makes sure the "... n more items" part is not taken into account. - outputLength--; - } - const separatorSpace = 2; // Add 1 for the space and 1 for the separator. - const dataLen = new Array(outputLength); - // Calculate the total length of all output entries and the individual max - // entries length of all output entries. We have to remove colors first, - // otherwise the length would not be calculated properly. - for (; i < outputLength; i++) { - const len = getStringWidth(output[i]!, ctx.colors); - dataLen[i] = len; - totalLength += len + separatorSpace; - if (maxLength < len) maxLength = len; - } - // Add two to `maxLength` as we add a single whitespace character plus a comma - // in-between two entries. - const actualMax = maxLength + separatorSpace; - // Check if at least three entries fit next to each other and prevent grouping - // of arrays that contains entries of very different length (i.e., if a single - // entry is longer than 1/5 of all other entries combined). Otherwise the - // space in-between small entries would be enormous. - if ( - actualMax * 3 + ctx.indentationLvl < ctx.breakLength && - (totalLength / actualMax > 5 || maxLength <= 6) - ) { - const approxCharHeights = 2.5; - const averageBias = Math.sqrt(actualMax - totalLength / output.length); - const biasedMax = Math.max(actualMax - 3 - averageBias, 1); - // Dynamically check how many columns seem possible. - const columns = Math.min( - // Ideally a square should be drawn. We expect a character to be about 2.5 - // times as high as wide. This is the area formula to calculate a square - // which contains n rectangles of size `actualMax * approxCharHeights`. - // Divide that by `actualMax` to receive the correct number of columns. - // The added bias increases the columns for short entries. - Math.round(Math.sqrt(approxCharHeights * biasedMax * outputLength) / biasedMax), - // Do not exceed the breakLength. - Math.floor((ctx.breakLength - ctx.indentationLvl) / actualMax), - // Limit array grouping for small `compact` modes as the user requested - // minimal grouping. - (ctx.compact === false - ? 0 - : ctx.compact === true - ? inspectDefaultOptions.compact - : ctx.compact) * 4, - // Limit the columns to a maximum of fifteen. - 15 - ); - // Return with the original output if no grouping should happen. - if (columns <= 1) { - return output; - } - const tmp: string[] = []; - const maxLineLength: number[] = []; - for (let i = 0; i < columns; i++) { - let lineMaxLength = 0; - for (let j = i; j < output.length; j += columns) { - if (dataLen[j] > lineMaxLength) lineMaxLength = dataLen[j]; - } - lineMaxLength += separatorSpace; - maxLineLength[i] = lineMaxLength; - } - let order = String.prototype.padStart; - if (value !== undefined) { - for (let i = 0; i < output.length; i++) { - if (typeof value[i] !== "number" && typeof value[i] !== "bigint") { - order = String.prototype.padEnd; - break; - } - } - } - // Each iteration creates a single line of grouped entries. - for (let i = 0; i < outputLength; i += columns) { - // The last lines may contain less entries than columns. - const max = Math.min(i + columns, outputLength); - let str = ""; - let j = i; - for (; j < max - 1; j++) { - // Calculate extra color padding in case it's active. This has to be - // done line by line as some lines might contain more colors than - // others. - const padding = maxLineLength[j - i]! + output[j]!.length - dataLen[j]; - str += order.call(`${output[j]}, `, padding, " "); - } - if (order === String.prototype.padStart) { - const padding = - maxLineLength[j - i]! + output[j]!.length - dataLen[j] - separatorSpace; - str += output[j]!.padStart(padding, " "); - } else { - str += output[j]; - } - tmp.push(str); - } - if (ctx.maxArrayLength !== null && ctx.maxArrayLength < output.length) { - tmp.push(output[outputLength]!); - } - output = tmp; - } - return output; -} - -function handleMaxCallStackSize( - ctx: Context, - err: Error, - constructorName: string, - indentationLvl: number -): string { - if (isStackOverflowError(err)) { - ctx.seen.pop(); - ctx.indentationLvl = indentationLvl; - return ctx.stylize( - `[${constructorName}: Inspection interrupted ` + - "prematurely. Maximum call stack size exceeded.]", - "special" - ); - } - /* c8 ignore next */ - assert.fail(err.stack); -} - -function addNumericSeparator(integerString: string): string { - let result = ""; - let i = integerString.length; - const start = integerString.startsWith("-") ? 1 : 0; - for (; i >= start + 4; i -= 3) { - result = `_${integerString.slice(i - 3, i)}${result}`; - } - return i === integerString.length ? integerString : `${integerString.slice(0, i)}${result}`; -} - -function addNumericSeparatorEnd(integerString: string): string { - let result = ""; - let i = 0; - for (; i < integerString.length - 3; i += 3) { - result += `${integerString.slice(i, i + 3)}_`; - } - return i === 0 ? integerString : `${result}${integerString.slice(i)}`; -} - -const remainingText = (remaining: number) => - `... ${remaining} more item${remaining > 1 ? "s" : ""}`; - -function formatNumber( - fn: InspectOptionsStylized["stylize"], - number: number, - numericSeparator?: boolean -): string { - if (!numericSeparator) { - // Format -0 as '-0'. Checking `number === -0` won't distinguish 0 from -0. - if (Object.is(number, -0)) { - return fn("-0", "number"); - } - return fn(`${number}`, "number"); - } - const integer = Math.trunc(number); - const string = String(integer); - if (integer === number) { - if (!Number.isFinite(number) || string.includes("e")) { - return fn(string, "number"); - } - return fn(`${addNumericSeparator(string)}`, "number"); - } - if (Number.isNaN(number)) { - return fn(string, "number"); - } - return fn( - `${addNumericSeparator(string)}.${addNumericSeparatorEnd( - String(number).slice(string.length + 1) - )}`, - "number" - ); -} - -function formatBigInt( - fn: InspectOptionsStylized["stylize"], - bigint: bigint, - numericSeparator?: boolean -): string { - const string = String(bigint); - if (!numericSeparator) { - return fn(`${string}n`, "bigint"); - } - return fn(`${addNumericSeparator(string)}n`, "bigint"); -} - -type Primitive = string | number | bigint | boolean | undefined | symbol; -function formatPrimitive( - fn: InspectOptionsStylized["stylize"], - value: Primitive, - ctx: Context -): string { - if (typeof value === "string") { - let trailer = ""; - if (ctx.maxStringLength !== null && value.length > ctx.maxStringLength) { - const remaining = value.length - ctx.maxStringLength; - value = value.slice(0, ctx.maxStringLength); - trailer = `... ${remaining} more character${remaining > 1 ? "s" : ""}`; - } - if ( - ctx.compact !== true && - // We do not support handling unicode characters width with - // the readline getStringWidth function as there are - // performance implications. - value.length > kMinLineLength && - value.length > ctx.breakLength - ctx.indentationLvl - 4 - ) { - return ( - value - .split(/(?<=\n)/) - .map((line) => fn(strEscape(line), "string")) - .join(` +\n${" ".repeat(ctx.indentationLvl + 2)}`) + trailer - ); - } - return fn(strEscape(value), "string") + trailer; - } - if (typeof value === "number") return formatNumber(fn, value, ctx.numericSeparator); - if (typeof value === "bigint") return formatBigInt(fn, value, ctx.numericSeparator); - if (typeof value === "boolean") return fn(`${value}`, "boolean"); - if (typeof value === "undefined") return fn("undefined", "undefined"); - // es6 symbol primitive - return fn(Symbol.prototype.toString.call(value), "symbol"); -} - -function formatNamespaceObject( - keys: PropertyKey[], - ctx: Context, - value: object, - recurseTimes: number -): string[] { - const output = new Array(keys.length); - for (let i = 0; i < keys.length; i++) { - try { - output[i] = formatProperty(ctx, value, recurseTimes, keys[i]!, kObjectType); - } catch (err) { - assert(isNativeError(err) && err.name === "ReferenceError"); - // Use the existing functionality. This makes sure the indentation and - // line breaks are always correct. Otherwise it is very difficult to keep - // this aligned, even though this is a hacky way of dealing with this. - const tmp = { [keys[i]!]: "" }; - output[i] = formatProperty(ctx, tmp, recurseTimes, keys[i]!, kObjectType); - const pos = output[i]!.lastIndexOf(" "); - // We have to find the last whitespace and have to replace that value as - // it will be visualized as a regular string. - output[i] = output[i]!.slice(0, pos + 1) + ctx.stylize("", "special"); - } - } - // Reset the keys to an empty array. This prevents duplicated inspection. - keys.length = 0; - return output; -} - -// The array is sparse and/or has extra keys -function formatSpecialArray( - ctx: Context, - value: unknown[], - recurseTimes: number, - maxLength: number, - output: string[], - i: number -): string[] { - const keys = Object.keys(value); - let index = i; - for (; i < keys.length && output.length < maxLength; i++) { - const key = keys[i]!; - const tmp = +key; - // Arrays can only have up to 2^32 - 1 entries - if (tmp > 2 ** 32 - 2) { - break; - } - if (`${index}` !== key) { - if (numberRegExp.exec(key) === null) { - break; - } - const emptyItems = tmp - index; - const ending = emptyItems > 1 ? "s" : ""; - const message = `<${emptyItems} empty item${ending}>`; - output.push(ctx.stylize(message, "undefined")); - index = tmp; - if (output.length === maxLength) { - break; - } - } - output.push(formatProperty(ctx, value, recurseTimes, key, kArrayType)); - index++; - } - const remaining = value.length - index; - if (output.length !== maxLength) { - if (remaining > 0) { - const ending = remaining > 1 ? "s" : ""; - const message = `<${remaining} empty item${ending}>`; - output.push(ctx.stylize(message, "undefined")); - } - } else if (remaining > 0) { - output.push(remainingText(remaining)); - } - return output; -} - -function formatArrayBuffer(ctx: Context, value: ArrayBuffer): string[] { - let buffer; - try { - buffer = new Uint8Array(value); - } catch { - return [ctx.stylize("(detached)", "special")]; - } - const maxArrayLength = ctx.maxArrayLength; - let str = Buffer.prototype.hexSlice - .call(buffer, 0, Math.min(maxArrayLength, buffer.length)) - .replace(/(.{2})/g, "$1 ") - .trim(); - const remaining = buffer.length - maxArrayLength; - if (remaining > 0) str += ` ... ${remaining} more byte${remaining > 1 ? "s" : ""}`; - return [`${ctx.stylize("[Uint8Contents]", "special")}: <${str}>`]; -} - -function formatArray(ctx: Context, value: unknown[], recurseTimes: number): string[] { - const valLen = value.length; - const len = Math.min(Math.max(0, ctx.maxArrayLength), valLen); - - const remaining = valLen - len; - const output: string[] = []; - for (let i = 0; i < len; i++) { - // Special handle sparse arrays. - if (!Object.prototype.hasOwnProperty.call(value, i)) { - return formatSpecialArray(ctx, value, recurseTimes, len, output, i); - } - output.push(formatProperty(ctx, value, recurseTimes, i, kArrayType)); - } - if (remaining > 0) { - output.push(remainingText(remaining)); - } - return output; -} - -function formatTypedArray( - value: internal.TypedArray, - length: number, - ctx: Context, - _ignored: unknown, - recurseTimes: number -): string[] { - const maxLength = Math.min(Math.max(0, ctx.maxArrayLength), length); - const remaining = value.length - maxLength; - const output = new Array(maxLength); - const elementFormatter = - value.length > 0 && typeof value[0] === "number" ? formatNumber : formatBigInt; - for (let i = 0; i < maxLength; ++i) { - // @ts-expect-error `value[i]` assumed to be of correct numeric type - output[i] = elementFormatter(ctx.stylize, value[i], ctx.numericSeparator); - } - if (remaining > 0) { - output[maxLength] = remainingText(remaining); - } - if (ctx.showHidden) { - // .buffer goes last, it's not a primitive like the others. - // All besides `BYTES_PER_ELEMENT` are actually getters. - ctx.indentationLvl += 2; - for (const key of [ - "BYTES_PER_ELEMENT", - "length", - "byteLength", - "byteOffset", - "buffer", - ] as const) { - const str = formatValue(ctx, value[key], recurseTimes, true); - output.push(`[${key}]: ${str}`); - } - ctx.indentationLvl -= 2; - } - return output; -} - -function formatSet( - value: Set | IterableIterator, - ctx: Context, - _ignored: unknown, - recurseTimes: number -): string[] { - const length = isSet(value) ? value.size : NaN; - const maxLength = Math.min(Math.max(0, ctx.maxArrayLength), length); - const remaining = length - maxLength; - const output: string[] = []; - ctx.indentationLvl += 2; - let i = 0; - for (const v of value) { - if (i >= maxLength) break; - output.push(formatValue(ctx, v, recurseTimes)); - i++; - } - if (remaining > 0) { - output.push(remainingText(remaining)); - } - ctx.indentationLvl -= 2; - return output; -} - -function formatMap( - value: Map | IterableIterator<[unknown, unknown]>, - ctx: Context, - _ignored: unknown, - recurseTimes: number -): string[] { - const length = isMap(value) ? value.size : NaN; - const maxLength = Math.min(Math.max(0, ctx.maxArrayLength), length); - const remaining = length - maxLength; - const output: string[] = []; - ctx.indentationLvl += 2; - let i = 0; - for (const { 0: k, 1: v } of value) { - if (i >= maxLength) break; - output.push(`${formatValue(ctx, k, recurseTimes)} => ${formatValue(ctx, v, recurseTimes)}`); - i++; - } - if (remaining > 0) { - output.push(remainingText(remaining)); - } - ctx.indentationLvl -= 2; - return output; -} - -function formatSetIterInner( - ctx: Context, - recurseTimes: number, - entries: unknown[], - state: number -): string[] { - const maxArrayLength = Math.max(ctx.maxArrayLength, 0); - const maxLength = Math.min(maxArrayLength, entries.length); - const output = new Array(maxLength); - ctx.indentationLvl += 2; - for (let i = 0; i < maxLength; i++) { - output[i] = formatValue(ctx, entries[i], recurseTimes); - } - ctx.indentationLvl -= 2; - if (state === kWeak && !ctx.sorted) { - // Sort all entries to have a halfway reliable output (if more entries than - // retrieved ones exist, we can not reliably return the same output) if the - // output is not sorted anyway. - output.sort(); - } - const remaining = entries.length - maxLength; - if (remaining > 0) { - output.push(remainingText(remaining)); - } - return output; -} - -function formatMapIterInner( - ctx: Context, - recurseTimes: number, - entries: unknown[], - state: number -): string[] { - const maxArrayLength = Math.max(ctx.maxArrayLength, 0); - // Entries exist as [key1, val1, key2, val2, ...] - const len = entries.length / 2; - const remaining = len - maxArrayLength; - const maxLength = Math.min(maxArrayLength, len); - const output = new Array(maxLength); - let i = 0; - ctx.indentationLvl += 2; - if (state === kWeak) { - for (; i < maxLength; i++) { - const pos = i * 2; - output[i] = `${formatValue(ctx, entries[pos], recurseTimes)} => ${formatValue( - ctx, - entries[pos + 1], - recurseTimes - )}`; - } - // Sort all entries to have a halfway reliable output (if more entries than - // retrieved ones exist, we can not reliably return the same output) if the - // output is not sorted anyway. - if (!ctx.sorted) output.sort(); - } else { - for (; i < maxLength; i++) { - const pos = i * 2; - const res = [ - formatValue(ctx, entries[pos], recurseTimes), - formatValue(ctx, entries[pos + 1], recurseTimes), - ]; - output[i] = reduceToSingleString( - ctx, - res, - "", - ["[", "]"], - kArrayExtrasType, - recurseTimes - ); - } - } - ctx.indentationLvl -= 2; - if (remaining > 0) { - output.push(remainingText(remaining)); - } - return output; -} - -function formatWeakCollection(ctx: Context): string[] { - return [ctx.stylize("", "special")]; -} - -function formatWeakSet(ctx: Context, value: WeakSet, recurseTimes: number): string[] { - const { entries } = internal.previewEntries(value)!; - return formatSetIterInner(ctx, recurseTimes, entries, kWeak); -} - -function formatWeakMap(ctx: Context, value: WeakMap, recurseTimes: number): string[] { - const { entries } = internal.previewEntries(value)!; - return formatMapIterInner(ctx, recurseTimes, entries, kWeak); -} - -function formatIterator( - braces: [string, string], - ctx: Context, - value: Iterator, - recurseTimes: number -): string[] { - const { entries, isKeyValue } = internal.previewEntries(value)!; - if (isKeyValue) { - // Mark entry iterators as such. - braces[0] = braces[0].replace(/ Iterator] {$/, " Entries] {"); - return formatMapIterInner(ctx, recurseTimes, entries, kMapEntries); - } - - return formatSetIterInner(ctx, recurseTimes, entries, kIterator); -} - -function formatPromise(ctx: Context, value: Promise, recurseTimes: number): string[] { - let output: string[]; - const { state, result } = internal.getPromiseDetails(value)!; - if (state === internal.kPending) { - output = [ctx.stylize("", "special")]; - } else { - ctx.indentationLvl += 2; - const str = formatValue(ctx, result, recurseTimes); - ctx.indentationLvl -= 2; - output = [ - state === internal.kRejected ? `${ctx.stylize("", "special")} ${str}` : str, - ]; - } - return output; -} - -function formatProperty( - ctx: Context, - value: object, - recurseTimes: number, - key: PropertyKey, - type: number, - desc?: PropertyDescriptor, - original = value -): string { - let name: string, str: string; - let extra = " "; - desc = desc || - Object.getOwnPropertyDescriptor(value, key) || { - value: (value as Record)[key], - enumerable: true, - }; - if (desc.value !== undefined) { - const diff = ctx.compact !== true || type !== kObjectType ? 2 : 3; - ctx.indentationLvl += diff; - str = formatValue(ctx, desc.value, recurseTimes); - if (diff === 3 && ctx.breakLength < getStringWidth(str, ctx.colors)) { - extra = `\n${" ".repeat(ctx.indentationLvl)}`; - } - ctx.indentationLvl -= diff; - } else if (desc.get !== undefined) { - const label = desc.set !== undefined ? "Getter/Setter" : "Getter"; - const s = ctx.stylize; - const sp = "special"; - if ( - ctx.getters && - (ctx.getters === true || - (ctx.getters === "get" && desc.set === undefined) || - (ctx.getters === "set" && desc.set !== undefined)) - ) { - try { - const tmp = desc.get.call(original); - ctx.indentationLvl += 2; - if (tmp === null) { - str = `${s(`[${label}:`, sp)} ${s("null", "null")}${s("]", sp)}`; - } else if (typeof tmp === "object") { - str = `${s(`[${label}]`, sp)} ${formatValue(ctx, tmp, recurseTimes)}`; - } else { - const primitive = formatPrimitive(s, tmp, ctx); - str = `${s(`[${label}:`, sp)} ${primitive}${s("]", sp)}`; - } - ctx.indentationLvl -= 2; - } catch (err) { - const message = ``; - str = `${s(`[${label}:`, sp)} ${message}${s("]", sp)}`; - } - } else { - str = ctx.stylize(`[${label}]`, sp); - } - } else if (desc.set !== undefined) { - str = ctx.stylize("[Setter]", "special"); - } else { - str = ctx.stylize("undefined", "undefined"); - } - if (type === kArrayType) { - return str; - } - if (typeof key === "symbol") { - const tmp = Symbol.prototype.toString - .call(key) - .replace(strEscapeSequencesReplacer, escapeFn); - name = `[${ctx.stylize(tmp, "symbol")}]`; - } else if (key === "__proto__") { - name = "['__proto__']"; - } else if (desc.enumerable === false) { - const tmp = String(key).replace(strEscapeSequencesReplacer, escapeFn); - name = `[${tmp}]`; - } else if (keyStrRegExp.exec(String(key)) !== null) { - name = ctx.stylize(String(key), "name"); - } else { - name = ctx.stylize(strEscape(String(key)), "string"); - } - return `${name}:${extra}${str}`; -} - -function isBelowBreakLength(ctx: Context, output: string[], start: number, base: string): boolean { - // Each entry is separated by at least a comma. Thus, we start with a total - // length of at least `output.length`. In addition, some cases have a - // whitespace in-between each other that is added to the total as well. - // TODO(BridgeAR): Add unicode support. Use the readline getStringWidth - // function. Check the performance overhead and make it an opt-in in case it's - // significant. - let totalLength = output.length + start; - if (totalLength + output.length > ctx.breakLength) return false; - for (let i = 0; i < output.length; i++) { - if (ctx.colors) { - totalLength += removeColors(output[i]!).length; - } else { - totalLength += output[i]!.length; - } - if (totalLength > ctx.breakLength) { - return false; - } - } - // Do not line up properties on the same line if `base` contains line breaks. - return base === "" || !base.includes("\n"); -} - -function reduceToSingleString( - ctx: Context, - output: string[], - base: string, - braces: [string, string], - extrasType: number, - recurseTimes: number, - value?: unknown -): string { - if (ctx.compact !== true) { - if (typeof ctx.compact === "number" && ctx.compact >= 1) { - // Memorize the original output length. In case the output is grouped, - // prevent lining up the entries on a single line. - const entries = output.length; - // Group array elements together if the array contains at least six - // separate entries. - if (extrasType === kArrayExtrasType && entries > 6) { - output = groupArrayElements(ctx, output, value as unknown[]); - } - // `ctx.currentDepth` is set to the most inner depth of the currently - // inspected object part while `recurseTimes` is the actual current depth - // that is inspected. - // - // Example: - // - // const a = { first: [ 1, 2, 3 ], second: { inner: [ 1, 2, 3 ] } } - // - // The deepest depth of `a` is 2 (a.second.inner) and `a.first` has a max - // depth of 1. - // - // Consolidate all entries of the local most inner depth up to - // `ctx.compact`, as long as the properties are smaller than - // `ctx.breakLength`. - if (ctx.currentDepth - recurseTimes < ctx.compact && entries === output.length) { - // Line up all entries on a single line in case the entries do not - // exceed `breakLength`. Add 10 as constant to start next to all other - // factors that may reduce `breakLength`. - const start = - output.length + ctx.indentationLvl + braces[0].length + base.length + 10; - if (isBelowBreakLength(ctx, output, start, base)) { - const joinedOutput = output.join(", "); - if (!joinedOutput.includes("\n")) { - return ( - `${base ? `${base} ` : ""}${braces[0]} ${joinedOutput}` + - ` ${braces[1]}` - ); - } - } - } - } - // Line up each entry on an individual line. - const indentation = `\n${" ".repeat(ctx.indentationLvl)}`; - return ( - `${base ? `${base} ` : ""}${braces[0]}${indentation} ` + - `${output.join(`,${indentation} `)}${indentation}${braces[1]}` - ); - } - // Line up all entries on a single line in case the entries do not exceed - // `breakLength`. - if (isBelowBreakLength(ctx, output, 0, base)) { - return `${braces[0]}${base ? ` ${base}` : ""} ${output.join(", ")} ` + braces[1]; - } - const indentation = " ".repeat(ctx.indentationLvl); - // If the opening "brace" is too large, like in the case of "Set {", - // we need to force the first item to be on the next line or the - // items will not line up correctly. - const ln = - base === "" && braces[0].length === 1 ? " " : `${base ? ` ${base}` : ""}\n${indentation} `; - // Line up each entry on an individual line. - return `${braces[0]}${ln}${output.join(`,\n${indentation} `)} ${braces[1]}`; -} - -function hasBuiltInToString(value: object): boolean { - // Prevent triggering proxy traps. - const proxyTarget = internal.getProxyDetails(value); - if (proxyTarget !== undefined) { - if (proxyTarget === null) { - return true; - } - value = proxyTarget.target as object; - } - - // Count objects that have no `toString` function as built-in. - if (typeof value?.toString !== "function") { - return true; - } - - // The object has a own `toString` property. Thus it's not not a built-in one. - if (Object.prototype.hasOwnProperty.call(value, "toString")) { - return false; - } - - // Find the object that has the `toString` property as own property in the - // prototype chain. - let pointer = value; - do { - pointer = Object.getPrototypeOf(pointer); - } while (!Object.prototype.hasOwnProperty.call(pointer, "toString")); - - // Check closer if the object is a built-in. - const descriptor = Object.getOwnPropertyDescriptor(pointer, "constructor"); - return ( - descriptor !== undefined && - typeof descriptor.value === "function" && - builtInObjects.has(descriptor.value.name) - ); -} - -const firstErrorLine = (error: unknown) => - (isError(error) ? error.message : String(error)).split("\n", 1)[0]; -let CIRCULAR_ERROR_MESSAGE: string | undefined; -function tryStringify(arg: unknown): string { - try { - return JSON.stringify(arg); - } catch (err) { - // Populate the circular error message lazily - if (!CIRCULAR_ERROR_MESSAGE) { - try { - const a: { a?: unknown } = {}; - a.a = a; - JSON.stringify(a); - } catch (circularError) { - CIRCULAR_ERROR_MESSAGE = firstErrorLine(circularError); - } - } - if ( - typeof err === "object" && - err !== null && - "name" in err && - err.name === "TypeError" && - firstErrorLine(err) === CIRCULAR_ERROR_MESSAGE - ) { - return "[Circular]"; - } - throw err; - } -} - -export function format(...args: unknown[]): string { - return formatWithOptionsInternal(undefined, args); -} - -export function formatWithOptions(inspectOptions: InspectOptions, ...args: unknown[]): string { - validateObject(inspectOptions, "inspectOptions", { allowArray: true }); - return formatWithOptionsInternal(inspectOptions, args); -} - -function formatNumberNoColor(number: number, options?: InspectOptions): string { - return formatNumber( - stylizeNoColor, - number, - options?.numericSeparator ?? inspectDefaultOptions.numericSeparator - ); -} - -function formatBigIntNoColor(bigint: bigint, options?: InspectOptions): string { - return formatBigInt( - stylizeNoColor, - bigint, - options?.numericSeparator ?? inspectDefaultOptions.numericSeparator - ); -} - -function formatWithOptionsInternal( - inspectOptions: InspectOptions | undefined, - args: unknown[] -): string { - const first = args[0]; - let a = 0; - let str = ""; - let join = ""; - - if (typeof first === "string") { - if (args.length === 1) { - return first; - } - let tempStr; - let lastPos = 0; - - for (let i = 0; i < first.length - 1; i++) { - if (first.charCodeAt(i) === 37) { - // '%' - const nextChar = first.charCodeAt(++i); - if (a + 1 !== args.length) { - switch (nextChar) { - case 115: { - // 's' - const tempArg = args[++a]; - if (typeof tempArg === "number") { - tempStr = formatNumberNoColor(tempArg, inspectOptions); - } else if (typeof tempArg === "bigint") { - tempStr = formatBigIntNoColor(tempArg, inspectOptions); - } else if ( - typeof tempArg !== "object" || - tempArg === null || - !hasBuiltInToString(tempArg) - ) { - tempStr = String(tempArg); - } else { - tempStr = inspect(tempArg, { - ...inspectOptions, - compact: 3, - colors: false, - depth: 0, - }); - } - break; - } - case 106: // 'j' - tempStr = tryStringify(args[++a]); - break; - case 100: { - // 'd' - const tempNum = args[++a]; - if (typeof tempNum === "bigint") { - tempStr = formatBigIntNoColor(tempNum, inspectOptions); - } else if (typeof tempNum === "symbol") { - tempStr = "NaN"; - } else { - tempStr = formatNumberNoColor(Number(tempNum), inspectOptions); - } - break; - } - case 79: // 'O' - tempStr = inspect(args[++a], inspectOptions); - break; - case 111: // 'o' - tempStr = inspect(args[++a], { - ...inspectOptions, - showHidden: true, - showProxy: true, - depth: 4, - }); - break; - case 105: { - // 'i' - const tempInteger = args[++a]; - if (typeof tempInteger === "bigint") { - tempStr = formatBigIntNoColor(tempInteger, inspectOptions); - } else if (typeof tempInteger === "symbol") { - tempStr = "NaN"; - } else { - tempStr = formatNumberNoColor( - Number.parseInt(tempInteger as unknown as string), - inspectOptions - ); - } - break; - } - case 102: { - // 'f' - const tempFloat = args[++a]; - if (typeof tempFloat === "symbol") { - tempStr = "NaN"; - } else { - tempStr = formatNumberNoColor( - Number.parseFloat(tempFloat as unknown as string), - inspectOptions - ); - } - break; - } - case 99: // 'c' - a += 1; - tempStr = ""; - break; - case 37: // '%' - str += first.slice(lastPos, i); - lastPos = i + 1; - continue; - default: // Any other character is not a correct placeholder - continue; - } - if (lastPos !== i - 1) { - str += first.slice(lastPos, i - 1); - } - str += tempStr; - lastPos = i + 1; - } else if (nextChar === 37) { - str += first.slice(lastPos, i); - lastPos = i + 1; - } - } - } - if (lastPos !== 0) { - a++; - join = " "; - if (lastPos < first.length) { - str += first.slice(lastPos); - } - } - } - - while (a < args.length) { - const value = args[a]; - str += join; - str += typeof value !== "string" ? inspect(value, inspectOptions) : value; - join = " "; - a++; - } - return str; -} - -export function isZeroWidthCodePoint(code: number): boolean { - return ( - code <= 0x1f || // C0 control codes - (code >= 0x7f && code <= 0x9f) || // C1 control codes - (code >= 0x300 && code <= 0x36f) || // Combining Diacritical Marks - (code >= 0x200b && code <= 0x200f) || // Modifying Invisible Characters - // Combining Diacritical Marks for Symbols - (code >= 0x20d0 && code <= 0x20ff) || - (code >= 0xfe00 && code <= 0xfe0f) || // Variation Selectors - (code >= 0xfe20 && code <= 0xfe2f) || // Combining Half Marks - (code >= 0xe0100 && code <= 0xe01ef) - ); // Variation Selectors -} - -/** - * Returns the number of columns required to display the given string. - */ -export function getStringWidth(str: string, removeControlChars = true): number { - let width = 0; - - if (removeControlChars) str = stripVTControlCharacters(str); - str = str.normalize("NFC"); - for (const char of str) { - const code = char.codePointAt(0)!; - if (isFullWidthCodePoint(code)) { - width += 2; - } else if (!isZeroWidthCodePoint(code)) { - width++; - } - } - - return width; -} - -/** - * Returns true if the character represented by a given - * Unicode code point is full-width. Otherwise returns false. - */ -const isFullWidthCodePoint = (code: number) => { - // Code points are partially derived from: - // https://www.unicode.org/Public/UNIDATA/EastAsianWidth.txt - return ( - code >= 0x1100 && - (code <= 0x115f || // Hangul Jamo - code === 0x2329 || // LEFT-POINTING ANGLE BRACKET - code === 0x232a || // RIGHT-POINTING ANGLE BRACKET - // CJK Radicals Supplement .. Enclosed CJK Letters and Months - (code >= 0x2e80 && code <= 0x3247 && code !== 0x303f) || - // Enclosed CJK Letters and Months .. CJK Unified Ideographs Extension A - (code >= 0x3250 && code <= 0x4dbf) || - // CJK Unified Ideographs .. Yi Radicals - (code >= 0x4e00 && code <= 0xa4c6) || - // Hangul Jamo Extended-A - (code >= 0xa960 && code <= 0xa97c) || - // Hangul Syllables - (code >= 0xac00 && code <= 0xd7a3) || - // CJK Compatibility Ideographs - (code >= 0xf900 && code <= 0xfaff) || - // Vertical Forms - (code >= 0xfe10 && code <= 0xfe19) || - // CJK Compatibility Forms .. Small Form Variants - (code >= 0xfe30 && code <= 0xfe6b) || - // Halfwidth and Fullwidth Forms - (code >= 0xff01 && code <= 0xff60) || - (code >= 0xffe0 && code <= 0xffe6) || - // Kana Supplement - (code >= 0x1b000 && code <= 0x1b001) || - // Enclosed Ideographic Supplement - (code >= 0x1f200 && code <= 0x1f251) || - // Miscellaneous Symbols and Pictographs 0x1f300 - 0x1f5ff - // Emoticons 0x1f600 - 0x1f64f - (code >= 0x1f300 && code <= 0x1f64f) || - // CJK Unified Ideographs Extension B .. Tertiary Ideographic Plane - (code >= 0x20000 && code <= 0x3fffd)) - ); -}; - -/** - * Remove all VT control characters. Use to estimate displayed string width. - */ -export function stripVTControlCharacters(str: string): string { - validateString(str, "str"); - - return str.replace(ansi, ""); -} - -// ================================================================================================ -// WORKERD SPECIFIC CODE - -// Called from C++ on `console.log()`s to format values -export function formatLog(...args: [...values: unknown[], colors: boolean]): string { - const inspectOptions: InspectOptions = { colors: args.pop() as boolean }; - try { - return formatWithOptions(inspectOptions, ...args); - } catch (err) { - return ``; - } -} - -function isBuiltinPrototype(proto: unknown) { - if (proto === null) return true; - const descriptor = Object.getOwnPropertyDescriptor(proto, "constructor"); - return ( - descriptor !== undefined && - typeof descriptor.value === "function" && - builtInObjects.has(descriptor.value.name) - ); -} - -function isEntry(value: unknown): value is [unknown, unknown] { - return Array.isArray(value) && value.length === 2; -} -function maybeGetEntries(value: Record): [unknown, unknown][] | undefined { - const entriesFunction = value["entries"]; - if (typeof entriesFunction !== "function") return; - const entriesIterator: unknown = entriesFunction.call(value); - if (typeof entriesIterator !== "object" || entriesIterator === null) return; - if (!(Symbol.iterator in entriesIterator)) return; - const entries = Array.from(entriesIterator as Iterable); - if (!entries.every(isEntry)) return; - return entries; -} - -const kEntries = Symbol("kEntries"); -function hasEntries(value: unknown): value is { [kEntries]: [unknown, unknown][] } { - return typeof value === "object" && value !== null && kEntries in value; -} - -// Default custom inspect implementation for JSG resource types -function formatJsgResourceType( - this: Record, - additionalProperties: Record, - depth: number, - options: InspectOptionsStylized -): unknown { - const name = this.constructor.name; - if (depth < 0) return options.stylize(`[${name}]`, "special"); - - // Build a plain object for inspection. If this value has an `entries()` function, add those - // entries for map-like `K => V` formatting. Note we can't use a `Map` here as a key may have - // multiple values (e.g. URLSearchParams). - const record: Record = {}; - const maybeEntries = maybeGetEntries(this); - if (maybeEntries !== undefined) record[kEntries] = maybeEntries; - - // Add all instance and prototype non-function-valued properties - let current: object = this; - do { - for (const key of Object.getOwnPropertyNames(current)) { - // `Object.getOwnPropertyDescriptor()` throws `Illegal Invocation` for our prototypes here - const value = this[key]; - // Ignore function-valued and static properties - if (typeof value === "function" || this.constructor.propertyIsEnumerable(key)) continue; - record[key] = value; - } - } while (!isBuiltinPrototype((current = Object.getPrototypeOf(current)))); - - // Add additional inspect-only properties as non-enumerable so they appear in square brackets - for (const [key, symbol] of Object.entries(additionalProperties)) { - Object.defineProperty(record, key, { value: this[symbol], enumerable: false }); - } - - // Format the plain object - const inspected = inspect(record, { - ...options, - depth: options.depth == null ? null : depth, - showHidden: true, // Show non-enumerable inspect-only properties - }); - - if (maybeEntries === undefined) { - return `${name} ${inspected}`; - } else { - // Inspecting a entries object gives something like `Object(1) { 'a' => '1' }`, whereas we want - // something like `Headers(1) { 'a' => '1' }`. - return `${name}${inspected.replace("Object", "")}`; - } -} diff --git a/JS/wasm/crates/wasmjs-engine/shims/src/internal/internal_path.ts b/JS/wasm/crates/wasmjs-engine/shims/src/internal/internal_path.ts deleted file mode 100644 index 174193c23..000000000 --- a/JS/wasm/crates/wasmjs-engine/shims/src/internal/internal_path.ts +++ /dev/null @@ -1,583 +0,0 @@ -import { CHAR_DOT, CHAR_FORWARD_SLASH } from "./constants"; - -import { validateObject, validateString } from "./validators"; - -function isPosixPathSeparator(code: number) { - return code === CHAR_FORWARD_SLASH; -} - -// Resolves . and .. elements in a path with directory names -function normalizeString( - path: string, - allowAboveRoot: boolean, - separator: string, - isPathSeparator: (code: number) => boolean -) { - let res = ""; - let lastSegmentLength = 0; - let lastSlash = -1; - let dots = 0; - let code = 0; - for (let i = 0; i <= path.length; ++i) { - if (i < path.length) code = path.charCodeAt(i); - else if (isPathSeparator(code)) break; - else code = CHAR_FORWARD_SLASH; - - if (isPathSeparator(code)) { - if (lastSlash === i - 1 || dots === 1) { - // NOOP - } else if (dots === 2) { - if ( - res.length < 2 || - lastSegmentLength !== 2 || - res.charCodeAt(res.length - 1) !== CHAR_DOT || - res.charCodeAt(res.length - 2) !== CHAR_DOT - ) { - if (res.length > 2) { - const lastSlashIndex = res.lastIndexOf(separator); - if (lastSlashIndex === -1) { - res = ""; - lastSegmentLength = 0; - } else { - res = res.slice(0, lastSlashIndex); - lastSegmentLength = res.length - 1 - res.lastIndexOf(separator); - } - lastSlash = i; - dots = 0; - continue; - } else if (res.length !== 0) { - res = ""; - lastSegmentLength = 0; - lastSlash = i; - dots = 0; - continue; - } - } - if (allowAboveRoot) { - res += res.length > 0 ? `${separator}..` : ".."; - lastSegmentLength = 2; - } - } else { - if (res.length > 0) res += `${separator}${path.slice(lastSlash + 1, i)}`; - else res = path.slice(lastSlash + 1, i); - lastSegmentLength = i - lastSlash - 1; - } - lastSlash = i; - dots = 0; - } else if (code === CHAR_DOT && dots !== -1) { - ++dots; - } else { - dots = -1; - } - } - return res; -} - -function formatExt(ext: string) { - return ext ? `${ext[0] === "." ? "" : "."}${ext}` : ""; -} - -/** - * @param {string} sep - * @param {{ - * dir?: string; - * root?: string; - * base?: string; - * name?: string; - * ext?: string; - * }} pathObject - * @returns {string} - */ - -type PathObject = { - dir?: string; - root?: string; - base?: string; - name?: string; - ext?: string; -}; - -function _format(sep: string, pathObject: PathObject) { - validateObject(pathObject, "pathObject", {}); - const dir = pathObject.dir || pathObject.root; - const base = pathObject.base || `${pathObject.name || ""}${formatExt(pathObject.ext!)}`; - if (!dir) { - return base; - } - return dir === pathObject.root ? `${dir}${base}` : `${dir}${sep}${base}`; -} - -// We currently do not implement the path.win32 subset. -const win32 = { - resolve(..._: [string[], string]) { - throw new Error("path.win32.resolve() is not implemented."); - }, - - normalize(_: string) { - throw new Error("path.win32.normalize() is not implemented."); - }, - - isAbsolute(_: string) { - throw new Error("path.win32.isAbsolute() is not implemented."); - }, - - join(..._: string[]) { - throw new Error("path.win32.join() is not implemented."); - }, - - relative(_0: string, _1: string) { - throw new Error("path.win32.relative() is not implemented."); - }, - - toNamespacedPath(_: string) { - throw new Error("path.win32.toNamedspacedPath() is not implemented."); - }, - - dirname(_: string) { - throw new Error("path.win32.dirname() is not implemented."); - }, - - basename(_0: string, _1?: string) { - throw new Error("path.win32.basename() is not implemented."); - }, - - extname(_: string) { - throw new Error("path.win32.extname() is not implemented."); - }, - - format(_: PathObject) { - throw new Error("path.win32.format() is not implemented."); - }, - - parse(_: string) { - throw new Error("path.win32.parse() is not implemented."); - }, - - sep: "\\", - delimiter: ";", - win32: null as Object | null, - posix: null as Object | null, -}; - -const posix = { - /** - * path.resolve([from ...], to) - * @param {...string} args - * @returns {string} - */ - resolve(...args: string[]) { - let resolvedPath = ""; - let resolvedAbsolute = false; - - for (let i = args.length - 1; i >= -1 && !resolvedAbsolute; i--) { - const path = i >= 0 ? args[i] : "/"; - - validateString(path, "path"); - - // Skip empty entries - if (path!.length === 0) { - continue; - } - - resolvedPath = `${path}/${resolvedPath}`; - resolvedAbsolute = path!.charCodeAt(0) === CHAR_FORWARD_SLASH; - } - - // At this point the path should be resolved to a full absolute path, but - // handle relative paths to be safe (might happen when process.cwd() fails) - - // Normalize the path - resolvedPath = normalizeString(resolvedPath, !resolvedAbsolute, "/", isPosixPathSeparator); - - if (resolvedAbsolute) { - return `/${resolvedPath}`; - } - return resolvedPath.length > 0 ? resolvedPath : "."; - }, - - /** - * @param {string} path - * @returns {string} - */ - normalize(path: string) { - validateString(path, "path"); - - if (path.length === 0) return "."; - - const isAbsolute = path.charCodeAt(0) === CHAR_FORWARD_SLASH; - const trailingSeparator = path.charCodeAt(path.length - 1) === CHAR_FORWARD_SLASH; - - // Normalize the path - path = normalizeString(path, !isAbsolute, "/", isPosixPathSeparator); - - if (path.length === 0) { - if (isAbsolute) return "/"; - return trailingSeparator ? "./" : "."; - } - if (trailingSeparator) path += "/"; - - return isAbsolute ? `/${path}` : path; - }, - - /** - * @param {string} path - * @returns {boolean} - */ - isAbsolute(path: string) { - validateString(path, "path"); - return path.length > 0 && path.charCodeAt(0) === CHAR_FORWARD_SLASH; - }, - - /** - * @param {...string} args - * @returns {string} - */ - join(...args: string[]) { - if (args.length === 0) return "."; - let joined; - for (let i = 0; i < args.length; ++i) { - const arg = args[i]; - validateString(arg, "path"); - if (arg!.length > 0) { - if (joined === undefined) joined = arg; - else joined += `/${arg}`; - } - } - if (joined === undefined) return "."; - return posix.normalize(joined); - }, - - /** - * @param {string} from - * @param {string} to - * @returns {string} - */ - relative(from: string, to: string) { - validateString(from, "from"); - validateString(to, "to"); - - if (from === to) return ""; - - // Trim leading forward slashes. - from = posix.resolve(from); - to = posix.resolve(to); - - if (from === to) return ""; - - const fromStart = 1; - const fromEnd = from.length; - const fromLen = fromEnd - fromStart; - const toStart = 1; - const toLen = to.length - toStart; - - // Compare paths to find the longest common path from root - const length = fromLen < toLen ? fromLen : toLen; - let lastCommonSep = -1; - let i = 0; - for (; i < length; i++) { - const fromCode = from.charCodeAt(fromStart + i); - if (fromCode !== to.charCodeAt(toStart + i)) break; - else if (fromCode === CHAR_FORWARD_SLASH) lastCommonSep = i; - } - if (i === length) { - if (toLen > length) { - if (to.charCodeAt(toStart + i) === CHAR_FORWARD_SLASH) { - // We get here if `from` is the exact base path for `to`. - // For example: from='/foo/bar'; to='/foo/bar/baz' - return to.slice(toStart + i + 1); - } - if (i === 0) { - // We get here if `from` is the root - // For example: from='/'; to='/foo' - return to.slice(toStart + i); - } - } else if (fromLen > length) { - if (from.charCodeAt(fromStart + i) === CHAR_FORWARD_SLASH) { - // We get here if `to` is the exact base path for `from`. - // For example: from='/foo/bar/baz'; to='/foo/bar' - lastCommonSep = i; - } else if (i === 0) { - // We get here if `to` is the root. - // For example: from='/foo/bar'; to='/' - lastCommonSep = 0; - } - } - } - - let out = ""; - // Generate the relative path based on the path difference between `to` - // and `from`. - for (i = fromStart + lastCommonSep + 1; i <= fromEnd; ++i) { - if (i === fromEnd || from.charCodeAt(i) === CHAR_FORWARD_SLASH) { - out += out.length === 0 ? ".." : "/.."; - } - } - - // Lastly, append the rest of the destination (`to`) path that comes after - // the common path parts. - return `${out}${to.slice(toStart + lastCommonSep)}`; - }, - - /** - * @param {string} path - * @returns {string} - */ - toNamespacedPath(path: string) { - // Non-op on posix systems - return path; - }, - - /** - * @param {string} path - * @returns {string} - */ - dirname(path: string) { - validateString(path, "path"); - if (path.length === 0) return "."; - const hasRoot = path.charCodeAt(0) === CHAR_FORWARD_SLASH; - let end = -1; - let matchedSlash = true; - for (let i = path.length - 1; i >= 1; --i) { - if (path.charCodeAt(i) === CHAR_FORWARD_SLASH) { - if (!matchedSlash) { - end = i; - break; - } - } else { - // We saw the first non-path separator - matchedSlash = false; - } - } - - if (end === -1) return hasRoot ? "/" : "."; - if (hasRoot && end === 1) return "//"; - return path.slice(0, end); - }, - - /** - * @param {string} path - * @param {string} [suffix] - * @returns {string} - */ - basename(path: string, suffix?: string) { - if (suffix !== undefined) validateString(suffix, "ext"); - validateString(path, "path"); - - let start = 0; - let end = -1; - let matchedSlash = true; - - if (suffix !== undefined && suffix.length > 0 && suffix.length <= path.length) { - if (suffix === path) return ""; - let extIdx = suffix.length - 1; - let firstNonSlashEnd = -1; - for (let i = path.length - 1; i >= 0; --i) { - const code = path.charCodeAt(i); - if (code === CHAR_FORWARD_SLASH) { - // If we reached a path separator that was not part of a set of path - // separators at the end of the string, stop now - if (!matchedSlash) { - start = i + 1; - break; - } - } else { - if (firstNonSlashEnd === -1) { - // We saw the first non-path separator, remember this index in case - // we need it if the extension ends up not matching - matchedSlash = false; - firstNonSlashEnd = i + 1; - } - if (extIdx >= 0) { - // Try to match the explicit extension - if (code === suffix.charCodeAt(extIdx)) { - if (--extIdx === -1) { - // We matched the extension, so mark this as the end of our path - // component - end = i; - } - } else { - // Extension does not match, so our result is the entire path - // component - extIdx = -1; - end = firstNonSlashEnd; - } - } - } - } - - if (start === end) end = firstNonSlashEnd; - else if (end === -1) end = path.length; - return path.slice(start, end); - } - for (let i = path.length - 1; i >= 0; --i) { - if (path.charCodeAt(i) === CHAR_FORWARD_SLASH) { - // If we reached a path separator that was not part of a set of path - // separators at the end of the string, stop now - if (!matchedSlash) { - start = i + 1; - break; - } - } else if (end === -1) { - // We saw the first non-path separator, mark this as the end of our - // path component - matchedSlash = false; - end = i + 1; - } - } - - if (end === -1) return ""; - return path.slice(start, end); - }, - - /** - * @param {string} path - * @returns {string} - */ - extname(path: string) { - validateString(path, "path"); - let startDot = -1; - let startPart = 0; - let end = -1; - let matchedSlash = true; - // Track the state of characters (if any) we see before our first dot and - // after any path separator we find - let preDotState = 0; - for (let i = path.length - 1; i >= 0; --i) { - const code = path.charCodeAt(i); - if (code === CHAR_FORWARD_SLASH) { - // If we reached a path separator that was not part of a set of path - // separators at the end of the string, stop now - if (!matchedSlash) { - startPart = i + 1; - break; - } - continue; - } - if (end === -1) { - // We saw the first non-path separator, mark this as the end of our - // extension - matchedSlash = false; - end = i + 1; - } - if (code === CHAR_DOT) { - // If this is our first dot, mark it as the start of our extension - if (startDot === -1) startDot = i; - else if (preDotState !== 1) preDotState = 1; - } else if (startDot !== -1) { - // We saw a non-dot and non-path separator before our dot, so we should - // have a good chance at having a non-empty extension - preDotState = -1; - } - } - - if ( - startDot === -1 || - end === -1 || - // We saw a non-dot character immediately before the dot - preDotState === 0 || - // The (right-most) trimmed path component is exactly '..' - (preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) - ) { - return ""; - } - return path.slice(startDot, end); - }, - - format: _format.bind(null, "/"), - - /** - * @param {string} path - * @returns {{ - * dir: string; - * root: string; - * base: string; - * name: string; - * ext: string; - * }} - */ - parse(path: string): PathObject { - validateString(path, "path"); - - const ret = { root: "", dir: "", base: "", ext: "", name: "" }; - if (path.length === 0) return ret; - const isAbsolute = path.charCodeAt(0) === CHAR_FORWARD_SLASH; - let start; - if (isAbsolute) { - ret.root = "/"; - start = 1; - } else { - start = 0; - } - let startDot = -1; - let startPart = 0; - let end = -1; - let matchedSlash = true; - let i = path.length - 1; - - // Track the state of characters (if any) we see before our first dot and - // after any path separator we find - let preDotState = 0; - - // Get non-dir info - for (; i >= start; --i) { - const code = path.charCodeAt(i); - if (code === CHAR_FORWARD_SLASH) { - // If we reached a path separator that was not part of a set of path - // separators at the end of the string, stop now - if (!matchedSlash) { - startPart = i + 1; - break; - } - continue; - } - if (end === -1) { - // We saw the first non-path separator, mark this as the end of our - // extension - matchedSlash = false; - end = i + 1; - } - if (code === CHAR_DOT) { - // If this is our first dot, mark it as the start of our extension - if (startDot === -1) startDot = i; - else if (preDotState !== 1) preDotState = 1; - } else if (startDot !== -1) { - // We saw a non-dot and non-path separator before our dot, so we should - // have a good chance at having a non-empty extension - preDotState = -1; - } - } - - if (end !== -1) { - const start = startPart === 0 && isAbsolute ? 1 : startPart; - if ( - startDot === -1 || - // We saw a non-dot character immediately before the dot - preDotState === 0 || - // The (right-most) trimmed path component is exactly '..' - (preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) - ) { - ret.base = ret.name = path.slice(start, end); - } else { - ret.name = path.slice(start, startDot); - ret.base = path.slice(start, end); - ret.ext = path.slice(startDot, end); - } - } - - if (startPart > 0) ret.dir = path.slice(0, startPart - 1); - else if (isAbsolute) ret.dir = "/"; - - return ret; - }, - - sep: "/", - delimiter: ":", - win32: null as Object | null, - posix: null as Object | null, -}; - -posix.win32 = win32.win32 = win32; -posix.posix = win32.posix = posix; - -export default posix; -export { posix, win32 }; diff --git a/JS/wasm/crates/wasmjs-engine/shims/src/internal/internal_stringdecoder.ts b/JS/wasm/crates/wasmjs-engine/shims/src/internal/internal_stringdecoder.ts deleted file mode 100644 index 0ed5a1db5..000000000 --- a/JS/wasm/crates/wasmjs-engine/shims/src/internal/internal_stringdecoder.ts +++ /dev/null @@ -1,135 +0,0 @@ -import { Buffer, isEncoding } from "./internal_buffer"; -import { normalizeEncoding } from "./internal_utils"; -import { ERR_INVALID_ARG_TYPE, ERR_INVALID_THIS, ERR_UNKNOWN_ENCODING } from "./internal_errors"; - -import * as bufferUtil from "./buffer"; - -const kIncompleteCharactersStart = 0; -const kIncompleteCharactersEnd = 4; -const kMissingBytes = 4; -const kBufferedBytes = 5; -const kEncoding = 6; -const kSize = 7; - -const encodings: Record = { - ascii: 0, - latin1: 1, - utf8: 2, - utf16le: 3, - base64: 4, - base64url: 5, - hex: 6, -}; - -const kNativeDecoder = Symbol("kNativeDecoder"); - -export interface StringDecoder { - encoding: string; - readonly lastChar: Uint8Array; - readonly lastNeed: number; - readonly lastTotal: number; - new (encoding?: string): StringDecoder; - write(buf: ArrayBufferView | DataView | string): string; - end(buf?: ArrayBufferView | DataView | string): string; - text(buf: ArrayBufferView | DataView | string, offset?: number): string; - new (encoding?: string): StringDecoder; -} - -interface InternalDecoder extends StringDecoder { - [kNativeDecoder]: Buffer; -} - -export function StringDecoder(this: StringDecoder, encoding: string = "utf8") { - const normalizedEncoding = normalizeEncoding(encoding); - if (!isEncoding(normalizedEncoding)) { - throw new ERR_UNKNOWN_ENCODING(encoding); - } - (this as InternalDecoder)[kNativeDecoder] = Buffer.alloc(kSize); - (this as InternalDecoder)[kNativeDecoder][kEncoding] = encodings[normalizedEncoding!]!; - this.encoding = normalizedEncoding!; -} - -function write(this: StringDecoder, buf: ArrayBufferView | DataView | string): string { - if ((this as InternalDecoder)[kNativeDecoder] === undefined) { - throw new ERR_INVALID_THIS("StringDecoder"); - } - if (typeof buf === "string") { - return buf; - } - if (!ArrayBuffer.isView(buf)) { - throw new ERR_INVALID_ARG_TYPE("buf", ["Buffer", "TypedArray", "DataView", "string"], buf); - } - const buffer = new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength); - return bufferUtil.decode(buffer, (this as InternalDecoder)[kNativeDecoder]); -} - -function end(this: StringDecoder, buf?: ArrayBufferView | DataView | string): string { - if ((this as InternalDecoder)[kNativeDecoder] === undefined) { - throw new ERR_INVALID_THIS("StringDecoder"); - } - let ret = ""; - if (buf !== undefined) { - ret = this.write(buf); - } - if ((this as InternalDecoder)[kNativeDecoder][kBufferedBytes]! > 0) { - ret += bufferUtil.flush((this as InternalDecoder)[kNativeDecoder]); - } - return ret; -} - -function text( - this: StringDecoder, - buf: ArrayBufferView | DataView | string, - offset?: number -): string { - if ((this as InternalDecoder)[kNativeDecoder] === undefined) { - throw new ERR_INVALID_THIS("StringDecoder"); - } - (this as InternalDecoder)[kNativeDecoder][kMissingBytes] = 0; - (this as InternalDecoder)[kNativeDecoder][kBufferedBytes] = 0; - return this.write((buf as any).slice(offset)); -} - -StringDecoder.prototype.write = write; -StringDecoder.prototype.end = end; -StringDecoder.prototype.text = text; - -Object.defineProperties(StringDecoder.prototype, { - lastChar: { - enumerable: true, - get(this: StringDecoder): Buffer { - if ((this as InternalDecoder)[kNativeDecoder] === undefined) { - throw new ERR_INVALID_THIS("StringDecoder"); - } - return (this as InternalDecoder)[kNativeDecoder].subarray( - kIncompleteCharactersStart, - kIncompleteCharactersEnd - ) as Buffer; - }, - }, - lastNeed: { - enumerable: true, - get(this: StringDecoder): number { - if ((this as InternalDecoder)[kNativeDecoder] === undefined) { - throw new ERR_INVALID_THIS("StringDecoder"); - } - return (this as InternalDecoder)[kNativeDecoder][kMissingBytes]!; - }, - }, - lastTotal: { - enumerable: true, - get(this: StringDecoder): number { - if ((this as InternalDecoder)[kNativeDecoder] === undefined) { - throw new ERR_INVALID_THIS("StringDecoder"); - } - return ( - (this as InternalDecoder)[kNativeDecoder][kBufferedBytes]! + - (this as InternalDecoder)[kNativeDecoder][kMissingBytes]! - ); - }, - }, -}); - -export default { - StringDecoder, -}; diff --git a/JS/wasm/crates/wasmjs-engine/shims/src/internal/internal_types.ts b/JS/wasm/crates/wasmjs-engine/shims/src/internal/internal_types.ts deleted file mode 100644 index 5fd751258..000000000 --- a/JS/wasm/crates/wasmjs-engine/shims/src/internal/internal_types.ts +++ /dev/null @@ -1,96 +0,0 @@ -import * as internal from "./util"; - -export function isCryptoKey(value: unknown): boolean { - return value instanceof CryptoKey; -} - -export function isKeyObject(_value: unknown): boolean { - // TODO(nodecompat): We currently do not implement KeyObject - return false; -} - -export const isAsyncFunction = internal.isAsyncFunction.bind(internal); -export const isGeneratorFunction = internal.isGeneratorFunction.bind(internal); -export const isGeneratorObject = internal.isGeneratorObject.bind(internal); -export const isAnyArrayBuffer = internal.isAnyArrayBuffer.bind(internal); -export const isArrayBuffer = internal.isArrayBuffer.bind(internal); -export const isArgumentsObject = internal.isArgumentsObject.bind(internal); -export const isBoxedPrimitive = internal.isBoxedPrimitive.bind(internal); -export const isDataView = internal.isDataView.bind(internal); -export const isMap = internal.isMap.bind(internal); -export const isMapIterator = internal.isMapIterator.bind(internal); -export const isModuleNamespaceObject = internal.isModuleNamespaceObject.bind(internal); -export const isNativeError = internal.isNativeError.bind(internal); -export const isPromise = internal.isPromise.bind(internal); -export const isProxy = internal.isProxy.bind(internal); -export const isSet = internal.isSet.bind(internal); -export const isSetIterator = internal.isSetIterator.bind(internal); -export const isSharedArrayBuffer = internal.isSharedArrayBuffer.bind(internal); -export const isWeakMap = internal.isWeakMap.bind(internal); -export const isWeakSet = internal.isWeakSet.bind(internal); -export const isRegExp = internal.isRegExp.bind(internal); -export const isDate = internal.isDate.bind(internal); -export const isStringObject = internal.isStringObject.bind(internal); -export const isSymbolObject = internal.isSymbolObject.bind(internal); -export const isNumberObject = internal.isNumberObject.bind(internal); -export const isBooleanObject = internal.isBooleanObject.bind(internal); -export const isBigIntObject = internal.isBigIntObject.bind(internal); -export const isArrayBufferView = internal.isArrayBufferView.bind(internal); -export const isBigInt64Array = internal.isBigInt64Array.bind(internal); -export const isBigUint64Array = internal.isBigUint64Array.bind(internal); -export const isFloat32Array = internal.isFloat32Array.bind(internal); -export const isFloat64Array = internal.isFloat64Array.bind(internal); -export const isInt8Array = internal.isInt8Array.bind(internal); -export const isInt16Array = internal.isInt16Array.bind(internal); -export const isInt32Array = internal.isInt32Array.bind(internal); -export const isTypedArray = internal.isTypedArray.bind(internal); -export const isUint8Array = internal.isUint8Array.bind(internal); -export const isUint8ClampedArray = internal.isUint8ClampedArray.bind(internal); -export const isUint16Array = internal.isUint16Array.bind(internal); -export const isUint32Array = internal.isUint32Array.bind(internal); - -export default { - isCryptoKey, - isKeyObject, - - isAsyncFunction, - isGeneratorFunction, - isGeneratorObject, - isAnyArrayBuffer, - isArrayBuffer, - isArgumentsObject, - isBoxedPrimitive, - isDataView, - isMap, - isMapIterator, - isModuleNamespaceObject, - isNativeError, - isPromise, - isProxy, - isSet, - isSetIterator, - isSharedArrayBuffer, - isWeakMap, - isWeakSet, - isRegExp, - isDate, - isStringObject, - isSymbolObject, - isNumberObject, - isBooleanObject, - isBigIntObject, - isArrayBufferView, - isBigInt64Array, - isBigUint64Array, - isFloat32Array, - isFloat64Array, - isInt8Array, - isInt16Array, - isInt32Array, - isTypedArray, - isUint8Array, - isUint8ClampedArray, - isUint16Array, - isUint32Array, - // TODO(soon): isExternal -}; diff --git a/JS/wasm/crates/wasmjs-engine/shims/src/internal/internal_utils.ts b/JS/wasm/crates/wasmjs-engine/shims/src/internal/internal_utils.ts deleted file mode 100644 index 6cf8b3848..000000000 --- a/JS/wasm/crates/wasmjs-engine/shims/src/internal/internal_utils.ts +++ /dev/null @@ -1,167 +0,0 @@ -export function normalizeEncoding(enc?: string): string | undefined { - if (enc == null || enc === "utf8" || enc === "utf-8" || enc === "UTF8" || enc === "UTF-8") - return "utf8"; - return slowCases(enc); -} - -export function slowCases(enc: string): string | undefined { - switch (enc.length) { - case 4: - if (enc === "UTF8") return "utf8"; - if (enc === "ucs2" || enc === "UCS2") return "utf16le"; - enc = `${enc}`.toLowerCase(); - if (enc === "utf8") return "utf8"; - if (enc === "ucs2") return "utf16le"; - break; - case 3: - if (enc === "hex" || enc === "HEX" || `${enc}`.toLowerCase() === "hex") { - return "hex"; - } - break; - case 5: - if (enc === "ascii") return "ascii"; - if (enc === "ucs-2") return "utf16le"; - if (enc === "UTF-8") return "utf8"; - if (enc === "ASCII") return "ascii"; - if (enc === "UCS-2") return "utf16le"; - enc = `${enc}`.toLowerCase(); - if (enc === "utf-8") return "utf8"; - if (enc === "ascii") return "ascii"; - if (enc === "ucs-2") return "utf16le"; - break; - case 6: - if (enc === "base64") return "base64"; - if (enc === "latin1" || enc === "binary") return "latin1"; - if (enc === "BASE64") return "base64"; - if (enc === "LATIN1" || enc === "BINARY") return "latin1"; - enc = `${enc}`.toLowerCase(); - if (enc === "base64") return "base64"; - if (enc === "latin1" || enc === "binary") return "latin1"; - break; - case 7: - if (enc === "utf16le" || enc === "UTF16LE" || `${enc}`.toLowerCase() === "utf16le") { - return "utf16le"; - } - break; - case 8: - if (enc === "utf-16le" || enc === "UTF-16LE" || `${enc}`.toLowerCase() === "utf-16le") { - return "utf16le"; - } - break; - case 9: - if ( - enc === "base64url" || - enc === "BASE64URL" || - `${enc}`.toLowerCase() === "base64url" - ) { - return "base64url"; - } - break; - default: - if (enc === "") return "utf8"; - } - return undefined; -} - -export function spliceOne(list: (string | undefined)[], index: number) { - for (; index + 1 < list.length; index++) list[index] = list[index + 1]; - list.pop(); -} - -export const ALL_PROPERTIES = 0; -export const ONLY_WRITABLE = 1; -export const ONLY_ENUMERABLE = 2; -export const ONLY_CONFIGURABLE = 4; -export const ONLY_ENUM_WRITABLE = 6; -export const SKIP_STRINGS = 8; -export const SKIP_SYMBOLS = 16; - -const isNumericLookup: Record = {}; -export function isArrayIndex(value: unknown): value is number | string { - switch (typeof value) { - case "number": - return value >= 0 && (value | 0) === value; - case "string": { - const result = isNumericLookup[value]; - if (result !== void 0) { - return result; - } - const length = value.length; - if (length === 0) { - return (isNumericLookup[value] = false); - } - let ch = 0; - let i = 0; - for (; i < length; ++i) { - ch = value.charCodeAt(i); - if ( - (i === 0 && ch === 0x30 && length > 1) /* must not start with 0 */ || - ch < 0x30 /* 0 */ || - ch > 0x39 /* 9 */ - ) { - return (isNumericLookup[value] = false); - } - } - return (isNumericLookup[value] = true); - } - default: - return false; - } -} - -export function getOwnNonIndexProperties( - // deno-lint-ignore ban-types - obj: object, - filter: number -): (string | symbol)[] { - let allProperties = [...Object.getOwnPropertyNames(obj), ...Object.getOwnPropertySymbols(obj)]; - - if (Array.isArray(obj)) { - allProperties = allProperties.filter((k) => !isArrayIndex(k)); - } - - if (filter === ALL_PROPERTIES) { - return allProperties; - } - - const result: (string | symbol)[] = []; - for (const key of allProperties) { - const desc = Object.getOwnPropertyDescriptor(obj, key); - if (desc === undefined) { - continue; - } - if (filter & ONLY_WRITABLE && !desc.writable) { - continue; - } - if (filter & ONLY_ENUMERABLE && !desc.enumerable) { - continue; - } - if (filter & ONLY_CONFIGURABLE && !desc.configurable) { - continue; - } - if (filter & SKIP_STRINGS && typeof key === "string") { - continue; - } - if (filter & SKIP_SYMBOLS && typeof key === "symbol") { - continue; - } - result.push(key); - } - return result; -} - -export function createDeferredPromise() { - let resolve; - let reject; - - // eslint-disable-next-line promise/param-names - const promise = new Promise((res, rej) => { - resolve = res; - reject = rej; - }); - return { - promise, - resolve, - reject, - }; -} diff --git a/JS/wasm/crates/wasmjs-engine/shims/src/internal/process.ts b/JS/wasm/crates/wasmjs-engine/shims/src/internal/process.ts deleted file mode 100644 index 522a74ecd..000000000 --- a/JS/wasm/crates/wasmjs-engine/shims/src/internal/process.ts +++ /dev/null @@ -1,80 +0,0 @@ -import { validateObject } from "./validators"; - -import { ERR_INVALID_ARG_VALUE } from "./internal_errors"; - -export function nextTick(cb: Function, ...args: unknown[]) { - queueMicrotask(() => { - cb(...args); - }); -} - -// Note that there is no process-level environment in workers so the process.env -// object is initially empty. This is different from Node.js where process.env -// picks up values from the operating system environment. The configured bindings -// for the worker are accessible from the env argument passed into the fetch -// handler and have no impact here. - -export const env = new Proxy( - {}, - { - // Per Node.js rules. process.env values must be coerced to strings. - // When defined using defineProperty, the property descriptor must be writable, - // configurable, and enumerable using just a falsy check. Getters and setters - // are not permitted. - set(obj: object, prop: PropertyKey, value: any) { - return Reflect.set(obj, prop, `${value}`); - }, - defineProperty(obj: object, prop: PropertyKey, descriptor: PropertyDescriptor) { - validateObject(descriptor, "descriptor", {}); - if (Reflect.has(descriptor, "get") || Reflect.has(descriptor, "set")) { - throw new ERR_INVALID_ARG_VALUE( - "descriptor", - descriptor, - "process.env value must not have getter/setter" - ); - } - if (!descriptor.configurable) { - throw new ERR_INVALID_ARG_VALUE( - "descriptor.configurable", - descriptor, - "process.env value must be configurable" - ); - } - if (!descriptor.enumerable) { - throw new ERR_INVALID_ARG_VALUE( - "descriptor.enumerable", - descriptor, - "process.env value must be enumerable" - ); - } - if (!descriptor.writable) { - throw new ERR_INVALID_ARG_VALUE( - "descriptor.writable", - descriptor, - "process.env value must be writable" - ); - } - if (Reflect.has(descriptor, "value")) { - Reflect.set(descriptor, "value", `${descriptor.value}`); - } else { - throw new ERR_INVALID_ARG_VALUE( - "descriptor.value", - descriptor, - "process.env value must be specified explicitly" - ); - } - return Reflect.defineProperty(obj, prop, descriptor); - }, - } -); - -export const argv = []; - -export const platform = "wasm"; - -export default { - nextTick, - env, - argv, - platform, -}; diff --git a/JS/wasm/crates/wasmjs-engine/shims/src/internal/streams_adapters.js b/JS/wasm/crates/wasmjs-engine/shims/src/internal/streams_adapters.js deleted file mode 100644 index 819808333..000000000 --- a/JS/wasm/crates/wasmjs-engine/shims/src/internal/streams_adapters.js +++ /dev/null @@ -1,687 +0,0 @@ -/* eslint-disable */ -import { Readable } from "./streams_readable"; - -import { TextEncoder, TextDecoder } from "@sinonjs/text-encoding"; - -import { Writable } from "./streams_writable"; - -import { Duplex } from "./streams_duplex"; - -import { - destroy, - eos as finished, - isDestroyed, - isReadable, - isWritable, - isWritableEnded, -} from "./streams_util"; - -import { Buffer } from "./internal_buffer"; - -import { - ERR_INVALID_ARG_TYPE, - ERR_INVALID_ARG_VALUE, - ERR_STREAM_PREMATURE_CLOSE, - AbortError, -} from "./internal_errors"; - -import { createDeferredPromise, normalizeEncoding } from "./internal_utils"; - -import { validateBoolean, validateObject } from "./validators"; - -import * as process from "./process"; - -const encoder = new TextEncoder(); - -/** - * @param {Writable} streamWritable - * @returns {WritableStream} - */ -export function newWritableStreamFromStreamWritable(streamWritable) { - // Not using the internal/streams/utils isWritableNodeStream utility - // here because it will return false if streamWritable is a Duplex - // whose writable option is false. For a Duplex that is not writable, - // we want it to pass this check but return a closed WritableStream. - // We check if the given stream is a stream.Writable or http.OutgoingMessage - const checkIfWritableOrOutgoingMessage = - streamWritable && - typeof streamWritable?.write === "function" && - typeof streamWritable?.on === "function"; - if (!checkIfWritableOrOutgoingMessage) { - throw new ERR_INVALID_ARG_TYPE("streamWritable", "stream.Writable", streamWritable); - } - - if (isDestroyed(streamWritable) || !isWritable(streamWritable)) { - const writable = new WritableStream(); - writable.close(); - return writable; - } - - const highWaterMark = streamWritable.writableHighWaterMark; - const strategy = streamWritable.writableObjectMode - ? new CountQueuingStrategy({ highWaterMark }) - : { highWaterMark }; - - let controller; - let backpressurePromise; - let closed; - - function onDrain() { - if (backpressurePromise !== undefined) backpressurePromise.resolve(); - } - - const cleanup = finished(streamWritable, (error) => { - if (error?.code === "ERR_STREAM_PREMATURE_CLOSE") { - const err = new AbortError(undefined, { cause: error }); - error = err; - } - - cleanup(); - // This is a protection against non-standard, legacy streams - // that happen to emit an error event again after finished is called. - streamWritable.on("error", () => {}); - if (error != null) { - if (backpressurePromise !== undefined) backpressurePromise.reject(error); - // If closed is not undefined, the error is happening - // after the WritableStream close has already started. - // We need to reject it here. - if (closed !== undefined) { - closed.reject(error); - closed = undefined; - } - controller.error(error); - controller = undefined; - return; - } - - if (closed !== undefined) { - closed.resolve(); - closed = undefined; - return; - } - controller.error(new AbortError()); - controller = undefined; - }); - - streamWritable.on("drain", onDrain); - - return new WritableStream( - { - start(c) { - controller = c; - }, - - async write(chunk) { - if (streamWritable.writableNeedDrain || !streamWritable.write(chunk)) { - backpressurePromise = createDeferredPromise(); - return backpressurePromise.promise.finally(() => { - backpressurePromise = undefined; - }); - } - }, - - abort(reason) { - destroy(streamWritable, reason); - }, - - close() { - if (closed === undefined && !isWritableEnded(streamWritable)) { - closed = createDeferredPromise(); - streamWritable.end(); - return closed.promise; - } - - controller = undefined; - return Promise.resolve(); - }, - }, - strategy - ); -} - -/** - * @param {WritableStream} writableStream - * @param {{ - * decodeStrings? : boolean, - * highWaterMark? : number, - * objectMode? : boolean, - * signal? : AbortSignal, - * }} [options] - * @returns {Writable} - */ -export function newStreamWritableFromWritableStream(writableStream, options = {}) { - if (!(writableStream instanceof WritableStream)) { - throw new ERR_INVALID_ARG_TYPE("writableStream", "WritableStream", writableStream); - } - - validateObject(options, "options"); - const { highWaterMark, decodeStrings = true, objectMode = false, signal } = options; - - validateBoolean(objectMode, "options.objectMode"); - validateBoolean(decodeStrings, "options.decodeStrings"); - - const writer = writableStream.getWriter(); - let closed = false; - - const writable = new Writable({ - highWaterMark, - objectMode, - decodeStrings, - signal, - - writev(chunks, callback) { - function done(error) { - error = error.filter((e) => e); - try { - callback(error.length === 0 ? undefined : error); - } catch (error) { - // In a next tick because this is happening within - // a promise context, and if there are any errors - // thrown we don't want those to cause an unhandled - // rejection. Let's just escape the promise and - // handle it separately. - process.nextTick(() => destroy(writable, error)); - } - } - - writer.ready.then(() => { - return Promise.all(chunks.map((data) => writer.write(data))).then(done, done); - }, done); - }, - - write(chunk, encoding, callback) { - if (typeof chunk === "string" && decodeStrings && !objectMode) { - const enc = normalizeEncoding(encoding); - - if (enc === "utf8") { - chunk = encoder.encode(chunk); - } else { - chunk = Buffer.from(chunk, encoding); - chunk = new Uint8Array(chunk.buffer, chunk.byteOffset, chunk.byteLength); - } - } - - function done(error) { - try { - callback(error); - } catch (error) { - destroy(writable, error); - } - } - - writer.ready.then(() => { - return writer.write(chunk).then(done, done); - }, done); - }, - - destroy(error, callback) { - function done() { - try { - callback(error); - } catch (error) { - // In a next tick because this is happening within - // a promise context, and if there are any errors - // thrown we don't want those to cause an unhandled - // rejection. Let's just escape the promise and - // handle it separately. - process.nextTick(() => { - throw error; - }); - } - } - - if (!closed) { - if (error != null) { - writer.abort(error).then(done, done); - } else { - writer.close().then(done, done); - } - return; - } - - done(); - }, - - final(callback) { - function done(error) { - try { - callback(error); - } catch (error) { - // In a next tick because this is happening within - // a promise context, and if there are any errors - // thrown we don't want those to cause an unhandled - // rejection. Let's just escape the promise and - // handle it separately. - process.nextTick(() => destroy(writable, error)); - } - } - - if (!closed) { - writer.close().then(done, done); - } - }, - }); - - writer.closed.then( - () => { - // If the WritableStream closes before the stream.Writable has been - // ended, we signal an error on the stream.Writable. - closed = true; - if (!isWritableEnded(writable)) destroy(writable, new ERR_STREAM_PREMATURE_CLOSE()); - }, - (error) => { - // If the WritableStream errors before the stream.Writable has been - // destroyed, signal an error on the stream.Writable. - closed = true; - destroy(writable, error); - } - ); - - return writable; -} - -/** - * @typedef {import('./queuingstrategies').QueuingStrategy} QueuingStrategy - * @param {Readable} streamReadable - * @param {{ - * strategy : QueuingStrategy - * }} [options] - * @returns {ReadableStream} - */ -export function newReadableStreamFromStreamReadable(streamReadable, options = {}) { - // Not using the internal/streams/utils isReadableNodeStream utility - // here because it will return false if streamReadable is a Duplex - // whose readable option is false. For a Duplex that is not readable, - // we want it to pass this check but return a closed ReadableStream. - if (typeof streamReadable?._readableState !== "object") { - throw new ERR_INVALID_ARG_TYPE("streamReadable", "stream.Readable", streamReadable); - } - - if (isDestroyed(streamReadable) || !isReadable(streamReadable)) { - const readable = new ReadableStream(); - readable.cancel(); - return readable; - } - - const objectMode = streamReadable.readableObjectMode; - const highWaterMark = streamReadable.readableHighWaterMark; - - const evaluateStrategyOrFallback = (strategy) => { - // If there is a strategy available, use it - if (strategy) return strategy; - - if (objectMode) { - // When running in objectMode explicitly but no strategy, we just fall - // back to CountQueuingStrategy - return new CountQueuingStrategy({ highWaterMark }); - } - - // When not running in objectMode explicitly, we just fall - // back to a minimal strategy that just specifies the highWaterMark - // and no size algorithm. Using a ByteLengthQueuingStrategy here - // is unnecessary. - return { highWaterMark }; - }; - - const strategy = evaluateStrategyOrFallback(options?.strategy); - - let controller; - - function onData(chunk) { - // Copy the Buffer to detach it from the pool. - if (Buffer.isBuffer(chunk) && !objectMode) chunk = new Uint8Array(chunk); - controller.enqueue(chunk); - if (controller.desiredSize <= 0) streamReadable.pause(); - } - - streamReadable.pause(); - - const cleanup = finished(streamReadable, (error) => { - if (error?.code === "ERR_STREAM_PREMATURE_CLOSE") { - const err = new AbortError(undefined, { cause: error }); - error = err; - } - - cleanup(); - // This is a protection against non-standard, legacy streams - // that happen to emit an error event again after finished is called. - streamReadable.on("error", () => {}); - if (error) return controller.error(error); - controller.close(); - }); - - streamReadable.on("data", onData); - - return new ReadableStream( - { - start(c) { - controller = c; - }, - - pull() { - streamReadable.resume(); - }, - - cancel(reason) { - destroy(streamReadable, reason); - }, - }, - strategy - ); -} - -/** - * @param {ReadableStream} readableStream - * @param {{ - * highWaterMark? : number, - * encoding? : string, - * objectMode? : boolean, - * signal? : AbortSignal, - * }} [options] - * @returns {Readable} - */ -export function newStreamReadableFromReadableStream(readableStream, options = {}) { - if (!(readableStream instanceof ReadableStream)) { - throw new ERR_INVALID_ARG_TYPE("readableStream", "ReadableStream", readableStream); - } - - validateObject(options, "options"); - const { highWaterMark, encoding, objectMode = false, signal } = options; - - if (encoding !== undefined && !Buffer.isEncoding(encoding)) - throw new ERR_INVALID_ARG_VALUE(encoding, "options.encoding"); - validateBoolean(objectMode, "options.objectMode"); - - const reader = readableStream.getReader(); - let closed = false; - - const readable = new Readable({ - objectMode, - highWaterMark, - encoding, - signal, - - read() { - reader.read().then( - (chunk) => { - if (chunk.done) { - // Value should always be undefined here. - readable.push(null); - } else { - readable.push(chunk.value); - } - }, - (error) => destroy(readable, error) - ); - }, - - destroy(error, callback) { - function done() { - try { - callback(error); - } catch (error) { - // In a next tick because this is happening within - // a promise context, and if there are any errors - // thrown we don't want those to cause an unhandled - // rejection. Let's just escape the promise and - // handle it separately. - process.nextTick(() => { - throw error; - }); - } - } - - if (!closed) { - reader.cancel(error).then(done, done); - return; - } - done(); - }, - }); - - reader.closed.then( - () => { - closed = true; - }, - (error) => { - closed = true; - destroy(readable, error); - } - ); - - return readable; -} - -/** - * @typedef {import('./readablestream').ReadableWritablePair - * } ReadableWritablePair - * @typedef {import('../../stream').Duplex} Duplex - */ - -/** - * @param {Duplex} duplex - * @returns {ReadableWritablePair} - */ -export function newReadableWritablePairFromDuplex(duplex) { - // Not using the internal/streams/utils isWritableNodeStream and - // isReadableNodeStream utilities here because they will return false - // if the duplex was created with writable or readable options set to - // false. Instead, we'll check the readable and writable state after - // and return closed WritableStream or closed ReadableStream as - // necessary. - if (typeof duplex?._writableState !== "object" || typeof duplex?._readableState !== "object") { - throw new ERR_INVALID_ARG_TYPE("duplex", "stream.Duplex", duplex); - } - - if (isDestroyed(duplex)) { - const writable = new WritableStream(); - const readable = new ReadableStream(); - writable.close(); - readable.cancel(); - return { readable, writable }; - } - - const writable = isWritable(duplex) - ? newWritableStreamFromStreamWritable(duplex) - : new WritableStream(); - - if (!isWritable(duplex)) writable.close(); - - const readable = isReadable(duplex) - ? newReadableStreamFromStreamReadable(duplex) - : new ReadableStream(); - - if (!isReadable(duplex)) readable.cancel(); - - return { writable, readable }; -} - -/** - * @param {ReadableWritablePair} pair - * @param {{ - * allowHalfOpen? : boolean, - * decodeStrings? : boolean, - * encoding? : string, - * highWaterMark? : number, - * objectMode? : boolean, - * signal? : AbortSignal, - * }} [options] - * @returns {Duplex} - */ -export function newStreamDuplexFromReadableWritablePair(pair = {}, options = {}) { - validateObject(pair, "pair"); - const { readable: readableStream, writable: writableStream } = pair; - - if (!(readableStream instanceof ReadableStream)) { - throw new ERR_INVALID_ARG_TYPE("pair.readable", "ReadableStream", readableStream); - } - if (!(writableStream instanceof WritableStream)) { - throw new ERR_INVALID_ARG_TYPE("pair.writable", "WritableStream", writableStream); - } - - validateObject(options, "options"); - const { - allowHalfOpen = false, - objectMode = false, - encoding, - decodeStrings = true, - highWaterMark, - signal, - } = options; - - validateBoolean(objectMode, "options.objectMode"); - if (encoding !== undefined && !Buffer.isEncoding(encoding)) - throw new ERR_INVALID_ARG_VALUE(encoding, "options.encoding"); - - const writer = writableStream.getWriter(); - const reader = readableStream.getReader(); - let writableClosed = false; - let readableClosed = false; - - const duplex = new Duplex({ - allowHalfOpen, - highWaterMark, - objectMode, - encoding, - decodeStrings, - signal, - - writev(chunks, callback) { - function done(error) { - error = error.filter((e) => e); - try { - callback(error.length === 0 ? undefined : error); - } catch (error) { - // In a next tick because this is happening within - // a promise context, and if there are any errors - // thrown we don't want those to cause an unhandled - // rejection. Let's just escape the promise and - // handle it separately. - process.nextTick(() => destroy(duplex, error)); - } - } - - writer.ready.then(() => { - return Promise.all( - chunks.map((data) => { - return writer.write(data); - }) - ).then(done, done); - }, done); - }, - - write(chunk, encoding, callback) { - if (typeof chunk === "string" && decodeStrings && !objectMode) { - const enc = normalizeEncoding(encoding); - - if (enc === "utf8") { - chunk = encoder.encode(chunk); - } else { - chunk = Buffer.from(chunk, encoding); - chunk = new Uint8Array(chunk.buffer, chunk.byteOffset, chunk.byteLength); - } - } - - function done(error) { - try { - callback(error); - } catch (error) { - destroy(duplex, error); - } - } - - writer.ready.then(() => { - return writer.write(chunk).then(done, done); - }, done); - }, - - final(callback) { - function done(error) { - try { - callback(error); - } catch (error) { - // In a next tick because this is happening within - // a promise context, and if there are any errors - // thrown we don't want those to cause an unhandled - // rejection. Let's just escape the promise and - // handle it separately. - process.nextTick(() => destroy(duplex, error)); - } - } - - if (!writableClosed) { - writer.close().then(done, done); - } - }, - - read() { - reader.read().then( - (chunk) => { - if (chunk.done) { - duplex.push(null); - } else { - duplex.push(chunk.value); - } - }, - (error) => destroy(duplex, error) - ); - }, - - destroy(error, callback) { - function done() { - try { - callback(error); - } catch (error) { - // In a next tick because this is happening within - // a promise context, and if there are any errors - // thrown we don't want those to cause an unhandled - // rejection. Let's just escape the promise and - // handle it separately. - process.nextTick(() => { - throw error; - }); - } - } - - async function closeWriter() { - if (!writableClosed) await writer.abort(error); - } - - async function closeReader() { - if (!readableClosed) await reader.cancel(error); - } - - if (!writableClosed || !readableClosed) { - Promise.all([closeWriter(), closeReader()]).then(done, done); - return; - } - - done(); - }, - }); - - writer.closed.then( - () => { - writableClosed = true; - if (!isWritableEnded(duplex)) destroy(duplex, new ERR_STREAM_PREMATURE_CLOSE()); - }, - (error) => { - writableClosed = true; - readableClosed = true; - destroy(duplex, error); - } - ); - - reader.closed.then( - () => { - readableClosed = true; - }, - (error) => { - writableClosed = true; - readableClosed = true; - destroy(duplex, error); - } - ); - - return duplex; -} diff --git a/JS/wasm/crates/wasmjs-engine/shims/src/internal/streams_duplex.js b/JS/wasm/crates/wasmjs-engine/shims/src/internal/streams_duplex.js deleted file mode 100644 index 61439b173..000000000 --- a/JS/wasm/crates/wasmjs-engine/shims/src/internal/streams_duplex.js +++ /dev/null @@ -1,475 +0,0 @@ -import { Readable, from } from "./streams_readable"; - -import { Writable } from "./streams_writable"; - -import { - newStreamDuplexFromReadableWritablePair, - newReadableWritablePairFromDuplex, -} from "./streams_adapters"; - -import { createDeferredPromise } from "./internal_utils"; - -import * as process from "./process"; - -import { - destroyer, - eos, - isReadable, - isWritable, - isIterable, - isNodeStream, - isReadableNodeStream, - isWritableNodeStream, - isDuplexNodeStream, -} from "./streams_util"; - -import { AbortError, ERR_INVALID_ARG_TYPE, ERR_INVALID_RETURN_VALUE } from "./internal_errors"; - -Object.setPrototypeOf(Duplex.prototype, Readable.prototype); -Object.setPrototypeOf(Duplex, Readable); -{ - const keys = Object.keys(Writable.prototype); - // Allow the keys array to be GC'ed. - for (let i = 0; i < keys.length; i++) { - const method = keys[i]; - if (!Duplex.prototype[method]) Duplex.prototype[method] = Writable.prototype[method]; - } -} - -export function isDuplexInstance(obj) { - return obj instanceof Duplex; -} - -export function Duplex(options) { - if (!(this instanceof Duplex)) return new Duplex(options); - Readable.call(this, options); - Writable.call(this, options); - if (options) { - this.allowHalfOpen = options.allowHalfOpen !== false; - if (options.readable === false) { - this._readableState.readable = false; - this._readableState.ended = true; - this._readableState.endEmitted = true; - } - if (options.writable === false) { - this._writableState.writable = false; - this._writableState.ending = true; - this._writableState.ended = true; - this._writableState.finished = true; - } - } else { - this.allowHalfOpen = true; - } -} -Object.defineProperties(Duplex.prototype, { - writable: { - ...Object.getOwnPropertyDescriptor(Writable.prototype, "writable"), - }, - writableHighWaterMark: { - ...Object.getOwnPropertyDescriptor(Writable.prototype, "writableHighWaterMark"), - }, - writableObjectMode: { - ...Object.getOwnPropertyDescriptor(Writable.prototype, "writableObjectMode"), - }, - writableBuffer: { - ...Object.getOwnPropertyDescriptor(Writable.prototype, "writableBuffer"), - }, - writableLength: { - ...Object.getOwnPropertyDescriptor(Writable.prototype, "writableLength"), - }, - writableFinished: { - ...Object.getOwnPropertyDescriptor(Writable.prototype, "writableFinished"), - }, - writableCorked: { - ...Object.getOwnPropertyDescriptor(Writable.prototype, "writableCorked"), - }, - writableEnded: { - ...Object.getOwnPropertyDescriptor(Writable.prototype, "writableEnded"), - }, - writableNeedDrain: { - ...Object.getOwnPropertyDescriptor(Writable.prototype, "writableNeedDrain"), - }, - destroyed: { - get() { - if (this._readableState === undefined || this._writableState === undefined) { - return false; - } - return this._readableState.destroyed && this._writableState.destroyed; - }, - set(value) { - // Backward compatibility, the user is explicitly - // managing destroyed. - if (this._readableState && this._writableState) { - this._readableState.destroyed = value; - this._writableState.destroyed = value; - } - }, - }, -}); - -Duplex.fromWeb = function (pair, options) { - return newStreamDuplexFromReadableWritablePair(pair, options); -}; -Duplex.toWeb = function (duplex) { - return newReadableWritablePairFromDuplex(duplex); -}; - -// ====================================================================================== - -Duplex.from = function (body) { - return duplexify(body, "body"); -}; - -function isBlob(b) { - return b instanceof Blob; -} - -// This is needed for pre node 17. -class Duplexify extends Duplex { - constructor(options) { - super(options); - // https://github.com/nodejs/node/pull/34385 - - if ((options === null || options === undefined ? undefined : options.readable) === false) { - this["_readableState"].readable = false; - this["_readableState"].ended = true; - this["_readableState"].endEmitted = true; - } - if ((options === null || options === undefined ? undefined : options.writable) === false) { - this["_readableState"].writable = false; - this["_readableState"].ending = true; - this["_readableState"].ended = true; - this["_readableState"].finished = true; - } - } -} - -function duplexify(body, name) { - if (isDuplexNodeStream(body)) { - return body; - } - if (isReadableNodeStream(body)) { - return _duplexify({ - readable: body, - }); - } - if (isWritableNodeStream(body)) { - return _duplexify({ - writable: body, - }); - } - if (isNodeStream(body)) { - return _duplexify({ - writable: false, - readable: false, - }); - } - - // TODO: Webstreams - // if (isReadableStream(body)) { - // return _duplexify({ readable: Readable.fromWeb(body) }); - // } - - // TODO: Webstreams - // if (isWritableStream(body)) { - // return _duplexify({ writable: Writable.fromWeb(body) }); - // } - - if (typeof body === "function") { - const { value, write, final, destroy } = fromAsyncGen(body); - if (isIterable(value)) { - return from(Duplexify, value, { - // TODO (ronag): highWaterMark? - objectMode: true, - write, - final, - destroy, - }); - } - const then = value.then; - if (typeof then === "function") { - let d; - const promise = Reflect.apply(then, value, [ - (val) => { - if (val != null) { - throw new ERR_INVALID_RETURN_VALUE("nully", "body", val); - } - }, - (err) => { - destroyer(d, err); - }, - ]); - - return (d = new Duplexify({ - // TODO (ronag): highWaterMark? - objectMode: true, - readable: false, - write, - final(cb) { - final(async () => { - try { - await promise; - process.nextTick(cb, null); - } catch (err) { - process.nextTick(cb, err); - } - }); - }, - destroy, - })); - } - throw new ERR_INVALID_RETURN_VALUE("Iterable, AsyncIterable or AsyncFunction", name, value); - } - if (isBlob(body)) { - return duplexify(body.arrayBuffer(), name); - } - if (isIterable(body)) { - return from(Duplexify, body, { - // TODO (ronag): highWaterMark? - objectMode: true, - writable: false, - }); - } - - // TODO: Webstreams. - // if ( - // isReadableStream(body?.readable) && - // isWritableStream(body?.writable) - // ) { - // return Duplexify.fromWeb(body); - // } - - if ( - typeof (body === null || body === undefined ? undefined : body.writable) === "object" || - typeof (body === null || body === undefined ? undefined : body.readable) === "object" - ) { - const readable = - body !== null && body !== undefined && body.readable - ? isReadableNodeStream( - body === null || body === undefined ? undefined : body.readable - ) - ? body === null || body === undefined - ? undefined - : body.readable - : duplexify(body.readable, name) - : undefined; - const writable = - body !== null && body !== undefined && body.writable - ? isWritableNodeStream( - body === null || body === undefined ? undefined : body.writable - ) - ? body === null || body === undefined - ? undefined - : body.writable - : duplexify(body.writable, name) - : undefined; - return _duplexify({ - readable, - writable, - }); - } - const then = body?.then; - if (typeof then === "function") { - let d; - Reflect.apply(then, body, [ - (val) => { - if (val != null) { - d.push(val); - } - d.push(null); - }, - (err) => { - destroyer(d, err); - }, - ]); - - return (d = new Duplexify({ - objectMode: true, - writable: false, - read() {}, - })); - } - throw new ERR_INVALID_ARG_TYPE( - name, - [ - "Blob", - "ReadableStream", - "WritableStream", - "Stream", - "Iterable", - "AsyncIterable", - "Function", - "{ readable, writable } pair", - "Promise", - ], - body - ); -} - -function fromAsyncGen(fn) { - let { promise, resolve } = createDeferredPromise(); - const ac = new AbortController(); - const signal = ac.signal; - const value = fn( - (async function* () { - while (true) { - const _promise = promise; - promise = null; - const { chunk, done, cb } = await _promise; - process.nextTick(cb); - if (done) return; - if (signal.aborted) - throw new AbortError(undefined, { - cause: signal.reason, - }); - ({ promise, resolve } = createDeferredPromise()); - yield chunk; - } - })(), - { - signal, - } - ); - return { - value, - write(chunk, _encoding, cb) { - const _resolve = resolve; - resolve = null; - _resolve({ - chunk, - done: false, - cb, - }); - }, - final(cb) { - const _resolve = resolve; - resolve = null; - _resolve({ - done: true, - cb, - }); - }, - destroy(err, cb) { - ac.abort(); - cb(err); - }, - }; -} - -function _duplexify(pair) { - const r = - pair.readable && typeof pair.readable.read !== "function" - ? Readable.wrap(pair.readable) - : pair.readable; - const w = pair.writable; - let readable = !!isReadable(r); - let writable = !!isWritable(w); - let ondrain; - let onfinish; - let onreadable; - let onclose; - let d; - function onfinished(err) { - const cb = onclose; - onclose = null; - if (cb) { - cb(err); - } else if (err) { - d.destroy(err); - } else if (!readable && !writable) { - d.destroy(); - } - } - - // TODO(ronag): Avoid double buffering. - // Implement Writable/Readable/Duplex traits. - // See, https://github.com/nodejs/node/pull/33515. - d = new Duplexify({ - // TODO (ronag): highWaterMark? - readableObjectMode: !!(r !== null && r !== undefined && r.readableObjectMode), - writableObjectMode: !!(w !== null && w !== undefined && w.writableObjectMode), - readable, - writable, - }); - if (writable) { - eos(w, (err) => { - writable = false; - if (err) { - destroyer(r, err); - } - onfinished(err); - }); - d._write = function (chunk, encoding, callback) { - if (w.write(chunk, encoding)) { - callback(); - } else { - ondrain = callback; - } - }; - d._final = function (callback) { - w.end(); - onfinish = callback; - }; - w.on("drain", function () { - if (ondrain) { - const cb = ondrain; - ondrain = null; - cb(); - } - }); - w.on("finish", function () { - if (onfinish) { - const cb = onfinish; - onfinish = null; - cb(); - } - }); - } - if (readable) { - eos(r, (err) => { - readable = false; - if (err) { - destroyer(r, err); - } - onfinished(err); - }); - r.on("readable", function () { - if (onreadable) { - const cb = onreadable; - onreadable = null; - cb(); - } - }); - r.on("end", function () { - d.push(null); - }); - d._read = function () { - while (true) { - const buf = r.read(); - if (buf === null) { - onreadable = d._read; - return; - } - if (!d.push(buf)) { - return; - } - } - }; - } - d._destroy = function (err, callback) { - if (!err && onclose !== null) { - err = new AbortError(); - } - onreadable = null; - ondrain = null; - onfinish = null; - if (onclose === null) { - callback(err); - } else { - onclose = callback; - destroyer(w, err); - destroyer(r, err); - } - }; - return d; -} diff --git a/JS/wasm/crates/wasmjs-engine/shims/src/internal/streams_legacy.js b/JS/wasm/crates/wasmjs-engine/shims/src/internal/streams_legacy.js deleted file mode 100644 index 1f859aae7..000000000 --- a/JS/wasm/crates/wasmjs-engine/shims/src/internal/streams_legacy.js +++ /dev/null @@ -1,83 +0,0 @@ -import EventEmitter from "./events"; - -import { Buffer } from "./internal_buffer"; - -export function Stream(opts) { - EventEmitter.call(this, opts || {}); -} - -Object.setPrototypeOf(Stream.prototype, EventEmitter.prototype); -Object.setPrototypeOf(Stream, EventEmitter); - -Stream.prototype.pipe = function (dest, options) { - const source = this; - function ondata(chunk) { - if (dest.writable && dest.write(chunk) === false && source.pause) { - source.pause(); - } - } - source.on("data", ondata); - function ondrain() { - if (source.readable && source.resume) { - source.resume(); - } - } - dest.on("drain", ondrain); - - // If the 'end' option is not supplied, dest.end() will be called when - // source gets the 'end' or 'close' events. Only dest.end() once. - if (!dest._isStdio && (!options || options.end !== false)) { - source.on("end", onend); - source.on("close", onclose); - } - let didOnEnd = false; - function onend() { - if (didOnEnd) return; - didOnEnd = true; - dest.end(); - } - function onclose() { - if (didOnEnd) return; - didOnEnd = true; - if (typeof dest.destroy === "function") dest.destroy(); - } - - // Don't leave dangling pipes when there are errors. - function onerror(er) { - cleanup(); - if (EventEmitter.listenerCount(this, "error") === 0) { - this.emit("error", er); - } - } - source.prependListener("error", onerror); - dest.prependListener("error", onerror); - - // Remove all the event listeners that were added. - function cleanup() { - source.removeListener("data", ondata); - dest.removeListener("drain", ondrain); - source.removeListener("end", onend); - source.removeListener("close", onclose); - source.removeListener("error", onerror); - dest.removeListener("error", onerror); - source.removeListener("end", cleanup); - source.removeListener("close", cleanup); - dest.removeListener("close", cleanup); - } - source.on("end", cleanup); - source.on("close", cleanup); - dest.on("close", cleanup); - dest.emit("pipe", source); - - // Allow for unix-like usage: A.pipe(B).pipe(C) - return dest; -}; - -// Backwards-compat with node 0.4.x -Stream.Stream = Stream; -Stream._isUint8Array = function isUint8Array(value) { - return value instanceof Uint8Array; -}; -Stream._uint8ArrayToBuffer = function _uint8ArrayToBuffer(chunk) { - return Buffer.from(chunk.buffer, chunk.byteOffset, chunk.byteLength); -}; diff --git a/JS/wasm/crates/wasmjs-engine/shims/src/internal/streams_readable.js b/JS/wasm/crates/wasmjs-engine/shims/src/internal/streams_readable.js deleted file mode 100644 index af1d687b6..000000000 --- a/JS/wasm/crates/wasmjs-engine/shims/src/internal/streams_readable.js +++ /dev/null @@ -1,1767 +0,0 @@ -/* eslint-disable */ - -import { - nop, - getHighWaterMark, - getDefaultHighWaterMark, - kPaused, - addAbortSignal, - BufferList, - eos, - construct, - destroy, - destroyer, - undestroy, - errorOrDestroy, - finished, -} from "./streams_util"; - -import * as process from "./process"; - -import EventEmitter from "./events"; - -import { Stream } from "./streams_legacy"; - -import { - newStreamReadableFromReadableStream, - newReadableStreamFromStreamReadable, -} from "./streams_adapters"; - -import { Buffer } from "./internal_buffer"; - -import { - AbortError, - aggregateTwoErrors, - ERR_INVALID_ARG_TYPE, - ERR_METHOD_NOT_IMPLEMENTED, - ERR_MISSING_ARGS, - ERR_OUT_OF_RANGE, - ERR_STREAM_PUSH_AFTER_EOF, - ERR_STREAM_UNSHIFT_AFTER_END_EVENT, - ERR_STREAM_NULL_VALUES, -} from "./internal_errors"; - -import { validateObject, validateAbortSignal, validateInteger } from "./validators"; - -import { StringDecoder } from "./internal_stringdecoder"; - -import { isDuplexInstance } from "./streams_duplex"; - -// ====================================================================================== -// ReadableState - -function ReadableState(options, stream, isDuplex) { - // Duplex streams are both readable and writable, but share - // the same options object. - // However, some cases require setting options to different - // values for the readable and the writable sides of the duplex stream. - // These options can be provided separately as readableXXX and writableXXX. - if (typeof isDuplex !== "boolean") isDuplex = isDuplexInstance(stream); - - // Object stream flag. Used to make read(n) ignore n and to - // make all the buffer merging and length checks go away. - this.objectMode = !!options?.objectMode; - if (isDuplex) this.objectMode = this.objectMode || !!options?.readableObjectMode; - - // The point at which it stops calling _read() to fill the buffer - // Note: 0 is a valid value, means "don't call _read preemptively ever" - this.highWaterMark = options - ? getHighWaterMark(this, options, "readableHighWaterMark", isDuplex) - : getDefaultHighWaterMark(false); - - // A linked list is used to store data chunks instead of an array because the - // linked list can remove elements from the beginning faster than - // array.shift(). - this.buffer = new BufferList(); - this.length = 0; - this.pipes = []; - this.flowing = null; - this.ended = false; - this.endEmitted = false; - this.reading = false; - - // Stream is still being constructed and cannot be - // destroyed until construction finished or failed. - // Async construction is opt in, therefore we start as - // constructed. - this.constructed = true; - - // A flag to be able to tell if the event 'readable'/'data' is emitted - // immediately, or on a later tick. We set this to true at first, because - // any actions that shouldn't happen until "later" should generally also - // not happen before the first read call. - this.sync = true; - - // Whenever we return null, then we set a flag to say - // that we're awaiting a 'readable' event emission. - this.needReadable = false; - this.emittedReadable = false; - this.readableListening = false; - this.resumeScheduled = false; - this[kPaused] = null; - - // True if the error was already emitted and should not be thrown again. - this.errorEmitted = false; - - // Should close be emitted on destroy. Defaults to true. - this.emitClose = !options || options.emitClose !== false; - - // Should .destroy() be called after 'end' (and potentially 'finish'). - this.autoDestroy = !options || options.autoDestroy !== false; - - // Has it been destroyed. - this.destroyed = false; - - // Indicates whether the stream has errored. When true no further - // _read calls, 'data' or 'readable' events should occur. This is needed - // since when autoDestroy is disabled we need a way to tell whether the - // stream has failed. - this.errored = null; - - // Indicates whether the stream has finished destroying. - this.closed = false; - - // True if close has been emitted or would have been emitted - // depending on emitClose. - this.closeEmitted = false; - - // Crypto is kind of old and crusty. Historically, its default string - // encoding is 'binary' so we have to make this configurable. - // Everything else in the universe uses 'utf8', though. - this.defaultEncoding = options?.defaultEncoding || "utf8"; - - // Ref the piped dest which we need a drain event on it - // type: null | Writable | Set. - this.awaitDrainWriters = null; - this.multiAwaitDrain = false; - - // If true, a maybeReadMore has been scheduled. - this.readingMore = false; - this.dataEmitted = false; - this.decoder = null; - this.encoding = null; - if (options && options.encoding) { - this.decoder = new StringDecoder(options.encoding); - this.encoding = options.encoding; - } -} - -// ====================================================================================== -// Readable - -Readable.ReadableState = ReadableState; - -Object.setPrototypeOf(Readable.prototype, Stream.prototype); -Object.setPrototypeOf(Readable, Stream); - -export function Readable(options) { - if (!(this instanceof Readable)) return new Readable(options); - - // Checking for a Stream.Duplex instance is faster here instead of inside - // the ReadableState constructor, at least with V8 6.5. - const isDuplex = isDuplexInstance(this); - this._readableState = new ReadableState(options, this, isDuplex); - if (options) { - if (typeof options.read === "function") this._read = options.read; - if (typeof options.destroy === "function") this._destroy = options.destroy; - if (typeof options.construct === "function") this._construct = options.construct; - if (options.signal && !isDuplex) addAbortSignal(options.signal, this); - } - Stream.call(this, options); - construct(this, () => { - if (this._readableState.needReadable) { - maybeReadMore(this, this._readableState); - } - }); -} -Readable.prototype.destroy = destroy; -Readable.prototype._undestroy = undestroy; -Readable.prototype._destroy = function (err, cb) { - if (cb) cb(err); -}; - -Readable.prototype[EventEmitter.captureRejectionSymbol] = function (err) { - this.destroy(err); -}; - -// Manually shove something into the read() buffer. -// This returns true if the highWaterMark has not been hit yet, -// similar to how Writable.write() returns true if you should -// write() some more. -Readable.prototype.push = function (chunk, encoding) { - return readableAddChunk(this, chunk, encoding, false); -}; - -// Unshift should *always* be something directly out of read(). -Readable.prototype.unshift = function (chunk, encoding) { - return readableAddChunk(this, chunk, encoding, true); -}; - -function readableAddChunk(stream, chunk, encoding, addToFront) { - const state = stream._readableState; - let err; - if (!state.objectMode) { - if (typeof chunk === "string") { - encoding ||= state.defaultEncoding; - if (state.encoding !== encoding) { - if (addToFront && state.encoding) { - // When unshifting, if state.encoding is set, we have to save - // the string in the BufferList with the state encoding. - chunk = Buffer.from(chunk, encoding).toString(state.encoding); - } else { - chunk = Buffer.from(chunk, encoding); - encoding = ""; - } - } - } else if (chunk instanceof Buffer) { - encoding = ""; - } else if (Stream._isUint8Array(chunk)) { - chunk = Stream._uint8ArrayToBuffer(chunk); - encoding = ""; - } else if (chunk != null) { - err = new ERR_INVALID_ARG_TYPE("chunk", ["string", "Buffer", "Uint8Array"], chunk); - } - } - if (err) { - errorOrDestroy(stream, err); - } else if (chunk === null) { - state.reading = false; - onEofChunk(stream, state); - } else if (state.objectMode || (chunk && chunk.length > 0)) { - if (addToFront) { - if (state.endEmitted) errorOrDestroy(stream, new ERR_STREAM_UNSHIFT_AFTER_END_EVENT()); - else if (state.destroyed || state.errored) return false; - else addChunk(stream, state, chunk, true); - } else if (state.ended) { - errorOrDestroy(stream, new ERR_STREAM_PUSH_AFTER_EOF()); - } else if (state.destroyed || state.errored) { - return false; - } else { - state.reading = false; - if (state.decoder && !encoding) { - chunk = state.decoder.write(chunk); - if (state.objectMode || chunk.length !== 0) addChunk(stream, state, chunk, false); - else maybeReadMore(stream, state); - } else { - addChunk(stream, state, chunk, false); - } - } - } else if (!addToFront) { - state.reading = false; - maybeReadMore(stream, state); - } - - // We can push more data if we are below the highWaterMark. - // Also, if we have no data yet, we can stand some more bytes. - // This is to work around cases where hwm=0, such as the repl. - return !state.ended && (state.length < state.highWaterMark || state.length === 0); -} - -function addChunk(stream, state, chunk, addToFront) { - if (state.flowing && state.length === 0 && !state.sync && stream.listenerCount("data") > 0) { - // Use the guard to avoid creating `Set()` repeatedly - // when we have multiple pipes. - if (state.multiAwaitDrain) { - state.awaitDrainWriters.clear(); - } else { - state.awaitDrainWriters = null; - state.multiAwaitDrain = false; - } - state.dataEmitted = true; - stream.emit("data", chunk); - } else { - // Update the buffer info. - state.length += state.objectMode ? 1 : chunk.length; - if (addToFront) state.buffer.unshift(chunk); - else state.buffer.push(chunk); - if (state.needReadable) emitReadable(stream); - } - maybeReadMore(stream, state); -} - -Readable.prototype.isPaused = function () { - const state = this._readableState; - return state[kPaused] === true || state.flowing === false; -}; - -// Backwards compatibility. -Readable.prototype.setEncoding = function (enc) { - const decoder = new StringDecoder(enc); - this._readableState.decoder = decoder; - // If setEncoding(null), decoder.encoding equals utf8. - this._readableState.encoding = decoder.encoding; - const buffer = this._readableState.buffer; - // Iterate over current buffer to convert already stored Buffers: - let content = ""; - for (const data of buffer) { - content += decoder.write(data); - } - buffer.clear(); - if (content !== "") buffer.push(content); - this._readableState.length = content.length; - return this; -}; - -// Don't raise the hwm > 1GB. -const MAX_HWM = 0x40000000; -function computeNewHighWaterMark(n) { - if (n > MAX_HWM) { - throw new ERR_OUT_OF_RANGE("size", "<= 1GiB", n); - } else { - // Get the next highest power of 2 to prevent increasing hwm excessively in - // tiny amounts. - n--; - n |= n >>> 1; - n |= n >>> 2; - n |= n >>> 4; - n |= n >>> 8; - n |= n >>> 16; - n++; - } - return n; -} - -// This function is designed to be inlinable, so please take care when making -// changes to the function body. -function howMuchToRead(n, state) { - if (n <= 0 || (state.length === 0 && state.ended)) return 0; - if (state.objectMode) return 1; - if (Number.isNaN(n)) { - // Only flow one buffer at a time. - if (state.flowing && state.length) return state.buffer.first().length; - return state.length; - } - if (n <= state.length) return n; - return state.ended ? state.length : 0; -} - -// You can override either this method, or the async _read(n) below. -Readable.prototype.read = function (n) { - // Same as parseInt(undefined, 10), however V8 7.3 performance regressed - // in this scenario, so we are doing it manually. - if (n === undefined) { - n = NaN; - } else if (!Number.isInteger(n)) { - n = Number.parseInt(`${n}`, 10); - } - const state = this._readableState; - const nOrig = n; - - // If we're asking for more than the current hwm, then raise the hwm. - if (n > state.highWaterMark) state.highWaterMark = computeNewHighWaterMark(n); - if (n !== 0) state.emittedReadable = false; - - // If we're doing read(0) to trigger a readable event, but we - // already have a bunch of data in the buffer, then just trigger - // the 'readable' event and move on. - if ( - n === 0 && - state.needReadable && - ((state.highWaterMark !== 0 ? state.length >= state.highWaterMark : state.length > 0) || - state.ended) - ) { - if (state.length === 0 && state.ended) endReadable(this); - else emitReadable(this); - return null; - } - n = howMuchToRead(n, state); - - // If we've ended, and we're now clear, then finish it up. - if (n === 0 && state.ended) { - if (state.length === 0) endReadable(this); - return null; - } - - // All the actual chunk generation logic needs to be - // *below* the call to _read. The reason is that in certain - // synthetic stream cases, such as passthrough streams, _read - // may be a completely synchronous operation which may change - // the state of the read buffer, providing enough data when - // before there was *not* enough. - // - // So, the steps are: - // 1. Figure out what the state of things will be after we do - // a read from the buffer. - // - // 2. If that resulting state will trigger a _read, then call _read. - // Note that this may be asynchronous, or synchronous. Yes, it is - // deeply ugly to write APIs this way, but that still doesn't mean - // that the Readable class should behave improperly, as streams are - // designed to be sync/async agnostic. - // Take note if the _read call is sync or async (ie, if the read call - // has returned yet), so that we know whether or not it's safe to emit - // 'readable' etc. - // - // 3. Actually pull the requested chunks out of the buffer and return. - - // if we need a readable event, then we need to do some reading. - let doRead = state.needReadable; - - // If we currently have less than the highWaterMark, then also read some. - if (state.length === 0 || state.length - n < state.highWaterMark) { - doRead = true; - } - - // However, if we've ended, then there's no point, if we're already - // reading, then it's unnecessary, if we're constructing we have to wait, - // and if we're destroyed or errored, then it's not allowed, - if (state.ended || state.reading || state.destroyed || state.errored || !state.constructed) { - doRead = false; - } else if (doRead) { - state.reading = true; - state.sync = true; - // If the length is currently zero, then we *need* a readable event. - if (state.length === 0) state.needReadable = true; - - // Call internal read method - try { - this._read(state.highWaterMark); - } catch (err) { - errorOrDestroy(this, err); - } - state.sync = false; - // If _read pushed data synchronously, then `reading` will be false, - // and we need to re-evaluate how much data we can return to the user. - if (!state.reading) n = howMuchToRead(nOrig, state); - } - let ret; - if (n > 0) ret = fromList(n, state); - else ret = null; - if (ret === null) { - state.needReadable = state.length <= state.highWaterMark; - n = 0; - } else { - state.length -= n; - if (state.multiAwaitDrain) { - state.awaitDrainWriters.clear(); - } else { - state.awaitDrainWriters = null; - state.multiAwaitDrain = false; - } - } - if (state.length === 0) { - // If we have nothing in the buffer, then we want to know - // as soon as we *do* get something into the buffer. - if (!state.ended) state.needReadable = true; - - // If we tried to read() past the EOF, then emit end on the next tick. - if (nOrig !== n && state.ended) endReadable(this); - } - if (ret !== null && !state.errorEmitted && !state.closeEmitted) { - state.dataEmitted = true; - this.emit("data", ret); - } - return ret; -}; - -function onEofChunk(stream, state) { - if (state.ended) return; - if (state.decoder) { - const chunk = state.decoder.end(); - if (chunk && chunk.length) { - state.buffer.push(chunk); - state.length += state.objectMode ? 1 : chunk.length; - } - } - state.ended = true; - if (state.sync) { - // If we are sync, wait until next tick to emit the data. - // Otherwise we risk emitting data in the flow() - // the readable code triggers during a read() call. - emitReadable(stream); - } else { - // Emit 'readable' now to make sure it gets picked up. - state.needReadable = false; - state.emittedReadable = true; - // We have to emit readable now that we are EOF. Modules - // in the ecosystem (e.g. dicer) rely on this event being sync. - emitReadable_(stream); - } -} - -// Don't emit readable right away in sync mode, because this can trigger -// another read() call => stack overflow. This way, it might trigger -// a nextTick recursion warning, but that's not so bad. -function emitReadable(stream) { - const state = stream._readableState; - state.needReadable = false; - if (!state.emittedReadable) { - state.emittedReadable = true; - process.nextTick(emitReadable_, stream); - } -} - -function emitReadable_(stream) { - const state = stream._readableState; - if (!state.destroyed && !state.errored && (state.length || state.ended)) { - stream.emit("readable"); - state.emittedReadable = false; - } - - // The stream needs another readable event if: - // 1. It is not flowing, as the flow mechanism will take - // care of it. - // 2. It is not ended. - // 3. It is below the highWaterMark, so we can schedule - // another readable later. - state.needReadable = !state.flowing && !state.ended && state.length <= state.highWaterMark; - flow(stream); -} - -// At this point, the user has presumably seen the 'readable' event, -// and called read() to consume some data. that may have triggered -// in turn another _read(n) call, in which case reading = true if -// it's in progress. -// However, if we're not ended, or reading, and the length < hwm, -// then go ahead and try to read some more preemptively. -function maybeReadMore(stream, state) { - if (!state.readingMore && state.constructed) { - state.readingMore = true; - process.nextTick(maybeReadMore_, stream, state); - } -} - -function maybeReadMore_(stream, state) { - // Attempt to read more data if we should. - // - // The conditions for reading more data are (one of): - // - Not enough data buffered (state.length < state.highWaterMark). The loop - // is responsible for filling the buffer with enough data if such data - // is available. If highWaterMark is 0 and we are not in the flowing mode - // we should _not_ attempt to buffer any extra data. We'll get more data - // when the stream consumer calls read() instead. - // - No data in the buffer, and the stream is in flowing mode. In this mode - // the loop below is responsible for ensuring read() is called. Failing to - // call read here would abort the flow and there's no other mechanism for - // continuing the flow if the stream consumer has just subscribed to the - // 'data' event. - // - // In addition to the above conditions to keep reading data, the following - // conditions prevent the data from being read: - // - The stream has ended (state.ended). - // - There is already a pending 'read' operation (state.reading). This is a - // case where the stream has called the implementation defined _read() - // method, but they are processing the call asynchronously and have _not_ - // called push() with new data. In this case we skip performing more - // read()s. The execution ends in this method again after the _read() ends - // up calling push() with more data. - while ( - !state.reading && - !state.ended && - (state.length < state.highWaterMark || (state.flowing && state.length === 0)) - ) { - const len = state.length; - stream.read(0); - if (len === state.length) - // Didn't get any data, stop spinning. - break; - } - state.readingMore = false; -} - -// Abstract method. to be overridden in specific implementation classes. -// call cb(er, data) where data is <= n in length. -// for virtual (non-string, non-buffer) streams, "length" is somewhat -// arbitrary, and perhaps not very meaningful. -Readable.prototype._read = function (_size) { - throw new ERR_METHOD_NOT_IMPLEMENTED("_read()"); -}; - -Readable.prototype.pipe = function (dest, pipeOpts) { - const src = this; - const state = this._readableState; - if (state.pipes.length === 1) { - if (!state.multiAwaitDrain) { - state.multiAwaitDrain = true; - state.awaitDrainWriters = new Set( - state.awaitDrainWriters ? [state.awaitDrainWriters] : [] - ); - } - } - state.pipes.push(dest); - const doEnd = !pipeOpts || pipeOpts.end !== false; - const endFn = doEnd ? onend : unpipe; - if (state.endEmitted) process.nextTick(endFn); - else src.once("end", endFn); - dest.on("unpipe", onunpipe); - function onunpipe(readable, unpipeInfo) { - if (readable === src) { - if (unpipeInfo && unpipeInfo.hasUnpiped === false) { - unpipeInfo.hasUnpiped = true; - cleanup(); - } - } - } - function onend() { - dest.end(); - } - let ondrain; - let cleanedUp = false; - function cleanup() { - // Cleanup event handlers once the pipe is broken. - dest.removeListener("close", onclose); - dest.removeListener("finish", onfinish); - if (ondrain) { - dest.removeListener("drain", ondrain); - } - dest.removeListener("error", onerror); - dest.removeListener("unpipe", onunpipe); - src.removeListener("end", onend); - src.removeListener("end", unpipe); - src.removeListener("data", ondata); - cleanedUp = true; - - // If the reader is waiting for a drain event from this - // specific writer, then it would cause it to never start - // flowing again. - // So, if this is awaiting a drain, then we just call it now. - // If we don't know, then assume that we are waiting for one. - if ( - ondrain && - state.awaitDrainWriters && - (!dest._writableState || dest._writableState.needDrain) - ) - ondrain(); - } - function pause() { - // If the user unpiped during `dest.write()`, it is possible - // to get stuck in a permanently paused state if that write - // also returned false. - // => Check whether `dest` is still a piping destination. - if (!cleanedUp) { - if (state.pipes.length === 1 && state.pipes[0] === dest) { - state.awaitDrainWriters = dest; - state.multiAwaitDrain = false; - } else if (state.pipes.length > 1 && state.pipes.includes(dest)) { - state.awaitDrainWriters.add(dest); - } - src.pause(); - } - if (!ondrain) { - // When the dest drains, it reduces the awaitDrain counter - // on the source. This would be more elegant with a .once() - // handler in flow(), but adding and removing repeatedly is - // too slow. - ondrain = pipeOnDrain(src, dest); - dest.on("drain", ondrain); - } - } - src.on("data", ondata); - function ondata(chunk) { - const ret = dest.write(chunk); - if (ret === false) { - pause(); - } - } - - // If the dest has an error, then stop piping into it. - // However, don't suppress the throwing behavior for this. - function onerror(er) { - unpipe(); - dest.removeListener("error", onerror); - if (dest.listenerCount("error") === 0) { - const s = dest._writableState || dest._readableState; - if (s && !s.errorEmitted) { - // User incorrectly emitted 'error' directly on the stream. - errorOrDestroy(dest, er); - } else { - dest.emit("error", er); - } - } - } - - // Make sure our error handler is attached before userland ones. - dest.prependListener("error", onerror); - - // Both close and finish should trigger unpipe, but only once. - function onclose() { - dest.removeListener("finish", onfinish); - unpipe(); - } - dest.once("close", onclose); - function onfinish() { - dest.removeListener("close", onclose); - unpipe(); - } - dest.once("finish", onfinish); - function unpipe() { - src.unpipe(dest); - } - - // Tell the dest that it's being piped to. - dest.emit("pipe", src); - - // Start the flow if it hasn't been started already. - - if (dest.writableNeedDrain === true) { - if (state.flowing) { - pause(); - } - } else if (!state.flowing) { - src.resume(); - } - return dest; -}; - -function pipeOnDrain(src, dest) { - return function pipeOnDrainFunctionResult() { - const state = src._readableState; - - // `ondrain` will call directly, - // `this` maybe not a reference to dest, - // so we use the real dest here. - if (state.awaitDrainWriters === dest) { - state.awaitDrainWriters = null; - } else if (state.multiAwaitDrain) { - state.awaitDrainWriters.delete(dest); - } - if ( - (!state.awaitDrainWriters || state.awaitDrainWriters.size === 0) && - src.listenerCount("data") - ) { - src.resume(); - } - }; -} - -Readable.prototype.unpipe = function (dest) { - const state = this._readableState; - const unpipeInfo = { - hasUnpiped: false, - }; - - // If we're not piping anywhere, then do nothing. - if (state.pipes.length === 0) return this; - if (!dest) { - // remove all. - const dests = state.pipes; - state.pipes = []; - this.pause(); - for (let i = 0; i < dests.length; i++) - dests[i].emit("unpipe", this, { - hasUnpiped: false, - }); - return this; - } - - // Try to find the right one. - const index = state.pipes.indexOf(dest); - if (index === -1) return this; - state.pipes.splice(index, 1); - if (state.pipes.length === 0) this.pause(); - dest.emit("unpipe", this, unpipeInfo); - return this; -}; - -// Set up data events if they are asked for -// Ensure readable listeners eventually get something. -Readable.prototype.on = function (ev, fn) { - const res = Stream.prototype.on.call(this, ev, fn); - const state = this._readableState; - if (ev === "data") { - // Update readableListening so that resume() may be a no-op - // a few lines down. This is needed to support once('readable'). - state.readableListening = this.listenerCount("readable") > 0; - - // Try start flowing on next tick if stream isn't explicitly paused. - if (state.flowing !== false) this.resume(); - } else if (ev === "readable") { - if (!state.endEmitted && !state.readableListening) { - state.readableListening = state.needReadable = true; - state.flowing = false; - state.emittedReadable = false; - if (state.length) { - emitReadable(this); - } else if (!state.reading) { - process.nextTick(nReadingNextTick, this); - } - } - } - return res; -}; -Readable.prototype.addListener = Readable.prototype.on; -Readable.prototype.removeListener = function (ev, fn) { - const res = Stream.prototype.removeListener.call(this, ev, fn); - if (ev === "readable") { - // We need to check if there is someone still listening to - // readable and reset the state. However this needs to happen - // after readable has been emitted but before I/O (nextTick) to - // support once('readable', fn) cycles. This means that calling - // resume within the same tick will have no - // effect. - process.nextTick(updateReadableListening, this); - } - return res; -}; -Readable.prototype.off = Readable.prototype.removeListener; -Readable.prototype.removeAllListeners = function (ev) { - const res = Stream.prototype.removeAllListeners.apply(this, arguments); - if (ev === "readable" || ev === undefined) { - // We need to check if there is someone still listening to - // readable and reset the state. However this needs to happen - // after readable has been emitted but before I/O (nextTick) to - // support once('readable', fn) cycles. This means that calling - // resume within the same tick will have no - // effect. - process.nextTick(updateReadableListening, this); - } - return res; -}; - -function updateReadableListening(self) { - const state = self._readableState; - state.readableListening = self.listenerCount("readable") > 0; - if (state.resumeScheduled && state[kPaused] === false) { - // Flowing needs to be set to true now, otherwise - // the upcoming resume will not flow. - state.flowing = true; - - // Crude way to check if we should resume. - } else if (self.listenerCount("data") > 0) { - self.resume(); - } else if (!state.readableListening) { - state.flowing = null; - } -} - -function nReadingNextTick(self) { - self.read(0); -} - -// pause() and resume() are remnants of the legacy readable stream API -// If the user uses them, then switch into old mode. -Readable.prototype.resume = function () { - const state = this._readableState; - if (!state.flowing) { - // We flow only if there is no one listening - // for readable, but we still have to call - // resume(). - state.flowing = !state.readableListening; - resume(this, state); - } - state[kPaused] = false; - return this; -}; - -function resume(stream, state) { - if (!state.resumeScheduled) { - state.resumeScheduled = true; - process.nextTick(resume_, stream, state); - } -} - -function resume_(stream, state) { - if (!state.reading) { - stream.read(0); - } - state.resumeScheduled = false; - stream.emit("resume"); - flow(stream); - if (state.flowing && !state.reading) stream.read(0); -} - -Readable.prototype.pause = function () { - if (this._readableState.flowing !== false) { - this._readableState.flowing = false; - this.emit("pause"); - } - this._readableState[kPaused] = true; - return this; -}; - -function flow(stream) { - const state = stream._readableState; - while (state.flowing && stream.read() !== null); -} - -// Wrap an old-style stream as the async data source. -// This is *not* part of the readable stream interface. -// It is an ugly unfortunate mess of history. -Readable.prototype.wrap = function (stream) { - let paused = false; - - // TODO (ronag): Should this.destroy(err) emit - // 'error' on the wrapped stream? Would require - // a static factory method, e.g. Readable.wrap(stream). - stream.on("data", (chunk) => { - if (!this.push(chunk) && stream.pause) { - paused = true; - stream.pause(); - } - }); - - stream.on("end", () => { - this.push(null); - }); - stream.on("error", (err) => { - errorOrDestroy(this, err); - }); - stream.on("close", () => { - this.destroy(); - }); - stream.on("destroy", () => { - this.destroy(); - }); - this._read = () => { - if (paused && stream.resume) { - paused = false; - stream.resume(); - } - }; - - // Proxy all the other methods. Important when wrapping filters and duplexes. - const streamKeys = Object.keys(stream); - for (let j = 1; j < streamKeys.length; j++) { - const i = streamKeys[j]; - if (this[i] === undefined && typeof stream[i] === "function") { - this[i] = stream[i].bind(stream); - } - } - return this; -}; - -Readable.prototype[Symbol.asyncIterator] = function () { - return streamToAsyncIterator(this); -}; - -Readable.prototype.iterator = function (options) { - if (options !== undefined) { - validateObject(options, "options", options); - } - return streamToAsyncIterator(this, options); -}; - -function streamToAsyncIterator(stream, options) { - if (typeof stream.read !== "function") { - stream = Readable.wrap(stream, { - objectMode: true, - }); - } - const iter = createAsyncIterator(stream, options); - iter.stream = stream; - return iter; -} - -async function* createAsyncIterator(stream, options) { - let callback = nop; - function next(resolve) { - if (this === stream) { - callback(); - callback = nop; - } else { - callback = resolve; - } - } - stream.on("readable", next); - let error; - const cleanup = eos( - stream, - { - writable: false, - }, - (err) => { - error = err ? aggregateTwoErrors(error, err) : null; - callback(); - callback = nop; - } - ); - try { - while (true) { - const chunk = stream.destroyed ? null : stream.read(); - if (chunk !== null) { - yield chunk; - } else if (error) { - throw error; - } else if (error === null) { - return; - } else { - await new Promise(next); - } - } - } catch (err) { - error = aggregateTwoErrors(error, err); - throw error; - } finally { - if ( - (error || - (options === null || options === undefined - ? undefined - : options.destroyOnReturn) !== false) && - (error === undefined || stream._readableState.autoDestroy) - ) { - destroyer(stream, null); - } else { - stream.off("readable", next); - cleanup(); - } - } -} - -// Making it explicit these properties are not enumerable -// because otherwise some prototype manipulation in -// userland will fail. -Object.defineProperties(Readable.prototype, { - readable: { - get() { - const r = this._readableState; - // r.readable === false means that this is part of a Duplex stream - // where the readable side was disabled upon construction. - // Compat. The user might manually disable readable side through - // deprecated setter. - return !!r && r.readable !== false && !r.destroyed && !r.errorEmitted && !r.endEmitted; - }, - set(val) { - // Backwards compat. - if (this._readableState) { - this._readableState.readable = !!val; - } - }, - }, - readableDidRead: { - enumerable: false, - get: function () { - return !!this._readableState?.dataEmitted; - }, - }, - readableAborted: { - enumerable: false, - get: function () { - return !!( - this._readableState?.readable !== false && - (this._readableState?.destroyed || this._readableState?.errored) && - !this._readableState?.endEmitted - ); - }, - }, - readableHighWaterMark: { - enumerable: false, - get: function () { - return this._readableState?.highWaterMark; - }, - }, - readableBuffer: { - enumerable: false, - get: function () { - return this._readableState?.buffer; - }, - }, - readableFlowing: { - enumerable: false, - get: function () { - return !!this._readableState?.flowing; - }, - set: function (state) { - if (this._readableState) { - this._readableState.flowing = state; - } - }, - }, - readableLength: { - enumerable: false, - get() { - return this._readableState?.length | 0; - }, - }, - readableObjectMode: { - enumerable: false, - get() { - return this._readableState ? this._readableState.objectMode : false; - }, - }, - readableEncoding: { - enumerable: false, - get() { - return this._readableState?.encoding || null; - }, - }, - errored: { - enumerable: false, - get() { - return this._readableState?.errored || null; - }, - }, - closed: { - get() { - return !!this._readableState?.closed; - }, - }, - destroyed: { - enumerable: false, - get() { - return !!this._readableState?.destroyed; - }, - set(value) { - // We ignore the value if the stream - // has not been initialized yet. - if (!this._readableState) { - return; - } - - // Backward compatibility, the user is explicitly - // managing destroyed. - this._readableState.destroyed = value; - }, - }, - readableEnded: { - enumerable: false, - get() { - return !!this._readableState?.endEmitted; - }, - }, -}); - -Object.defineProperties(ReadableState.prototype, { - // Legacy getter for `pipesCount`. - pipesCount: { - get() { - return this.pipes.length; - }, - }, - // Legacy property for `paused`. - paused: { - get() { - return this[kPaused] !== false; - }, - set(value) { - this[kPaused] = !!value; - }, - }, -}); - -// Exposed for testing purposes only. -Readable._fromList = fromList; - -// Pluck off n bytes from an array of buffers. -// Length is the combined lengths of all the buffers in the list. -// This function is designed to be inlinable, so please take care when making -// changes to the function body. -function fromList(n, state) { - // nothing buffered. - if (state.length === 0) return null; - let ret; - if (state.objectMode) ret = state.buffer.shift(); - else if (!n || n >= state.length) { - // Read it all, truncate the list. - if (state.decoder) ret = state.buffer.join(""); - else if (state.buffer.length === 1) ret = state.buffer.first(); - else ret = state.buffer.concat(state.length); - state.buffer.clear(); - } else { - // read part of list. - ret = state.buffer.consume(n, !!state.decoder); - } - return ret; -} - -function endReadable(stream) { - const state = stream._readableState; - if (!state.endEmitted) { - state.ended = true; - process.nextTick(endReadableNT, state, stream); - } -} - -function endReadableNT(state, stream) { - // Check that we didn't get one last unshift. - if (!state.errored && !state.closeEmitted && !state.endEmitted && state.length === 0) { - state.endEmitted = true; - stream.emit("end"); - if (stream.writable && stream.allowHalfOpen === false) { - process.nextTick(endWritableNT, stream); - } else if (state.autoDestroy) { - // In case of duplex streams we need a way to detect - // if the writable side is ready for autoDestroy as well. - const wState = stream._writableState; - const autoDestroy = - !wState || - (wState.autoDestroy && - // We don't expect the writable to ever 'finish' - // if writable is explicitly set to false. - (wState.finished || wState.writable === false)); - if (autoDestroy) { - stream.destroy(); - } - } - } -} - -function endWritableNT(stream) { - const writable = stream.writable && !stream.writableEnded && !stream.destroyed; - if (writable) { - stream.end(); - } -} - -Readable.fromWeb = function (readableStream, options) { - return newStreamReadableFromReadableStream(readableStream, options); -}; -Readable.toWeb = function (streamReadable, options) { - return newReadableStreamFromStreamReadable(streamReadable, options); -}; - -Readable.wrap = function (src, options) { - let _ref, _src$readableObjectMo; - return new Readable({ - objectMode: - (_ref = - (_src$readableObjectMo = src.readableObjectMode) !== null && - _src$readableObjectMo !== undefined - ? _src$readableObjectMo - : src.objectMode) !== null && _ref !== undefined - ? _ref - : true, - ...options, - destroy(err, callback) { - destroyer(src, err); - callback(err); - }, - }).wrap(src); -}; - -// ====================================================================================== -// - -Readable.from = function (iterable, opts) { - return from(Readable, iterable, opts); -}; - -export function from(Readable, iterable, opts) { - let iterator; - if (typeof iterable === "string" || iterable instanceof Buffer) { - return new Readable({ - objectMode: true, - ...opts, - read() { - this.push(iterable); - this.push(null); - }, - }); - } - let isAsync; - if (iterable && iterable[Symbol.asyncIterator]) { - isAsync = true; - iterator = iterable[Symbol.asyncIterator](); - } else if (iterable && iterable[Symbol.iterator]) { - isAsync = false; - iterator = iterable[Symbol.iterator](); - } else { - throw new ERR_INVALID_ARG_TYPE("iterable", ["Iterable"], iterable); - } - const readable = new Readable({ - objectMode: true, - highWaterMark: 1, - // TODO(ronag): What options should be allowed? - ...opts, - }); - - // Flag to protect against _read - // being called before last iteration completion. - let reading = false; - readable._read = function () { - if (!reading) { - reading = true; - next(); - } - }; - readable._destroy = function (error, cb) { - close(error).then( - () => process.nextTick(cb, error), - (err) => process.nextTick(cb, err || error) - ); - }; - async function close(error) { - const hadError = error !== undefined && error !== null; - const hasThrow = typeof iterator.throw === "function"; - if (hadError && hasThrow) { - const { value, done } = await iterator.throw(error); - await value; - if (done) { - return; - } - } - if (typeof iterator.return === "function") { - const { value } = await iterator.return(); - await value; - } - } - async function next() { - for (;;) { - try { - const { value, done } = isAsync ? await iterator.next() : iterator.next(); - if (done) { - readable.push(null); - } else { - const res = value && typeof value.then === "function" ? await value : value; - if (res === null) { - reading = false; - throw new ERR_STREAM_NULL_VALUES(); - } else if (readable.push(res)) { - continue; - } else { - reading = false; - } - } - } catch (err) { - readable.destroy(err); - } - break; - } - } - return readable; -} - -// ====================================================================================== -// Operators - -const kWeakHandler = Symbol("kWeak"); -const kEmpty = Symbol("kEmpty"); -const kEof = Symbol("kEof"); - -function map(fn, options) { - if (typeof fn !== "function") { - throw new ERR_INVALID_ARG_TYPE("fn", ["Function", "AsyncFunction"], fn); - } - if (options != null) { - validateObject(options, "options", options); - } - if (options?.signal != null) { - validateAbortSignal(options.signal, "options.signal"); - } - let concurrency = 1; - if (options?.concurrency != null) { - concurrency = Math.floor(options.concurrency); - } - validateInteger(concurrency, "concurrency", 1); - return async function* map() { - let _options$signal, _options$signal2; - const ac = new AbortController(); - const stream = this; - const queue = []; - const signal = ac.signal; - const signalOpt = { - signal, - }; - const abort = () => ac.abort(); - if ( - options !== null && - options !== undefined && - (_options$signal = options.signal) !== null && - _options$signal !== undefined && - _options$signal.aborted - ) { - abort(); - } - options === null || options === undefined - ? undefined - : (_options$signal2 = options.signal) === null || _options$signal2 === undefined - ? undefined - : _options$signal2.addEventListener("abort", abort); - let next; - let resume; - let done = false; - function onDone() { - done = true; - } - async function pump() { - try { - for await (let val of stream) { - let _val; - if (done) { - return; - } - if (signal.aborted) { - throw new AbortError(); - } - try { - val = fn(val, signalOpt); - } catch (err) { - val = Promise.reject(err); - } - if (val === kEmpty) { - continue; - } - if ( - typeof ((_val = val) === null || _val === undefined - ? undefined - : _val.catch) === "function" - ) { - val.catch(onDone); - } - queue.push(val); - if (next) { - next(); - next = null; - } - if (!done && queue.length && queue.length >= concurrency) { - await new Promise((resolve) => { - resume = resolve; - }); - } - } - queue.push(kEof); - } catch (err) { - const val = Promise.reject(err); - val.then(undefined, onDone); - queue.push(val); - } finally { - let _options$signal3; - done = true; - if (next) { - next(); - next = null; - } - options === null || options === undefined - ? undefined - : (_options$signal3 = options.signal) === null || _options$signal3 === undefined - ? undefined - : _options$signal3.removeEventListener("abort", abort); - } - } - pump(); - try { - while (true) { - while (queue.length > 0) { - const val = await queue[0]; - if (val === kEof) { - return; - } - if (signal.aborted) { - throw new AbortError(); - } - if (val !== kEmpty) { - yield val; - } - queue.shift(); - if (resume) { - resume(); - resume = null; - } - } - await new Promise((resolve) => { - next = resolve; - }); - } - } finally { - ac.abort(); - done = true; - if (resume) { - resume(); - resume = null; - } - } - }.call(this); -} - -function asIndexedPairs(options) { - if (options != null) { - validateObject(options, "options", options); - } - if ((options === null || options === undefined ? undefined : options.signal) != null) { - validateAbortSignal(options.signal, "options.signal"); - } - return async function* asIndexedPairs() { - let index = 0; - for await (const val of this) { - let _options$signal4; - if ( - options !== null && - options !== undefined && - (_options$signal4 = options.signal) !== null && - _options$signal4 !== undefined && - _options$signal4.aborted - ) { - throw new AbortError("Aborted", { - cause: options.signal?.reason, - }); - } - yield [index++, val]; - } - }.call(this); -} - -async function some(fn, options) { - if (typeof fn !== "function") { - throw new ERR_INVALID_ARG_TYPE("fn", ["Function", "AsyncFunction"], fn); - } - for await (const _ of filter.call(this, fn, options)) { - return true; - } - return false; -} - -async function every(fn, options) { - if (typeof fn !== "function") { - throw new ERR_INVALID_ARG_TYPE("fn", ["Function", "AsyncFunction"], fn); - } - // https://en.wikipedia.org/wiki/De_Morgan%27s_laws - return !(await some.call( - this, - async (...args) => { - return !(await fn(...args)); - }, - options - )); -} - -async function find(fn, options) { - for await (const result of filter.call(this, fn, options)) { - return result; - } - return undefined; -} - -async function forEach(fn, options) { - if (typeof fn !== "function") { - throw new ERR_INVALID_ARG_TYPE("fn", ["Function", "AsyncFunction"], fn); - } - async function forEachFn(value, options) { - await fn(value, options); - return kEmpty; - } - // eslint-disable-next-line no-unused-vars - for await (const _ of map.call(this, forEachFn, options)); -} - -function filter(fn, options) { - if (typeof fn !== "function") { - throw new ERR_INVALID_ARG_TYPE("fn", ["Function", "AsyncFunction"], fn); - } - async function filterFn(value, options) { - if (await fn(value, options)) { - return value; - } - return kEmpty; - } - return map.call(this, filterFn, options); -} - -// Specific to provide better error to reduce since the argument is only -// missing if the stream has no items in it - but the code is still appropriate -class ReduceAwareErrMissingArgs extends ERR_MISSING_ARGS { - constructor() { - super("reduce"); - this.message = "Reduce of an empty stream requires an initial value"; - } -} - -async function reduce(reducer, initialValue, options) { - let _options$signal5; - if (typeof reducer !== "function") { - throw new ERR_INVALID_ARG_TYPE("reducer", ["Function", "AsyncFunction"], reducer); - } - if (options != null) { - validateObject(options, "options", options); - } - if (options?.signal != null) { - validateAbortSignal(options?.signal, "options.signal"); - } - let hasInitialValue = arguments.length > 1; - if ( - options !== null && - options !== undefined && - (_options$signal5 = options.signal) !== null && - _options$signal5 !== undefined && - _options$signal5.aborted - ) { - const err = new AbortError(undefined, { - cause: options.signal?.reason, - }); - this.once("error", () => {}); // The error is already propagated - await finished(this.destroy(err)); - throw err; - } - const ac = new AbortController(); - const signal = ac.signal; - if (options?.signal) { - const opts = { - once: true, - [kWeakHandler]: this, - }; - options.signal.addEventListener("abort", () => ac.abort(), opts); - } - let gotAnyItemFromStream = false; - try { - for await (const value of this) { - let _options$signal6; - gotAnyItemFromStream = true; - if ( - options !== null && - options !== undefined && - (_options$signal6 = options.signal) !== null && - _options$signal6 !== undefined && - _options$signal6.aborted - ) { - throw new AbortError(); - } - if (!hasInitialValue) { - initialValue = value; - hasInitialValue = true; - } else { - initialValue = await reducer(initialValue, value, { - signal, - }); - } - } - if (!gotAnyItemFromStream && !hasInitialValue) { - throw new ReduceAwareErrMissingArgs(); - } - } finally { - ac.abort(); - } - return initialValue; -} - -async function toArray(options) { - if (options != null) { - validateObject(options, "options", options); - } - if (options?.signal != null) { - validateAbortSignal(options?.signal, "options.signal"); - } - const result = []; - for await (const val of this) { - let _options$signal7; - if ( - options !== null && - options !== undefined && - (_options$signal7 = options.signal) !== null && - _options$signal7 !== undefined && - _options$signal7.aborted - ) { - throw new AbortError(undefined, { - cause: options.signal?.reason, - }); - } - result.push(val); - } - return result; -} - -function flatMap(fn, options) { - const values = map.call(this, fn, options); - return async function* flatMap() { - for await (const val of values) { - yield* val; - } - }.call(this); -} - -function toIntegerOrInfinity(number) { - // We coerce here to align with the spec - // https://github.com/tc39/proposal-iterator-helpers/issues/169 - number = Number(number); - if (Number.isNaN(number)) { - return 0; - } - if (number < 0) { - throw new ERR_OUT_OF_RANGE("number", ">= 0", number); - } - return number; -} - -function drop(number, options) { - if (options != null) { - validateObject(options, "options", options); - } - if (options?.signal != null) { - validateAbortSignal(options?.signal, "options.signal"); - } - number = toIntegerOrInfinity(number); - return async function* drop() { - let _options$signal8; - if ( - options !== null && - options !== undefined && - (_options$signal8 = options.signal) !== null && - _options$signal8 !== undefined && - _options$signal8.aborted - ) { - throw new AbortError(); - } - for await (const val of this) { - let _options$signal9; - if ( - options !== null && - options !== undefined && - (_options$signal9 = options.signal) !== null && - _options$signal9 !== undefined && - _options$signal9.aborted - ) { - throw new AbortError(); - } - if (number-- <= 0) { - yield val; - } - } - }.call(this); -} - -function take(number, options) { - if (options != null) { - validateObject(options, "options", options); - } - if (options?.signal != null) { - validateAbortSignal(options?.signal, "options.signal"); - } - number = toIntegerOrInfinity(number); - return async function* take() { - let _options$signal10; - if ( - options !== null && - options !== undefined && - (_options$signal10 = options.signal) !== null && - _options$signal10 !== undefined && - _options$signal10.aborted - ) { - throw new AbortError(); - } - for await (const val of this) { - let _options$signal11; - if ( - options !== null && - options !== undefined && - (_options$signal11 = options.signal) !== null && - _options$signal11 !== undefined && - _options$signal11.aborted - ) { - throw new AbortError(); - } - if (number-- > 0) { - yield val; - } else { - return; - } - } - }.call(this); -} - -Readable.prototype.map = function (fn, options) { - return from(Readable, map.call(this, fn, options)); -}; - -Readable.prototype.asIndexedPairs = function (options) { - return from(Readable, asIndexedPairs.call(this, options)); -}; - -Readable.prototype.drop = function (number, options) { - return from(Readable, drop.call(this, number, options)); -}; - -Readable.prototype.filter = function (fn, options) { - return from(Readable, filter.call(this, fn, options)); -}; - -Readable.prototype.flatMap = function (fn, options) { - return from(Readable, flatMap.call(this, fn, options)); -}; - -Readable.prototype.take = function (number, options) { - return from(Readable, take.call(this, number, options)); -}; - -Readable.prototype.every = every; -Readable.prototype.forEach = forEach; -Readable.prototype.reduce = reduce; -Readable.prototype.toArray = toArray; -Readable.prototype.some = some; -Readable.prototype.find = find; diff --git a/JS/wasm/crates/wasmjs-engine/shims/src/internal/streams_transform.d.ts b/JS/wasm/crates/wasmjs-engine/shims/src/internal/streams_transform.d.ts deleted file mode 100644 index 7add11339..000000000 --- a/JS/wasm/crates/wasmjs-engine/shims/src/internal/streams_transform.d.ts +++ /dev/null @@ -1,392 +0,0 @@ -import EventEmitter from "./events"; - -interface WritableOptions { - highWaterMark?: number | undefined; - decodeStrings?: boolean | undefined; - defaultEncoding?: BufferEncoding | undefined; - objectMode?: boolean | undefined; - emitClose?: boolean | undefined; - write?( - this: Writable, - chunk: any, - encoding: BufferEncoding, - callback: (error?: Error | null) => void - ): void; - writev?( - this: Writable, - chunks: Array<{ chunk: any; encoding: BufferEncoding }>, - callback: (error?: Error | null) => void - ): void; - destroy?(this: Writable, error: Error | null, callback: (error: Error | null) => void): void; - final?(this: Writable, callback: (error?: Error | null) => void): void; - autoDestroy?: boolean | undefined; -} - -export class internal extends EventEmitter { - pipe( - destination: T, - options?: { end?: boolean | undefined } - ): T; -} - -export class Stream extends internal { - constructor(opts?: ReadableOptions); -} - -interface ReadableOptions { - highWaterMark?: number | undefined; - encoding?: BufferEncoding | undefined; - objectMode?: boolean | undefined; - read?(this: Readable, size: number): void; - destroy?(this: Readable, error: Error | null, callback: (error: Error | null) => void): void; - autoDestroy?: boolean | undefined; -} - -export class Readable extends Stream implements NodeJS.ReadableStream { - static from(iterable: Iterable | AsyncIterable, options?: ReadableOptions): Readable; - - readable: boolean; - readonly readableEncoding: BufferEncoding | null; - readonly readableEnded: boolean; - readonly readableFlowing: boolean | null; - readonly readableHighWaterMark: number; - readonly readableLength: number; - readonly readableObjectMode: boolean; - destroyed: boolean; - constructor(opts?: ReadableOptions); - _read(size: number): void; - read(size?: number): any; - setEncoding(encoding: BufferEncoding): this; - pause(): this; - resume(): this; - isPaused(): boolean; - unpipe(destination?: NodeJS.WritableStream): this; - unshift(chunk: any, encoding?: BufferEncoding): void; - wrap(oldStream: NodeJS.ReadableStream): this; - push(chunk: any, encoding?: BufferEncoding): boolean; - _destroy(error: Error | null, callback: (error?: Error | null) => void): void; - destroy(error?: Error): this; - - addListener(event: "close", listener: () => void): this; - addListener(event: "data", listener: (chunk: any) => void): this; - addListener(event: "end", listener: () => void): this; - addListener(event: "error", listener: (err: Error) => void): this; - addListener(event: "pause", listener: () => void): this; - addListener(event: "readable", listener: () => void): this; - addListener(event: "resume", listener: () => void): this; - addListener(event: string | symbol, listener: (...args: any[]) => void): this; - - emit(event: "close"): boolean; - emit(event: "data", chunk: any): boolean; - emit(event: "end"): boolean; - emit(event: "error", err: Error): boolean; - emit(event: "pause"): boolean; - emit(event: "readable"): boolean; - emit(event: "resume"): boolean; - emit(event: string | symbol, ...args: any[]): boolean; - - on(event: "close", listener: () => void): this; - on(event: "data", listener: (chunk: any) => void): this; - on(event: "end", listener: () => void): this; - on(event: "error", listener: (err: Error) => void): this; - on(event: "pause", listener: () => void): this; - on(event: "readable", listener: () => void): this; - on(event: "resume", listener: () => void): this; - on(event: string | symbol, listener: (...args: any[]) => void): this; - - once(event: "close", listener: () => void): this; - once(event: "data", listener: (chunk: any) => void): this; - once(event: "end", listener: () => void): this; - once(event: "error", listener: (err: Error) => void): this; - once(event: "pause", listener: () => void): this; - once(event: "readable", listener: () => void): this; - once(event: "resume", listener: () => void): this; - once(event: string | symbol, listener: (...args: any[]) => void): this; - - prependListener(event: "close", listener: () => void): this; - prependListener(event: "data", listener: (chunk: any) => void): this; - prependListener(event: "end", listener: () => void): this; - prependListener(event: "error", listener: (err: Error) => void): this; - prependListener(event: "pause", listener: () => void): this; - prependListener(event: "readable", listener: () => void): this; - prependListener(event: "resume", listener: () => void): this; - prependListener(event: string | symbol, listener: (...args: any[]) => void): this; - - prependOnceListener(event: "close", listener: () => void): this; - prependOnceListener(event: "data", listener: (chunk: any) => void): this; - prependOnceListener(event: "end", listener: () => void): this; - prependOnceListener(event: "error", listener: (err: Error) => void): this; - prependOnceListener(event: "pause", listener: () => void): this; - prependOnceListener(event: "readable", listener: () => void): this; - prependOnceListener(event: "resume", listener: () => void): this; - prependOnceListener(event: string | symbol, listener: (...args: any[]) => void): this; - - removeListener(event: "close", listener: () => void): this; - removeListener(event: "data", listener: (chunk: any) => void): this; - removeListener(event: "end", listener: () => void): this; - removeListener(event: "error", listener: (err: Error) => void): this; - removeListener(event: "pause", listener: () => void): this; - removeListener(event: "readable", listener: () => void): this; - removeListener(event: "resume", listener: () => void): this; - removeListener(event: string | symbol, listener: (...args: any[]) => void): this; - - [Symbol.asyncIterator](): AsyncIterableIterator; -} - -export class Writable extends Stream implements NodeJS.WritableStream { - readonly writable: boolean; - readonly writableEnded: boolean; - readonly writableFinished: boolean; - readonly writableHighWaterMark: number; - readonly writableLength: number; - readonly writableObjectMode: boolean; - readonly writableCorked: number; - destroyed: boolean; - constructor(opts?: WritableOptions); - _write(chunk: any, encoding: BufferEncoding, callback: (error?: Error | null) => void): void; - _writev?( - chunks: Array<{ chunk: any; encoding: BufferEncoding }>, - callback: (error?: Error | null) => void - ): void; - _destroy(error: Error | null, callback: (error?: Error | null) => void): void; - _final(callback: (error?: Error | null) => void): void; - write(chunk: any, cb?: (error: Error | null | undefined) => void): boolean; - write( - chunk: any, - encoding: BufferEncoding, - cb?: (error: Error | null | undefined) => void - ): boolean; - setDefaultEncoding(encoding: BufferEncoding): this; - end(cb?: () => void): this; - end(chunk: any, cb?: () => void): this; - end(chunk: any, encoding: BufferEncoding, cb?: () => void): this; - cork(): void; - uncork(): void; - destroy(error?: Error): this; - - addListener(event: "close", listener: () => void): this; - addListener(event: "drain", listener: () => void): this; - addListener(event: "error", listener: (err: Error) => void): this; - addListener(event: "finish", listener: () => void): this; - addListener(event: "pipe", listener: (src: Readable) => void): this; - addListener(event: "unpipe", listener: (src: Readable) => void): this; - addListener(event: string | symbol, listener: (...args: any[]) => void): this; - - emit(event: "close"): boolean; - emit(event: "drain"): boolean; - emit(event: "error", err: Error): boolean; - emit(event: "finish"): boolean; - emit(event: "pipe", src: Readable): boolean; - emit(event: "unpipe", src: Readable): boolean; - emit(event: string | symbol, ...args: any[]): boolean; - - on(event: "close", listener: () => void): this; - on(event: "drain", listener: () => void): this; - on(event: "error", listener: (err: Error) => void): this; - on(event: "finish", listener: () => void): this; - on(event: "pipe", listener: (src: Readable) => void): this; - on(event: "unpipe", listener: (src: Readable) => void): this; - on(event: string | symbol, listener: (...args: any[]) => void): this; - - once(event: "close", listener: () => void): this; - once(event: "drain", listener: () => void): this; - once(event: "error", listener: (err: Error) => void): this; - once(event: "finish", listener: () => void): this; - once(event: "pipe", listener: (src: Readable) => void): this; - once(event: "unpipe", listener: (src: Readable) => void): this; - once(event: string | symbol, listener: (...args: any[]) => void): this; - - prependListener(event: "close", listener: () => void): this; - prependListener(event: "drain", listener: () => void): this; - prependListener(event: "error", listener: (err: Error) => void): this; - prependListener(event: "finish", listener: () => void): this; - prependListener(event: "pipe", listener: (src: Readable) => void): this; - prependListener(event: "unpipe", listener: (src: Readable) => void): this; - prependListener(event: string | symbol, listener: (...args: any[]) => void): this; - - prependOnceListener(event: "close", listener: () => void): this; - prependOnceListener(event: "drain", listener: () => void): this; - prependOnceListener(event: "error", listener: (err: Error) => void): this; - prependOnceListener(event: "finish", listener: () => void): this; - prependOnceListener(event: "pipe", listener: (src: Readable) => void): this; - prependOnceListener(event: "unpipe", listener: (src: Readable) => void): this; - prependOnceListener(event: string | symbol, listener: (...args: any[]) => void): this; - - removeListener(event: "close", listener: () => void): this; - removeListener(event: "drain", listener: () => void): this; - removeListener(event: "error", listener: (err: Error) => void): this; - removeListener(event: "finish", listener: () => void): this; - removeListener(event: "pipe", listener: (src: Readable) => void): this; - removeListener(event: "unpipe", listener: (src: Readable) => void): this; - removeListener(event: string | symbol, listener: (...args: any[]) => void): this; -} - -export class Duplex extends Readable implements Writable { - readonly writable: boolean; - readonly writableEnded: boolean; - readonly writableFinished: boolean; - readonly writableHighWaterMark: number; - readonly writableLength: number; - readonly writableObjectMode: boolean; - readonly writableCorked: number; - allowHalfOpen: boolean; - constructor(opts?: DuplexOptions); - _write(chunk: any, encoding: BufferEncoding, callback: (error?: Error | null) => void): void; - _writev?( - chunks: Array<{ chunk: any; encoding: BufferEncoding }>, - callback: (error?: Error | null) => void - ): void; - _destroy(error: Error | null, callback: (error: Error | null) => void): void; - _final(callback: (error?: Error | null) => void): void; - write( - chunk: any, - encoding?: BufferEncoding, - cb?: (error: Error | null | undefined) => void - ): boolean; - write(chunk: any, cb?: (error: Error | null | undefined) => void): boolean; - setDefaultEncoding(encoding: BufferEncoding): this; - end(cb?: () => void): this; - end(chunk: any, cb?: () => void): this; - end(chunk: any, encoding?: BufferEncoding, cb?: () => void): this; - cork(): void; - uncork(): void; - addListener(event: "close", listener: () => void): this; - addListener(event: "data", listener: (chunk: any) => void): this; - addListener(event: "drain", listener: () => void): this; - addListener(event: "end", listener: () => void): this; - addListener(event: "error", listener: (err: Error) => void): this; - addListener(event: "finish", listener: () => void): this; - addListener(event: "pause", listener: () => void): this; - addListener(event: "pipe", listener: (src: Readable) => void): this; - addListener(event: "readable", listener: () => void): this; - addListener(event: "resume", listener: () => void): this; - addListener(event: "unpipe", listener: (src: Readable) => void): this; - addListener(event: string | symbol, listener: (...args: any[]) => void): this; - emit(event: "close"): boolean; - emit(event: "data", chunk: any): boolean; - emit(event: "drain"): boolean; - emit(event: "end"): boolean; - emit(event: "error", err: Error): boolean; - emit(event: "finish"): boolean; - emit(event: "pause"): boolean; - emit(event: "pipe", src: Readable): boolean; - emit(event: "readable"): boolean; - emit(event: "resume"): boolean; - emit(event: "unpipe", src: Readable): boolean; - emit(event: string | symbol, ...args: any[]): boolean; - on(event: "close", listener: () => void): this; - on(event: "data", listener: (chunk: any) => void): this; - on(event: "drain", listener: () => void): this; - on(event: "end", listener: () => void): this; - on(event: "error", listener: (err: Error) => void): this; - on(event: "finish", listener: () => void): this; - on(event: "pause", listener: () => void): this; - on(event: "pipe", listener: (src: Readable) => void): this; - on(event: "readable", listener: () => void): this; - on(event: "resume", listener: () => void): this; - on(event: "unpipe", listener: (src: Readable) => void): this; - on(event: string | symbol, listener: (...args: any[]) => void): this; - once(event: "close", listener: () => void): this; - once(event: "data", listener: (chunk: any) => void): this; - once(event: "drain", listener: () => void): this; - once(event: "end", listener: () => void): this; - once(event: "error", listener: (err: Error) => void): this; - once(event: "finish", listener: () => void): this; - once(event: "pause", listener: () => void): this; - once(event: "pipe", listener: (src: Readable) => void): this; - once(event: "readable", listener: () => void): this; - once(event: "resume", listener: () => void): this; - once(event: "unpipe", listener: (src: Readable) => void): this; - once(event: string | symbol, listener: (...args: any[]) => void): this; - prependListener(event: "close", listener: () => void): this; - prependListener(event: "data", listener: (chunk: any) => void): this; - prependListener(event: "drain", listener: () => void): this; - prependListener(event: "end", listener: () => void): this; - prependListener(event: "error", listener: (err: Error) => void): this; - prependListener(event: "finish", listener: () => void): this; - prependListener(event: "pause", listener: () => void): this; - prependListener(event: "pipe", listener: (src: Readable) => void): this; - prependListener(event: "readable", listener: () => void): this; - prependListener(event: "resume", listener: () => void): this; - prependListener(event: "unpipe", listener: (src: Readable) => void): this; - prependListener(event: string | symbol, listener: (...args: any[]) => void): this; - prependOnceListener(event: "close", listener: () => void): this; - prependOnceListener(event: "data", listener: (chunk: any) => void): this; - prependOnceListener(event: "drain", listener: () => void): this; - prependOnceListener(event: "end", listener: () => void): this; - prependOnceListener(event: "error", listener: (err: Error) => void): this; - prependOnceListener(event: "finish", listener: () => void): this; - prependOnceListener(event: "pause", listener: () => void): this; - prependOnceListener(event: "pipe", listener: (src: Readable) => void): this; - prependOnceListener(event: "readable", listener: () => void): this; - prependOnceListener(event: "resume", listener: () => void): this; - prependOnceListener(event: "unpipe", listener: (src: Readable) => void): this; - prependOnceListener(event: string | symbol, listener: (...args: any[]) => void): this; - removeListener(event: "close", listener: () => void): this; - removeListener(event: "data", listener: (chunk: any) => void): this; - removeListener(event: "drain", listener: () => void): this; - removeListener(event: "end", listener: () => void): this; - removeListener(event: "error", listener: (err: Error) => void): this; - removeListener(event: "finish", listener: () => void): this; - removeListener(event: "pause", listener: () => void): this; - removeListener(event: "pipe", listener: (src: Readable) => void): this; - removeListener(event: "readable", listener: () => void): this; - removeListener(event: "resume", listener: () => void): this; - removeListener(event: "unpipe", listener: (src: Readable) => void): this; - removeListener(event: string | symbol, listener: (...args: any[]) => void): this; -} - -interface DuplexOptions extends ReadableOptions, WritableOptions { - allowHalfOpen?: boolean | undefined; - readableObjectMode?: boolean | undefined; - writableObjectMode?: boolean | undefined; - readableHighWaterMark?: number | undefined; - writableHighWaterMark?: number | undefined; - writableCorked?: number | undefined; - read?(this: Duplex, size: number): void; - write?( - this: Duplex, - chunk: any, - encoding: BufferEncoding, - callback: (error?: Error | null) => void - ): void; - writev?( - this: Duplex, - chunks: Array<{ chunk: any; encoding: BufferEncoding }>, - callback: (error?: Error | null) => void - ): void; - final?(this: Duplex, callback: (error?: Error | null) => void): void; - destroy?(this: Duplex, error: Error | null, callback: (error: Error | null) => void): void; -} - -interface TransformOptions extends DuplexOptions { - read?(this: Transform, size: number): void; - write?( - this: Transform, - chunk: any, - encoding: BufferEncoding, - callback: (error?: Error | null) => void - ): void; - writev?( - this: Transform, - chunks: Array<{ chunk: any; encoding: BufferEncoding }>, - callback: (error?: Error | null) => void - ): void; - final?(this: Transform, callback: (error?: Error | null) => void): void; - destroy?(this: Transform, error: Error | null, callback: (error: Error | null) => void): void; - transform?( - this: Transform, - chunk: any, - encoding: BufferEncoding, - callback: TransformCallback - ): void; - flush?(this: Transform, callback: TransformCallback): void; -} - -type TransformCallback = (error?: Error | null, data?: any) => void; - -export class Transform extends Duplex { - constructor(opts?: TransformOptions); - _transform(chunk: any, encoding: BufferEncoding, callback: TransformCallback): void; - _flush(callback: TransformCallback): void; -} diff --git a/JS/wasm/crates/wasmjs-engine/shims/src/internal/streams_transform.js b/JS/wasm/crates/wasmjs-engine/shims/src/internal/streams_transform.js deleted file mode 100644 index 213c21c61..000000000 --- a/JS/wasm/crates/wasmjs-engine/shims/src/internal/streams_transform.js +++ /dev/null @@ -1,143 +0,0 @@ -"use strict"; - -import { ERR_METHOD_NOT_IMPLEMENTED } from "./internal_errors"; - -import { Duplex } from "./streams_duplex"; - -import { getHighWaterMark } from "./streams_util"; - -Object.setPrototypeOf(Transform.prototype, Duplex.prototype); -Object.setPrototypeOf(Transform, Duplex); - -const kCallback = Symbol("kCallback"); - -export function Transform(options) { - if (!(this instanceof Transform)) return new Transform(options); - - // TODO (ronag): This should preferably always be - // applied but would be semver-major. Or even better; - // make Transform a Readable with the Writable interface. - const readableHighWaterMark = options - ? getHighWaterMark(options, "readableHighWaterMark", true) - : null; - if (readableHighWaterMark === 0) { - // A Duplex will buffer both on the writable and readable side while - // a Transform just wants to buffer hwm number of elements. To avoid - // buffering twice we disable buffering on the writable side. - options = { - ...options, - highWaterMark: null, - readableHighWaterMark, - // TODO (ronag): 0 is not optimal since we have - // a "bug" where we check needDrain before calling _write and not after. - // Refs: https://github.com/nodejs/node/pull/32887 - // Refs: https://github.com/nodejs/node/pull/35941 - writableHighWaterMark: options?.writableHighWaterMark || 0, - }; - } - Duplex.call(this, options); - - // We have implemented the _read method, and done the other things - // that Readable wants before the first _read call, so unset the - // sync guard flag. - this._readableState.sync = false; - this[kCallback] = null; - if (options) { - if (typeof options.transform === "function") this._transform = options.transform; - if (typeof options.flush === "function") this._flush = options.flush; - } - - // When the writable side finishes, then flush out anything remaining. - // Backwards compat. Some Transform streams incorrectly implement _final - // instead of or in addition to _flush. By using 'prefinish' instead of - // implementing _final we continue supporting this unfortunate use case. - this.on("prefinish", prefinish); -} - -function final(cb) { - if (typeof this._flush === "function" && !this.destroyed) { - this._flush((er, data) => { - if (er) { - if (cb) { - cb(er); - } else { - this.destroy(er); - } - return; - } - if (data != null) { - this.push(data); - } - this.push(null); - if (cb) { - cb(); - } - }); - } else { - this.push(null); - if (cb) { - cb(); - } - } -} - -function prefinish() { - if (this._final !== final) { - final.call(this); - } -} -Transform.prototype._final = final; - -Transform.prototype._transform = function () { - throw new ERR_METHOD_NOT_IMPLEMENTED("_transform()"); -}; - -Transform.prototype._write = function (chunk, encoding, callback) { - const rState = this._readableState; - const wState = this._writableState; - const length = rState.length; - this._transform(chunk, encoding, (err, val) => { - if (err) { - callback(err); - return; - } - if (val != null) { - this.push(val); - } - if ( - wState.ended || - // Backwards compat. - length === rState.length || - // Backwards compat. - rState.length < rState.highWaterMark - ) { - callback(); - } else { - this[kCallback] = callback; - } - }); -}; - -Transform.prototype._read = function (_size) { - if (this[kCallback]) { - const callback = this[kCallback]; - this[kCallback] = null; - callback(); - } -}; - -Object.setPrototypeOf(PassThrough.prototype, Transform.prototype); -Object.setPrototypeOf(PassThrough, Transform); - -export function PassThrough(options) { - if (!(this instanceof PassThrough)) return new PassThrough(options); - Transform.call(this, { - ...options, - transform: undefined, - flush: undefined, - }); -} - -PassThrough.prototype._transform = function (chunk, _, cb) { - cb(null, chunk); -}; diff --git a/JS/wasm/crates/wasmjs-engine/shims/src/internal/streams_util.js b/JS/wasm/crates/wasmjs-engine/shims/src/internal/streams_util.js deleted file mode 100644 index 91949bd71..000000000 --- a/JS/wasm/crates/wasmjs-engine/shims/src/internal/streams_util.js +++ /dev/null @@ -1,1043 +0,0 @@ -export const kDestroyed = Symbol("kDestroyed"); -export const kIsErrored = Symbol("kIsErrored"); -export const kIsReadable = Symbol("kIsReadable"); -export const kIsDisturbed = Symbol("kIsDisturbed"); -export const kPaused = Symbol("kPaused"); -export const kOnFinished = Symbol("kOnFinished"); -export const kDestroy = Symbol("kDestroy"); -export const kConstruct = Symbol("kConstruct"); - -import { - AbortError, - ERR_INVALID_ARG_TYPE, - ERR_INVALID_ARG_VALUE, - ERR_STREAM_PREMATURE_CLOSE, - ERR_MULTIPLE_CALLBACK, - aggregateTwoErrors, -} from "./internal_errors"; - -import * as process from "./process"; - -import { Buffer } from "./internal_buffer"; - -import { validateAbortSignal, validateFunction, validateObject } from "./validators"; - -export function isReadableNodeStream(obj, strict = false) { - let _obj$_readableState; - return !!( - ( - obj && - typeof obj.pipe === "function" && - typeof obj.on === "function" && - (!strict || (typeof obj.pause === "function" && typeof obj.resume === "function")) && - (!obj._writableState || - ((_obj$_readableState = obj._readableState) === null || - _obj$_readableState === undefined - ? undefined - : _obj$_readableState.readable) !== false) && - // Duplex - (!obj._writableState || obj._readableState) - ) // Writable has .pipe. - ); -} - -export function isWritableNodeStream(obj) { - let _obj$_writableState; - return !!( - ( - obj && - typeof obj.write === "function" && - typeof obj.on === "function" && - (!obj._readableState || - ((_obj$_writableState = obj._writableState) === null || - _obj$_writableState === undefined - ? undefined - : _obj$_writableState.writable) !== false) - ) // Duplex - ); -} - -export function isDuplexNodeStream(obj) { - return !!( - obj && - typeof obj.pipe === "function" && - obj._readableState && - typeof obj.on === "function" && - typeof obj.write === "function" - ); -} - -export function isNodeStream(obj) { - return ( - obj && - (obj._readableState || - obj._writableState || - (typeof obj.write === "function" && typeof obj.on === "function") || - (typeof obj.pipe === "function" && typeof obj.on === "function")) - ); -} - -export function isIterable(obj, isAsync = false) { - if (obj == null) return false; - if (isAsync === true) return typeof obj[Symbol.asyncIterator] === "function"; - if (isAsync === false) return typeof obj[Symbol.iterator] === "function"; - return ( - typeof obj[Symbol.asyncIterator] === "function" || - typeof obj[Symbol.iterator] === "function" - ); -} - -export function isDestroyed(stream) { - if (!isNodeStream(stream)) return null; - const wState = stream._writableState; - const rState = stream._readableState; - const state = wState || rState; - return !!( - stream.destroyed || - stream[kDestroyed] || - (state !== null && state !== undefined && state.destroyed) - ); -} - -export function isWritableEnded(stream) { - if (!isWritableNodeStream(stream)) return null; - if (stream.writableEnded === true) return true; - const wState = stream._writableState; - if (wState !== null && wState !== undefined && wState.errored) return false; - if (typeof (wState === null || wState === undefined ? undefined : wState.ended) !== "boolean") - return null; - return wState.ended; -} - -export function isWritableFinished(stream, strict = false) { - if (!isWritableNodeStream(stream)) return null; - if (stream.writableFinished === true) return true; - const wState = stream._writableState; - if (wState !== null && wState !== undefined && wState.errored) return false; - if ( - typeof (wState === null || wState === undefined ? undefined : wState.finished) !== "boolean" - ) - return null; - return !!( - wState.finished || - (strict === false && wState.ended === true && wState.length === 0) - ); -} - -export function isReadableEnded(stream) { - if (!isReadableNodeStream(stream)) return null; - if (stream.readableEnded === true) return true; - const rState = stream._readableState; - if (!rState || rState.errored) return false; - if (typeof (rState === null || rState === undefined ? undefined : rState.ended) !== "boolean") - return null; - return rState.ended; -} - -export function isReadableFinished(stream, strict = false) { - if (!isReadableNodeStream(stream)) return null; - const rState = stream._readableState; - if (rState !== null && rState !== undefined && rState.errored) return false; - if ( - typeof (rState === null || rState === undefined ? undefined : rState.endEmitted) !== - "boolean" - ) - return null; - return !!( - rState.endEmitted || - (strict === false && rState.ended === true && rState.length === 0) - ); -} - -export function isReadable(stream) { - if (stream && stream[kIsReadable] != null) return stream[kIsReadable]; - if ( - typeof (stream === null || stream === undefined ? undefined : stream.readable) !== "boolean" - ) - return null; - if (isDestroyed(stream)) return false; - return isReadableNodeStream(stream) && stream.readable && !isReadableFinished(stream); -} - -export function isWritable(stream) { - if ( - typeof (stream === null || stream === undefined ? undefined : stream.writable) !== "boolean" - ) - return null; - if (isDestroyed(stream)) return false; - return isWritableNodeStream(stream) && stream.writable && !isWritableEnded(stream); -} - -export function isFinished(stream, opts = {}) { - if (!isNodeStream(stream)) { - return null; - } - if (isDestroyed(stream)) { - return true; - } - if ( - (opts === null || opts === undefined ? undefined : opts.readable) !== false && - isReadable(stream) - ) { - return false; - } - if ( - (opts === null || opts === undefined ? undefined : opts.writable) !== false && - isWritable(stream) - ) { - return false; - } - return true; -} - -export function isWritableErrored(stream) { - let _stream$_writableStat, _stream$_writableStat2; - if (!isNodeStream(stream)) { - return null; - } - if (stream.writableErrored) { - return stream.writableErrored; - } - return (_stream$_writableStat = - (_stream$_writableStat2 = stream._writableState) === null || - _stream$_writableStat2 === undefined - ? undefined - : _stream$_writableStat2.errored) !== null && _stream$_writableStat !== undefined - ? _stream$_writableStat - : null; -} - -export function isReadableErrored(stream) { - let _stream$_readableStat, _stream$_readableStat2; - if (!isNodeStream(stream)) { - return null; - } - if (stream.readableErrored) { - return stream.readableErrored; - } - return (_stream$_readableStat = - (_stream$_readableStat2 = stream._readableState) === null || - _stream$_readableStat2 === undefined - ? undefined - : _stream$_readableStat2.errored) !== null && _stream$_readableStat !== undefined - ? _stream$_readableStat - : null; -} - -export function isClosed(stream) { - if (!isNodeStream(stream)) { - return null; - } - if (typeof stream.closed === "boolean") { - return stream.closed; - } - const wState = stream._writableState; - const rState = stream._readableState; - if ( - typeof (wState === null || wState === undefined ? undefined : wState.closed) === - "boolean" || - typeof (rState === null || rState === undefined ? undefined : rState.closed) === "boolean" - ) { - return ( - (wState === null || wState === undefined ? undefined : wState.closed) || - (rState === null || rState === undefined ? undefined : rState.closed) - ); - } - if (typeof stream._closed === "boolean" && isOutgoingMessage(stream)) { - return stream._closed; - } - return null; -} - -// TODO(later): We do not actually support OutgoingMessage yet. Might not ever? -// Keeping this here tho just to keep things simple. -export function isOutgoingMessage(stream) { - return ( - typeof stream._closed === "boolean" && - typeof stream._defaultKeepAlive === "boolean" && - typeof stream._removedConnection === "boolean" && - typeof stream._removedContLen === "boolean" - ); -} - -// TODO(later): We do not actually support Server Response yet. Might not ever? -// Keeping this here tho just to keep things simple. -export function isServerResponse(stream) { - return typeof stream._sent100 === "boolean" && isOutgoingMessage(stream); -} - -// TODO(later): We do not actually support Server Request yet. Might not ever? -// Keeping this here tho just to keep things simple. -export function isServerRequest(stream) { - let _stream$req; - return ( - typeof stream._consuming === "boolean" && - typeof stream._dumped === "boolean" && - ((_stream$req = stream.req) === null || _stream$req === undefined - ? undefined - : _stream$req.upgradeOrConnect) === undefined - ); -} - -export function willEmitClose(stream) { - if (!isNodeStream(stream)) return null; - const wState = stream._writableState; - const rState = stream._readableState; - const state = wState || rState; - return ( - (!state && isServerResponse(stream)) || - !!(state && state.autoDestroy && state.emitClose && state.closed === false) - ); -} - -export function isDisturbed(stream) { - let _stream$kIsDisturbed; - return !!( - stream && - ((_stream$kIsDisturbed = stream[kIsDisturbed]) !== null && - _stream$kIsDisturbed !== undefined - ? _stream$kIsDisturbed - : stream.readableDidRead || stream.readableAborted) - ); -} - -export function isErrored(stream) { - var _ref, - _ref2, - _ref3, - _ref4, - _ref5, - _stream$kIsErrored, - _stream$_readableStat3, - _stream$_writableStat3, - _stream$_readableStat4, - _stream$_writableStat4; - return !!( - stream && - ((_ref = - (_ref2 = - (_ref3 = - (_ref4 = - (_ref5 = - (_stream$kIsErrored = stream[kIsErrored]) !== null && - _stream$kIsErrored !== undefined - ? _stream$kIsErrored - : stream.readableErrored) !== null && _ref5 !== undefined - ? _ref5 - : stream.writableErrored) !== null && _ref4 !== undefined - ? _ref4 - : (_stream$_readableStat3 = stream._readableState) === null || - _stream$_readableStat3 === undefined - ? undefined - : _stream$_readableStat3.errorEmitted) !== null && _ref3 !== undefined - ? _ref3 - : (_stream$_writableStat3 = stream._writableState) === null || - _stream$_writableStat3 === undefined - ? undefined - : _stream$_writableStat3.errorEmitted) !== null && _ref2 !== undefined - ? _ref2 - : (_stream$_readableStat4 = stream._readableState) === null || - _stream$_readableStat4 === undefined - ? undefined - : _stream$_readableStat4.errored) !== null && _ref !== undefined - ? _ref - : (_stream$_writableStat4 = stream._writableState) === null || - _stream$_writableStat4 === undefined - ? undefined - : _stream$_writableStat4.errored) - ); -} - -export const nop = () => {}; - -export function once(callback) { - let called = false; - return function (...args) { - if (called) { - return; - } - called = true; - callback.apply(this, args); - }; -} - -// ====================================================================================== -// highWaterMark handling - -export function highWaterMarkFrom(options, isDuplex, duplexKey) { - return options.highWaterMark != null - ? options.highWaterMark - : isDuplex - ? options[duplexKey] - : null; -} - -export function getDefaultHighWaterMark(objectMode = false) { - return objectMode ? 16 : 16 * 1024; -} - -export function getHighWaterMark(state, options, duplexKey, isDuplex) { - const hwm = highWaterMarkFrom(options, isDuplex, duplexKey); - if (hwm != null) { - if (!Number.isInteger(hwm) || hwm < 0) { - const name = isDuplex ? `options.${duplexKey}` : "options.highWaterMark"; - throw new ERR_INVALID_ARG_VALUE(name, hwm, name); - } - return Math.floor(hwm); - } - - // Default value - return getDefaultHighWaterMark(state.objectMode); -} - -// ====================================================================================== -// addAbortSignal - -export function addAbortSignal(signal, stream) { - validateAbortSignal(signal, "signal"); - if (!isNodeStream(stream)) { - throw new ERR_INVALID_ARG_TYPE("stream", "stream.Stream", stream); - } - const onAbort = () => { - stream.destroy( - new AbortError(undefined, { - cause: signal.reason, - }) - ); - }; - if (signal.aborted) { - onAbort(); - } else { - signal.addEventListener("abort", onAbort); - eos(stream, () => signal.removeEventListener("abort", onAbort)); - } - return stream; -} - -// ====================================================================================== -// BufferList - -export class BufferList { - head = null; - tail = null; - length = 0; - - push(v) { - const entry = { - data: v, - next: null, - }; - if (this.length > 0) this.tail.next = entry; - else this.head = entry; - this.tail = entry; - ++this.length; - } - unshift(v) { - const entry = { - data: v, - next: this.head, - }; - if (this.length === 0) this.tail = entry; - this.head = entry; - ++this.length; - } - shift() { - if (this.length === 0) return; - const ret = this.head.data; - if (this.length === 1) this.head = this.tail = null; - else this.head = this.head.next; - --this.length; - return ret; - } - - clear() { - this.head = this.tail = null; - this.length = 0; - } - - join(s) { - if (this.length === 0) return ""; - let p = this.head; - let ret = "" + p.data; - while ((p = p.next) !== null) ret += s + p.data; - return ret; - } - - concat(n) { - if (this.length === 0) return Buffer.alloc(0); - const ret = Buffer.allocUnsafe(n >>> 0); - let p = this.head; - let i = 0; - while (p) { - ret.set(p.data, i); - i += p.data.length; - p = p.next; - } - return ret; - } - - consume(n, hasStrings = false) { - const data = this.head.data; - if (n < data.length) { - // `slice` is the same for buffers and strings. - const slice = data.slice(0, n); - this.head.data = data.slice(n); - return slice; - } - if (n === data.length) { - // First chunk is a perfect match. - return this.shift(); - } - // Result spans more than one buffer. - return hasStrings ? this._getString(n) : this._getBuffer(n); - } - - first() { - return this.head.data; - } - - *[Symbol.iterator]() { - for (let p = this.head; p; p = p.next) { - yield p.data; - } - } - - _getString(n) { - let ret = ""; - let p = this.head; - let c = 0; - do { - const str = p.data; - if (n > str.length) { - ret += str; - n -= str.length; - } else { - if (n === str.length) { - ret += str; - ++c; - if (p.next) this.head = p.next; - else this.head = this.tail = null; - } else { - ret += str.slice(0, n); - this.head = p; - p.data = str.slice(n); - } - break; - } - ++c; - } while ((p = p.next) !== null); - this.length -= c; - return ret; - } - - _getBuffer(n) { - const ret = Buffer.allocUnsafe(n); - const retLen = n; - let p = this.head; - let c = 0; - do { - const buf = p.data; - if (n > buf.length) { - ret.set(buf, retLen - n); - n -= buf.length; - } else { - if (n === buf.length) { - ret.set(buf, retLen - n); - ++c; - if (p.next) this.head = p.next; - else this.head = this.tail = null; - } else { - ret.set(new Uint8Array(buf.buffer, buf.byteOffset, n), retLen - n); - this.head = p; - p.data = buf.slice(n); - } - break; - } - ++c; - } while ((p = p.next) !== null); - this.length -= c; - return ret; - } -} - -// ====================================================================================== - -// TODO(later): We do not current implement Node.js' Request object. Might never? -function isRequest(stream) { - return stream && stream.setHeader && typeof stream.abort === "function"; -} - -export function eos(stream, options, callback) { - let _options$readable, _options$writable; - if (arguments.length === 2) { - callback = options; - options = {}; - } else if (options == null) { - options = {}; - } else { - validateObject(options, "options", options); - } - validateFunction(callback, "callback"); - validateAbortSignal(options.signal, "options.signal"); - callback = once(callback); - const readable = - (_options$readable = options.readable) !== null && _options$readable !== undefined - ? _options$readable - : isReadableNodeStream(stream); - const writable = - (_options$writable = options.writable) !== null && _options$writable !== undefined - ? _options$writable - : isWritableNodeStream(stream); - if (!isNodeStream(stream)) { - // TODO: Webstreams. - throw new ERR_INVALID_ARG_TYPE("stream", "Stream", stream); - } - const wState = stream._writableState; - const rState = stream._readableState; - const onlegacyfinish = () => { - if (!stream.writable) { - onfinish(); - } - }; - - // TODO (ronag): Improve soft detection to include core modules and - // common ecosystem modules that do properly emit 'close' but fail - // this generic check. - let _willEmitClose = - willEmitClose(stream) && - isReadableNodeStream(stream) === readable && - isWritableNodeStream(stream) === writable; - let writableFinished = isWritableFinished(stream, false); - const onfinish = () => { - writableFinished = true; - // Stream should not be destroyed here. If it is that - // means that user space is doing something differently and - // we cannot trust willEmitClose. - if (stream.destroyed) { - _willEmitClose = false; - } - if (_willEmitClose && (!stream.readable || readable)) { - return; - } - if (!readable || readableFinished) { - callback.call(stream); - } - }; - let readableFinished = isReadableFinished(stream, false); - const onend = () => { - readableFinished = true; - // Stream should not be destroyed here. If it is that - // means that user space is doing something differently and - // we cannot trust willEmitClose. - if (stream.destroyed) { - _willEmitClose = false; - } - if (_willEmitClose && (!stream.writable || writable)) { - return; - } - if (!writable || writableFinished) { - callback.call(stream); - } - }; - const onerror = (err) => { - callback.call(stream, err); - }; - let closed = isClosed(stream); - const onclose = () => { - closed = true; - const errored = isWritableErrored(stream) || isReadableErrored(stream); - if (errored && typeof errored !== "boolean") { - return callback.call(stream, errored); - } - if (readable && !readableFinished && isReadableNodeStream(stream, true)) { - if (!isReadableFinished(stream, false)) - return callback.call(stream, new ERR_STREAM_PREMATURE_CLOSE()); - } - if (writable && !writableFinished) { - if (!isWritableFinished(stream, false)) - return callback.call(stream, new ERR_STREAM_PREMATURE_CLOSE()); - } - callback.call(stream); - }; - const onrequest = () => { - stream.req.on("finish", onfinish); - }; - if (isRequest(stream)) { - stream.on("complete", onfinish); - if (!_willEmitClose) { - stream.on("abort", onclose); - } - if (stream.req) { - onrequest(); - } else { - stream.on("request", onrequest); - } - } else if (writable && !wState) { - // legacy streams - stream.on("end", onlegacyfinish); - stream.on("close", onlegacyfinish); - } - - // Not all streams will emit 'close' after 'aborted'. - if (!_willEmitClose && typeof stream.aborted === "boolean") { - stream.on("aborted", onclose); - } - stream.on("end", onend); - stream.on("finish", onfinish); - if (options.error !== false) { - stream.on("error", onerror); - } - stream.on("close", onclose); - if (closed) { - process.nextTick(onclose); - } else if ( - (wState !== null && wState !== undefined && wState.errorEmitted) || - (rState !== null && rState !== undefined && rState.errorEmitted) - ) { - if (!_willEmitClose) { - process.nextTick(onclose); - } - } else if ( - !readable && - (!_willEmitClose || isReadable(stream)) && - (writableFinished || isWritable(stream) === false) - ) { - process.nextTick(onclose); - } else if ( - !writable && - (!_willEmitClose || isWritable(stream)) && - (readableFinished || isReadable(stream) === false) - ) { - process.nextTick(onclose); - } else if (rState && stream.req && stream.aborted) { - process.nextTick(onclose); - } - const cleanup = () => { - callback = nop; - stream.removeListener("aborted", onclose); - stream.removeListener("complete", onfinish); - stream.removeListener("abort", onclose); - stream.removeListener("request", onrequest); - if (stream.req) stream.req.removeListener("finish", onfinish); - stream.removeListener("end", onlegacyfinish); - stream.removeListener("close", onlegacyfinish); - stream.removeListener("finish", onfinish); - stream.removeListener("end", onend); - stream.removeListener("error", onerror); - stream.removeListener("close", onclose); - }; - if (options.signal && !closed) { - const abort = () => { - // Keep it because cleanup removes it. - const endCallback = callback; - cleanup(); - endCallback.call( - stream, - new AbortError(undefined, { - cause: options.signal?.reason, - }) - ); - }; - if (options.signal.aborted) { - process.nextTick(abort); - } else { - const originalCallback = callback; - callback = once((...args) => { - options.signal.removeEventListener("abort", abort); - originalCallback.apply(stream, args); - }); - options.signal.addEventListener("abort", abort); - } - } - return cleanup; -} - -export function finished(stream, opts) { - return new Promise((resolve, reject) => { - eos(stream, opts, (err) => { - if (err) { - reject(err); - } else { - resolve(); - } - }); - }); -} - -eos.finished = finished; - -// ====================================================================================== -// Destroy - -function checkError(err, w, r) { - if (err) { - // Avoid V8 leak, https://github.com/nodejs/node/pull/34103#issuecomment-652002364 - err.stack; // eslint-disable-line no-unused-expressions - - if (w && !w.errored) { - w.errored = err; - } - if (r && !r.errored) { - r.errored = err; - } - } -} - -export function destroy(err, cb) { - const r = this._readableState; - const w = this._writableState; - // With duplex streams we use the writable side for state. - const s = w || r; - if ((w && w.destroyed) || (r && r.destroyed)) { - if (typeof cb === "function") { - cb(); - } - return this; - } - - // We set destroyed to true before firing error callbacks in order - // to make it re-entrance safe in case destroy() is called within callbacks - checkError(err, w, r); - if (w) { - w.destroyed = true; - } - if (r) { - r.destroyed = true; - } - - // If still constructing then defer calling _destroy. - if (!s.constructed) { - this.once(kDestroy, function (er) { - _destroy(this, aggregateTwoErrors(er, err), cb); - }); - } else { - _destroy(this, err, cb); - } - return this; -} - -function _destroy(self, err, cb) { - let called = false; - function onDestroy(err) { - if (called) { - return; - } - called = true; - const r = self._readableState; - const w = self._writableState; - checkError(err, w, r); - if (w) { - w.closed = true; - } - if (r) { - r.closed = true; - } - if (typeof cb === "function") { - cb(err); - } - if (err) { - process.nextTick(emitErrorCloseNT, self, err); - } else { - process.nextTick(emitCloseNT, self); - } - } - try { - self._destroy(err || null, onDestroy); - } catch (err) { - onDestroy(err); - } -} - -function emitErrorCloseNT(self, err) { - emitErrorNT(self, err); - emitCloseNT(self); -} - -function emitCloseNT(self) { - const r = self._readableState; - const w = self._writableState; - if (w) { - w.closeEmitted = true; - } - if (r) { - r.closeEmitted = true; - } - if ((w && w.emitClose) || (r && r.emitClose)) { - self.emit("close"); - } -} - -function emitErrorNT(self, err) { - const r = self._readableState; - const w = self._writableState; - if ((w && w.errorEmitted) || (r && r.errorEmitted)) { - return; - } - if (w) { - w.errorEmitted = true; - } - if (r) { - r.errorEmitted = true; - } - self.emit("error", err); -} - -export function undestroy() { - const r = this._readableState; - const w = this._writableState; - if (r) { - r.constructed = true; - r.closed = false; - r.closeEmitted = false; - r.destroyed = false; - r.errored = null; - r.errorEmitted = false; - r.reading = false; - r.ended = r.readable === false; - r.endEmitted = r.readable === false; - } - if (w) { - w.constructed = true; - w.destroyed = false; - w.closed = false; - w.closeEmitted = false; - w.errored = null; - w.errorEmitted = false; - w.finalCalled = false; - w.prefinished = false; - w.ended = w.writable === false; - w.ending = w.writable === false; - w.finished = w.writable === false; - } -} - -export function errorOrDestroy(stream, err, sync = false) { - // We have tests that rely on errors being emitted - // in the same tick, so changing this is semver major. - // For now when you opt-in to autoDestroy we allow - // the error to be emitted nextTick. In a future - // semver major update we should change the default to this. - - const r = stream._readableState; - const w = stream._writableState; - if ((w && w.destroyed) || (r && r.destroyed)) { - return; - } - if ((r && r.autoDestroy) || (w && w.autoDestroy)) stream.destroy(err); - else if (err) { - // Avoid V8 leak, https://github.com/nodejs/node/pull/34103#issuecomment-652002364 - err.stack; // eslint-disable-line no-unused-expressions - - if (w && !w.errored) { - w.errored = err; - } - if (r && !r.errored) { - r.errored = err; - } - if (sync) { - process.nextTick(emitErrorNT, stream, err); - } else { - emitErrorNT(stream, err); - } - } -} - -export function construct(stream, cb) { - if (typeof stream._construct !== "function") { - return; - } - const r = stream._readableState; - const w = stream._writableState; - if (r) { - r.constructed = false; - } - if (w) { - w.constructed = false; - } - stream.once(kConstruct, cb); - if (stream.listenerCount(kConstruct) > 1) { - // Duplex - return; - } - process.nextTick(constructNT, stream); -} - -function constructNT(stream) { - let called = false; - function onConstruct(err) { - if (called) { - errorOrDestroy( - stream, - err !== null && err !== undefined ? err : new ERR_MULTIPLE_CALLBACK() - ); - return; - } - called = true; - const r = stream._readableState; - const w = stream._writableState; - const s = w || r; - if (r) { - r.constructed = true; - } - if (w) { - w.constructed = true; - } - if (s.destroyed) { - stream.emit(kDestroy, err); - } else if (err) { - errorOrDestroy(stream, err, true); - } else { - process.nextTick(emitConstructNT, stream); - } - } - try { - stream._construct(onConstruct); - } catch (err) { - onConstruct(err); - } -} - -function emitConstructNT(stream) { - stream.emit(kConstruct); -} - -function emitCloseLegacy(stream) { - stream.emit("close"); -} - -function emitErrorCloseLegacy(stream, err) { - stream.emit("error", err); - process.nextTick(emitCloseLegacy, stream); -} - -// Normalize destroy for legacy. -export function destroyer(stream, err) { - if (!stream || isDestroyed(stream)) { - return; - } - if (!err && !isFinished(stream)) { - err = new AbortError(); - } - - // TODO: Remove isRequest branches. - if (isServerRequest(stream)) { - stream.socket = null; - stream.destroy(err); - } else if (isRequest(stream)) { - stream.abort(); - } else if (isRequest(stream.req)) { - stream.req.abort(); - } else if (typeof stream.destroy === "function") { - stream.destroy(err); - } else if (typeof stream.close === "function") { - // TODO: Don't lose err? - stream.close(); - } else if (err) { - process.nextTick(emitErrorCloseLegacy, stream, err); - } else { - process.nextTick(emitCloseLegacy, stream); - } - if (!stream.destroyed) { - stream[kDestroyed] = true; - } -} diff --git a/JS/wasm/crates/wasmjs-engine/shims/src/internal/streams_writable.js b/JS/wasm/crates/wasmjs-engine/shims/src/internal/streams_writable.js deleted file mode 100644 index 6a288b6d6..000000000 --- a/JS/wasm/crates/wasmjs-engine/shims/src/internal/streams_writable.js +++ /dev/null @@ -1,816 +0,0 @@ -import EventEmitter from "./events"; - -import { Stream } from "./streams_legacy"; - -import { Buffer } from "./internal_buffer"; - -import * as process from "./process"; - -import { - nop, - kOnFinished, - getHighWaterMark, - getDefaultHighWaterMark, - addAbortSignal, - construct, - destroy, - undestroy, - errorOrDestroy, -} from "./streams_util"; - -import { - newStreamWritableFromWritableStream, - newWritableStreamFromStreamWritable, -} from "./streams_adapters"; - -import { - ERR_INVALID_ARG_TYPE, - ERR_METHOD_NOT_IMPLEMENTED, - ERR_MULTIPLE_CALLBACK, - ERR_STREAM_CANNOT_PIPE, - ERR_STREAM_DESTROYED, - ERR_STREAM_ALREADY_FINISHED, - ERR_STREAM_NULL_VALUES, - ERR_STREAM_WRITE_AFTER_END, - ERR_UNKNOWN_ENCODING, -} from "./internal_errors"; - -import { isDuplexInstance } from "./streams_duplex"; - -// ====================================================================================== -// WritableState - -function WritableState(options, stream, isDuplex) { - // Duplex streams are both readable and writable, but share - // the same options object. - // However, some cases require setting options to different - // values for the readable and the writable sides of the duplex stream, - // e.g. options.readableObjectMode vs. options.writableObjectMode, etc. - if (typeof isDuplex !== "boolean") isDuplex = isDuplexInstance(stream); - - // Object stream flag to indicate whether or not this stream - // contains buffers or objects. - this.objectMode = !!options?.objectMode; - if (isDuplex) this.objectMode = this.objectMode || !!options?.writableObjectMode; - - // The point at which write() starts returning false - // Note: 0 is a valid value, means that we always return false if - // the entire buffer is not flushed immediately on write(). - this.highWaterMark = options - ? getHighWaterMark(this, options, "writableHighWaterMark", isDuplex) - : getDefaultHighWaterMark(false); - - // if _final has been called. - this.finalCalled = false; - - // drain event flag. - this.needDrain = false; - // At the start of calling end() - this.ending = false; - // When end() has been called, and returned. - this.ended = false; - // When 'finish' is emitted. - this.finished = false; - - // Has it been destroyed - this.destroyed = false; - - // Should we decode strings into buffers before passing to _write? - // this is here so that some node-core streams can optimize string - // handling at a lower level. - const noDecode = !!(options?.decodeStrings === false); - this.decodeStrings = !noDecode; - - // Crypto is kind of old and crusty. Historically, its default string - // encoding is 'binary' so we have to make this configurable. - // Everything else in the universe uses 'utf8', though. - this.defaultEncoding = options?.defaultEncoding || "utf8"; - - // Not an actual buffer we keep track of, but a measurement - // of how much we're waiting to get pushed to some underlying - // socket or file. - this.length = 0; - - // A flag to see when we're in the middle of a write. - this.writing = false; - - // When true all writes will be buffered until .uncork() call. - this.corked = 0; - - // A flag to be able to tell if the onwrite cb is called immediately, - // or on a later tick. We set this to true at first, because any - // actions that shouldn't happen until "later" should generally also - // not happen before the first write call. - this.sync = true; - - // A flag to know if we're processing previously buffered items, which - // may call the _write() callback in the same tick, so that we don't - // end up in an overlapped onwrite situation. - this.bufferProcessing = false; - - // The callback that's passed to _write(chunk, cb). - this.onwrite = (err) => onwrite.call(undefined, stream, err); - - // The callback that the user supplies to write(chunk, encoding, cb). - this.writecb = null; - - // The amount that is being written when _write is called. - this.writelen = 0; - - // Storage for data passed to the afterWrite() callback in case of - // synchronous _write() completion. - this.afterWriteTickInfo = null; - resetBuffer(this); - - // Number of pending user-supplied write callbacks - // this must be 0 before 'finish' can be emitted. - this.pendingcb = 0; - - // Stream is still being constructed and cannot be - // destroyed until construction finished or failed. - // Async construction is opt in, therefore we start as - // constructed. - this.constructed = true; - - // Emit prefinish if the only thing we're waiting for is _write cbs - // This is relevant for synchronous Transform streams. - this.prefinished = false; - - // True if the error was already emitted and should not be thrown again. - this.errorEmitted = false; - - // Should close be emitted on destroy. Defaults to true. - this.emitClose = !options || options.emitClose !== false; - - // Should .destroy() be called after 'finish' (and potentially 'end'). - this.autoDestroy = !options || options.autoDestroy !== false; - - // Indicates whether the stream has errored. When true all write() calls - // should return false. This is needed since when autoDestroy - // is disabled we need a way to tell whether the stream has failed. - this.errored = null; - - // Indicates whether the stream has finished destroying. - this.closed = false; - - // True if close has been emitted or would have been emitted - // depending on emitClose. - this.closeEmitted = false; - this[kOnFinished] = []; -} - -function resetBuffer(state) { - state.buffered = []; - state.bufferedIndex = 0; - state.allBuffers = true; - state.allNoop = true; -} - -WritableState.prototype.getBuffer = function getBuffer() { - return this.buffered.slice(this.bufferedIndex); -}; - -Object.defineProperty(WritableState.prototype, "bufferedRequestCount", { - get() { - return this.buffered.length - this.bufferedIndex; - }, -}); - -// ====================================================================================== -// Writable - -Writable.WritableState = WritableState; - -Object.setPrototypeOf(Writable.prototype, Stream.prototype); -Object.setPrototypeOf(Writable, Stream); - -export function Writable(options) { - // Writable ctor is applied to Duplexes, too. - // `realHasInstance` is necessary because using plain `instanceof` - // would return false, as no `_writableState` property is attached. - - // Trying to use the custom `instanceof` for Writable here will also break the - // Node.js LazyTransform implementation, which has a non-trivial getter for - // `_writableState` that would lead to infinite recursion. - - // Checking for a Stream.Duplex instance is faster here instead of inside - // the WritableState constructor, at least with V8 6.5. - const isDuplex = isDuplexInstance(this); - if (!isDuplex && !Writable[Symbol.hasInstance](this)) return new Writable(options); - this._writableState = new WritableState(options, this, isDuplex); - if (options) { - if (typeof options.write === "function") this._write = options.write; - if (typeof options.writev === "function") this._writev = options.writev; - if (typeof options.destroy === "function") this._destroy = options.destroy; - if (typeof options.final === "function") this._final = options.final; - if (typeof options.construct === "function") this._construct = options.construct; - if (options.signal) addAbortSignal(options.signal, this); - } - Stream.call(this, options); - construct(this, () => { - const state = this._writableState; - if (!state.writing) { - clearBuffer(this, state); - } - finishMaybe(this, state); - }); -} - -Object.defineProperty(Writable, Symbol.hasInstance, { - value: function (object) { - if (Function.prototype[Symbol.hasInstance].call(this, object)) return true; - if (this !== Writable) return false; - return object?._writableState instanceof WritableState; - }, -}); - -// Otherwise people can pipe Writable streams, which is just wrong. -Writable.prototype.pipe = function (_1, _2) { - errorOrDestroy(this, new ERR_STREAM_CANNOT_PIPE()); -}; - -function _write(stream, chunk, encoding, cb) { - const state = stream._writableState; - if (typeof encoding === "function") { - cb = encoding; - encoding = state.defaultEncoding; - } else { - if (!encoding) encoding = state.defaultEncoding; - else if (encoding !== "buffer" && !Buffer.isEncoding(encoding)) { - throw new ERR_UNKNOWN_ENCODING(encoding); - } - if (typeof cb !== "function") cb = nop; - } - if (chunk === null) { - throw new ERR_STREAM_NULL_VALUES(); - } else if (!state.objectMode) { - if (typeof chunk === "string") { - if (state.decodeStrings !== false) { - chunk = Buffer.from(chunk, encoding); - encoding = "buffer"; - } - } else if (chunk instanceof Buffer) { - encoding = "buffer"; - } else if (Stream._isUint8Array(chunk)) { - chunk = Stream._uint8ArrayToBuffer(chunk); - encoding = "buffer"; - } else { - throw new ERR_INVALID_ARG_TYPE("chunk", ["string", "Buffer", "Uint8Array"], chunk); - } - } - let err; - if (state.ending) { - err = new ERR_STREAM_WRITE_AFTER_END(); - } else if (state.destroyed) { - err = new ERR_STREAM_DESTROYED("write"); - } - if (err) { - process.nextTick(cb, err); - errorOrDestroy(stream, err, true); - return err; - } - state.pendingcb++; - return writeOrBuffer(stream, state, chunk, encoding, cb); -} - -function write(chunk, encoding, cb) { - return _write(this, chunk, encoding, cb) === true; -} - -Writable.prototype.write = write; - -Writable.prototype.cork = function () { - this._writableState.corked++; -}; - -Writable.prototype.uncork = function () { - const state = this._writableState; - if (state.corked) { - state.corked--; - if (!state.writing) clearBuffer(this, state); - } -}; - -function setDefaultEncoding(encoding) { - if (typeof encoding === "string") encoding = encoding.toLowerCase(); - if (!Buffer.isEncoding(encoding)) throw new ERR_UNKNOWN_ENCODING(encoding); - this._writableState.defaultEncoding = encoding; - return this; -} - -Writable.prototype.setDefaultEncoding = setDefaultEncoding; - -// If we're already writing something, then just put this -// in the queue, and wait our turn. Otherwise, call _write -// If we return false, then we need a drain event, so set that flag. -function writeOrBuffer(stream, state, chunk, encoding, callback) { - const len = state.objectMode ? 1 : chunk.length; - state.length += len; - - // stream._write resets state.length - const ret = state.length < state.highWaterMark; - // We must ensure that previous needDrain will not be reset to false. - if (!ret) state.needDrain = true; - if (state.writing || state.corked || state.errored || !state.constructed) { - state.buffered.push({ - chunk, - encoding, - callback, - }); - if (state.allBuffers && encoding !== "buffer") { - state.allBuffers = false; - } - if (state.allNoop && callback !== nop) { - state.allNoop = false; - } - } else { - state.writelen = len; - state.writecb = callback; - state.writing = true; - state.sync = true; - stream._write(chunk, encoding, state.onwrite); - state.sync = false; - } - - // Return false if errored or destroyed in order to break - // any synchronous while(stream.write(data)) loops. - return ret && !state.errored && !state.destroyed; -} - -function doWrite(stream, state, writev, len, chunk, encoding, cb) { - state.writelen = len; - state.writecb = cb; - state.writing = true; - state.sync = true; - if (state.destroyed) state.onwrite(new ERR_STREAM_DESTROYED("write")); - else if (writev) stream._writev(chunk, state.onwrite); - else stream._write(chunk, encoding, state.onwrite); - state.sync = false; -} - -function onwriteError(stream, state, er, cb) { - --state.pendingcb; - cb(er); - // Ensure callbacks are invoked even when autoDestroy is - // not enabled. Passing `er` here doesn't make sense since - // it's related to one specific write, not to the buffered - // writes. - errorBuffer(state); - // This can emit error, but error must always follow cb. - errorOrDestroy(stream, er); -} - -function onwrite(stream, er) { - const state = stream._writableState; - const sync = state.sync; - const cb = state.writecb; - if (typeof cb !== "function") { - errorOrDestroy(stream, new ERR_MULTIPLE_CALLBACK()); - return; - } - state.writing = false; - state.writecb = null; - state.length -= state.writelen; - state.writelen = 0; - if (er) { - // Avoid V8 leak, https://github.com/nodejs/node/pull/34103#issuecomment-652002364 - er.stack; // eslint-disable-line no-unused-expressions - - if (!state.errored) { - state.errored = er; - } - - // In case of duplex streams we need to notify the readable side of the - // error. - if (stream._readableState && !stream._readableState.errored) { - stream._readableState.errored = er; - } - if (sync) { - process.nextTick(onwriteError, stream, state, er, cb); - } else { - onwriteError(stream, state, er, cb); - } - } else { - if (state.buffered.length > state.bufferedIndex) { - clearBuffer(stream, state); - } - if (sync) { - // It is a common case that the callback passed to .write() is always - // the same. In that case, we do not schedule a new nextTick(), but - // rather just increase a counter, to improve performance and avoid - // memory allocations. - if (state.afterWriteTickInfo !== null && state.afterWriteTickInfo.cb === cb) { - state.afterWriteTickInfo.count++; - } else { - state.afterWriteTickInfo = { - count: 1, - cb, - stream, - state, - }; - process.nextTick(afterWriteTick, state.afterWriteTickInfo); - } - } else { - afterWrite(stream, state, 1, cb); - } - } -} - -function afterWriteTick({ stream, state, count, cb }) { - state.afterWriteTickInfo = null; - return afterWrite(stream, state, count, cb); -} - -function afterWrite(stream, state, count, cb) { - const needDrain = !state.ending && !stream.destroyed && state.length === 0 && state.needDrain; - if (needDrain) { - state.needDrain = false; - stream.emit("drain"); - } - while (count-- > 0) { - state.pendingcb--; - cb(); - } - if (state.destroyed) { - errorBuffer(state); - } - finishMaybe(stream, state); -} - -// If there's something in the buffer waiting, then invoke callbacks. -function errorBuffer(state) { - if (state.writing) { - return; - } - for (let n = state.bufferedIndex; n < state.buffered.length; ++n) { - let _state$errored; - const { chunk, callback } = state.buffered[n]; - const len = state.objectMode ? 1 : chunk.length; - state.length -= len; - callback( - (_state$errored = state.errored) !== null && _state$errored !== undefined - ? _state$errored - : new ERR_STREAM_DESTROYED("write") - ); - } - const onfinishCallbacks = state[kOnFinished].splice(0); - for (let i = 0; i < onfinishCallbacks.length; i++) { - let _state$errored2; - onfinishCallbacks[i]( - (_state$errored2 = state.errored) !== null && _state$errored2 !== undefined - ? _state$errored2 - : new ERR_STREAM_DESTROYED("end") - ); - } - resetBuffer(state); -} - -// If there's something in the buffer waiting, then process it. -function clearBuffer(stream, state) { - if (state.corked || state.bufferProcessing || state.destroyed || !state.constructed) { - return; - } - const { buffered, bufferedIndex, objectMode } = state; - const bufferedLength = buffered.length - bufferedIndex; - if (!bufferedLength) { - return; - } - let i = bufferedIndex; - state.bufferProcessing = true; - if (bufferedLength > 1 && stream._writev) { - state.pendingcb -= bufferedLength - 1; - const callback = state.allNoop - ? nop - : (err) => { - for (let n = i; n < buffered.length; ++n) { - buffered[n].callback(err); - } - }; - // Make a copy of `buffered` if it's going to be used by `callback` above, - // since `doWrite` will mutate the array. - const chunks = state.allNoop && i === 0 ? buffered : buffered.slice(i); - chunks.allBuffers = state.allBuffers; - doWrite(stream, state, true, state.length, chunks, "", callback); - resetBuffer(state); - } else { - do { - const { chunk, encoding, callback } = buffered[i]; - buffered[i++] = null; - const len = objectMode ? 1 : chunk.length; - doWrite(stream, state, false, len, chunk, encoding, callback); - } while (i < buffered.length && !state.writing); - if (i === buffered.length) { - resetBuffer(state); - } else if (i > 256) { - buffered.splice(0, i); - state.bufferedIndex = 0; - } else { - state.bufferedIndex = i; - } - } - state.bufferProcessing = false; -} - -Writable.prototype._write = function (chunk, encoding, cb) { - if (this._writev) { - this._writev( - [ - { - chunk, - encoding, - }, - ], - cb - ); - } else { - throw new ERR_METHOD_NOT_IMPLEMENTED("_write()"); - } -}; - -Writable.prototype._writev = null; - -function end(chunk, encoding, cb) { - const state = this._writableState; - if (typeof chunk === "function") { - cb = chunk; - chunk = null; - encoding = null; - } else if (typeof encoding === "function") { - cb = encoding; - encoding = null; - } - let err; - if (chunk !== null && chunk !== undefined) { - const ret = _write(this, chunk, encoding); - if (ret instanceof Error) { - err = ret; - } - } - - // .end() fully uncorks. - if (state.corked) { - state.corked = 1; - this.uncork(); - } - if (err) { - // Do nothing... - } else if (!state.errored && !state.ending) { - // This is forgiving in terms of unnecessary calls to end() and can hide - // logic errors. However, usually such errors are harmless and causing a - // hard error can be disproportionately destructive. It is not always - // trivial for the user to determine whether end() needs to be called - // or not. - - state.ending = true; - finishMaybe(this, state, true); - state.ended = true; - } else if (state.finished) { - err = new ERR_STREAM_ALREADY_FINISHED("end"); - } else if (state.destroyed) { - err = new ERR_STREAM_DESTROYED("end"); - } - if (typeof cb === "function") { - if (err || state.finished) { - process.nextTick(cb, err); - } else { - state[kOnFinished].push(cb); - } - } - return this; -} - -Writable.prototype.end = end; - -function needFinish(state) { - return ( - state.ending && - !state.destroyed && - state.constructed && - state.length === 0 && - !state.errored && - state.buffered.length === 0 && - !state.finished && - !state.writing && - !state.errorEmitted && - !state.closeEmitted - ); -} - -function callFinal(stream, state) { - let called = false; - function onFinish(err) { - if (called) { - errorOrDestroy(stream, err || new ERR_MULTIPLE_CALLBACK()); - return; - } - called = true; - state.pendingcb--; - if (err) { - const onfinishCallbacks = state[kOnFinished].splice(0); - for (let i = 0; i < onfinishCallbacks.length; i++) { - onfinishCallbacks[i](err); - } - errorOrDestroy(stream, err, state.sync); - } else if (needFinish(state)) { - state.prefinished = true; - stream.emit("prefinish"); - // Backwards compat. Don't check state.sync here. - // Some streams assume 'finish' will be emitted - // asynchronously relative to _final callback. - state.pendingcb++; - process.nextTick(finish, stream, state); - } - } - state.sync = true; - state.pendingcb++; - try { - stream._final(onFinish); - } catch (err) { - onFinish(err); - } - state.sync = false; -} - -function prefinish(stream, state) { - if (!state.prefinished && !state.finalCalled) { - if (typeof stream._final === "function" && !state.destroyed) { - state.finalCalled = true; - callFinal(stream, state); - } else { - state.prefinished = true; - stream.emit("prefinish"); - } - } -} - -function finishMaybe(stream, state, sync = false) { - if (needFinish(state)) { - prefinish(stream, state); - if (state.pendingcb === 0) { - if (sync) { - state.pendingcb++; - process.nextTick(() => { - ((stream, state) => { - if (needFinish(state)) { - finish(stream, state); - } else { - state.pendingcb--; - } - })(stream, state); - }); - } else if (needFinish(state)) { - state.pendingcb++; - finish(stream, state); - } - } - } -} - -function finish(stream, state) { - state.pendingcb--; - state.finished = true; - const onfinishCallbacks = state[kOnFinished].splice(0); - for (let i = 0; i < onfinishCallbacks.length; i++) { - onfinishCallbacks[i](); - } - stream.emit("finish"); - if (state.autoDestroy) { - // In case of duplex streams we need a way to detect - // if the readable side is ready for autoDestroy as well. - const rState = stream._readableState; - const autoDestroy = - !rState || - (rState.autoDestroy && - // We don't expect the readable to ever 'end' - // if readable is explicitly set to false. - (rState.endEmitted || rState.readable === false)); - if (autoDestroy) { - stream.destroy(); - } - } -} - -Object.defineProperties(Writable.prototype, { - closed: { - get() { - return !!this._writableState?.closed; - }, - }, - destroyed: { - get() { - return !!this._writableState?.destroyed; - }, - set(value) { - // Backward compatibility, the user is explicitly managing destroyed. - if (this._writableState) { - this._writableState.destroyed = value; - } - }, - }, - errored: { - enumerable: false, - get() { - return this._writableState?.errored || null; - }, - }, - writable: { - get() { - const w = this._writableState; - // w.writable === false means that this is part of a Duplex stream - // where the writable side was disabled upon construction. - // Compat. The user might manually disable writable side through - // deprecated setter. - return ( - !!w && w.writable !== false && !w.destroyed && !w.errored && !w.ending && !w.ended - ); - }, - set(val) { - // Backwards compatible. - if (this._writableState) { - this._writableState.writable = !!val; - } - }, - }, - writableFinished: { - get() { - return !!this._writableState?.finished; - }, - }, - writableObjectMode: { - get() { - return !!this._writableState?.objectMode; - }, - }, - writableBuffer: { - get() { - return this._writableState?.getBuffer(); - }, - }, - writableEnded: { - get() { - return !!this._writableState?.ending; - }, - }, - writableNeedDrain: { - get() { - const wState = this._writableState; - if (!wState) return false; - return !wState.destroyed && !wState.ending && wState.needDrain; - }, - }, - writableHighWaterMark: { - get() { - return this._writableState?.highWaterMark; - }, - }, - writableCorked: { - get() { - return this._writableState?.corked | 0; - }, - }, - writableLength: { - get() { - return this._writableState?.length; - }, - }, - writableAborted: { - enumerable: false, - get() { - return !!( - this._writableState.writable !== false && - (this._writableState.destroyed || this._writableState.errored) && - !this._writableState.finished - ); - }, - }, -}); - -Writable.prototype.destroy = function (err, cb) { - const state = this._writableState; - - // Invoke pending callbacks. - if ( - !state.destroyed && - (state.bufferedIndex < state.buffered.length || state[kOnFinished].length) - ) { - process.nextTick(errorBuffer, state); - } - destroy.call(this, err, cb); - return this; -}; - -Writable.prototype._undestroy = undestroy; - -Writable.prototype._destroy = function (err, cb) { - if (cb) cb(err); -}; -Writable.prototype[EventEmitter.captureRejectionSymbol] = function (err) { - this.destroy(err); -}; - -Writable.fromWeb = function (writableStream, options) { - return newStreamWritableFromWritableStream(writableStream, options); -}; -Writable.toWeb = function (streamWritable) { - return newWritableStreamFromStreamWritable(streamWritable); -}; diff --git a/JS/wasm/crates/wasmjs-engine/shims/src/internal/util.d.ts b/JS/wasm/crates/wasmjs-engine/shims/src/internal/util.d.ts deleted file mode 100644 index d97761026..000000000 --- a/JS/wasm/crates/wasmjs-engine/shims/src/internal/util.d.ts +++ /dev/null @@ -1,107 +0,0 @@ -export abstract class MIMEType { - public constructor(input: string); - public type: string; - public subtype: string; - public readonly essence: string; - public readonly params: MIMEParams; - public toString(): string; - public toJSON(): string; -} - -export abstract class MIMEParams { - public constructor(); - public delete(name: string): void; - public get(name: string): string | undefined; - public has(name: string): boolean; - public set(name: string, value: string): void; - public entries(): Iterable; - public keys(): Iterable; - public values(): Iterable; -} - -export const kResourceTypeInspect: unique symbol; - -export const ALL_PROPERTIES: 0; -export const ONLY_ENUMERABLE: 1; -export function getOwnNonIndexProperties( - value: unknown, - filter: typeof ALL_PROPERTIES | typeof ONLY_ENUMERABLE -): PropertyKey[]; - -export const kPending: 0; -export const kFulfilled: 1; -export const kRejected: 2; -export interface PromiseDetails { - state: typeof kPending | typeof kFulfilled | typeof kRejected; - result: unknown; -} -export function getPromiseDetails(value: unknown): PromiseDetails | undefined; - -export interface ProxyDetails { - target: unknown; - handler: unknown; -} -export function getProxyDetails(value: unknown): ProxyDetails | undefined; - -export interface PreviewedEntries { - entries: unknown[]; - isKeyValue: boolean; -} -export function previewEntries(value: unknown): PreviewedEntries | undefined; - -export function getConstructorName(value: unknown): string; - -export type TypedArray = - | Uint8Array - | Uint8ClampedArray - | Uint16Array - | Uint32Array - | Int8Array - | Int16Array - | Int32Array - | BigUint64Array - | BigInt64Array - | Float32Array - | Float64Array; - -export function isArrayBufferView(value: unknown): value is ArrayBufferView; -export function isArgumentsObject(value: unknown): value is IArguments; -export function isArrayBuffer(value: unknown): value is ArrayBuffer; -export function isAsyncFunction(value: unknown): value is Function; -export function isBigInt64Array(value: unknown): value is BigInt64Array; -export function isBigIntObject(value: unknown): value is BigInt; -export function isBigUint64Array(value: unknown): value is BigUint64Array; -export function isBooleanObject(value: unknown): value is Boolean; -export function isDataView(value: unknown): value is DataView; -export function isDate(value: unknown): value is Date; -export function isFloat32Array(value: unknown): value is Float32Array; -export function isFloat64Array(value: unknown): value is Float64Array; -export function isGeneratorFunction(value: unknown): value is GeneratorFunction; -export function isGeneratorObject(value: unknown): value is Generator; -export function isInt8Array(value: unknown): value is Int8Array; -export function isInt16Array(value: unknown): value is Int16Array; -export function isInt32Array(value: unknown): value is Int32Array; -export function isMap(value: unknown): value is Map; -export function isMapIterator(value: unknown): value is IterableIterator; -export function isModuleNamespaceObject(value: unknown): boolean; -export function isNativeError(value: unknown): value is Error; -export function isNumberObject(value: unknown): value is Number; -export function isPromise(value: unknown): value is Promise; -export function isProxy(value: unknown): boolean; -export function isRegExp(value: unknown): value is RegExp; -export function isSet(value: unknown): value is Set; -export function isSetIterator(value: unknown): value is IterableIterator; -export function isSharedArrayBuffer(value: unknown): value is SharedArrayBuffer; -export function isStringObject(value: unknown): value is String; -export function isSymbolObject(value: unknown): value is Symbol; -export function isTypedArray(value: unknown): value is TypedArray; -export function isUint8Array(value: unknown): value is Uint8Array; -export function isUint8ClampedArray(value: unknown): value is Uint8ClampedArray; -export function isUint16Array(value: unknown): value is Uint16Array; -export function isUint32Array(value: unknown): value is Uint32Array; -export function isWeakMap(value: unknown): value is WeakMap; -export function isWeakSet(value: unknown): value is WeakSet; -export function isAnyArrayBuffer(value: unknown): value is ArrayBuffer | SharedArrayBuffer; -export function isBoxedPrimitive( - value: unknown -): value is Number | String | Boolean | BigInt | Symbol; diff --git a/JS/wasm/crates/wasmjs-engine/shims/src/internal/util.ts b/JS/wasm/crates/wasmjs-engine/shims/src/internal/util.ts deleted file mode 100644 index 13f506b0b..000000000 --- a/JS/wasm/crates/wasmjs-engine/shims/src/internal/util.ts +++ /dev/null @@ -1,261 +0,0 @@ -import { - ALL_PROPERTIES as A_PROPERTIES, - ONLY_CONFIGURABLE, - ONLY_ENUMERABLE as O_ENUMERABLE, - ONLY_WRITABLE, - SKIP_STRINGS, - SKIP_SYMBOLS, - isArrayIndex, -} from "./internal_utils"; - -export const kPending = 0; -export const kFulfilled = 1; -export const kRejected = 2; - -export const kResourceTypeInspect: unique symbol = Symbol.for("nodejs.util.inspect.custom"); - -export interface PromiseDetails { - state: typeof kPending | typeof kFulfilled | typeof kRejected; - result: unknown; -} - -export type TypedArray = - | Uint8Array - | Uint8ClampedArray - | Uint16Array - | Uint32Array - | Int8Array - | Int16Array - | Int32Array - | BigUint64Array - | BigInt64Array - | Float32Array - | Float64Array; - -export interface PreviewedEntries { - entries: unknown[]; - isKeyValue: boolean; -} -export interface ProxyDetails { - target: unknown; - handler: unknown; -} - -export function getOwnNonIndexProperties( - // deno-lint-ignore ban-types - obj: object, - filter: number -): (string | symbol)[] { - let allProperties = [...Object.getOwnPropertyNames(obj), ...Object.getOwnPropertySymbols(obj)]; - - if (Array.isArray(obj)) { - allProperties = allProperties.filter((k) => !isArrayIndex(k)); - } - - if (filter === A_PROPERTIES) { - return allProperties; - } - - const result: (string | symbol)[] = []; - for (const key of allProperties) { - const desc = Object.getOwnPropertyDescriptor(obj, key); - if (desc === undefined) { - continue; - } - if (filter & ONLY_WRITABLE && !desc.writable) { - continue; - } - if (filter & O_ENUMERABLE && !desc.enumerable) { - continue; - } - if (filter & ONLY_CONFIGURABLE && !desc.configurable) { - continue; - } - if (filter & SKIP_STRINGS && typeof key === "string") { - continue; - } - if (filter & SKIP_SYMBOLS && typeof key === "symbol") { - continue; - } - result.push(key); - } - return result; -} - -export const ALL_PROPERTIES = A_PROPERTIES; -export const ONLY_ENUMERABLE = O_ENUMERABLE; - -// TODO: implement this properly -export function isArrayBufferView(value: unknown): value is ArrayBufferView { - return false; -} - -export function isArgumentsObject(value: unknown): value is IArguments { - return false; -} - -export function isArrayBuffer(value: unknown): value is ArrayBuffer { - return false; -} - -export function isAsyncFunction(value: unknown): value is Function { - return false; -} - -export function isBigInt64Array(value: unknown): value is BigInt64Array { - return false; -} - -export function isBigIntObject(value: unknown): value is BigInt { - return false; -} - -export function isBigUint64Array(value: unknown): value is BigUint64Array { - return false; -} - -export function isBooleanObject(value: unknown): value is Boolean { - return false; -} - -export function isDataView(value: unknown): value is DataView { - return false; -} - -export function isDate(value: unknown): value is Date { - return false; -} - -export function isFloat32Array(value: unknown): value is Float32Array { - return false; -} - -export function isFloat64Array(value: unknown): value is Float64Array { - return false; -} - -export function isGeneratorFunction(value: unknown): value is GeneratorFunction { - return false; -} - -export function isGeneratorObject(value: unknown): value is Generator { - return false; -} - -export function isInt8Array(value: unknown): value is Int8Array { - return false; -} - -export function isInt16Array(value: unknown): value is Int16Array { - return false; -} - -export function isInt32Array(value: unknown): value is Int32Array { - return false; -} - -export function isMap(value: unknown): value is Map { - return false; -} - -export function isMapIterator(value: unknown): value is IterableIterator { - return false; -} - -export function isModuleNamespaceObject(value: unknown): boolean { - return false; -} - -export function isNativeError(value: unknown): value is Error { - return false; -} - -export function isNumberObject(value: unknown): value is Number { - return false; -} - -export function isPromise(value: unknown): value is Promise { - return false; -} - -export function isProxy(value: unknown): boolean { - return false; -} - -export function isRegExp(value: unknown): value is RegExp { - return false; -} - -export function isSet(value: unknown): value is Set { - return false; -} - -export function isSetIterator(value: unknown): value is IterableIterator { - return false; -} - -export function isSharedArrayBuffer(value: unknown): value is SharedArrayBuffer { - return false; -} - -export function isStringObject(value: unknown): value is String { - return false; -} - -export function isSymbolObject(value: unknown): value is Symbol { - return false; -} - -export function isTypedArray(value: unknown): value is TypedArray { - return false; -} - -export function isUint8Array(value: unknown): value is Uint8Array { - return false; -} - -export function isUint8ClampedArray(value: unknown): value is Uint8ClampedArray { - return false; -} - -export function isUint16Array(value: unknown): value is Uint16Array { - return false; -} - -export function isUint32Array(value: unknown): value is Uint32Array { - return false; -} - -export function isWeakMap(value: unknown): value is WeakMap { - return false; -} - -export function isWeakSet(value: unknown): value is WeakSet { - return false; -} - -export function isAnyArrayBuffer(value: unknown): value is ArrayBuffer | SharedArrayBuffer { - return false; -} - -export function isBoxedPrimitive( - value: unknown -): value is Number | String | Boolean | BigInt | Symbol { - return false; -} - -export function getPromiseDetails(value: unknown): PromiseDetails | undefined { - return undefined; -} - -export function getProxyDetails(value: unknown): ProxyDetails | undefined { - return undefined; -} - -export function previewEntries(value: unknown): PreviewedEntries | undefined { - return undefined; -} - -export function getConstructorName(value: unknown): string { - return ""; -} diff --git a/JS/wasm/crates/wasmjs-engine/shims/src/internal/validators.ts b/JS/wasm/crates/wasmjs-engine/shims/src/internal/validators.ts deleted file mode 100644 index f34d63533..000000000 --- a/JS/wasm/crates/wasmjs-engine/shims/src/internal/validators.ts +++ /dev/null @@ -1,171 +0,0 @@ -import { isArrayBufferView } from "./internal_types"; -import { normalizeEncoding } from "./internal_utils"; -import { ERR_INVALID_ARG_TYPE, ERR_INVALID_ARG_VALUE, ERR_OUT_OF_RANGE } from "./internal_errors"; - -// TODO(someday): Not current implementing parseFileMode, validatePort - -export const isInt32 = (value: any) => value === (value | 0); -export const isUint32 = (value: any) => value === value >>> 0; - -export function validateBuffer(buffer: unknown, name = "buffer") { - if (!isArrayBufferView(buffer)) { - throw new ERR_INVALID_ARG_TYPE(name, ["Buffer", "TypedArray", "DataView"], buffer); - } -} - -export function validateInteger( - value: unknown, - name: string, - min = Number.MIN_SAFE_INTEGER, - max = Number.MAX_SAFE_INTEGER -) { - if (typeof value !== "number") { - throw new ERR_INVALID_ARG_TYPE(name, "number", value); - } - if (!Number.isInteger(value)) { - throw new ERR_OUT_OF_RANGE(name, "an integer", value); - } - if (value < min || value > max) { - throw new ERR_OUT_OF_RANGE(name, `>= ${min} && <= ${max}`, value); - } -} - -export interface ValidateObjectOptions { - allowArray?: boolean; - allowFunction?: boolean; - nullable?: boolean; -} - -export function validateObject(value: unknown, name: string, options?: ValidateObjectOptions) { - const useDefaultOptions = options == null; - const allowArray = useDefaultOptions ? false : options.allowArray; - const allowFunction = useDefaultOptions ? false : options.allowFunction; - const nullable = useDefaultOptions ? false : options.nullable; - if ( - (!nullable && value === null) || - (!allowArray && Array.isArray(value)) || - (typeof value !== "object" && (!allowFunction || typeof value !== "function")) - ) { - throw new ERR_INVALID_ARG_TYPE(name, "Object", value); - } -} - -export function validateInt32(value: any, name: string, min = -2147483648, max = 2147483647) { - if (!isInt32(value)) { - if (typeof value !== "number") { - throw new ERR_INVALID_ARG_TYPE(name, "number", value); - } - - if (!Number.isInteger(value)) { - throw new ERR_OUT_OF_RANGE(name, "an integer", value); - } - - throw new ERR_OUT_OF_RANGE(name, `>= ${min} && <= ${max}`, value); - } - - if (value < min || value > max) { - throw new ERR_OUT_OF_RANGE(name, `>= ${min} && <= ${max}`, value); - } -} - -export function validateUint32(value: unknown, name: string, positive?: boolean) { - if (!isUint32(value)) { - if (typeof value !== "number") { - throw new ERR_INVALID_ARG_TYPE(name, "number", value); - } - if (!Number.isInteger(value)) { - throw new ERR_OUT_OF_RANGE(name, "an integer", value); - } - const min = positive ? 1 : 0; - // 2 ** 32 === 4294967296 - throw new ERR_OUT_OF_RANGE(name, `>= ${min} && < 4294967296`, value); - } - if (positive && value === 0) { - throw new ERR_OUT_OF_RANGE(name, ">= 1 && < 4294967296", value); - } -} - -export function validateString(value: unknown, name: string) { - if (typeof value !== "string") { - throw new ERR_INVALID_ARG_TYPE(name, "string", value); - } -} - -export function validateNumber(value: unknown, name: string) { - if (typeof value !== "number") { - throw new ERR_INVALID_ARG_TYPE(name, "number", value); - } -} - -export function validateBoolean(value: unknown, name: string) { - if (typeof value !== "boolean") { - throw new ERR_INVALID_ARG_TYPE(name, "boolean", value); - } -} - -export function validateOneOf(value: unknown, name: string, oneOf: any[]) { - if (!Array.prototype.includes.call(oneOf, value)) { - const allowed = Array.prototype.join.call( - Array.prototype.map.call(oneOf, (v) => (typeof v === "string" ? `'${v}'` : String(v))), - ", " - ); - const reason = "must be one of: " + allowed; - - throw new ERR_INVALID_ARG_VALUE(name, value, reason); - } -} - -export function validateEncoding(data: unknown, encoding: string): void { - const normalizedEncoding = normalizeEncoding(encoding); - const length = (data as any).length; - - if (normalizedEncoding === "hex" && length % 2 !== 0) { - throw new ERR_INVALID_ARG_VALUE( - "encoding", - encoding, - `is invalid for data of length ${length}` - ); - } -} - -export function validateAbortSignal(signal: unknown, name: string) { - if ( - signal !== undefined && - (signal === null || typeof signal !== "object" || !("aborted" in signal)) - ) { - throw new ERR_INVALID_ARG_TYPE(name, "AbortSignal", signal); - } -} - -export function validateFunction(value: unknown, name: string) { - if (typeof value !== "function") { - throw new ERR_INVALID_ARG_TYPE(name, "Function", value); - } -} - -export function validateArray(value: unknown, name: string, minLength = 0) { - if (!Array.isArray(value)) { - throw new ERR_INVALID_ARG_TYPE(name, "Array", value); - } - if (value.length < minLength) { - const reason = `must be longer than ${minLength}`; - throw new ERR_INVALID_ARG_VALUE(name, value, reason); - } -} - -export default { - isInt32, - isUint32, - validateAbortSignal, - validateArray, - validateBoolean, - validateBuffer, - validateFunction, - validateInt32, - validateInteger, - validateNumber, - validateObject, - validateOneOf, - validateString, - validateUint32, -}; diff --git a/JS/wasm/crates/wasmjs-engine/shims/src/path.js b/JS/wasm/crates/wasmjs-engine/shims/src/path.js deleted file mode 100644 index f5f64f2c4..000000000 --- a/JS/wasm/crates/wasmjs-engine/shims/src/path.js +++ /dev/null @@ -1,58 +0,0 @@ -import { posix, win32 } from "./internal/internal_path"; - -const { - resolve, - normalize, - isAbsolute, - join, - relative, - toNamespacedPath, - dirname, - basename, - extname, - format, - parse, - sep, - delimiter, -} = posix; - -export { - resolve, - normalize, - isAbsolute, - join, - relative, - toNamespacedPath, - dirname, - basename, - extname, - format, - parse, - sep, - delimiter, - posix, - win32, -}; - -export { default } from "./internal/internal_path"; -import process from "./internal/process"; - -globalThis.process = process; - -globalThis.path = { - resolve, - normalize, - isAbsolute, - join, - relative, - toNamespacedPath, - dirname, - basename, - extname, - format, - parse, - sep, - delimiter, - posix, - win32, -}; diff --git a/JS/wasm/crates/wasmjs-engine/shims/src/path/posix.ts b/JS/wasm/crates/wasmjs-engine/shims/src/path/posix.ts deleted file mode 100644 index 7a16fe830..000000000 --- a/JS/wasm/crates/wasmjs-engine/shims/src/path/posix.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { posix } from "../internal/internal_path"; - -export default posix; diff --git a/JS/wasm/crates/wasmjs-engine/shims/src/path/win32.ts b/JS/wasm/crates/wasmjs-engine/shims/src/path/win32.ts deleted file mode 100644 index f67ec9e71..000000000 --- a/JS/wasm/crates/wasmjs-engine/shims/src/path/win32.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { win32 } from "../internal/internal_path"; - -export default win32; diff --git a/JS/wasm/crates/wasmjs-engine/src/main.rs b/JS/wasm/crates/wasmjs-engine/src/main.rs deleted file mode 100644 index 92861f98e..000000000 --- a/JS/wasm/crates/wasmjs-engine/src/main.rs +++ /dev/null @@ -1,324 +0,0 @@ -use std::{ - collections::HashMap, - env, fs, - io::{stdin, stdout, Read, Write}, -}; - -use javy::{ - json, - quickjs::{JSContextRef, JSValue, JSValueRef}, - Runtime, -}; - -wit_bindgen_rust::import!({paths: ["../../assets/wasmjs/wit/http.wit"]}); -use crate::http::*; - -pub enum RuntimeError { - InvalidBinding { invalid_export: String }, -} - -pub fn load_bindings(context: &JSContextRef, global: JSValueRef) -> Result<(), RuntimeError> { - global - .set_property( - "__send_http_request", - context - .wrap_callback(|_ctx, _this_arg, args| { - let uri = args[0].to_string(); - - let opts: HashMap = args[1].try_into()?; - let method = opts.get("method").unwrap().to_string(); - let headers = opts.get("headers").unwrap(); - let body = opts.get("body").unwrap(); - - let method = match method.as_str() { - "GET" => HttpMethod::Get, - "POST" => HttpMethod::Post, - _ => HttpMethod::Get, - }; - - let mut parsed_headers: Vec<(String, String)> = Vec::new(); - - if let JSValue::Object(headers) = headers { - for (key, val) in headers.iter() { - parsed_headers.push((key.to_string(), val.to_string())); - } - } - - let headers_slice: &[(&str, &str)] = &parsed_headers - .iter() - .map(|(k, v)| (k.as_str(), v.as_str())) - .collect::>(); - - let parsed_body: Option<&[u8]>; - - if let JSValue::ArrayBuffer(buf) = body { - parsed_body = Some(buf.as_ref()); - } else if let JSValue::String(data) = body { - parsed_body = Some(data.as_bytes()); - } else { - parsed_body = None; - } - - let req = HttpRequest { - uri: uri.as_str(), - body: parsed_body, - headers: headers_slice, - method, - params: &[], - }; - - match send_http_request(req) { - Ok(result) => { - let body = result.body.unwrap_or(Vec::new()); - let mut headers = HashMap::new(); - - for (key, val) in result.headers.iter() { - headers.insert(key.as_str(), JSValue::String(val.to_string())); - } - - let parsed_result = HashMap::from([ - ("status", JSValue::Int(result.status as i32)), - ("body", JSValue::ArrayBuffer(body)), - ("headers", JSValue::from_hashmap(headers)), - ]); - - Ok(JSValue::from_hashmap(parsed_result)) - } - Err(err) => { - let kind = match err.error { - HttpError::InvalidRequest => "Invalid Request".to_string(), - HttpError::InvalidRequestBody => "Invalid Request Body".to_string(), - HttpError::InvalidResponseBody => { - "Invalid Response Body".to_string() - } - HttpError::NotAllowed => "Not allowed".to_string(), - HttpError::InternalError => "Internal Error".to_string(), - HttpError::Timeout => "Request Timeout".to_string(), - HttpError::RedirectLoop => "Redirect Loop".to_string(), - }; - - Ok(JSValue::from_hashmap(HashMap::from([ - ("error", JSValue::Bool(true)), - ("type", JSValue::String(kind)), - ("message", JSValue::String(err.message)), - ]))) - } - } - }) - .map_err(|_| RuntimeError::InvalidBinding { - invalid_export: "send_http_request".to_string(), - })?, - ) - .map_err(|_| RuntimeError::InvalidBinding { - invalid_export: "send_http_request".to_string(), - })?; - - global - .set_property( - "__console_log", - context - .wrap_callback(|_ctx, _this_arg, args| { - let msg = args[0].to_string(); - eprintln!("{msg}"); - - Ok(JSValue::Null) - }) - .map_err(|_| RuntimeError::InvalidBinding { - invalid_export: "console_log".to_string(), - })?, - ) - .map_err(|_| RuntimeError::InvalidBinding { - invalid_export: "console_log".to_string(), - })?; - - global - .set_property( - "readBytes", - context - .wrap_callback(|_ctx, _this_arg, args| { - let path = args[0].to_string(); - match read_bytes(path.as_str()) { - Ok(result) => Ok(JSValue::String(result)), - Err(err) => { - let kind = match err { - FileError::NotFound => "File not found".to_string(), - FileError::InvalidPath => "Not allowed".to_string(), - }; - - Ok(JSValue::from_hashmap(HashMap::from([ - ("error", JSValue::Bool(true)), - ("type", JSValue::String(kind)), - ]))) - } - } - }) - .map_err(|_| RuntimeError::InvalidBinding { - invalid_export: "readBytes".to_string(), - })?, - ) - .map_err(|_| RuntimeError::InvalidBinding { - invalid_export: "readBytes".to_string(), - })?; - - global - .set_property( - "jsonnet", - context - .wrap_callback(|_ctx, _this_arg, args| { - let path = args[0].to_string(); - match jsonnet(path.as_str()) { - Ok(result) => Ok(JSValue::String(result)), - Err(err) => { - let kind = match err { - FileError::NotFound => "File not found".to_string(), - FileError::InvalidPath => "Not allowed".to_string(), - }; - - Ok(JSValue::from_hashmap(HashMap::from([ - ("error", JSValue::Bool(true)), - ("type", JSValue::String(kind)), - ]))) - } - } - }) - .map_err(|_| RuntimeError::InvalidBinding { - invalid_export: "parseJsonnet".to_string(), - })?, - ) - .map_err(|_| RuntimeError::InvalidBinding { - invalid_export: "parseJsonnet".to_string(), - })?; - - global - .set_property( - "jsonnetExtVars", - context - .wrap_callback(|_ctx, _this_arg, args| { - let path = args[0].to_string(); - let ext_var = args[1].to_string(); - match jsonnet_ext_var(path.as_str(), ext_var.as_str()) { - Ok(result) => Ok(JSValue::String(result)), - Err(err) => { - let kind = match err { - FileError::NotFound => "File not found".to_string(), - FileError::InvalidPath => "Not allowed".to_string(), - }; - Ok(JSValue::from_hashmap(HashMap::from([ - ("error", JSValue::Bool(true)), - ("type", JSValue::String(kind)), - ]))) - } - } - }) - .map_err(|_| RuntimeError::InvalidBinding { - invalid_export: "parseJsonnet".to_string(), - })?, - ) - .map_err(|_| RuntimeError::InvalidBinding { - invalid_export: "parseJsonnet".to_string(), - })?; - - Ok(()) -} - -static POLYFILL: &str = include_str!("../shims/dist/index.js"); -static POLYFILL_BUFFER: &str = include_str!("../shims/dist/buffer.js"); -static POLYFILL_PATH: &str = include_str!("../shims/dist/path.js"); -static POLYFILL_CRYPTO: &str = include_str!("../shims/dist/crypto.js"); -static ARAKOOJSONNET: &str = include_str!("../shims/dist/arakoo-jsonnet.js"); - -fn main() { - let runtime = Runtime::default(); - let context = runtime.context(); - - let source = fs::read_to_string("/src/index.js"); - let mut contents = String::new(); - let mut buffer = String::new(); - let mut path = String::new(); - let mut crypto = String::new(); - - let mut request = String::new(); - contents.push_str(POLYFILL); - buffer.push_str(POLYFILL_BUFFER); - path.push_str(POLYFILL_PATH); - crypto.push_str(POLYFILL_CRYPTO); - - stdin().read_to_string(&mut request).unwrap(); - - let mut env_vars = HashMap::new(); - for (key, val) in env::vars() { - env_vars.insert(key, val); - } - let env_vars_json = serde_json::to_string(&env_vars).unwrap(); - contents.push_str(&format!("globalThis.env = {};", env_vars_json)); - - contents.push_str(&source.unwrap()); - - let global = context.global_object().unwrap(); - match load_bindings(context, global) { - Ok(_) => {} - Err(e) => match e { - RuntimeError::InvalidBinding { invalid_export } => { - eprintln!("There was an error adding the '{invalid_export}' binding"); - } - }, - } - - context.eval_module("buffer", &buffer).unwrap(); - context.eval_module("crypto", &crypto).unwrap(); - context - .eval_module("arakoo-jsonnet", &ARAKOOJSONNET) - .unwrap(); - - match context.eval_module("path", &path) { - Ok(_) => {} - Err(err) => eprintln!("Error loading the path shim: {err}"), - }; - - context.eval_module("handler.mjs", &contents).unwrap(); - - context - .eval_module( - "runtime.mjs", - &format!( - r#" - import {{ default as handler }} from 'handler.mjs'; - addEventListener('fetch', (e) => {{ - e.respondWith(handler.fetch(e.request)) - }}); - "# - ), - ) - .unwrap(); - - let global = context.global_object().unwrap(); - let entrypoint = global.get_property("entrypoint").unwrap(); - - let input_bytes = request.as_bytes(); - let input_value = json::transcode_input(context, input_bytes).unwrap(); - - match entrypoint.call(&global, &[input_value]) { - Ok(_) => {} - Err(err) => eprintln!("Error calling the main entrypoint: {err}"), - }; - - if context.is_pending() { - if let Err(err) = context.execute_pending() { - eprintln!("Error running async methods: {err}"); - } - } - - let global = context.global_object().unwrap(); - let error_value = global.get_property("error").unwrap(); - let output_value = global.get_property("result").unwrap(); - - if !error_value.is_null_or_undefined() { - eprintln!("{}", error_value.as_str_lossy()); - } - - let output = json::transcode_output(output_value).unwrap(); - - stdout() - .write_all(&output) - .expect("Error when returning the response"); -} diff --git a/JS/wasm/crates/wasmjs-engine/taskfile.yml b/JS/wasm/crates/wasmjs-engine/taskfile.yml deleted file mode 100644 index 26ac78188..000000000 --- a/JS/wasm/crates/wasmjs-engine/taskfile.yml +++ /dev/null @@ -1,23 +0,0 @@ -version: "3" - -tasks: - add:wasm32-wasi:target: rustup target add wasm32-wasi - build: - deps: - - add:wasm32-wasi:target - - build-shims - cmds: - - cargo build --target wasm32-wasi --release - - cp ./target/wasm32-wasi/release/wasmjs-engine.wasm ./ - build-shims: - deps: - - shims-install - dir: shims - cmds: - - echo pwd - - npm run build - shims-install: - dir: shims - cmds: - - pwd - - npm install diff --git a/JS/wasm/crates/wasmjs-engine/wasmjs-engine.wasm b/JS/wasm/crates/wasmjs-engine/wasmjs-engine.wasm deleted file mode 100755 index fa3bdb0e0..000000000 Binary files a/JS/wasm/crates/wasmjs-engine/wasmjs-engine.wasm and /dev/null differ diff --git a/JS/wasm/crates/wasmjs-runtime/Cargo.lock b/JS/wasm/crates/wasmjs-runtime/Cargo.lock deleted file mode 100644 index 2beed09ee..000000000 --- a/JS/wasm/crates/wasmjs-runtime/Cargo.lock +++ /dev/null @@ -1,3936 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "actix-codec" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "617a8268e3537fe1d8c9ead925fca49ef6400927ee7bc26750e90ecee14ce4b8" -dependencies = [ - "bitflags 1.3.2", - "bytes", - "futures-core", - "futures-sink", - "memchr", - "pin-project-lite", - "tokio", - "tokio-util", - "tracing", -] - -[[package]] -name = "actix-files" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d832782fac6ca7369a70c9ee9a20554623c5e51c76e190ad151780ebea1cf689" -dependencies = [ - "actix-http", - "actix-service", - "actix-utils", - "actix-web", - "askama_escape", - "bitflags 1.3.2", - "bytes", - "derive_more", - "futures-core", - "http-range", - "log", - "mime", - "mime_guess", - "percent-encoding", - "pin-project-lite", -] - -[[package]] -name = "actix-http" -version = "3.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a92ef85799cba03f76e4f7c10f533e66d87c9a7e7055f3391f09000ad8351bc9" -dependencies = [ - "actix-codec", - "actix-rt", - "actix-service", - "actix-utils", - "ahash", - "base64", - "bitflags 2.4.1", - "brotli", - "bytes", - "bytestring", - "derive_more", - "encoding_rs", - "flate2", - "futures-core", - "h2", - "http", - "httparse", - "httpdate", - "itoa", - "language-tags", - "local-channel", - "mime", - "percent-encoding", - "pin-project-lite", - "rand", - "sha1", - "smallvec", - "tokio", - "tokio-util", - "tracing", - "zstd 0.12.4", -] - -[[package]] -name = "actix-macros" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e01ed3140b2f8d422c68afa1ed2e85d996ea619c988ac834d255db32138655cb" -dependencies = [ - "quote", - "syn 2.0.41", -] - -[[package]] -name = "actix-router" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d66ff4d247d2b160861fa2866457e85706833527840e4133f8f49aa423a38799" -dependencies = [ - "bytestring", - "http", - "regex", - "serde", - "tracing", -] - -[[package]] -name = "actix-rt" -version = "2.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28f32d40287d3f402ae0028a9d54bef51af15c8769492826a69d28f81893151d" -dependencies = [ - "futures-core", - "tokio", -] - -[[package]] -name = "actix-server" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3eb13e7eef0423ea6eab0e59f6c72e7cb46d33691ad56a726b3cd07ddec2c2d4" -dependencies = [ - "actix-rt", - "actix-service", - "actix-utils", - "futures-core", - "futures-util", - "mio", - "socket2 0.5.5", - "tokio", - "tracing", -] - -[[package]] -name = "actix-service" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b894941f818cfdc7ccc4b9e60fa7e53b5042a2e8567270f9147d5591893373a" -dependencies = [ - "futures-core", - "paste", - "pin-project-lite", -] - -[[package]] -name = "actix-utils" -version = "3.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88a1dcdff1466e3c2488e1cb5c36a71822750ad43839937f85d2f4d9f8b705d8" -dependencies = [ - "local-waker", - "pin-project-lite", -] - -[[package]] -name = "actix-web" -version = "4.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e4a5b5e29603ca8c94a77c65cf874718ceb60292c5a5c3e5f4ace041af462b9" -dependencies = [ - "actix-codec", - "actix-http", - "actix-macros", - "actix-router", - "actix-rt", - "actix-server", - "actix-service", - "actix-utils", - "actix-web-codegen", - "ahash", - "bytes", - "bytestring", - "cfg-if", - "cookie", - "derive_more", - "encoding_rs", - "futures-core", - "futures-util", - "itoa", - "language-tags", - "log", - "mime", - "once_cell", - "pin-project-lite", - "regex", - "serde", - "serde_json", - "serde_urlencoded", - "smallvec", - "socket2 0.5.5", - "time", - "url", -] - -[[package]] -name = "actix-web-codegen" -version = "4.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb1f50ebbb30eca122b188319a4398b3f7bb4a8cdf50ecfb73bfc6a3c3ce54f5" -dependencies = [ - "actix-router", - "proc-macro2", - "quote", - "syn 2.0.41", -] - -[[package]] -name = "addr2line" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" -dependencies = [ - "gimli", -] - -[[package]] -name = "adler" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" - -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "getrandom", - "once_cell", - "version_check", - "zerocopy", -] - -[[package]] -name = "aho-corasick" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" -dependencies = [ - "memchr", -] - -[[package]] -name = "alloc-no-stdlib" -version = "2.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" - -[[package]] -name = "alloc-stdlib" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" -dependencies = [ - "alloc-no-stdlib", -] - -[[package]] -name = "ambient-authority" -version = "0.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9d4ee0d472d1cd2e28c97dfa124b3d8d992e10eb0a035f33f5d12e3a177ba3b" - -[[package]] -name = "anstream" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d664a92ecae85fd0a7392615844904654d1d5f5514837f471ddef4a057aba1b6" -dependencies = [ - "anstyle", - "anstyle-parse", - "anstyle-query", - "anstyle-wincon", - "colorchoice", - "utf8parse", -] - -[[package]] -name = "anstyle" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" - -[[package]] -name = "anstyle-parse" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" -dependencies = [ - "utf8parse", -] - -[[package]] -name = "anstyle-query" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" -dependencies = [ - "windows-sys 0.52.0", -] - -[[package]] -name = "anstyle-wincon" -version = "3.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" -dependencies = [ - "anstyle", - "windows-sys 0.52.0", -] - -[[package]] -name = "anyhow" -version = "1.0.75" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" - -[[package]] -name = "arbitrary" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110" - -[[package]] -name = "arrayref" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" - -[[package]] -name = "arrayvec" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" - -[[package]] -name = "askama_escape" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "619743e34b5ba4e9703bba34deac3427c72507c7159f5fd030aea8cac0cfe341" - -[[package]] -name = "async-trait" -version = "0.1.74" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.41", -] - -[[package]] -name = "autocfg" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" - -[[package]] -name = "backtrace" -version = "0.3.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" -dependencies = [ - "addr2line", - "cc", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", -] - -[[package]] -name = "base64" -version = "0.21.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" - -[[package]] -name = "bincode" -version = "1.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" -dependencies = [ - "serde", -] - -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "bitflags" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" - -[[package]] -name = "blake3" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0231f06152bf547e9c2b5194f247cd97aacf6dcd8b15d8e5ec0663f64580da87" -dependencies = [ - "arrayref", - "arrayvec", - "cc", - "cfg-if", - "constant_time_eq", -] - -[[package]] -name = "block-buffer" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" -dependencies = [ - "generic-array", -] - -[[package]] -name = "brotli" -version = "3.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "516074a47ef4bce09577a3b379392300159ce5b1ba2e501ff1c819950066100f" -dependencies = [ - "alloc-no-stdlib", - "alloc-stdlib", - "brotli-decompressor", -] - -[[package]] -name = "brotli-decompressor" -version = "2.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e2e4afe60d7dd600fdd3de8d0f08c2b7ec039712e3b6137ff98b7004e82de4f" -dependencies = [ - "alloc-no-stdlib", - "alloc-stdlib", -] - -[[package]] -name = "bumpalo" -version = "3.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" - -[[package]] -name = "byteorder" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" - -[[package]] -name = "bytes" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" - -[[package]] -name = "bytestring" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d80203ea6b29df88012294f62733de21cfeab47f17b41af3a38bc30a03ee72" -dependencies = [ - "bytes", -] - -[[package]] -name = "cap-fs-ext" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b779b2d0a001c125b4584ad586268fb4b92d957bff8d26d7fe0dd78283faa814" -dependencies = [ - "cap-primitives", - "cap-std", - "io-lifetimes", - "windows-sys 0.48.0", -] - -[[package]] -name = "cap-net-ext" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ffc30dee200c20b4dcb80572226f42658e1d9c4b668656d7cc59c33d50e396e" -dependencies = [ - "cap-primitives", - "cap-std", - "rustix", - "smallvec", -] - -[[package]] -name = "cap-primitives" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bf30c373a3bee22c292b1b6a7a26736a38376840f1af3d2d806455edf8c3899" -dependencies = [ - "ambient-authority", - "fs-set-times", - "io-extras", - "io-lifetimes", - "ipnet", - "maybe-owned", - "rustix", - "windows-sys 0.48.0", - "winx", -] - -[[package]] -name = "cap-rand" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "577de6cff7c2a47d6b13efe5dd28bf116bd7f8f7db164ea95b7cc2640711f522" -dependencies = [ - "ambient-authority", - "rand", -] - -[[package]] -name = "cap-std" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84bade423fa6403efeebeafe568fdb230e8c590a275fba2ba978dd112efcf6e9" -dependencies = [ - "cap-primitives", - "io-extras", - "io-lifetimes", - "rustix", -] - -[[package]] -name = "cap-time-ext" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8f52b3c8f4abfe3252fd0a071f3004aaa3b18936ec97bdbd8763ce03aff6247" -dependencies = [ - "cap-primitives", - "once_cell", - "rustix", - "winx", -] - -[[package]] -name = "cc" -version = "1.0.83" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" -dependencies = [ - "jobserver", - "libc", -] - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "clap" -version = "4.4.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfaff671f6b22ca62406885ece523383b9b64022e341e53e009a62ebc47a45f2" -dependencies = [ - "clap_builder", - "clap_derive", -] - -[[package]] -name = "clap_builder" -version = "4.4.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a216b506622bb1d316cd51328dce24e07bdff4a6128a47c7e7fad11878d5adbb" -dependencies = [ - "anstream", - "anstyle", - "clap_lex", - "strsim", -] - -[[package]] -name = "clap_derive" -version = "4.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" -dependencies = [ - "heck 0.4.1", - "proc-macro2", - "quote", - "syn 2.0.41", -] - -[[package]] -name = "clap_lex" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" - -[[package]] -name = "colorchoice" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" - -[[package]] -name = "const_format" -version = "0.2.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3a214c7af3d04997541b18d432afaff4c455e79e2029079647e72fc2bd27673" -dependencies = [ - "const_format_proc_macros", -] - -[[package]] -name = "const_format_proc_macros" -version = "0.2.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7f6ff08fd20f4f299298a28e2dfa8a8ba1036e6cd2460ac1de7b425d76f2500" -dependencies = [ - "proc-macro2", - "quote", - "unicode-xid", -] - -[[package]] -name = "constant_time_eq" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7144d30dcf0fafbce74250a3963025d8d52177934239851c917d29f1df280c2" - -[[package]] -name = "convert_case" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" - -[[package]] -name = "cookie" -version = "0.16.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e859cd57d0710d9e06c381b550c06e76992472a8c6d527aecd2fc673dcc231fb" -dependencies = [ - "percent-encoding", - "time", - "version_check", -] - -[[package]] -name = "core-foundation" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "core-foundation-sys" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" - -[[package]] -name = "cpp_demangle" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eeaa953eaad386a53111e47172c2fedba671e5684c8dd601a5f474f4f118710f" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "cpufeatures" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0" -dependencies = [ - "libc", -] - -[[package]] -name = "cranelift-bforest" -version = "0.100.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "751cbf89e513f283c0641eb7f95dc72fda5051dd95ca203d1dc45e26bc89dba8" -dependencies = [ - "cranelift-entity 0.100.1", -] - -[[package]] -name = "cranelift-codegen" -version = "0.100.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "210730edc05121e915201cc36595e1f00062094669fa07ac362340e3627b3dc5" -dependencies = [ - "bumpalo", - "cranelift-bforest", - "cranelift-codegen-meta", - "cranelift-codegen-shared", - "cranelift-control", - "cranelift-entity 0.100.1", - "cranelift-isle", - "gimli", - "hashbrown 0.14.3", - "log", - "regalloc2", - "smallvec", - "target-lexicon", -] - -[[package]] -name = "cranelift-codegen-meta" -version = "0.100.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5dc7fdf210c53db047f3eaf49b3a89efee0cc3d9a2ce0c0f0236933273d0c53" -dependencies = [ - "cranelift-codegen-shared", -] - -[[package]] -name = "cranelift-codegen-shared" -version = "0.100.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f46875cc87d963119d78fe5c19852757dc6eea3cb9622c0df69c26b242cd44b4" - -[[package]] -name = "cranelift-control" -version = "0.100.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "375dca8f58d8a801a85e11730c1529c5c4a9c3593dfb12118391ac437b037155" -dependencies = [ - "arbitrary", -] - -[[package]] -name = "cranelift-entity" -version = "0.100.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc619b86fe3c72f43fc417c9fd67a04ec0c98296e5940922d9fd9e6eedf72521" -dependencies = [ - "serde", - "serde_derive", -] - -[[package]] -name = "cranelift-entity" -version = "0.102.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdb25f573701284fe2bcf88209d405342125df00764b396c923e11eafc94d892" -dependencies = [ - "serde", - "serde_derive", -] - -[[package]] -name = "cranelift-frontend" -version = "0.100.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eb607fd19ae264da18f9f2532e7302b826f7fbf77bf88365fc075f2e3419436" -dependencies = [ - "cranelift-codegen", - "log", - "smallvec", - "target-lexicon", -] - -[[package]] -name = "cranelift-isle" -version = "0.100.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fe806a6470dddfdf79e878af6a96afb1235a09fe3e21f9e0c2f18d402820432" - -[[package]] -name = "cranelift-native" -version = "0.100.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fac7f1722660b10af1f7229c0048f716bfd8bd344549b0e06e3eb6417ec3fe5b" -dependencies = [ - "cranelift-codegen", - "libc", - "target-lexicon", -] - -[[package]] -name = "cranelift-wasm" -version = "0.100.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1b65810be56b619c3c55debade92798d999f34bf0670370c578afab5d905f06" -dependencies = [ - "cranelift-codegen", - "cranelift-entity 0.100.1", - "cranelift-frontend", - "itertools 0.10.5", - "log", - "smallvec", - "wasmparser 0.112.0", - "wasmtime-types 13.0.1", -] - -[[package]] -name = "crc32fast" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "crossbeam-deque" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fca89a0e215bab21874660c67903c5f143333cab1da83d041c7ded6053774751" -dependencies = [ - "cfg-if", - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d2fe95351b870527a5d09bf563ed3c97c0cffb87cf1c78a591bf48bb218d9aa" -dependencies = [ - "autocfg", - "cfg-if", - "crossbeam-utils", - "memoffset", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d96137f14f244c37f989d9fff8f95e6c18b918e71f36638f8c49112e4c78f" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "crypto-common" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" -dependencies = [ - "generic-array", - "typenum", -] - -[[package]] -name = "debugid" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef552e6f588e446098f6ba40d89ac146c8c7b64aade83c051ee00bb5d2bc18d" -dependencies = [ - "uuid", -] - -[[package]] -name = "deranged" -version = "0.3.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8eb30d70a07a3b04884d2677f06bec33509dc67ca60d92949e5535352d3191dc" -dependencies = [ - "powerfmt", -] - -[[package]] -name = "derive_more" -version = "0.99.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" -dependencies = [ - "convert_case", - "proc-macro2", - "quote", - "rustc_version", - "syn 1.0.109", -] - -[[package]] -name = "digest" -version = "0.10.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" -dependencies = [ - "block-buffer", - "crypto-common", -] - -[[package]] -name = "directories-next" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "339ee130d97a610ea5a5872d2bbb130fdf68884ff09d3028b81bec8a1ac23bbc" -dependencies = [ - "cfg-if", - "dirs-sys-next", -] - -[[package]] -name = "dirs" -version = "4.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" -dependencies = [ - "dirs-sys", -] - -[[package]] -name = "dirs-sys" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" -dependencies = [ - "libc", - "redox_users", - "winapi", -] - -[[package]] -name = "dirs-sys-next" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" -dependencies = [ - "libc", - "redox_users", - "winapi", -] - -[[package]] -name = "either" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" - -[[package]] -name = "encoding_rs" -version = "0.8.33" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "equivalent" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" - -[[package]] -name = "errno" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" -dependencies = [ - "libc", - "windows-sys 0.52.0", -] - -[[package]] -name = "fallible-iterator" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" - -[[package]] -name = "fastrand" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" - -[[package]] -name = "fd-lock" -version = "4.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b93f7a0db71c99f68398f80653ed05afb0b00e062e1a20c7ff849c4edfabbbcc" -dependencies = [ - "cfg-if", - "rustix", - "windows-sys 0.52.0", -] - -[[package]] -name = "flate2" -version = "1.0.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" -dependencies = [ - "crc32fast", - "miniz_oxide", -] - -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - -[[package]] -name = "foreign-types" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -dependencies = [ - "foreign-types-shared", -] - -[[package]] -name = "foreign-types-shared" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" - -[[package]] -name = "form_urlencoded" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" -dependencies = [ - "percent-encoding", -] - -[[package]] -name = "fs-set-times" -version = "0.20.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "033b337d725b97690d86893f9de22b67b80dcc4e9ad815f348254c38119db8fb" -dependencies = [ - "io-lifetimes", - "rustix", - "windows-sys 0.52.0", -] - -[[package]] -name = "futures" -version = "0.3.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0290714b38af9b4a7b094b8a37086d1b4e61f2df9122c3cad2577669145335" -dependencies = [ - "futures-channel", - "futures-core", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-channel" -version = "0.3.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacb" -dependencies = [ - "futures-core", - "futures-sink", -] - -[[package]] -name = "futures-core" -version = "0.3.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c" - -[[package]] -name = "futures-io" -version = "0.3.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bf34a163b5c4c52d0478a4d757da8fb65cabef42ba90515efee0f6f9fa45aaa" - -[[package]] -name = "futures-sink" -version = "0.3.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817" - -[[package]] -name = "futures-task" -version = "0.3.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2" - -[[package]] -name = "futures-util" -version = "0.3.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104" -dependencies = [ - "futures-core", - "futures-sink", - "futures-task", - "pin-project-lite", - "pin-utils", -] - -[[package]] -name = "fxhash" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" -dependencies = [ - "byteorder", -] - -[[package]] -name = "fxprof-processed-profile" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27d12c0aed7f1e24276a241aadc4cb8ea9f83000f34bc062b7cc2d51e3b0fabd" -dependencies = [ - "bitflags 2.4.1", - "debugid", - "fxhash", - "serde", - "serde_json", -] - -[[package]] -name = "generic-array" -version = "0.14.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" -dependencies = [ - "typenum", - "version_check", -] - -[[package]] -name = "getrandom" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" -dependencies = [ - "cfg-if", - "libc", - "wasi", -] - -[[package]] -name = "gimli" -version = "0.28.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" -dependencies = [ - "fallible-iterator", - "indexmap", - "stable_deref_trait", -] - -[[package]] -name = "h2" -version = "0.3.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d6250322ef6e60f93f9a2162799302cd6f68f79f6e5d85c8c16f14d1d958178" -dependencies = [ - "bytes", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http", - "indexmap", - "slab", - "tokio", - "tokio-util", - "tracing", -] - -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - -[[package]] -name = "hashbrown" -version = "0.14.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" -dependencies = [ - "ahash", -] - -[[package]] -name = "heck" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" -dependencies = [ - "unicode-segmentation", -] - -[[package]] -name = "heck" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" - -[[package]] -name = "hermit-abi" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" - -[[package]] -name = "hex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" - -[[package]] -name = "http" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" -dependencies = [ - "bytes", - "fnv", - "itoa", -] - -[[package]] -name = "http-body" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" -dependencies = [ - "bytes", - "http", - "pin-project-lite", -] - -[[package]] -name = "http-range" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21dec9db110f5f872ed9699c3ecf50cf16f423502706ba5c72462e28d3157573" - -[[package]] -name = "httparse" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" - -[[package]] -name = "httpdate" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" - -[[package]] -name = "hyper" -version = "0.14.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" -dependencies = [ - "bytes", - "futures-channel", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "httparse", - "httpdate", - "itoa", - "pin-project-lite", - "socket2 0.4.10", - "tokio", - "tower-service", - "tracing", - "want", -] - -[[package]] -name = "hyper-tls" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" -dependencies = [ - "bytes", - "hyper", - "native-tls", - "tokio", - "tokio-native-tls", -] - -[[package]] -name = "id-arena" -version = "2.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25a2bc672d1148e28034f176e01fffebb08b35768468cc954630da77a1449005" - -[[package]] -name = "idna" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" -dependencies = [ - "unicode-bidi", - "unicode-normalization", -] - -[[package]] -name = "indexmap" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" -dependencies = [ - "equivalent", - "hashbrown 0.14.3", - "serde", -] - -[[package]] -name = "io-extras" -version = "0.18.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c301e73fb90e8a29e600a9f402d095765f74310d582916a952f618836a1bd1ed" -dependencies = [ - "io-lifetimes", - "windows-sys 0.52.0", -] - -[[package]] -name = "io-lifetimes" -version = "2.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a611371471e98973dbcab4e0ec66c31a10bc356eeb4d54a0e05eac8158fe38c" - -[[package]] -name = "ipnet" -version = "2.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" - -[[package]] -name = "is-terminal" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" -dependencies = [ - "hermit-abi", - "rustix", - "windows-sys 0.48.0", -] - -[[package]] -name = "itertools" -version = "0.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" -dependencies = [ - "either", -] - -[[package]] -name = "itertools" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" -dependencies = [ - "either", -] - -[[package]] -name = "itoa" -version = "1.0.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" - -[[package]] -name = "ittapi" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25a5c0b993601cad796222ea076565c5d9f337d35592f8622c753724f06d7271" -dependencies = [ - "anyhow", - "ittapi-sys", - "log", -] - -[[package]] -name = "ittapi-sys" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb7b5e473765060536a660eed127f758cf1a810c73e49063264959c60d1727d9" -dependencies = [ - "cc", -] - -[[package]] -name = "jobserver" -version = "0.1.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d" -dependencies = [ - "libc", -] - -[[package]] -name = "js-sys" -version = "0.3.66" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cee9c64da59eae3b50095c18d3e74f8b73c0b86d2792824ff01bbce68ba229ca" -dependencies = [ - "wasm-bindgen", -] - -[[package]] -name = "jsonnet-rs" -version = "0.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82b396bdfc3ae94965555c9ec3efa2214e5f3921545a943ef9fc9873ff5e4723" -dependencies = [ - "jsonnet-sys", - "libc", -] - -[[package]] -name = "jsonnet-sys" -version = "0.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02347cbdf34234f30f0d92f0f8f678a15883bd5e1e4b3def4ed4a14f691d9add" -dependencies = [ - "cc", - "libc", -] - -[[package]] -name = "language-tags" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4345964bb142484797b161f473a503a434de77149dd8c7427788c6e13379388" - -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - -[[package]] -name = "leb128" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" - -[[package]] -name = "libc" -version = "0.2.151" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" - -[[package]] -name = "libredox" -version = "0.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" -dependencies = [ - "bitflags 2.4.1", - "libc", - "redox_syscall", -] - -[[package]] -name = "linux-raw-sys" -version = "0.4.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" - -[[package]] -name = "local-channel" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6cbc85e69b8df4b8bb8b89ec634e7189099cea8927a276b7384ce5488e53ec8" -dependencies = [ - "futures-core", - "futures-sink", - "local-waker", -] - -[[package]] -name = "local-waker" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d873d7c67ce09b42110d801813efbc9364414e356be9935700d368351657487" - -[[package]] -name = "lock_api" -version = "0.4.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" -dependencies = [ - "autocfg", - "scopeguard", -] - -[[package]] -name = "log" -version = "0.4.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" - -[[package]] -name = "mach" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b823e83b2affd8f40a9ee8c29dbc56404c1e34cd2710921f2801e2cf29527afa" -dependencies = [ - "libc", -] - -[[package]] -name = "maybe-owned" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4facc753ae494aeb6e3c22f839b158aebd4f9270f55cd3c79906c45476c47ab4" - -[[package]] -name = "memchr" -version = "2.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" - -[[package]] -name = "memfd" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2cffa4ad52c6f791f4f8b15f0c05f9824b2ced1160e88cc393d64fff9a8ac64" -dependencies = [ - "rustix", -] - -[[package]] -name = "memoffset" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" -dependencies = [ - "autocfg", -] - -[[package]] -name = "mime" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" - -[[package]] -name = "mime_guess" -version = "2.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef" -dependencies = [ - "mime", - "unicase", -] - -[[package]] -name = "minimal-lexical" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" - -[[package]] -name = "miniz_oxide" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" -dependencies = [ - "adler", -] - -[[package]] -name = "mio" -version = "0.8.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" -dependencies = [ - "libc", - "log", - "wasi", - "windows-sys 0.48.0", -] - -[[package]] -name = "native-tls" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" -dependencies = [ - "lazy_static", - "libc", - "log", - "openssl", - "openssl-probe", - "openssl-sys", - "schannel", - "security-framework", - "security-framework-sys", - "tempfile", -] - -[[package]] -name = "nom" -version = "7.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" -dependencies = [ - "memchr", - "minimal-lexical", -] - -[[package]] -name = "num_cpus" -version = "1.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" -dependencies = [ - "hermit-abi", - "libc", -] - -[[package]] -name = "object" -version = "0.32.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" -dependencies = [ - "crc32fast", - "hashbrown 0.14.3", - "indexmap", - "memchr", -] - -[[package]] -name = "once_cell" -version = "1.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" - -[[package]] -name = "openssl" -version = "0.10.61" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b8419dc8cc6d866deb801274bba2e6f8f6108c1bb7fcc10ee5ab864931dbb45" -dependencies = [ - "bitflags 2.4.1", - "cfg-if", - "foreign-types", - "libc", - "once_cell", - "openssl-macros", - "openssl-sys", -] - -[[package]] -name = "openssl-macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.41", -] - -[[package]] -name = "openssl-probe" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" - -[[package]] -name = "openssl-sys" -version = "0.9.97" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3eaad34cdd97d81de97964fc7f29e2d104f483840d906ef56daa1912338460b" -dependencies = [ - "cc", - "libc", - "pkg-config", - "vcpkg", -] - -[[package]] -name = "parking_lot" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" -dependencies = [ - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall", - "smallvec", - "windows-targets 0.48.5", -] - -[[package]] -name = "paste" -version = "1.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" - -[[package]] -name = "percent-encoding" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" - -[[package]] -name = "pin-project-lite" -version = "0.2.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - -[[package]] -name = "pkg-config" -version = "0.3.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" - -[[package]] -name = "pori" -version = "0.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a63d338dec139f56dacc692ca63ad35a6be6a797442479b55acd611d79e906" -dependencies = [ - "nom", -] - -[[package]] -name = "powerfmt" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" - -[[package]] -name = "ppv-lite86" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" - -[[package]] -name = "proc-macro2" -version = "1.0.70" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "psm" -version = "0.1.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5787f7cda34e3033a72192c018bc5883100330f362ef279a8cbccfce8bb4e874" -dependencies = [ - "cc", -] - -[[package]] -name = "pulldown-cmark" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffade02495f22453cd593159ea2f59827aae7f53fa8323f756799b670881dcf8" -dependencies = [ - "bitflags 1.3.2", - "memchr", - "unicase", -] - -[[package]] -name = "pulldown-cmark" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a1a2f1f0a7ecff9c31abbe177637be0e97a0aef46cf8738ece09327985d998" -dependencies = [ - "bitflags 1.3.2", - "memchr", - "unicase", -] - -[[package]] -name = "quote" -version = "1.0.33" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha", - "rand_core", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom", -] - -[[package]] -name = "rayon" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1" -dependencies = [ - "either", - "rayon-core", -] - -[[package]] -name = "rayon-core" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed" -dependencies = [ - "crossbeam-deque", - "crossbeam-utils", -] - -[[package]] -name = "redox_syscall" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" -dependencies = [ - "bitflags 1.3.2", -] - -[[package]] -name = "redox_users" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4" -dependencies = [ - "getrandom", - "libredox", - "thiserror", -] - -[[package]] -name = "regalloc2" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad156d539c879b7a24a363a2016d77961786e71f48f2e2fc8302a92abd2429a6" -dependencies = [ - "hashbrown 0.13.2", - "log", - "rustc-hash", - "slice-group-by", - "smallvec", -] - -[[package]] -name = "regex" -version = "1.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", -] - -[[package]] -name = "regex-automata" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" - -[[package]] -name = "reqwest" -version = "0.11.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "046cd98826c46c2ac8ddecae268eb5c2e58628688a5fc7a2643704a73faba95b" -dependencies = [ - "base64", - "bytes", - "encoding_rs", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "hyper", - "hyper-tls", - "ipnet", - "js-sys", - "log", - "mime", - "native-tls", - "once_cell", - "percent-encoding", - "pin-project-lite", - "serde", - "serde_json", - "serde_urlencoded", - "system-configuration", - "tokio", - "tokio-native-tls", - "tower-service", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "winreg", -] - -[[package]] -name = "rustc-demangle" -version = "0.1.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" - -[[package]] -name = "rustc-hash" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" - -[[package]] -name = "rustc_version" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" -dependencies = [ - "semver 1.0.20", -] - -[[package]] -name = "rustix" -version = "0.38.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72e572a5e8ca657d7366229cdde4bd14c4eb5499a9573d4d366fe1b599daa316" -dependencies = [ - "bitflags 2.4.1", - "errno", - "itoa", - "libc", - "linux-raw-sys", - "once_cell", - "windows-sys 0.52.0", -] - -[[package]] -name = "ryu" -version = "1.0.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" - -[[package]] -name = "same-file" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "schannel" -version = "0.1.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" -dependencies = [ - "windows-sys 0.48.0", -] - -[[package]] -name = "scopeguard" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" - -[[package]] -name = "security-framework" -version = "2.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" -dependencies = [ - "bitflags 1.3.2", - "core-foundation", - "core-foundation-sys", - "libc", - "security-framework-sys", -] - -[[package]] -name = "security-framework-sys" -version = "2.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "semver" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "394cec28fa623e00903caf7ba4fa6fb9a0e260280bb8cdbbba029611108a0190" -dependencies = [ - "semver-parser", -] - -[[package]] -name = "semver" -version = "1.0.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" - -[[package]] -name = "semver-parser" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" - -[[package]] -name = "serde" -version = "1.0.193" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.193" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.41", -] - -[[package]] -name = "serde_json" -version = "1.0.108" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" -dependencies = [ - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "serde_spanned" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12022b835073e5b11e90a14f86838ceb1c8fb0325b72416845c487ac0fa95e80" -dependencies = [ - "serde", -] - -[[package]] -name = "serde_urlencoded" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" -dependencies = [ - "form_urlencoded", - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "sha1" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] - -[[package]] -name = "sha2" -version = "0.10.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] - -[[package]] -name = "sha256" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7895c8ae88588ccead14ff438b939b0c569cd619116f14b4d13fdff7b8333386" -dependencies = [ - "async-trait", - "bytes", - "hex", - "sha2", - "tokio", -] - -[[package]] -name = "shellexpand" -version = "2.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ccc8076840c4da029af4f87e4e8daeb0fca6b87bbb02e10cb60b791450e11e4" -dependencies = [ - "dirs", -] - -[[package]] -name = "signal-hook-registry" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" -dependencies = [ - "libc", -] - -[[package]] -name = "slab" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" -dependencies = [ - "autocfg", -] - -[[package]] -name = "slice-group-by" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "826167069c09b99d56f31e9ae5c99049e932a98c9dc2dac47645b08dbbf76ba7" - -[[package]] -name = "smallvec" -version = "1.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" - -[[package]] -name = "socket2" -version = "0.4.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" -dependencies = [ - "libc", - "winapi", -] - -[[package]] -name = "socket2" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" -dependencies = [ - "libc", - "windows-sys 0.48.0", -] - -[[package]] -name = "sptr" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b9b39299b249ad65f3b7e96443bad61c02ca5cd3589f46cb6d610a0fd6c0d6a" - -[[package]] -name = "stable_deref_trait" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" - -[[package]] -name = "strsim" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" - -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.41" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44c8b28c477cc3bf0e7966561e3460130e1255f7a1cf71931075f1c5e7a7e269" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "system-configuration" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" -dependencies = [ - "bitflags 1.3.2", - "core-foundation", - "system-configuration-sys", -] - -[[package]] -name = "system-configuration-sys" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "system-interface" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27ce32341b2c0b70c144bbf35627fdc1ef18c76ced5e5e7b3ee8b5ba6b2ab6a0" -dependencies = [ - "bitflags 2.4.1", - "cap-fs-ext", - "cap-std", - "fd-lock", - "io-lifetimes", - "rustix", - "windows-sys 0.48.0", - "winx", -] - -[[package]] -name = "target-lexicon" -version = "0.12.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c39fd04924ca3a864207c66fc2cd7d22d7c016007f9ce846cbb9326331930a" - -[[package]] -name = "tempfile" -version = "3.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5" -dependencies = [ - "cfg-if", - "fastrand", - "redox_syscall", - "rustix", - "windows-sys 0.48.0", -] - -[[package]] -name = "thiserror" -version = "1.0.50" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.50" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.41", -] - -[[package]] -name = "time" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4a34ab300f2dee6e562c10a046fc05e358b29f9bf92277f30c3c8d82275f6f5" -dependencies = [ - "deranged", - "itoa", - "powerfmt", - "serde", - "time-core", - "time-macros", -] - -[[package]] -name = "time-core" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" - -[[package]] -name = "time-macros" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ad70d68dba9e1f8aceda7aa6711965dfec1cac869f311a51bd08b3a2ccbce20" -dependencies = [ - "time-core", -] - -[[package]] -name = "tinyvec" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" - -[[package]] -name = "tokio" -version = "1.35.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "841d45b238a16291a4e1584e61820b8ae57d696cc5015c459c229ccc6990cc1c" -dependencies = [ - "backtrace", - "bytes", - "libc", - "mio", - "num_cpus", - "parking_lot", - "pin-project-lite", - "signal-hook-registry", - "socket2 0.5.5", - "tokio-macros", - "windows-sys 0.48.0", -] - -[[package]] -name = "tokio-macros" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.41", -] - -[[package]] -name = "tokio-native-tls" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" -dependencies = [ - "native-tls", - "tokio", -] - -[[package]] -name = "tokio-util" -version = "0.7.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" -dependencies = [ - "bytes", - "futures-core", - "futures-sink", - "pin-project-lite", - "tokio", - "tracing", -] - -[[package]] -name = "toml" -version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" -dependencies = [ - "serde", -] - -[[package]] -name = "toml" -version = "0.8.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1a195ec8c9da26928f773888e0742ca3ca1040c6cd859c919c9f59c1954ab35" -dependencies = [ - "serde", - "serde_spanned", - "toml_datetime", - "toml_edit", -] - -[[package]] -name = "toml_datetime" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" -dependencies = [ - "serde", -] - -[[package]] -name = "toml_edit" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34d383cd00a163b4a5b85053df514d45bc330f6de7737edfe0a93311d1eaa03" -dependencies = [ - "indexmap", - "serde", - "serde_spanned", - "toml_datetime", - "winnow", -] - -[[package]] -name = "tower-service" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" - -[[package]] -name = "tracing" -version = "0.1.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" -dependencies = [ - "log", - "pin-project-lite", - "tracing-attributes", - "tracing-core", -] - -[[package]] -name = "tracing-attributes" -version = "0.1.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.41", -] - -[[package]] -name = "tracing-core" -version = "0.1.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" -dependencies = [ - "once_cell", -] - -[[package]] -name = "try-lock" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" - -[[package]] -name = "typenum" -version = "1.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" - -[[package]] -name = "unicase" -version = "2.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" -dependencies = [ - "version_check", -] - -[[package]] -name = "unicode-bidi" -version = "0.3.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f2528f27a9eb2b21e69c95319b30bd0efd85d09c379741b0f78ea1d86be2416" - -[[package]] -name = "unicode-ident" -version = "1.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" - -[[package]] -name = "unicode-normalization" -version = "0.1.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" -dependencies = [ - "tinyvec", -] - -[[package]] -name = "unicode-segmentation" -version = "1.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" - -[[package]] -name = "unicode-width" -version = "0.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" - -[[package]] -name = "unicode-xid" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" - -[[package]] -name = "url" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" -dependencies = [ - "form_urlencoded", - "idna", - "percent-encoding", -] - -[[package]] -name = "utf8parse" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" - -[[package]] -name = "uuid" -version = "1.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e395fcf16a7a3d8127ec99782007af141946b4795001f876d54fb0d55978560" - -[[package]] -name = "vcpkg" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" - -[[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "walkdir" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" -dependencies = [ - "same-file", - "winapi-util", -] - -[[package]] -name = "want" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" -dependencies = [ - "try-lock", -] - -[[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" - -[[package]] -name = "wasi-cap-std-sync" -version = "13.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77c4db6155e71cfae4ed732d87c2583faf4bbdcb77372697eb77d636f46108ba" -dependencies = [ - "anyhow", - "async-trait", - "cap-fs-ext", - "cap-rand", - "cap-std", - "cap-time-ext", - "fs-set-times", - "io-extras", - "io-lifetimes", - "is-terminal", - "once_cell", - "rustix", - "system-interface", - "tracing", - "wasi-common", - "windows-sys 0.48.0", -] - -[[package]] -name = "wasi-common" -version = "13.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf3f291b2a567f266ac488715f1742f62b2ca633524708c62ead9c0f71b7d72c" -dependencies = [ - "anyhow", - "bitflags 2.4.1", - "cap-rand", - "cap-std", - "io-extras", - "log", - "rustix", - "thiserror", - "tracing", - "wasmtime 13.0.1", - "wiggle 13.0.1", - "windows-sys 0.48.0", -] - -[[package]] -name = "wasm-bindgen" -version = "0.2.89" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ed0d4f68a3015cc185aff4db9506a015f4b96f95303897bfa23f846db54064e" -dependencies = [ - "cfg-if", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.89" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b56f625e64f3a1084ded111c4d5f477df9f8c92df113852fa5a374dbda78826" -dependencies = [ - "bumpalo", - "log", - "once_cell", - "proc-macro2", - "quote", - "syn 2.0.41", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-futures" -version = "0.4.39" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac36a15a220124ac510204aec1c3e5db8a22ab06fd6706d881dc6149f8ed9a12" -dependencies = [ - "cfg-if", - "js-sys", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.89" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0162dbf37223cd2afce98f3d0785506dcb8d266223983e4b5b525859e6e182b2" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.89" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.41", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.89" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f" - -[[package]] -name = "wasm-encoder" -version = "0.32.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ba64e81215916eaeb48fee292f29401d69235d62d8b8fd92a7b2844ec5ae5f7" -dependencies = [ - "leb128", -] - -[[package]] -name = "wasm-encoder" -version = "0.36.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "822b645bf4f2446b949776ffca47e2af60b167209ffb70814ef8779d299cd421" -dependencies = [ - "leb128", -] - -[[package]] -name = "wasm-encoder" -version = "0.38.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ad2b51884de9c7f4fe2fd1043fccb8dcad4b1e29558146ee57a144d15779f3f" -dependencies = [ - "leb128", -] - -[[package]] -name = "wasmjs-runtime" -version = "0.1.0" -dependencies = [ - "actix-files", - "actix-web", - "anyhow", - "base64", - "blake3", - "clap", - "http", - "jsonnet-rs", - "lazy_static", - "regex", - "reqwest", - "semver 0.10.0", - "serde", - "serde_json", - "sha256", - "thiserror", - "tokio", - "toml 0.8.8", - "tracing", - "wasi-common", - "wasmparser 0.115.0", - "wasmtime 13.0.1", - "wasmtime-wasi", - "wax", - "wiggle 15.0.1", - "wit-bindgen-wasmtime", -] - -[[package]] -name = "wasmparser" -version = "0.112.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e986b010f47fcce49cf8ea5d5f9e5d2737832f12b53ae8ae785bbe895d0877bf" -dependencies = [ - "indexmap", - "semver 1.0.20", -] - -[[package]] -name = "wasmparser" -version = "0.115.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e06c0641a4add879ba71ccb3a1e4278fd546f76f1eafb21d8f7b07733b547cd5" -dependencies = [ - "indexmap", - "semver 1.0.20", -] - -[[package]] -name = "wasmparser" -version = "0.116.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a58e28b80dd8340cb07b8242ae654756161f6fc8d0038123d679b7b99964fa50" -dependencies = [ - "indexmap", - "semver 1.0.20", -] - -[[package]] -name = "wasmparser" -version = "0.118.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95ee9723b928e735d53000dec9eae7b07a60e490c85ab54abb66659fc61bfcd9" -dependencies = [ - "indexmap", - "semver 1.0.20", -] - -[[package]] -name = "wasmprinter" -version = "0.2.75" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d027eb8294904fc715ac0870cebe6b0271e96b90605ee21511e7565c4ce568c" -dependencies = [ - "anyhow", - "wasmparser 0.118.1", -] - -[[package]] -name = "wasmtime" -version = "13.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0263693caa1486bd4d26a5f18511948a706c9290689386b81b851ce088063ce" -dependencies = [ - "anyhow", - "async-trait", - "bincode", - "bumpalo", - "cfg-if", - "encoding_rs", - "fxprof-processed-profile", - "indexmap", - "libc", - "log", - "object", - "once_cell", - "paste", - "psm", - "rayon", - "serde", - "serde_derive", - "serde_json", - "target-lexicon", - "wasm-encoder 0.32.0", - "wasmparser 0.112.0", - "wasmtime-cache", - "wasmtime-component-macro 13.0.1", - "wasmtime-component-util 13.0.1", - "wasmtime-cranelift", - "wasmtime-environ 13.0.1", - "wasmtime-fiber 13.0.1", - "wasmtime-jit 13.0.1", - "wasmtime-runtime 13.0.1", - "wasmtime-winch", - "wat", - "windows-sys 0.48.0", -] - -[[package]] -name = "wasmtime" -version = "15.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "642e12d108e800215263e3b95972977f473957923103029d7d617db701d67ba4" -dependencies = [ - "anyhow", - "async-trait", - "bincode", - "bumpalo", - "cfg-if", - "indexmap", - "libc", - "log", - "object", - "once_cell", - "paste", - "psm", - "serde", - "serde_derive", - "serde_json", - "target-lexicon", - "wasmparser 0.116.1", - "wasmtime-component-macro 15.0.1", - "wasmtime-environ 15.0.1", - "wasmtime-fiber 15.0.1", - "wasmtime-jit 15.0.1", - "wasmtime-runtime 15.0.1", - "windows-sys 0.48.0", -] - -[[package]] -name = "wasmtime-asm-macros" -version = "13.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4711e5969236ecfbe70c807804ff9ffb5206c1dbb5c55c5e8200d9f7e8e76adf" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "wasmtime-asm-macros" -version = "15.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "beada8bb15df52503de0a4c58de4357bfd2f96d9a44a6e547bad11efdd988b47" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "wasmtime-cache" -version = "13.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b79f9f79188e5a26b6911b79d3171c06699d9a17ae07f6a265c51635b8d80c2" -dependencies = [ - "anyhow", - "base64", - "bincode", - "directories-next", - "log", - "rustix", - "serde", - "serde_derive", - "sha2", - "toml 0.5.11", - "windows-sys 0.48.0", - "zstd 0.11.2+zstd.1.5.2", -] - -[[package]] -name = "wasmtime-component-macro" -version = "13.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed724d0f41c21bcf8754651a59d0423c530069ddca4cf3822768489ad313a812" -dependencies = [ - "anyhow", - "proc-macro2", - "quote", - "syn 2.0.41", - "wasmtime-component-util 13.0.1", - "wasmtime-wit-bindgen 13.0.1", - "wit-parser 0.11.3", -] - -[[package]] -name = "wasmtime-component-macro" -version = "15.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56ccba556991465cca68d5a54769684bcf489fb532059da55105f851642d52c1" -dependencies = [ - "anyhow", - "proc-macro2", - "quote", - "syn 2.0.41", - "wasmtime-component-util 15.0.1", - "wasmtime-wit-bindgen 15.0.1", - "wit-parser 0.13.0", -] - -[[package]] -name = "wasmtime-component-util" -version = "13.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e7d69464b94bd312a27d93d0b482cd74bedf01f030199ef0740d6300ebca1d3" - -[[package]] -name = "wasmtime-component-util" -version = "15.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05492a177a6006cb73f034d6e9a6fad6da55b23c4398835cb0012b5fa51ecf67" - -[[package]] -name = "wasmtime-cranelift" -version = "13.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e63f53c61ba05eb815f905c1738ad82c95333dd42ef5a8cc2aa3d7dfb2b08d7" -dependencies = [ - "anyhow", - "cfg-if", - "cranelift-codegen", - "cranelift-control", - "cranelift-entity 0.100.1", - "cranelift-frontend", - "cranelift-native", - "cranelift-wasm", - "gimli", - "log", - "object", - "target-lexicon", - "thiserror", - "wasmparser 0.112.0", - "wasmtime-cranelift-shared", - "wasmtime-environ 13.0.1", - "wasmtime-versioned-export-macros 13.0.1", -] - -[[package]] -name = "wasmtime-cranelift-shared" -version = "13.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f6b197d68612f7dc3a17aa9f9587533715ecb8b4755609ce9baf7fb92b74ddc" -dependencies = [ - "anyhow", - "cranelift-codegen", - "cranelift-control", - "cranelift-native", - "gimli", - "object", - "target-lexicon", - "wasmtime-environ 13.0.1", -] - -[[package]] -name = "wasmtime-environ" -version = "13.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18e2558c8b04fd27764d8601d46b8dc39555b79720a41e626bce210a80758932" -dependencies = [ - "anyhow", - "cranelift-entity 0.100.1", - "gimli", - "indexmap", - "log", - "object", - "serde", - "serde_derive", - "target-lexicon", - "thiserror", - "wasm-encoder 0.32.0", - "wasmparser 0.112.0", - "wasmprinter", - "wasmtime-component-util 13.0.1", - "wasmtime-types 13.0.1", -] - -[[package]] -name = "wasmtime-environ" -version = "15.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6d33a9f421da810a070cd56add9bc51f852bd66afbb8b920489d6242f15b70e" -dependencies = [ - "anyhow", - "cranelift-entity 0.102.1", - "gimli", - "indexmap", - "log", - "object", - "serde", - "serde_derive", - "target-lexicon", - "thiserror", - "wasmparser 0.116.1", - "wasmtime-types 15.0.1", -] - -[[package]] -name = "wasmtime-fiber" -version = "13.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a615a2cf64a49c0dc659c7d850c6cd377b975e0abfdcf0888b282d274a82e730" -dependencies = [ - "cc", - "cfg-if", - "rustix", - "wasmtime-asm-macros 13.0.1", - "wasmtime-versioned-export-macros 13.0.1", - "windows-sys 0.48.0", -] - -[[package]] -name = "wasmtime-fiber" -version = "15.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "404741f4c6d7f4e043be2e8b466406a2aee289ccdba22bf9eba6399921121b97" -dependencies = [ - "anyhow", - "cc", - "cfg-if", - "rustix", - "wasmtime-asm-macros 15.0.1", - "wasmtime-versioned-export-macros 15.0.1", - "windows-sys 0.48.0", -] - -[[package]] -name = "wasmtime-jit" -version = "13.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd775514b8034b85b0323bfdc60abb1c28d27dbf6e22aad083ed57dac95cf72e" -dependencies = [ - "addr2line", - "anyhow", - "bincode", - "cfg-if", - "cpp_demangle", - "gimli", - "ittapi", - "log", - "object", - "rustc-demangle", - "rustix", - "serde", - "serde_derive", - "target-lexicon", - "wasmtime-environ 13.0.1", - "wasmtime-jit-debug 13.0.1", - "wasmtime-jit-icache-coherence 13.0.1", - "wasmtime-runtime 13.0.1", - "windows-sys 0.48.0", -] - -[[package]] -name = "wasmtime-jit" -version = "15.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d0994a86d6dca5f7d9740d7f2bd0568be06d2014a550361dc1c397d289d81ef" -dependencies = [ - "anyhow", - "bincode", - "cfg-if", - "gimli", - "log", - "object", - "rustix", - "serde", - "serde_derive", - "target-lexicon", - "wasmtime-environ 15.0.1", - "wasmtime-jit-icache-coherence 15.0.1", - "wasmtime-runtime 15.0.1", - "windows-sys 0.48.0", -] - -[[package]] -name = "wasmtime-jit-debug" -version = "13.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c054e27c6ce2a6191edabe89e646da013044dd5369e1d203c89f977f9bd32937" -dependencies = [ - "object", - "once_cell", - "rustix", - "wasmtime-versioned-export-macros 13.0.1", -] - -[[package]] -name = "wasmtime-jit-debug" -version = "15.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e0c4b74e606d1462d648631d5bc328e3d5b14e7f9d3ff93bc6db062fb8c5cd8" -dependencies = [ - "once_cell", - "wasmtime-versioned-export-macros 15.0.1", -] - -[[package]] -name = "wasmtime-jit-icache-coherence" -version = "13.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f323977cddf4a262d1b856366b665c5b4d01793c57b79fb42505b9fd9e61e5b" -dependencies = [ - "cfg-if", - "libc", - "windows-sys 0.48.0", -] - -[[package]] -name = "wasmtime-jit-icache-coherence" -version = "15.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3090a69ba1476979e090aa7ed4bc759178bafdb65b22f98b9ba24fc6e7e578d5" -dependencies = [ - "cfg-if", - "libc", - "windows-sys 0.48.0", -] - -[[package]] -name = "wasmtime-runtime" -version = "13.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29e26461bba043f73cb4183f4ce0d606c0eaac112475867b11e5ea36fe1cac8e" -dependencies = [ - "anyhow", - "cc", - "cfg-if", - "encoding_rs", - "indexmap", - "libc", - "log", - "mach", - "memfd", - "memoffset", - "paste", - "rand", - "rustix", - "sptr", - "wasm-encoder 0.32.0", - "wasmtime-asm-macros 13.0.1", - "wasmtime-environ 13.0.1", - "wasmtime-fiber 13.0.1", - "wasmtime-jit-debug 13.0.1", - "wasmtime-versioned-export-macros 13.0.1", - "wasmtime-wmemcheck 13.0.1", - "windows-sys 0.48.0", -] - -[[package]] -name = "wasmtime-runtime" -version = "15.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b993ac8380385ed67bf71b51b9553edcf1ab0801b78a805a067de581b9a3e88a" -dependencies = [ - "anyhow", - "cc", - "cfg-if", - "indexmap", - "libc", - "log", - "mach", - "memfd", - "memoffset", - "paste", - "rand", - "rustix", - "sptr", - "wasm-encoder 0.36.2", - "wasmtime-asm-macros 15.0.1", - "wasmtime-environ 15.0.1", - "wasmtime-fiber 15.0.1", - "wasmtime-jit-debug 15.0.1", - "wasmtime-versioned-export-macros 15.0.1", - "wasmtime-wmemcheck 15.0.1", - "windows-sys 0.48.0", -] - -[[package]] -name = "wasmtime-types" -version = "13.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fd7e9b29fee64eea5058cb5e7cb3480b52c2f1312d431d16ea8617ceebeb421" -dependencies = [ - "cranelift-entity 0.100.1", - "serde", - "serde_derive", - "thiserror", - "wasmparser 0.112.0", -] - -[[package]] -name = "wasmtime-types" -version = "15.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b5778112fcab2dc3d4371f4203ab8facf0c453dd94312b0a88dd662955e64e0" -dependencies = [ - "cranelift-entity 0.102.1", - "serde", - "serde_derive", - "thiserror", - "wasmparser 0.116.1", -] - -[[package]] -name = "wasmtime-versioned-export-macros" -version = "13.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6362c557c36d8ad4aaab735f14ed9e4f78d6b40ec85a02a88fd859af87682e52" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.41", -] - -[[package]] -name = "wasmtime-versioned-export-macros" -version = "15.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f50f51f8d79bfd2aa8e9d9a0ae7c2d02b45fe412e62ff1b87c0c81b07c738231" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.41", -] - -[[package]] -name = "wasmtime-wasi" -version = "13.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52c9e79f73320d96cd7644b021502dffee09dd92300b073f3541ae44e9ae377c" -dependencies = [ - "anyhow", - "async-trait", - "bitflags 2.4.1", - "bytes", - "cap-fs-ext", - "cap-net-ext", - "cap-rand", - "cap-std", - "cap-time-ext", - "fs-set-times", - "futures", - "io-extras", - "io-lifetimes", - "is-terminal", - "libc", - "once_cell", - "rustix", - "system-interface", - "thiserror", - "tokio", - "tracing", - "wasi-cap-std-sync", - "wasi-common", - "wasmtime 13.0.1", - "wiggle 13.0.1", - "windows-sys 0.48.0", -] - -[[package]] -name = "wasmtime-winch" -version = "13.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa5fc7212424c04c01a20bfa66c4c518e8749dde6546f5e05815dcacbec80723" -dependencies = [ - "anyhow", - "cranelift-codegen", - "gimli", - "object", - "target-lexicon", - "wasmparser 0.112.0", - "wasmtime-cranelift-shared", - "wasmtime-environ 13.0.1", - "winch-codegen", -] - -[[package]] -name = "wasmtime-wit-bindgen" -version = "13.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcc03bd58f77a68dc6a0b2ba2f8e64b1f902b50389d21bbcc690ef2f3bb87198" -dependencies = [ - "anyhow", - "heck 0.4.1", - "indexmap", - "wit-parser 0.11.3", -] - -[[package]] -name = "wasmtime-wit-bindgen" -version = "15.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b804dfd3d0c0d6d37aa21026fe7772ba1a769c89ee4f5c4f13b82d91d75216f" -dependencies = [ - "anyhow", - "heck 0.4.1", - "indexmap", - "wit-parser 0.13.0", -] - -[[package]] -name = "wasmtime-wmemcheck" -version = "13.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e485bf54eba675ca615f8f55788d3a8cd44e7bd09b8b4011edc22c2c41d859e" - -[[package]] -name = "wasmtime-wmemcheck" -version = "15.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b6060bc082cc32d9a45587c7640e29e3c7b89ada82677ac25d87850aaccb368" - -[[package]] -name = "wast" -version = "35.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ef140f1b49946586078353a453a1d28ba90adfc54dde75710bc1931de204d68" -dependencies = [ - "leb128", -] - -[[package]] -name = "wast" -version = "69.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1ee37317321afde358e4d7593745942c48d6d17e0e6e943704de9bbee121e7a" -dependencies = [ - "leb128", - "memchr", - "unicode-width", - "wasm-encoder 0.38.1", -] - -[[package]] -name = "wat" -version = "1.0.82" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aeb338ee8dee4d4cd05e6426683f21c5087dc7cfc8903e839ccf48d43332da3c" -dependencies = [ - "wast 69.0.1", -] - -[[package]] -name = "wax" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d12a78aa0bab22d2f26ed1a96df7ab58e8a93506a3e20adb47c51a93b4e1357" -dependencies = [ - "const_format", - "itertools 0.11.0", - "nom", - "pori", - "regex", - "thiserror", - "walkdir", -] - -[[package]] -name = "web-sys" -version = "0.3.66" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50c24a44ec86bb68fbecd1b3efed7e85ea5621b39b35ef2766b66cd984f8010f" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "wiggle" -version = "13.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e81ddbdc400b38d04241d740d0406ef343bd242c460f252fe59f29ad964ad24c" -dependencies = [ - "anyhow", - "async-trait", - "bitflags 2.4.1", - "thiserror", - "tracing", - "wasmtime 13.0.1", - "wiggle-macro 13.0.1", -] - -[[package]] -name = "wiggle" -version = "15.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f91028b241e692fdf30627ac10ba9d5ac378353ea4119b4f904ac95177057a44" -dependencies = [ - "anyhow", - "async-trait", - "bitflags 2.4.1", - "thiserror", - "tracing", - "wasmtime 15.0.1", - "wiggle-macro 15.0.1", - "witx", -] - -[[package]] -name = "wiggle-generate" -version = "13.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c993123d6db1a1908ef8352aabdf2e681a3dcdedc3656beb747e4db16d3cf08" -dependencies = [ - "anyhow", - "heck 0.4.1", - "proc-macro2", - "quote", - "shellexpand", - "syn 2.0.41", - "witx", -] - -[[package]] -name = "wiggle-generate" -version = "15.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e8b3d76531994513671b2ec3b29fd342bf041e2282945bb6c52eebe6aa9e7da" -dependencies = [ - "anyhow", - "heck 0.4.1", - "proc-macro2", - "quote", - "shellexpand", - "syn 2.0.41", - "witx", -] - -[[package]] -name = "wiggle-macro" -version = "13.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "476e3e09bc68e82624b70a322265515523754cb9e05fcacceabd216e276bc2ed" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.41", - "wiggle-generate 13.0.1", -] - -[[package]] -name = "wiggle-macro" -version = "15.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c189fe00c67f61bb330827f2abab1af9b5925c7929535cd13a68d265ec20b02d" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.41", - "wiggle-generate 15.0.1", -] - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-util" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" -dependencies = [ - "winapi", -] - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "winch-codegen" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9b01ca6722f7421c9cdbe4c9b62342ce864d0a9e8736d56dac717a86b1a65ae" -dependencies = [ - "anyhow", - "cranelift-codegen", - "gimli", - "regalloc2", - "smallvec", - "target-lexicon", - "wasmparser 0.112.0", - "wasmtime-environ 13.0.1", -] - -[[package]] -name = "windows-sys" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" -dependencies = [ - "windows-targets 0.48.5", -] - -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets 0.52.0", -] - -[[package]] -name = "windows-targets" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" -dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", -] - -[[package]] -name = "windows-targets" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" -dependencies = [ - "windows_aarch64_gnullvm 0.52.0", - "windows_aarch64_msvc 0.52.0", - "windows_i686_gnu 0.52.0", - "windows_i686_msvc 0.52.0", - "windows_x86_64_gnu 0.52.0", - "windows_x86_64_gnullvm 0.52.0", - "windows_x86_64_msvc 0.52.0", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" - -[[package]] -name = "windows_i686_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" - -[[package]] -name = "windows_i686_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" - -[[package]] -name = "winnow" -version = "0.5.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c830786f7720c2fd27a1a0e27a709dbd3c4d009b56d098fc742d4f4eab91fe2" -dependencies = [ - "memchr", -] - -[[package]] -name = "winreg" -version = "0.50.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" -dependencies = [ - "cfg-if", - "windows-sys 0.48.0", -] - -[[package]] -name = "winx" -version = "0.36.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9643b83820c0cd246ecabe5fa454dd04ba4fa67996369466d0747472d337346" -dependencies = [ - "bitflags 2.4.1", - "windows-sys 0.52.0", -] - -[[package]] -name = "wit-bindgen-gen-core" -version = "0.2.0" -source = "git+https://github.com/fermyon/wit-bindgen-backport?rev=598cd229bb43baceff9616d16930b8a5a3e79d79#598cd229bb43baceff9616d16930b8a5a3e79d79" -dependencies = [ - "anyhow", - "wit-parser 0.2.0", -] - -[[package]] -name = "wit-bindgen-gen-rust" -version = "0.2.0" -source = "git+https://github.com/fermyon/wit-bindgen-backport?rev=598cd229bb43baceff9616d16930b8a5a3e79d79#598cd229bb43baceff9616d16930b8a5a3e79d79" -dependencies = [ - "heck 0.3.3", - "wit-bindgen-gen-core", -] - -[[package]] -name = "wit-bindgen-gen-wasmtime" -version = "0.2.0" -source = "git+https://github.com/fermyon/wit-bindgen-backport?rev=598cd229bb43baceff9616d16930b8a5a3e79d79#598cd229bb43baceff9616d16930b8a5a3e79d79" -dependencies = [ - "heck 0.3.3", - "wit-bindgen-gen-core", - "wit-bindgen-gen-rust", -] - -[[package]] -name = "wit-bindgen-wasmtime" -version = "0.2.0" -source = "git+https://github.com/fermyon/wit-bindgen-backport?rev=598cd229bb43baceff9616d16930b8a5a3e79d79#598cd229bb43baceff9616d16930b8a5a3e79d79" -dependencies = [ - "anyhow", - "async-trait", - "bitflags 1.3.2", - "thiserror", - "wasmtime 13.0.1", - "wit-bindgen-wasmtime-impl", -] - -[[package]] -name = "wit-bindgen-wasmtime-impl" -version = "0.2.0" -source = "git+https://github.com/fermyon/wit-bindgen-backport?rev=598cd229bb43baceff9616d16930b8a5a3e79d79#598cd229bb43baceff9616d16930b8a5a3e79d79" -dependencies = [ - "proc-macro2", - "syn 1.0.109", - "wit-bindgen-gen-core", - "wit-bindgen-gen-wasmtime", -] - -[[package]] -name = "wit-parser" -version = "0.2.0" -source = "git+https://github.com/fermyon/wit-bindgen-backport?rev=598cd229bb43baceff9616d16930b8a5a3e79d79#598cd229bb43baceff9616d16930b8a5a3e79d79" -dependencies = [ - "anyhow", - "id-arena", - "pulldown-cmark 0.8.0", - "unicode-normalization", - "unicode-xid", -] - -[[package]] -name = "wit-parser" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a39edca9abb16309def3843af73b58d47d243fe33a9ceee572446bcc57556b9a" -dependencies = [ - "anyhow", - "id-arena", - "indexmap", - "log", - "pulldown-cmark 0.9.3", - "semver 1.0.20", - "serde", - "serde_json", - "unicode-xid", - "url", -] - -[[package]] -name = "wit-parser" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15df6b7b28ce94b8be39d8df5cb21a08a4f3b9f33b631aedb4aa5776f785ead3" -dependencies = [ - "anyhow", - "id-arena", - "indexmap", - "log", - "semver 1.0.20", - "serde", - "serde_derive", - "serde_json", - "unicode-xid", -] - -[[package]] -name = "witx" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e366f27a5cabcddb2706a78296a40b8fcc451e1a6aba2fc1d94b4a01bdaaef4b" -dependencies = [ - "anyhow", - "log", - "thiserror", - "wast 35.0.2", -] - -[[package]] -name = "zerocopy" -version = "0.7.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "306dca4455518f1f31635ec308b6b3e4eb1b11758cefafc782827d0aa7acb5c7" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be912bf68235a88fbefd1b73415cb218405958d1655b2ece9035a19920bdf6ba" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.41", -] - -[[package]] -name = "zstd" -version = "0.11.2+zstd.1.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20cc960326ece64f010d2d2107537f26dc589a6573a316bd5b1dba685fa5fde4" -dependencies = [ - "zstd-safe 5.0.2+zstd.1.5.2", -] - -[[package]] -name = "zstd" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a27595e173641171fc74a1232b7b1c7a7cb6e18222c11e9dfb9888fa424c53c" -dependencies = [ - "zstd-safe 6.0.6", -] - -[[package]] -name = "zstd-safe" -version = "5.0.2+zstd.1.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d2a5585e04f9eea4b2a3d1eca508c4dee9592a89ef6f450c11719da0726f4db" -dependencies = [ - "libc", - "zstd-sys", -] - -[[package]] -name = "zstd-safe" -version = "6.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee98ffd0b48ee95e6c5168188e44a54550b1564d9d530ee21d5f0eaed1069581" -dependencies = [ - "libc", - "zstd-sys", -] - -[[package]] -name = "zstd-sys" -version = "2.0.9+zstd.1.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e16efa8a874a0481a574084d34cc26fdb3b99627480f785888deb6386506656" -dependencies = [ - "cc", - "pkg-config", -] diff --git a/JS/wasm/crates/wasmjs-runtime/Cargo.toml b/JS/wasm/crates/wasmjs-runtime/Cargo.toml deleted file mode 100644 index 3f6e47f8d..000000000 --- a/JS/wasm/crates/wasmjs-runtime/Cargo.toml +++ /dev/null @@ -1,36 +0,0 @@ -[package] -name = "wasmjs-runtime" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -anyhow = "1" -actix-web = "4" -lazy_static = "1" -reqwest = "0.11" -serde = { version = "1", features = ["derive"] } -serde_json = "1" -clap = { version = "4", features = ["derive"] } -tokio = { version = "1", features = ["full"] } -wasmtime = "13" -wasmtime-wasi = "13" -wasi-common = "13" -wit-bindgen-wasmtime = { git = "https://github.com/fermyon/wit-bindgen-backport", rev = "598cd229bb43baceff9616d16930b8a5a3e79d79", features = [ - "async", -] } -wax = "0.6" -regex = "1" -base64 = "0.21" -sha256 = "1" -blake3 = "1.5.0" -wasmparser = "0.115.0" -toml = "0.8.6" -actix-files = "0.6.2" -http = "0.2.11" -wiggle = "15.0.0" -thiserror = "1.0" -tracing = "0.1.40" -semver = "^0.10.0" -jsonnet-rs = "0.17.0" diff --git a/JS/wasm/crates/wasmjs-runtime/arakoo.toml b/JS/wasm/crates/wasmjs-runtime/arakoo.toml deleted file mode 100644 index c18b6ba81..000000000 --- a/JS/wasm/crates/wasmjs-runtime/arakoo.toml +++ /dev/null @@ -1,61 +0,0 @@ -[local_server] -[local_server.geolocation] -use_default_loopback = false -[local_server.geolocation.mapping.InlineToml.addresses] -[local_server.geolocation.mapping.InlineToml.addresses."103.117.185.66".data] -as_name = "shree net online services private limited" -as_number = 137679 -area_code = 0 -city = "bhiwandi" -conn_speed = "broadband" -conn_type = "wifi" -continent = "AS" -country_code = "IN" -country_code3 = "IND" -country_name = "india" -latitude = 19.24 -longitude = 73.02 -metro_code = 356002 -postal_code = "421302" -proxy_description = "?" -proxy_type = "?" -region = "MH" -utc_offset = 530 -[local_server.geolocation.mapping.InlineToml.addresses."127.0.0.1".data] -as_name = "Arakoo Test" -as_number = 12345 -area_code = 123 -city = "Test City" -conn_speed = "broadband" -conn_type = "wired" -continent = "NA" -country_code = "CA" -country_code3 = "CAN" -country_name = "Canada" -latitude = 12.345 -longitude = 54.321 -metro_code = 0 -postal_code = "12345" -proxy_description = "?" -proxy_type = "?" -region = "BC" -utc_offset = -700 -[local_server.geolocation.mapping.InlineToml.addresses."0000:0000:0000:0000:0000:0000:0000:0001".data] -as_name = "Arakoo Test IPv6" -as_number = 12345 -area_code = 123 -city = "Test City IPv6" -conn_speed = "broadband" -conn_type = "wired" -continent = "NA" -country_code = "CA" -country_code3 = "CAN" -country_name = "Canada" -latitude = 12.345 -longitude = 54.321 -metro_code = 0 -postal_code = "12345" -proxy_description = "?" -proxy_type = "?" -region = "BC" -utc_offset = -700 diff --git a/JS/wasm/crates/wasmjs-runtime/src/bindings.rs b/JS/wasm/crates/wasmjs-runtime/src/bindings.rs deleted file mode 100644 index 4de98ca39..000000000 --- a/JS/wasm/crates/wasmjs-runtime/src/bindings.rs +++ /dev/null @@ -1,299 +0,0 @@ -use std::collections::HashMap; - -use crate::error::Error; -use actix_web::http::Uri; -use jsonnet::JsonnetVm; -use reqwest::Method; -use serde::Deserialize; -use serde_json::Value; -use tokio::runtime::Builder; -use wiggle::GuestErrorType; - -wit_bindgen_wasmtime::export!({paths: ["../../assets/wasmjs/wit/http.wit",], - async:[] - } -); - -wiggle::from_witx!({ - witx:["$CARGO_MANIFEST_DIR/../../assets/wasmjs/wit/arakoo-geo.witx"], - errors: { arakoo_status => Error }, -}); - -impl GuestErrorType for ArakooStatus { - fn success() -> Self { - ArakooStatus::Ok - } -} - -use self::{ - http::{FileError, Http, HttpError, HttpMethod, HttpRequest, HttpRequestError, HttpResponse}, - types::ArakooStatus, -}; - -#[derive(Deserialize, Clone)] -#[serde(default)] -pub struct HttpRequestsConfig { - pub allowed_hosts: Vec, - pub allowed_methods: Vec, - pub allow_http: bool, -} - -impl Default for HttpRequestsConfig { - fn default() -> Self { - Self { - allowed_hosts: vec!["aws.connect.psdb.cloud".to_string()], - allowed_methods: Vec::from([ - String::from("GET"), - String::from("POST"), - String::from("PUT"), - String::from("PATCH"), - String::from("DELETE"), - ]), - allow_http: false, - } - } -} - -pub struct HttpBindings { - pub http_config: HttpRequestsConfig, -} - -impl From for Method { - fn from(value: HttpMethod) -> Self { - match value { - HttpMethod::Get => Method::GET, - HttpMethod::Post => Method::POST, - HttpMethod::Put => Method::PUT, - HttpMethod::Patch => Method::PATCH, - HttpMethod::Delete => Method::DELETE, - HttpMethod::Options => Method::OPTIONS, - HttpMethod::Head => Method::HEAD, - } - } -} - -impl From for HttpError { - fn from(value: reqwest::Error) -> Self { - if value.is_timeout() { - HttpError::Timeout - } else if value.is_redirect() { - HttpError::RedirectLoop - } else if value.is_request() { - HttpError::InvalidRequest - } else if value.is_body() { - HttpError::InvalidRequestBody - } else if value.is_decode() { - HttpError::InvalidResponseBody - } else { - HttpError::InternalError - } - } -} - -impl Http for HttpBindings { - fn send_http_request( - &mut self, - req: HttpRequest<'_>, - ) -> Result { - let mut headers = Vec::new(); - let url = req.uri.to_string(); - let body = req.body.unwrap_or(&[]).to_vec(); - let uri = url.parse::().map_err(|e| HttpRequestError { - error: HttpError::InvalidRequest, - message: e.to_string(), - })?; - let method: Method = req.method.into(); - - if uri.host().is_some() - && !self - .http_config - .allowed_hosts - .contains(&uri.host().unwrap().to_string()) - { - return Err(HttpRequestError { - error: HttpError::NotAllowed, - message: format!("'{}' is not in the allowed hosts list", uri.host().unwrap()), - }); - } - - if uri.scheme().is_some() - && (!self.http_config.allow_http && uri.scheme_str().unwrap() == "http") - { - return Err(HttpRequestError { - error: HttpError::NotAllowed, - message: "Only https is allowed".to_string(), - }); - } - - if !self - .http_config - .allowed_methods - .contains(&method.to_string()) - { - return Err(HttpRequestError { - error: HttpError::NotAllowed, - message: format!("'{}' method not allowed", method.as_str()), - }); - } - - for (key, value) in req.headers { - headers.push((key.to_string(), value.to_string())); - } - - let thread_result = std::thread::spawn(move || { - Builder::new_current_thread() - .enable_all() - .build() - .unwrap() - .block_on(async { - let client = reqwest::Client::new(); - - let mut builder = client.request(method, url); - - for (key, value) in headers { - builder = builder.header(key, value); - } - - builder = builder.body(body); - - match builder.send().await { - Ok(res) => { - let mut headers = Vec::new(); - let status = res.status().as_u16(); - - for (name, value) in res.headers().iter() { - headers - .push((name.to_string(), value.to_str().unwrap().to_string())); - } - - let body = res.bytes().await; - - Ok(HttpResponse { - headers, - status, - body: Some(body.unwrap().to_vec()), - }) - } - Err(e) => { - let message = e.to_string(); - - Err(HttpRequestError { - error: e.into(), - message, - }) - } - } - }) - }) - .join(); - - match thread_result { - Ok(res) => match res { - Ok(res) => Ok(res), - Err(err) => Err(err), - }, - Err(_) => Err(HttpRequestError { - error: HttpError::InternalError, - message: "Could not process the request".to_string(), - }), - } - } - - fn read_bytes(&mut self, path: &str) -> Result { - // read the file from the path and return the bytes - // if the file does not exist, return FileError::NotFound - let path = path.to_owned(); - let thread_result = std::thread::spawn(move || { - Builder::new_current_thread() - .enable_all() - .build() - .unwrap() - .block_on(async { - let bytes = tokio::fs::read(path).await; - match bytes { - Ok(bytes) => Ok(std::str::from_utf8(&bytes).unwrap().to_string()), - Err(_) => Err(FileError::NotFound), - } - }) - }) - .join(); - - match thread_result { - Ok(res) => match res { - Ok(res) => Ok(res), - Err(err) => Err(err), - }, - Err(_) => Err(FileError::NotFound), - } - } - - fn jsonnet(&mut self, file: &str) -> Result { - jsonnet(file) - } - - fn jsonnet_ext_var(&mut self, file: &str, ext_var: &str) -> Result { - let file = file.to_owned(); - let ext_var = ext_var.to_owned(); - let thread_result = std::thread::spawn(move || { - Builder::new_current_thread() - .enable_all() - .build() - .unwrap() - .block_on(async { - let mut vm = JsonnetVm::new(); - let ext_var_str = ext_var.as_str(); - let ext_vars: HashMap<&str, Value> = serde_json::from_str(ext_var_str).unwrap(); - for (key, value) in ext_vars { - vm.ext_var(key, value.as_str().unwrap()); - } - let json = vm.evaluate_file(&file); - match json { - Ok(json) => Ok(json.to_string()), - Err(e) => { - println!("Error: {}", e); - Err(FileError::NotFound) - } - } - }) - }) - .join(); - match thread_result { - Ok(res) => match res { - Ok(res) => Ok(res), - Err(err) => Err(err), - }, - Err(_) => Err(FileError::NotFound), - } - } -} - -pub fn jsonnet(file: &str) -> Result { - let file = file.to_owned(); - let thread_result = std::thread::spawn(move || { - Builder::new_current_thread() - .enable_all() - .build() - .unwrap() - .block_on(async { - let mut vm = JsonnetVm::new(); - let json = vm.evaluate_file(&file); - - match json { - Ok(json) => Ok(json.to_string()), - Err(e) => { - println!("Error: {}", e); - Err(FileError::NotFound) - } - } - }) - }) - .join(); - - match thread_result { - Ok(res) => match res { - Ok(res) => Ok(res), - Err(err) => Err(err), - }, - Err(_) => Err(FileError::NotFound), - } -} diff --git a/JS/wasm/crates/wasmjs-runtime/src/config.rs b/JS/wasm/crates/wasmjs-runtime/src/config.rs deleted file mode 100644 index 69123fd29..000000000 --- a/JS/wasm/crates/wasmjs-runtime/src/config.rs +++ /dev/null @@ -1,181 +0,0 @@ -use crate::bindings::HttpRequestsConfig; -use anyhow::Result; -use serde::Deserialize; -use serde::Deserializer; -use std::collections::HashMap; -use std::{env, fs}; -use std::path::{Path, PathBuf}; -use std::str::FromStr; -use toml::Table; -use crate::error::ArakooConfigError; -use crate::geolocation::Geolocation; - -#[derive(Deserialize, Clone, Default)] -#[serde(default)] -pub struct Features { - pub http_requests: HttpRequestsConfig, - pub geo: ArakooConfig -} - -#[derive(Deserialize, Clone, Default)] -pub struct Folder { - #[serde(deserialize_with = "deserialize_path", default)] - pub from: PathBuf, - pub to: String, -} - -fn deserialize_path<'de, D>(deserializer: D) -> Result -where - D: Deserializer<'de>, -{ - let result: Result = Deserialize::deserialize(deserializer); - - match result { - Ok(value) => { - let split = if value.contains('/') { - value.split('/') - } else { - value.split('\\') - }; - - Ok(split.fold(PathBuf::new(), |mut acc, el| { - acc.push(el); - acc - })) - } - Err(err) => Err(err), - } -} - -#[derive(Debug, Clone, Deserialize)] -pub struct ArakooConfig { - pub(crate) local_server: LocalServerConfig, -} - -impl Default for ArakooConfig { - fn default() -> Self { - ArakooConfig{ - local_server: LocalServerConfig::default() - } - } -} - -impl ArakooConfig { - pub fn geolocation(&self) -> &Geolocation { - &self.local_server.geolocation - } - pub fn from_file(path: impl AsRef) -> Result { - fs::read_to_string(path.as_ref()) - .map_err(|err| ArakooConfigError::IoError { - path: path.as_ref().display().to_string(), - err, - }) - .and_then(Self::from_str) - } - - /// Parse a string containing TOML data into a `ArakooConfig`. - fn from_str(toml: impl AsRef) -> Result { - toml::from_str::(toml.as_ref()) - .map_err(Into::into) - .and_then(TryInto::try_into) - } - -} - -impl FromStr for ArakooConfig { - type Err = ArakooConfigError; - fn from_str(s: &str) -> Result { - Self::from_str(s) - } -} - -#[derive(Deserialize)] -struct TomlArakooConfig { - local_server: Option, -} - -impl TryInto for TomlArakooConfig { - type Error = ArakooConfigError; - fn try_into(self) -> Result { - let Self { - local_server, - } = self; - let local_server: LocalServerConfig = local_server - .map(TryInto::try_into) - .transpose()? - .unwrap_or_default(); - Ok(ArakooConfig { - local_server, - }) - } -} - -#[derive(Deserialize, Clone, Default)] -pub struct Config { - pub name: Option, - #[serde(default)] - pub features: Features, - pub folders: Option>, - #[serde(deserialize_with = "read_environment_variables", default)] - pub vars: HashMap, -} - -fn read_environment_variables<'de, D>( - deserializer: D, -) -> core::result::Result, D::Error> -where - D: Deserializer<'de>, -{ - let result: core::result::Result>, D::Error> = - Deserialize::deserialize(deserializer); - - match result { - Ok(value) => match value { - Some(mut options) => { - for (_, value) in options.iter_mut() { - if value.starts_with('$') && !value.contains(' ') { - value.remove(0); - - match env::var(&value) { - Ok(env_value) => *value = env_value, - Err(_) => *value = String::new(), - } - } - } - - Ok(options) - } - None => Ok(HashMap::new()), - }, - Err(err) => Err(err), - } -} - -#[derive(Clone, Debug, Default, Deserialize, )] -pub struct LocalServerConfig { - geolocation: Geolocation, -} - - -#[derive(Deserialize)] -struct RawLocalServerConfig { - geolocation: Option, -} - -impl TryInto for RawLocalServerConfig { - type Error = ArakooConfigError; - fn try_into(self) -> Result { - let Self { - geolocation, - } = self; - let geolocation = if let Some(geolocation) = geolocation { - geolocation.try_into()? - } else { - Geolocation::default() - }; - - Ok(LocalServerConfig { - geolocation, - }) - } -} diff --git a/JS/wasm/crates/wasmjs-runtime/src/error.rs b/JS/wasm/crates/wasmjs-runtime/src/error.rs deleted file mode 100644 index 944a5eff2..000000000 --- a/JS/wasm/crates/wasmjs-runtime/src/error.rs +++ /dev/null @@ -1,103 +0,0 @@ -//! Error types. - -use thiserror::Error; -use wiggle::GuestError; - -#[derive(Debug, Error)] -#[non_exhaustive] -pub enum Error { - #[error("Buffer length error: {buf} too long to fit in {len}")] - BufferLengthError { - buf: &'static str, - len: &'static str, - }, - #[error("Invalid argument given")] - InvalidArgument, - #[error(transparent)] - GeolocationError(#[from] crate::wiggle_abi::geo_impl::GeolocationError), - #[error("Shared memory not supported yet")] - SharedMemory, - #[error("Guest error: [{0}]")] - GuestError(#[from] GuestError), -} - -/// Errors that may occur while validating geolocation configurations. -#[derive(Debug, Error)] -pub enum GeolocationConfigError { - #[error(transparent)] - IoError(std::io::Error), - - #[error("definition was not provided as a TOML table")] - InvalidEntryType, - - #[error("missing 'file' field")] - MissingFile, - - #[error("'file' field is empty")] - EmptyFileEntry, - - #[error("missing 'addresses' field")] - MissingAddresses, - - #[error("inline geolocation value was not a string")] - InvalidInlineEntryType, - - #[error("'file' field was not a string")] - InvalidFileEntry, - - #[error("'addresses' was not provided as a TOML table")] - InvalidAddressesType, - - // #[error("unrecognized key '{0}'")] - // UnrecognizedKey(String), - - // #[error("missing 'format' field")] - // MissingFormat, - - #[error("'format' field was not a string")] - InvalidFormatEntry, - - #[error("IP address not valid: '{0}'")] - InvalidAddressEntry(String), - - #[error("'{0}' is not a valid format for the geolocation mapping. Supported format(s) are: 'inline-toml', 'json'.")] - InvalidGeolocationMappingFormat(String), - - #[error( - "The file is of the wrong format. The file is expected to contain a single JSON Object" - )] - GeolocationFileWrongFormat, - - #[error("'format' field is empty")] - EmptyFormatEntry, - - // #[error("Item value under key named '{key}' is of the wrong format. The value is expected to be a JSON String")] - // GeolocationItemValueWrongFormat { key: String }, -} - -#[derive(Debug, Error)] -pub enum ArakooConfigError { - - #[error("invalid configuration for '{name}': {err}")] - InvalidGeolocationDefinition { - name: String, - #[source] - err: GeolocationConfigError, - }, - - #[error("error parsing `edge.toml`: {0}")] - InvalidArakooToml(#[from] toml::de::Error), - - #[error("invalid manifest version: {0}")] - InvalidManifestVersion(#[from] semver::SemVerError), - - /// An I/O error that occurred while reading the file. - #[error("error reading '{path}': {err}")] - IoError { - path: String, - #[source] - err: std::io::Error, - }, - // #[error("error reading: {err}")] - // TomlError { err: toml::de::Error }, -} diff --git a/JS/wasm/crates/wasmjs-runtime/src/geolocation.rs b/JS/wasm/crates/wasmjs-runtime/src/geolocation.rs deleted file mode 100644 index 72ffdc2a7..000000000 --- a/JS/wasm/crates/wasmjs-runtime/src/geolocation.rs +++ /dev/null @@ -1,308 +0,0 @@ -use serde::{Deserialize, Serialize}; -use { - crate::error::GeolocationConfigError, - serde_json::{ - Map, Number, Value as SerdeValue, Value::Number as SerdeNumber, - Value::String as SerdeString, - }, - std::{collections::HashMap, fs, iter::FromIterator, net::IpAddr, path::Path, path::PathBuf}, -}; - -#[derive(Clone, Debug,Deserialize)] -pub struct Geolocation { - mapping: GeolocationMapping, - use_default_loopback: bool, -} - -#[derive(Clone, Debug, Deserialize)] -pub enum GeolocationMapping { - Empty, - InlineToml { - addresses: HashMap, - }, - Json { - file: PathBuf, - }, -} - -#[derive(Clone, Debug, Deserialize, Serialize)] -pub struct GeolocationData { - pub(crate) data: Map, -} - -impl Default for Geolocation { - fn default() -> Self { - Self { - mapping: GeolocationMapping::default(), - use_default_loopback: true, - } - } -} - -impl Geolocation { - - pub fn lookup(&self, addr: &IpAddr) -> Option { - self.mapping.get(addr).or_else(|| { - if self.use_default_loopback && addr.is_loopback() { - Some(GeolocationData::default()) - } else { - None - } - }) - } -} - -mod deserialization { - use std::{net::IpAddr, str::FromStr}; - - use serde_json::Number; - - use { - super::{Geolocation, GeolocationData, GeolocationMapping}, - crate::error::{ArakooConfigError, GeolocationConfigError}, - serde_json::Value as SerdeValue, - std::path::PathBuf, - std::{collections::HashMap, convert::TryFrom}, - toml::value::{Table, Value}, - }; - - impl TryFrom
for Geolocation { - type Error = ArakooConfigError; - - fn try_from(toml: Table) -> Result { - fn process_config(mut toml: Table) -> Result { - let use_default_loopback = toml.remove("use_default_loopback").map_or( - Ok(true), - |use_default_loopback| match use_default_loopback { - Value::Boolean(use_default_loopback) => Ok(use_default_loopback), - _ => Err(GeolocationConfigError::InvalidEntryType), - }, - )?; - - let mapping = match toml.remove("format") { - Some(Value::String(value)) => match value.as_str() { - "inline-toml" => process_inline_toml_dictionary(&mut toml)?, - "json" => process_json_entries(&mut toml)?, - "" => return Err(GeolocationConfigError::EmptyFormatEntry), - format => { - return Err(GeolocationConfigError::InvalidGeolocationMappingFormat( - format.to_string(), - )) - } - }, - Some(_) => return Err(GeolocationConfigError::InvalidFormatEntry), - None => GeolocationMapping::Empty, - }; - - Ok(Geolocation { - mapping, - use_default_loopback, - }) - } - - process_config(toml).map_err(|err| ArakooConfigError::InvalidGeolocationDefinition { - name: "geolocation_mapping".to_string(), - err, - }) - } - } - - pub fn parse_ip_address(address: &str) -> Result { - IpAddr::from_str(address) - .map_err(|err| GeolocationConfigError::InvalidAddressEntry(err.to_string())) - } - - fn process_inline_toml_dictionary( - toml: &mut Table, - ) -> Result { - fn convert_value_to_json(value: Value) -> Option { - match value { - Value::String(value) => Some(SerdeValue::String(value)), - Value::Integer(value) => Number::try_from(value).ok().map(SerdeValue::Number), - Value::Float(value) => Number::from_f64(value).map(SerdeValue::Number), - Value::Boolean(value) => Some(SerdeValue::Bool(value)), - _ => None, - } - } - - // Take the `addresses` field from the provided TOML table. - let toml = match toml - .remove("addresses") - .ok_or(GeolocationConfigError::MissingAddresses)? - { - Value::Table(table) => table, - _ => return Err(GeolocationConfigError::InvalidAddressesType), - }; - - let mut addresses = HashMap::::with_capacity(toml.len()); - - for (address, value) in toml { - let address = parse_ip_address(address.as_str())?; - let table = value - .as_table() - .ok_or(GeolocationConfigError::InvalidInlineEntryType)? - .to_owned(); - - let mut geolocation_data = GeolocationData::new(); - - for (field, value) in table { - let value = convert_value_to_json(value) - .ok_or(GeolocationConfigError::InvalidInlineEntryType)?; - geolocation_data.insert(field, value); - } - - addresses.insert(address, geolocation_data); - } - - Ok(GeolocationMapping::InlineToml { addresses }) - } - - fn process_json_entries( - toml: &mut Table, - ) -> Result { - let file: PathBuf = match toml - .remove("file") - .ok_or(GeolocationConfigError::MissingFile)? - { - Value::String(file) => { - if file.is_empty() { - return Err(GeolocationConfigError::EmptyFileEntry); - } else { - file.into() - } - } - _ => return Err(GeolocationConfigError::InvalidFileEntry), - }; - - GeolocationMapping::read_json_contents(&file)?; - - Ok(GeolocationMapping::Json { file }) - } -} - -impl Default for GeolocationMapping { - fn default() -> Self { - Self::Empty - } -} - -impl GeolocationMapping { - pub fn get(&self, address: &IpAddr) -> Option { - match self { - Self::Empty => None, - Self::InlineToml { addresses } => addresses - .get(address) - .map(|geolocation_data| geolocation_data.to_owned()), - Self::Json { file } => Self::read_json_contents(file) - .ok() - .map(|addresses| { - addresses - .get(address) - .map(|geolocation_data| geolocation_data.to_owned()) - }) - .unwrap(), - } - } - - pub fn read_json_contents( - file: &Path, - ) -> Result, GeolocationConfigError> { - let data = fs::read_to_string(file).map_err(GeolocationConfigError::IoError)?; - - // Deserialize the contents of the given JSON file. - let json = match serde_json::from_str(&data) - .map_err(|_| GeolocationConfigError::GeolocationFileWrongFormat)? - { - // Check that we were given an object. - serde_json::Value::Object(obj) => obj, - _ => { - return Err(GeolocationConfigError::GeolocationFileWrongFormat); - } - }; - - let mut addresses = HashMap::::with_capacity(json.len()); - - for (address, value) in json { - let address = deserialization::parse_ip_address(address.as_str())?; - let table = value - .as_object() - .ok_or(GeolocationConfigError::InvalidInlineEntryType)? - .to_owned(); - - let geolocation_data = GeolocationData::from(&table); - - addresses.insert(address, geolocation_data); - } - - Ok(addresses) - } -} - -impl Default for GeolocationData { - fn default() -> Self { - let default_entries = HashMap::<&str, SerdeValue>::from([ - ("as_name", SerdeString(String::from("Arakoo Cloud, Inc"))), - ("as_number", SerdeNumber(Number::from(54113))), - ("area_code", SerdeNumber(Number::from(415))), - ("city", SerdeString(String::from("San Francisco"))), - ("conn_speed", SerdeString(String::from("broadband"))), - ("conn_type", SerdeString(String::from("wired"))), - ("continent", SerdeString(String::from("NA"))), - ("country_code", SerdeString(String::from("US"))), - ("country_code3", SerdeString(String::from("USA"))), - ( - "country_name", - SerdeString(String::from("United States of America")), - ), - ("latitude", SerdeNumber(Number::from_f64(37.77869).unwrap())), - ( - "longitude", - SerdeNumber(Number::from_f64(-122.39557).unwrap()), - ), - ("metro_code", SerdeNumber(Number::from(0))), - ("postal_code", SerdeString(String::from("94107"))), - ("proxy_description", SerdeString(String::from("?"))), - ("proxy_type", SerdeString(String::from("?"))), - ("region", SerdeString(String::from("CA"))), - ("utc_offset", SerdeNumber(Number::from(-700))), - ]); - - Self::from(default_entries) - } -} - -impl From> for GeolocationData { - fn from(value: HashMap<&str, SerdeValue>) -> Self { - let entries = value - .iter() - .map(|(&field, value)| (field.to_string(), value.to_owned())); - - Self { - data: Map::from_iter(entries), - } - } -} - -impl From<&Map> for GeolocationData { - fn from(data: &Map) -> Self { - Self { - data: data.to_owned(), - } - } -} - -impl GeolocationData { - pub fn new() -> Self { - Self { data: Map::new() } - } - - pub fn insert(&mut self, field: String, value: SerdeValue) { - self.data.insert(field, value); - } -} - -impl ToString for GeolocationData { - fn to_string(&self) -> String { - serde_json::to_string(&self.data).unwrap_or_else(|_| "".to_string()) - } -} diff --git a/JS/wasm/crates/wasmjs-runtime/src/handlers.rs b/JS/wasm/crates/wasmjs-runtime/src/handlers.rs deleted file mode 100644 index e70c556e3..000000000 --- a/JS/wasm/crates/wasmjs-runtime/src/handlers.rs +++ /dev/null @@ -1,163 +0,0 @@ -use std::{ - io::{Error, ErrorKind}, - path::{Component, Path, PathBuf}, -}; - -use actix_files::NamedFile; -use actix_web::{ - http::StatusCode, - web::{Bytes, Data}, - HttpRequest, HttpResponse, -}; - -use std::net::{IpAddr, Ipv4Addr}; -use std::str::FromStr; -use crate::geolocation::GeolocationData; -use crate::io::WasmOutput; -use crate::routes::WORKERS; -use crate::server::AppData; - -fn clean_up_path(uri: &str) -> PathBuf { - let path = PathBuf::from_iter(uri.split('/')); - - let valid_components: Vec> = path - .components() - .filter(|c| matches!(c, Component::Normal(_))) - .collect(); - - PathBuf::from_iter(valid_components) -} - -fn retrieve_asset_path(root_path: &Path, file_path: &Path, index_folder: bool) -> Option { - let public_folder = root_path.join("public"); - let asset_path = if index_folder { - public_folder.join(file_path).join("index.html") - } else { - public_folder.join(file_path) - }; - - if asset_path.starts_with(public_folder) && asset_path.exists() && asset_path.is_file() { - Some(asset_path) - } else { - None - } -} - -pub async fn handle_assets(req: &HttpRequest) -> Result { - let root_path = &req - .app_data::>() - .expect("error fetching app data") - .root_path; - let uri_path = req.path(); - - let parsed_path = clean_up_path(uri_path); - - if let Some(file_path) = retrieve_asset_path(root_path, &parsed_path, false) { - NamedFile::open_async(file_path).await - } else if let Some(index_folder_path) = retrieve_asset_path(root_path, &parsed_path, true) { - NamedFile::open_async(index_folder_path).await - } else { - Err(Error::new(ErrorKind::NotFound, "The file is not present")) - } -} - -pub async fn handle_not_found(req: &HttpRequest) -> HttpResponse { - let root_path = &req - .app_data::>() - .expect("error fetching app data") - .root_path; - let public_404_path = root_path.join("public").join("404.html"); - - if let Ok(file) = NamedFile::open_async(public_404_path).await { - file.into_response(req) - } else { - HttpResponse::NotFound().body("") - } -} - -const CORS_HEADER: &str = "Access-Control-Allow-Origin"; - -pub async fn handle_worker(req: HttpRequest, body: Bytes) -> HttpResponse { - let app_data = req - .app_data::>() - .expect("error fetching app data"); - - let selected_route = app_data.routes.retrieve_best_route(req.path()); - let worker = if let Some(route) = selected_route { - if route.is_dynamic() { - if let Ok(existing_file) = handle_assets(&req).await { - return existing_file.into_response(&req); - } - } - - let workers = WORKERS - .read() - .expect("error locking worker lock for reading"); - - Some( - workers - .get(&route.worker) - .expect("unexpected missing worker") - .clone(), - ) - } else { - None - }; - - if worker.is_none() { - return handle_not_found(&req).await; - }; - let worker = worker.unwrap(); - - let body_str = String::from_utf8(body.to_vec()).unwrap_or_else(|_| String::from("")); - - let vars = &worker.config.vars; - let geolocation = worker.config.features.geo.geolocation(); - - let client = req.connection_info(); - let ip = client.realip_remote_addr(); - - let loop_back_ip = IpAddr::V4(Ipv4Addr::new(127,0,0,1)); - - let look_up_ip = match ip { - None => { loop_back_ip } - Some(result) => {match IpAddr::from_str(result) { - Ok(ip_addr) => {ip_addr} - Err(_) => {loop_back_ip} - }} - }; - - let geo_details = match geolocation.lookup(&look_up_ip) { - None => { GeolocationData::default() } - Some(details) => {details} - }; - - let handler_result = match worker.run(&req, &body_str, vars, geo_details).await { - Ok(output) => output, - Err(err) => WasmOutput::failed( - err, - worker.config.name.clone(), - selected_route.map(|route| route.path.clone()), - ), - }; - - let mut builder = - HttpResponse::build(StatusCode::from_u16(handler_result.status).unwrap_or(StatusCode::OK)); - builder.insert_header(("Content-Type", "text/html")); - - if let Some(origins) = app_data.cors_origins.as_ref() { - if !handler_result.headers.contains_key(CORS_HEADER) { - let header_value = origins.join(","); - builder.insert_header((CORS_HEADER, header_value)); - } - } - - for (key, val) in handler_result.headers.iter() { - builder.insert_header((key.replace('_', "-").as_str(), val.as_str())); - } - - match handler_result.body() { - Ok(res) => builder.body(res), - Err(_) => HttpResponse::ServiceUnavailable().body("There was an error running the worker"), - } -} diff --git a/JS/wasm/crates/wasmjs-runtime/src/io.rs b/JS/wasm/crates/wasmjs-runtime/src/io.rs deleted file mode 100644 index c08511e3d..000000000 --- a/JS/wasm/crates/wasmjs-runtime/src/io.rs +++ /dev/null @@ -1,98 +0,0 @@ -use std::{collections::HashMap, fmt::Debug}; - -use actix_web::{ - http::{header::HeaderMap, StatusCode, Uri}, - HttpRequest, -}; -use serde::{Deserialize, Serialize}; -use serde_json::{Map, Value as SerdeValue}; -use crate::geolocation::GeolocationData; - -#[derive(Serialize, Deserialize, Debug)] -pub struct WasmInput<'a> { - url: String, - method: &'a str, - headers: HashMap, - body: &'a str, - params: HashMap, - geo: Map -} - -impl<'a> WasmInput<'a> { - pub fn new(request: &'a HttpRequest, body: &'a str, geo_details: GeolocationData) -> Self { - let mut params = HashMap::new(); - - for (k, v) in request.match_info().iter() { - params.insert(k.to_string(), v.to_string()); - } - - let url = Self::build_url(request); - - Self { - url, - method: request.method().as_str(), - headers: Self::build_headers_hash(request.headers()), - body, - params, - geo: geo_details.data.clone() - } - } - - fn build_url(request: &HttpRequest) -> String { - match Uri::builder() - .scheme(request.connection_info().scheme()) - .authority(request.connection_info().host()) - .path_and_query(request.uri().to_string()) - .build() - { - Ok(uri) => uri.to_string(), - Err(_) => request.uri().to_string(), - } - } - - fn build_headers_hash(headers: &HeaderMap) -> HashMap { - let mut parsed_headers = HashMap::new(); - - for (key, value) in headers.iter() { - parsed_headers.insert( - String::from(key.as_str()), - String::from(value.to_str().unwrap()), - ); - } - - parsed_headers - } -} - -#[derive(Deserialize, Debug)] -pub struct WasmOutput { - pub headers: HashMap, - pub status: u16, - data: String, -} - -impl WasmOutput { - pub fn new(body: &str, headers: HashMap, status: u16) -> Self { - Self { - data: String::from(body), - headers, - status, - } - } - - pub fn failed(err: anyhow::Error, worker_name: Option, route: Option) -> Self { - eprintln!( - "Error running {:?} at route {:?}: {:?}", - worker_name, route, err - ); - Self::new( - "err", - HashMap::from([("content-type".to_string(), "text/html".to_string())]), - StatusCode::INTERNAL_SERVER_ERROR.as_u16(), - ) - } - - pub fn body(&self) -> anyhow::Result> { - Ok(self.data.as_bytes().into()) - } -} diff --git a/JS/wasm/crates/wasmjs-runtime/src/main.rs b/JS/wasm/crates/wasmjs-runtime/src/main.rs deleted file mode 100644 index 15f5a3303..000000000 --- a/JS/wasm/crates/wasmjs-runtime/src/main.rs +++ /dev/null @@ -1,98 +0,0 @@ -use std::path::PathBuf; - -use clap::{Args, Parser, Subcommand}; - -use routes::Routes; -use server::run; - -use crate::server::{serve, ServeOptions}; - -mod bindings; -mod config; -mod error; -mod geolocation; -mod handlers; -mod io; -mod routes; -mod runtime; -mod server; -mod store; -mod wiggle_abi; -mod workers; - -#[derive(Parser, Debug)] -#[command(author, version, about, long_about = None)] -#[command(propagate_version = true)] -#[command(args_conflicts_with_subcommands = true)] -pub struct Opts { - #[command(subcommand)] - pub command: Option, - #[command(flatten)] - pub args: ServeArgs, -} - -#[derive(Debug, Clone, Subcommand)] -pub enum Command { - Server(ServeArgs), - Run(ServeArgs), -} - -#[derive(Debug, Args, Clone)] -pub struct ServeArgs { - #[arg(value_parser, default_value = ".")] - path: PathBuf, - #[arg(short = 'C', long = "config")] - config_path: Option, - #[arg(long = "host", default_value = "0.0.0.0")] - hostname: String, - #[arg(short, long, default_value_t = 8080)] - port: u16, - #[arg(long)] - cors: Option>, -} - -#[actix_web::main] -async fn main() -> std::io::Result<()> { - // let args = Args::parse(); - let opt = Opts::parse(); - let cmd = opt.command.unwrap_or(Command::Server(opt.args)); - match cmd { - Command::Server(args) => { - let routes = Routes::new(&args.path, &args); - for route in routes.routes.iter() { - println!( - "- http://{}:{}{}\n => {}", - &args.hostname, - args.port, - route.path, - route.handler.to_string_lossy() - ); - } - - let server = serve(ServeOptions { - root_path: args.path.clone(), - config_path: args.config_path, - base_routes: routes, - hostname: args.hostname, - port: args.port, - cors_origins: args.cors, - }) - .await - .unwrap(); - - server.await - } - Command::Run(args) => { - let routes = Routes::new(&args.path, &args); - let serve_options = ServeOptions { - root_path: args.path.clone(), - config_path: args.config_path, - base_routes: routes, - hostname: args.hostname, - port: args.port, - cors_origins: args.cors, - }; - run(serve_options).await.map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e.to_string())) - } - } -} diff --git a/JS/wasm/crates/wasmjs-runtime/src/routes.rs b/JS/wasm/crates/wasmjs-runtime/src/routes.rs deleted file mode 100644 index 7cebe67f9..000000000 --- a/JS/wasm/crates/wasmjs-runtime/src/routes.rs +++ /dev/null @@ -1,235 +0,0 @@ -use std::{ - collections::HashMap, - ffi::OsStr, - path::{Component, Path, PathBuf}, - str::FromStr, - sync::{Arc, RwLock}, -}; - -use lazy_static::lazy_static; -use regex::Regex; -use wax::{Glob, WalkEntry}; -use crate::ServeArgs; - -use crate::{store::STORE_FOLDER, workers::Worker}; - -pub struct Files<'t> { - root: PathBuf, - include_pattern: Glob<'t>, - ignore_patterns: Vec>, -} - -impl<'t> Files<'t> { - const DEFAULT_EXTENSIONS: [&'static str; 1] = ["js"]; - - pub fn new(root: &Path, file_extensions: Vec) -> Self { - Self { - root: root.to_path_buf(), - include_pattern: Self::build_include_pattern(file_extensions), - ignore_patterns: Self::build_ignore_patterns(vec![]), - } - } - - pub fn walk(&self) -> Vec { - self.include_pattern - .walk(&self.root) - .not(self.ignore_patterns.clone()) - .expect("Failed to walk the tree when processing files in the current directory") - .map(|e| e.unwrap()) - .collect() - } - - fn build_include_pattern(file_extensions: Vec) -> Glob<'t> { - let mut file_extensions = file_extensions; - for default_extension in Self::DEFAULT_EXTENSIONS { - file_extensions.push(default_extension.to_string()); - } - - let include_pattern = format!("**/*.{{{}}}", file_extensions.join(",")); - Glob::from_str(include_pattern.as_str()).unwrap() - } - - fn build_ignore_patterns(ignore_patterns: Vec) -> Vec> { - let default_ignore_patterns = vec![format!("**/{}/**", STORE_FOLDER)]; - - let mut result = default_ignore_patterns; - result.extend(ignore_patterns); - result - .iter() - .map(|s| Glob::from_str(s.as_str()).unwrap()) - .collect() - } -} - -#[derive(Clone, Default, Debug)] -pub struct Routes { - pub routes: Vec, -} - -impl Routes { - pub fn new(path: &Path, args: &ServeArgs) -> Self { - let mut routes = Vec::new(); - let runtime_extensions = vec![String::from("js")]; - - let files = Files::new(path, runtime_extensions); - - let mut route_paths: Vec = Vec::new(); - for entry in files.walk() { - route_paths.push(entry.into_path()); - } - - for route_path in route_paths { - routes.push(Route::new(path, route_path, args)); - } - - Self { routes } - } - - pub fn iter(&self) -> impl Iterator { - self.routes.iter() - } - - pub fn retrieve_best_route<'a>(&'a self, path: &str) -> Option<&'a Route> { - self.iter().find(|r| r.can_manage(path)) - } -} - -lazy_static! { - static ref PARAMETER_REGEX: Regex = - Regex::new(r"\[(?P\.{3})?(?P\w+)\]").unwrap(); - pub static ref WORKERS: RwLock = RwLock::new(WorkerSet::default()); -} - -#[derive(PartialEq, Eq, Debug, Clone)] -pub enum RouteType { - Tail { number_of_segments: usize }, -} - -impl From<&String> for RouteType { - fn from(route_path: &String) -> Self { - let number_of_segments = route_path.chars().filter(|&c| c == '/').count(); - RouteType::Tail { number_of_segments } - } -} - -#[derive(PartialEq, Eq, Debug, Clone)] -pub enum Segment { - Tail(String), -} - -impl From<&str> for Segment { - fn from(segment: &str) -> Self { - Segment::Tail(segment.to_owned()) - } -} - -#[derive(Clone, Debug)] -pub struct Route { - pub handler: PathBuf, - pub path: String, - pub route_type: RouteType, - pub segments: Vec, - pub worker: String, -} - -#[derive(Default)] -pub struct WorkerSet { - workers: HashMap>, -} - -impl WorkerSet { - pub fn get(&self, worker_id: &str) -> Option<&Arc> { - self.workers.get(worker_id) - } - - pub fn register(&mut self, worker_id: String, worker: Worker) { - self.workers.insert(worker_id, Arc::new(worker)); - } -} - -impl Route { - pub fn new(base_path: &Path, filepath: PathBuf, args: &ServeArgs) -> Self { - let worker = Worker::new(base_path, &filepath, args).unwrap(); - let worker_id = worker.id.clone(); - - WORKERS.write().unwrap().register(worker_id.clone(), worker); - let route_path = Self::retrieve_route(base_path, &filepath); - Self { - handler: filepath, - route_type: RouteType::from(&route_path), - segments: Self::get_segments(&route_path), - path: route_path, - worker: worker_id.clone(), - } - } - - fn retrieve_route(base_path: &Path, path: &Path) -> String { - let n_path = Self::normalize_path_to_url(path); - let n_base_path = Self::normalize_path_to_url(base_path); - - match n_path.strip_prefix(&n_base_path) { - Some(worker_path) => if worker_path.is_empty() { - "/" - } else { - worker_path - } - .into(), - None => String::from("/unknown"), - } - } - - fn normalize_path_to_url(path: &Path) -> String { - path.with_extension("") - .components() - .filter_map(|c| match c { - Component::Normal(os_str) if os_str != OsStr::new("index") => os_str - .to_str() - .map(|parsed_str| String::from("/") + parsed_str), - _ => None, - }) - .collect() - } - - fn get_segments(route_path: &str) -> Vec { - route_path.split('/').skip(1).map(Segment::from).collect() - } - - pub fn can_manage(&self, path: &str) -> bool { - let path_number_of_segments = path.chars().filter(|&c| c == '/').count(); - - match self.route_type { - RouteType::Tail { number_of_segments } - if number_of_segments > path_number_of_segments => - { - false - } - RouteType::Tail { .. } => true, - } - } - - pub fn actix_path(&self) -> String { - PARAMETER_REGEX - .replace_all(&self.path, |caps: ®ex::Captures| { - match (caps.name("ellipsis"), caps.name("segment")) { - (Some(_), Some(segment)) => format!("{{{}:.*}}", segment.as_str()), - (_, Some(segment)) => format!("{{{}}}", segment.as_str()), - _ => String::new(), - } - }) - .into() - } - - pub fn is_dynamic(&self) -> bool { - match self.route_type { - RouteType::Tail { .. } => true, - } - } -} - -impl Eq for Route {} - -impl PartialEq for Route { - fn eq(&self, other: &Self) -> bool { - self.path == other.path - } -} diff --git a/JS/wasm/crates/wasmjs-runtime/src/runtime.rs b/JS/wasm/crates/wasmjs-runtime/src/runtime.rs deleted file mode 100644 index ca48e2bc0..000000000 --- a/JS/wasm/crates/wasmjs-runtime/src/runtime.rs +++ /dev/null @@ -1,70 +0,0 @@ -use std::path::{Path, PathBuf}; - -use anyhow::Result; -use wasmtime_wasi::{ambient_authority, Dir, WasiCtxBuilder}; - -use crate::store::Store; - -static JS_ENGINE_WASM: &[u8] = include_bytes!("../../wasmjs-engine/wasmjs-engine.wasm"); - -pub struct JavaScriptRuntime { - path: PathBuf, - store: Store, -} - -impl JavaScriptRuntime { - pub fn new(project_root: &Path, path: PathBuf) -> Result { - let hash = Store::file_hash(&path)?; - let store = Store::create(project_root, &["js", &hash])?; - - Ok(Self { path, store }) - } -} - -impl Runtime for JavaScriptRuntime { - fn prepare(&self) -> Result<()> { - self.store.copy(&self.path, &["index.js"])?; - - Ok(()) - } - - fn prepare_wasi_ctx(&self, builder: &mut CtxBuilder) -> Result<()> { - match builder { - CtxBuilder::Preview1(ref mut builder) => { - builder.preopened_dir( - Dir::open_ambient_dir(&self.store.folder, ambient_authority())?, - "/src", - )?; - } - } - - Ok(()) - } - - fn module_bytes(&self) -> Result> { - Ok(JS_ENGINE_WASM.to_vec()) - } -} - -pub enum CtxBuilder { - Preview1(WasiCtxBuilder), -} - -pub trait Runtime { - fn prepare(&self) -> Result<()> { - Ok(()) - } - - fn prepare_wasi_ctx(&self, _builder: &mut CtxBuilder) -> Result<()> { - Ok(()) - } - - fn module_bytes(&self) -> Result>; -} - -pub fn init_runtime(project_root: &Path, path: &Path) -> Result> { - Ok(Box::new(JavaScriptRuntime::new( - project_root, - path.to_path_buf(), - )?)) -} diff --git a/JS/wasm/crates/wasmjs-runtime/src/server.rs b/JS/wasm/crates/wasmjs-runtime/src/server.rs deleted file mode 100644 index 8cc78632e..000000000 --- a/JS/wasm/crates/wasmjs-runtime/src/server.rs +++ /dev/null @@ -1,86 +0,0 @@ -use std::path::PathBuf; - -use actix_web::{ - App, - HttpServer, - middleware, web::{self, Data}, -}; -use actix_web::dev::Server; -use actix_web::HttpRequest; -use actix_web::web::Bytes; -use anyhow::{Ok, Result}; - -use crate::handlers::handle_worker; -use crate::routes::Routes; - -#[derive(Clone)] -pub struct ServeOptions { - pub root_path: PathBuf, - pub config_path: Option, - pub base_routes: Routes, - pub hostname: String, - pub port: u16, - pub cors_origins: Option>, -} - -#[derive(Default)] -pub struct AppData { - pub routes: Routes, - pub root_path: PathBuf, - pub cors_origins: Option>, -} - -impl From for AppData { - fn from(serve_options: ServeOptions) -> Self { - AppData { - routes: serve_options.base_routes, - root_path: serve_options.root_path.clone(), - cors_origins: serve_options.cors_origins, - } - } -} - -pub async fn serve(serve_options: ServeOptions) -> Result { - let (hostname, port) = (serve_options.hostname.clone(), serve_options.port); - let serve_options = serve_options.clone(); - - let server = HttpServer::new(move || { - let app_data: Data = - Data::new(>::try_into(serve_options.clone()).unwrap()); - - let mut app = App::new() - .wrap(middleware::Logger::default()) - .wrap(middleware::NormalizePath::trim()) - .app_data(Data::clone(&app_data)); - - for route in app_data.routes.iter() { - app = app.service(web::resource(route.actix_path()).to(handle_worker)); - } - - app - }) - .bind(format!("{}:{}", hostname, port))?; - - Ok(server.run()) -} - -pub async fn run(serve_options: ServeOptions) -> Result<()> { - - let app_data: Data = - Data::new(>::try_into(serve_options).unwrap()); - let request = actix_web::test::TestRequest::with_uri("/").app_data(app_data.clone()).to_http_request(); - let request_jsonnet = actix_web::test::TestRequest::with_uri("/jsonnet").app_data(app_data).to_http_request(); - let body: Bytes = Bytes::from(""); - let req = HttpRequest::from(request); - let req_jsonnet = HttpRequest::from(request_jsonnet); - - let res = handle_worker(req, body.clone()).await; - let res_jsonnet = handle_worker(req_jsonnet,body).await; - // print body of response - let res_body = res.body(); - println!("{:?}", res_body); - let res_body = res_jsonnet.body(); - println!("{:?}", res_body); - - Ok(()) -} diff --git a/JS/wasm/crates/wasmjs-runtime/src/store.rs b/JS/wasm/crates/wasmjs-runtime/src/store.rs deleted file mode 100644 index 3b72b7b97..000000000 --- a/JS/wasm/crates/wasmjs-runtime/src/store.rs +++ /dev/null @@ -1,46 +0,0 @@ -use std::{ - fs, - path::{Path, PathBuf}, -}; - -use anyhow::Result; - -pub const STORE_FOLDER: &str = ".wasmjs"; - -pub struct Store { - pub folder: PathBuf, -} - -impl Store { - pub fn create(project_root: &Path, folder: &[&str]) -> Result { - let folder = Self::build_root_path(project_root, folder); - - fs::create_dir_all(&folder)?; - - Ok(Self { folder }) - } - - pub fn copy(&self, source: &Path, dest: &[&str]) -> Result<()> { - let file_path = self.build_folder_path(dest); - fs::copy(source, file_path)?; - Ok(()) - } - - pub fn build_folder_path(&self, source: &[&str]) -> PathBuf { - source - .iter() - .fold(self.folder.clone(), |acc, comp| acc.join(comp)) - } - - pub fn file_hash(path: &Path) -> Result { - let content = fs::read(path)?; - - Ok(blake3::hash(&content).to_string()) - } - - fn build_root_path(root: &Path, source: &[&str]) -> PathBuf { - source - .iter() - .fold(root.join(STORE_FOLDER), |acc, comp| acc.join(comp)) - } -} diff --git a/JS/wasm/crates/wasmjs-runtime/src/wiggle_abi.rs b/JS/wasm/crates/wasmjs-runtime/src/wiggle_abi.rs deleted file mode 100644 index 834ccf472..000000000 --- a/JS/wasm/crates/wasmjs-runtime/src/wiggle_abi.rs +++ /dev/null @@ -1,69 +0,0 @@ -pub mod geo_impl; -use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; -use std::sync::Arc; -use wiggle::GuestPtr; - -use crate::bindings::arakoo_geo::ArakooGeo; -use crate::geolocation::Geolocation; -use crate::wiggle_abi::geo_impl::GeolocationError; -use crate::error::Error; - -pub struct Session { - geolocation: Arc, -} - -impl Session { - pub fn geolocation_lookup(&self, addr: &IpAddr) -> Option { - self.geolocation.lookup(addr).map(|data| data.to_string()) - } -} - -impl ArakooGeo for Session { - fn lookup( - &mut self, - addr_octets: &GuestPtr, - addr_len: u32, - buf: &GuestPtr, - buf_len: u32, - nwritten_out: &GuestPtr, - ) -> Result<(), Error> { - let octets = addr_octets - .as_array(addr_len) - .iter() - .map(|v| v.unwrap().read().unwrap()) - .collect::>(); - - let ip_addr: IpAddr = match addr_len { - 4 => IpAddr::V4(Ipv4Addr::from( - TryInto::<[u8; 4]>::try_into(octets).unwrap(), - )), - 16 => IpAddr::V6(Ipv6Addr::from( - TryInto::<[u8; 16]>::try_into(octets).unwrap(), - )), - _ => return Err(Error::InvalidArgument), - }; - - let result = self - .geolocation_lookup(&ip_addr) - .ok_or_else(|| GeolocationError::NoGeolocationData(ip_addr.to_string()))?; - - if result.len() > buf_len as usize { - return Err(Error::BufferLengthError { - buf: "geolocation_lookup", - len: "geolocation_lookup_max_len", - }); - } - - let result_len = - u32::try_from(result.len()).expect("smaller than value_max_len means it must fit"); - - let mut buf_ptr = buf - .as_array(result_len) - .as_slice_mut()? - .ok_or(Error::SharedMemory)?; - buf_ptr.copy_from_slice(result.as_bytes()); - nwritten_out.write(result_len)?; - Ok(()) - } -} - diff --git a/JS/wasm/crates/wasmjs-runtime/src/wiggle_abi/geo_impl.rs b/JS/wasm/crates/wasmjs-runtime/src/wiggle_abi/geo_impl.rs deleted file mode 100644 index ab5d39114..000000000 --- a/JS/wasm/crates/wasmjs-runtime/src/wiggle_abi/geo_impl.rs +++ /dev/null @@ -1,18 +0,0 @@ -use crate::bindings::types::ArakooStatus; - -#[derive(Debug, thiserror::Error)] -pub enum GeolocationError { - /// Geolocation data for given address not found. - #[error("No geolocation data: {0}")] - NoGeolocationData(String), -} - -impl GeolocationError { - /// Convert to an error code representation suitable for passing across the ABI boundary. - pub fn to_aradoo_status(&self) -> ArakooStatus { - use GeolocationError::*; - match self { - NoGeolocationData(_) => ArakooStatus::None, - } - } -} diff --git a/JS/wasm/crates/wasmjs-runtime/src/workers.rs b/JS/wasm/crates/wasmjs-runtime/src/workers.rs deleted file mode 100644 index cbe403958..000000000 --- a/JS/wasm/crates/wasmjs-runtime/src/workers.rs +++ /dev/null @@ -1,187 +0,0 @@ -use crate::bindings::HttpBindings; -use crate::config::{ArakooConfig, Config}; -use crate::io::{WasmInput, WasmOutput}; -use crate::runtime::{init_runtime, CtxBuilder, Runtime}; -use crate::bindings::http; -use std::{ - collections::HashMap, - io::Cursor, - path::{Path, PathBuf}, -}; - -use actix_web::HttpRequest; -use sha256::digest as sha256_digest; -use wasmtime::{Config as WasmtimeConfig, Engine, Linker, Module, Store}; -use wasmtime_wasi::{ambient_authority, Dir, WasiCtxBuilder}; - -use anyhow::Result; -use wasi_common::pipe::{ReadPipe, WritePipe}; -use crate::ServeArgs; -use crate::geolocation::GeolocationData; - -pub struct Stdio { - pub stdin: Vec, - pub stdout: WritePipe>>, -} - -impl Stdio { - pub fn new(input: &str) -> Self { - Self { - stdin: Vec::from(input), - stdout: WritePipe::new_in_memory(), - } - } - - pub fn configure_wasi_ctx(&self, mut builder: CtxBuilder) -> CtxBuilder { - match builder { - CtxBuilder::Preview1(ref mut wasi_builder) => { - wasi_builder - .stdin(Box::new(ReadPipe::from(self.stdin.clone()).clone())) - .stdout(Box::new(self.stdout.clone())) - .inherit_stderr(); - } - } - builder - } -} - -pub struct Worker { - pub id: String, - engine: Engine, - runtime: Box, - module: Module, - pub config: Config, - path: PathBuf, -} - -#[derive(Default)] -struct Host { - pub wasi_preview1_ctx: Option, - pub http: Option, -} - -impl Worker { - pub fn new(project_root: &Path, path: &Path, args: &ServeArgs) -> Result { - let id = sha256_digest(project_root.join(path).to_string_lossy().as_bytes()); - - let mut config=Config::default(); - match &args.config_path { - Some(path) => config.features.geo = ArakooConfig::from_file(&path)?, - _ => {}, - } - config.vars = std::env::vars().collect(); - - let engine = Engine::new(WasmtimeConfig::default().async_support(true))?; - let runtime = init_runtime(project_root, path)?; - let bytes = runtime.module_bytes()?; - - let module = if wasmparser::Parser::is_core_wasm(&bytes) { - Ok(Module::from_binary(&engine, &bytes)?) - } else { - Err("Invalid module".to_string()) - } - .map_err(|e| anyhow::anyhow!(e))?; - - runtime.prepare()?; - - Ok(Self { - id, - engine, - runtime, - module, - config, - path: path.to_path_buf(), - }) - } - - pub fn prepare_wasi_context( - &self, - environment_variables: &[(String, String)], - wasi_builder: &mut CtxBuilder, - ) -> Result<()> { - match wasi_builder { - CtxBuilder::Preview1(wasi_builder) => { - wasi_builder.envs(environment_variables)?; - - if let Some(folders) = self.config.folders.as_ref() { - for folder in folders { - if let Some(base) = &self.path.parent() { - let dir = Dir::open_ambient_dir( - base.join(&folder.from), - ambient_authority(), - )?; - wasi_builder.preopened_dir(dir, &folder.to)?; - } else { - panic!("Failed to initialize") - } - } - } - } - } - - Ok(()) - } - - pub async fn run( - &self, - request: &HttpRequest, - body: &str, - vars: &HashMap, - geo_details: GeolocationData, - ) -> Result { - let input = serde_json::to_string(&WasmInput::new(request, body, geo_details)).unwrap(); - - let mut linker = Linker::new(&self.engine); - - wasmtime_wasi::add_to_linker(&mut linker, |host: &mut Host| { - host.wasi_preview1_ctx.as_mut().unwrap() - })?; - - http::add_to_linker(&mut linker, |host: &mut Host| host.http.as_mut().unwrap())?; - - let environment_variables: Vec<(String, String)> = - vars.iter().map(|(k, v)| (k.clone(), v.clone())).collect(); - - let mut wasi_builder = CtxBuilder::Preview1(WasiCtxBuilder::new()); - - self.prepare_wasi_context(&environment_variables, &mut wasi_builder)?; - - let stdio = Stdio::new(&input); - let mut wasi_builder = stdio.configure_wasi_ctx(wasi_builder); - - self.runtime.prepare_wasi_ctx(&mut wasi_builder)?; - - let host = match wasi_builder { - CtxBuilder::Preview1(mut wasi_builder) => Host { - wasi_preview1_ctx: Some(wasi_builder.build()), - http: Some(HttpBindings { - http_config: self.config.features.http_requests.clone(), - }), - ..Host::default() - }, - }; - - let contents = { - let mut store = Store::new(&self.engine, host); - linker.module_async(&mut store, "", &self.module).await?; - - linker - .get_default(&mut store, "")? - .typed::<(), ()>(&store)? - .call_async(&mut store, ()) - .await?; - - drop(store); - - stdio - .stdout - .try_into_inner() - .unwrap_or_default() - .into_inner() - }; - - let output: WasmOutput = serde_json::from_slice(&contents)?; - - Ok(output) - } -} diff --git a/JS/wasm/crates/wasmjs-runtime/test-vars.jsonnet b/JS/wasm/crates/wasmjs-runtime/test-vars.jsonnet deleted file mode 100644 index b856b4a6a..000000000 --- a/JS/wasm/crates/wasmjs-runtime/test-vars.jsonnet +++ /dev/null @@ -1,6 +0,0 @@ -local var1 = std.extVar("var1"); - -{ - var: var1, -} - diff --git a/JS/wasm/crates/wasmjs-runtime/test.jsonnet b/JS/wasm/crates/wasmjs-runtime/test.jsonnet deleted file mode 100644 index 8c7488deb..000000000 --- a/JS/wasm/crates/wasmjs-runtime/test.jsonnet +++ /dev/null @@ -1,8 +0,0 @@ -local Person(name='Alice') = { - name: name, - welcome: 'Hello ' + name + '!', -}; -{ - person1: Person(), - person2: Person('Bob'), -} diff --git a/JS/wasm/examples/ec-wasmjs-hono/build.js b/JS/wasm/examples/ec-wasmjs-hono/build.js index 83f669710..5096bdfa0 100644 --- a/JS/wasm/examples/ec-wasmjs-hono/build.js +++ b/JS/wasm/examples/ec-wasmjs-hono/build.js @@ -1,14 +1,19 @@ import { build } from "esbuild"; +let runtime = process.argv[2]; + build({ entryPoints: ["src/index.js"], bundle: true, minify: true, - outfile: "bin/[...app].js", + outfile: "bin/app.js", format: "esm", target: "esnext", platform: "node", - external: ["arakoo-jsonnet"], + // external: ["arakoo"], + define: { + "process.env.arakoo": JSON.stringify(runtime === "arakoo"), + }, }).catch((error) => { console.error(error); process.exit(1); diff --git a/JS/wasm/examples/ec-wasmjs-hono/package-lock.json b/JS/wasm/examples/ec-wasmjs-hono/package-lock.json index 9678ce984..83f8b0299 100644 --- a/JS/wasm/examples/ec-wasmjs-hono/package-lock.json +++ b/JS/wasm/examples/ec-wasmjs-hono/package-lock.json @@ -1,568 +1,563 @@ { - "name": "hono", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "hono", - "dependencies": { - "@hono/node-server": "^1.3.1", - "arakoo-jsonnet": "file:../../types/jsonnet", - "axios": "^1.6.2", - "crypto": "^1.0.1", - "http": "^0.0.1-security", - "stream": "^0.0.2" - }, - "devDependencies": { - "@planetscale/database": "^1.4.0", - "esbuild": "^0.19", - "hono": "^3.9" - } - }, - "../../types/jsonnet": { - "name": "arakoo-jsonnet", - "version": "0.1.0", - "hasInstallScript": true, - "license": "ISC", - "devDependencies": { - "cargo-cp-artifact": "^0.1" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.5.tgz", - "integrity": "sha512-bhvbzWFF3CwMs5tbjf3ObfGqbl/17ict2/uwOSfr3wmxDE6VdS2GqY/FuzIPe0q0bdhj65zQsvqfArI9MY6+AA==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.5.tgz", - "integrity": "sha512-5d1OkoJxnYQfmC+Zd8NBFjkhyCNYwM4n9ODrycTFY6Jk1IGiZ+tjVJDDSwDt77nK+tfpGP4T50iMtVi4dEGzhQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.5.tgz", - "integrity": "sha512-9t+28jHGL7uBdkBjL90QFxe7DVA+KGqWlHCF8ChTKyaKO//VLuoBricQCgwhOjA1/qOczsw843Fy4cbs4H3DVA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.5.tgz", - "integrity": "sha512-mvXGcKqqIqyKoxq26qEDPHJuBYUA5KizJncKOAf9eJQez+L9O+KfvNFu6nl7SCZ/gFb2QPaRqqmG0doSWlgkqw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.5.tgz", - "integrity": "sha512-Ly8cn6fGLNet19s0X4unjcniX24I0RqjPv+kurpXabZYSXGM4Pwpmf85WHJN3lAgB8GSth7s5A0r856S+4DyiA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.5.tgz", - "integrity": "sha512-GGDNnPWTmWE+DMchq1W8Sd0mUkL+APvJg3b11klSGUDvRXh70JqLAO56tubmq1s2cgpVCSKYywEiKBfju8JztQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.5.tgz", - "integrity": "sha512-1CCwDHnSSoA0HNwdfoNY0jLfJpd7ygaLAp5EHFos3VWJCRX9DMwWODf96s9TSse39Br7oOTLryRVmBoFwXbuuQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.5.tgz", - "integrity": "sha512-lrWXLY/vJBzCPC51QN0HM71uWgIEpGSjSZZADQhq7DKhPcI6NH1IdzjfHkDQws2oNpJKpR13kv7/pFHBbDQDwQ==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.5.tgz", - "integrity": "sha512-o3vYippBmSrjjQUCEEiTZ2l+4yC0pVJD/Dl57WfPwwlvFkrxoSO7rmBZFii6kQB3Wrn/6GwJUPLU5t52eq2meA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.5.tgz", - "integrity": "sha512-MkjHXS03AXAkNp1KKkhSKPOCYztRtK+KXDNkBa6P78F8Bw0ynknCSClO/ztGszILZtyO/lVKpa7MolbBZ6oJtQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.5.tgz", - "integrity": "sha512-42GwZMm5oYOD/JHqHska3Jg0r+XFb/fdZRX+WjADm3nLWLcIsN27YKtqxzQmGNJgu0AyXg4HtcSK9HuOk3v1Dw==", - "cpu": [ - "loong64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.5.tgz", - "integrity": "sha512-kcjndCSMitUuPJobWCnwQ9lLjiLZUR3QLQmlgaBfMX23UEa7ZOrtufnRds+6WZtIS9HdTXqND4yH8NLoVVIkcg==", - "cpu": [ - "mips64el" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.5.tgz", - "integrity": "sha512-yJAxJfHVm0ZbsiljbtFFP1BQKLc8kUF6+17tjQ78QjqjAQDnhULWiTA6u0FCDmYT1oOKS9PzZ2z0aBI+Mcyj7Q==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.5.tgz", - "integrity": "sha512-5u8cIR/t3gaD6ad3wNt1MNRstAZO+aNyBxu2We8X31bA8XUNyamTVQwLDA1SLoPCUehNCymhBhK3Qim1433Zag==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.5.tgz", - "integrity": "sha512-Z6JrMyEw/EmZBD/OFEFpb+gao9xJ59ATsoTNlj39jVBbXqoZm4Xntu6wVmGPB/OATi1uk/DB+yeDPv2E8PqZGw==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.5.tgz", - "integrity": "sha512-psagl+2RlK1z8zWZOmVdImisMtrUxvwereIdyJTmtmHahJTKb64pAcqoPlx6CewPdvGvUKe2Jw+0Z/0qhSbG1A==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.5.tgz", - "integrity": "sha512-kL2l+xScnAy/E/3119OggX8SrWyBEcqAh8aOY1gr4gPvw76la2GlD4Ymf832UCVbmuWeTf2adkZDK+h0Z/fB4g==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.5.tgz", - "integrity": "sha512-sPOfhtzFufQfTBgRnE1DIJjzsXukKSvZxloZbkJDG383q0awVAq600pc1nfqBcl0ice/WN9p4qLc39WhBShRTA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.5.tgz", - "integrity": "sha512-dGZkBXaafuKLpDSjKcB0ax0FL36YXCvJNnztjKV+6CO82tTYVDSH2lifitJ29jxRMoUhgkg9a+VA/B03WK5lcg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.5.tgz", - "integrity": "sha512-dWVjD9y03ilhdRQ6Xig1NWNgfLtf2o/STKTS+eZuF90fI2BhbwD6WlaiCGKptlqXlURVB5AUOxUj09LuwKGDTg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.5.tgz", - "integrity": "sha512-4liggWIA4oDgUxqpZwrDhmEfAH4d0iljanDOK7AnVU89T6CzHon/ony8C5LeOdfgx60x5cnQJFZwEydVlYx4iw==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.5.tgz", - "integrity": "sha512-czTrygUsB/jlM8qEW5MD8bgYU2Xg14lo6kBDXW6HdxKjh8M5PzETGiSHaz9MtbXBYDloHNUAUW2tMiKW4KM9Mw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@hono/node-server": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.3.1.tgz", - "integrity": "sha512-eQBCDbH1Vv/TiYXNP8aGfJTuXi9xGhEd/EZg9u6dhr7zC5/WKKztcBmbrOTtixVBvvV6bfcay6KEginwiqHyXg==", - "engines": { - "node": ">=18.14.1" - } - }, - "node_modules/@planetscale/database": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@planetscale/database/-/database-1.11.0.tgz", - "integrity": "sha512-aWbU+D/IRHoDE9975y+Q4c+EwwAWxCPwFId+N1AhQVFXzbeJMkj6KN2iQtoi03elcLMRdfT+V3i9Z4WRw+/oIA==", - "dev": true, - "engines": { - "node": ">=16" - } - }, - "node_modules/arakoo-jsonnet": { - "resolved": "../../types/jsonnet", - "link": true - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" - }, - "node_modules/axios": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.2.tgz", - "integrity": "sha512-7i24Ri4pmDRfJTR7LDBhsOTtcm+9kjX5WiY1X3wIisx6G9So3pfMkEiU7emUBe46oceVImccTEM3k6C5dbVW8A==", - "dependencies": { - "follow-redirects": "^1.15.0", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" - } - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/crypto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/crypto/-/crypto-1.0.1.tgz", - "integrity": "sha512-VxBKmeNcqQdiUQUW2Tzq0t377b54N2bMtXO/qiLa+6eRRmmC4qT3D4OnTGoT/U6O9aklQ/jTwbOtRMTTY8G0Ig==", - "deprecated": "This package is no longer supported. It's now a built-in Node module. If you've depended on crypto, you should switch to the one that's built-in." - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/emitter-component": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/emitter-component/-/emitter-component-1.1.2.tgz", - "integrity": "sha512-QdXO3nXOzZB4pAjM0n6ZE+R9/+kPpECA/XSELIcc54NeYVnBqIk+4DFiBgK+8QbV3mdvTG6nedl7dTYgO+5wDw==", - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/esbuild": { - "version": "0.19.5", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.5.tgz", - "integrity": "sha512-bUxalY7b1g8vNhQKdB24QDmHeY4V4tw/s6Ak5z+jJX9laP5MoQseTOMemAr0gxssjNcH0MCViG8ONI2kksvfFQ==", - "dev": true, - "hasInstallScript": true, - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/android-arm": "0.19.5", - "@esbuild/android-arm64": "0.19.5", - "@esbuild/android-x64": "0.19.5", - "@esbuild/darwin-arm64": "0.19.5", - "@esbuild/darwin-x64": "0.19.5", - "@esbuild/freebsd-arm64": "0.19.5", - "@esbuild/freebsd-x64": "0.19.5", - "@esbuild/linux-arm": "0.19.5", - "@esbuild/linux-arm64": "0.19.5", - "@esbuild/linux-ia32": "0.19.5", - "@esbuild/linux-loong64": "0.19.5", - "@esbuild/linux-mips64el": "0.19.5", - "@esbuild/linux-ppc64": "0.19.5", - "@esbuild/linux-riscv64": "0.19.5", - "@esbuild/linux-s390x": "0.19.5", - "@esbuild/linux-x64": "0.19.5", - "@esbuild/netbsd-x64": "0.19.5", - "@esbuild/openbsd-x64": "0.19.5", - "@esbuild/sunos-x64": "0.19.5", - "@esbuild/win32-arm64": "0.19.5", - "@esbuild/win32-ia32": "0.19.5", - "@esbuild/win32-x64": "0.19.5" - } - }, - "node_modules/follow-redirects": { - "version": "1.15.3", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz", - "integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==", - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, - "node_modules/form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/hono": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/hono/-/hono-3.9.0.tgz", - "integrity": "sha512-MSGmerYD69jwDkBa631lY7y3xtEwbKFg2huFZ0TruzCdfJlmPd/rFzyvmMheePKsiA7CZp/KqL3mflBOzEmjLA==", - "dev": true, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/http": { - "version": "0.0.1-security", - "resolved": "https://registry.npmjs.org/http/-/http-0.0.1-security.tgz", - "integrity": "sha512-RnDvP10Ty9FxqOtPZuxtebw1j4L/WiqNMDtuc1YMH1XQm5TgDRaR1G9u8upL6KD1bXHSp9eSXo/ED+8Q7FAr+g==" - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" - }, - "node_modules/stream": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/stream/-/stream-0.0.2.tgz", - "integrity": "sha512-gCq3NDI2P35B2n6t76YJuOp7d6cN/C7Rt0577l91wllh0sY9ZBuw9KaSGqH/b0hzn3CWWJbpbW0W0WvQ1H/Q7g==", - "dependencies": { - "emitter-component": "^1.1.1" - } + "name": "hono", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "hono", + "dependencies": { + "@hono/node-server": "^1.3.1", + "arakoo-jsonnet": "file:../../types/jsonnet", + "axios": "^1.6.2", + "crypto": "^1.0.1", + "http": "^0.0.1-security", + "stream": "^0.0.2" + }, + "devDependencies": { + "@planetscale/database": "^1.4.0", + "esbuild": "^0.19", + "hono": "^3.9" + } + }, + "../../types/jsonnet": { + "name": "arakoo-jsonnet", + "version": "0.1.1" + }, + "node_modules/@esbuild/android-arm": { + "version": "0.19.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.5.tgz", + "integrity": "sha512-bhvbzWFF3CwMs5tbjf3ObfGqbl/17ict2/uwOSfr3wmxDE6VdS2GqY/FuzIPe0q0bdhj65zQsvqfArI9MY6+AA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.19.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.5.tgz", + "integrity": "sha512-5d1OkoJxnYQfmC+Zd8NBFjkhyCNYwM4n9ODrycTFY6Jk1IGiZ+tjVJDDSwDt77nK+tfpGP4T50iMtVi4dEGzhQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.19.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.5.tgz", + "integrity": "sha512-9t+28jHGL7uBdkBjL90QFxe7DVA+KGqWlHCF8ChTKyaKO//VLuoBricQCgwhOjA1/qOczsw843Fy4cbs4H3DVA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.19.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.5.tgz", + "integrity": "sha512-mvXGcKqqIqyKoxq26qEDPHJuBYUA5KizJncKOAf9eJQez+L9O+KfvNFu6nl7SCZ/gFb2QPaRqqmG0doSWlgkqw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.19.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.5.tgz", + "integrity": "sha512-Ly8cn6fGLNet19s0X4unjcniX24I0RqjPv+kurpXabZYSXGM4Pwpmf85WHJN3lAgB8GSth7s5A0r856S+4DyiA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.19.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.5.tgz", + "integrity": "sha512-GGDNnPWTmWE+DMchq1W8Sd0mUkL+APvJg3b11klSGUDvRXh70JqLAO56tubmq1s2cgpVCSKYywEiKBfju8JztQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.19.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.5.tgz", + "integrity": "sha512-1CCwDHnSSoA0HNwdfoNY0jLfJpd7ygaLAp5EHFos3VWJCRX9DMwWODf96s9TSse39Br7oOTLryRVmBoFwXbuuQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.19.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.5.tgz", + "integrity": "sha512-lrWXLY/vJBzCPC51QN0HM71uWgIEpGSjSZZADQhq7DKhPcI6NH1IdzjfHkDQws2oNpJKpR13kv7/pFHBbDQDwQ==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.19.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.5.tgz", + "integrity": "sha512-o3vYippBmSrjjQUCEEiTZ2l+4yC0pVJD/Dl57WfPwwlvFkrxoSO7rmBZFii6kQB3Wrn/6GwJUPLU5t52eq2meA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.19.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.5.tgz", + "integrity": "sha512-MkjHXS03AXAkNp1KKkhSKPOCYztRtK+KXDNkBa6P78F8Bw0ynknCSClO/ztGszILZtyO/lVKpa7MolbBZ6oJtQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.19.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.5.tgz", + "integrity": "sha512-42GwZMm5oYOD/JHqHska3Jg0r+XFb/fdZRX+WjADm3nLWLcIsN27YKtqxzQmGNJgu0AyXg4HtcSK9HuOk3v1Dw==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.19.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.5.tgz", + "integrity": "sha512-kcjndCSMitUuPJobWCnwQ9lLjiLZUR3QLQmlgaBfMX23UEa7ZOrtufnRds+6WZtIS9HdTXqND4yH8NLoVVIkcg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.19.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.5.tgz", + "integrity": "sha512-yJAxJfHVm0ZbsiljbtFFP1BQKLc8kUF6+17tjQ78QjqjAQDnhULWiTA6u0FCDmYT1oOKS9PzZ2z0aBI+Mcyj7Q==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.19.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.5.tgz", + "integrity": "sha512-5u8cIR/t3gaD6ad3wNt1MNRstAZO+aNyBxu2We8X31bA8XUNyamTVQwLDA1SLoPCUehNCymhBhK3Qim1433Zag==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.19.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.5.tgz", + "integrity": "sha512-Z6JrMyEw/EmZBD/OFEFpb+gao9xJ59ATsoTNlj39jVBbXqoZm4Xntu6wVmGPB/OATi1uk/DB+yeDPv2E8PqZGw==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.19.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.5.tgz", + "integrity": "sha512-psagl+2RlK1z8zWZOmVdImisMtrUxvwereIdyJTmtmHahJTKb64pAcqoPlx6CewPdvGvUKe2Jw+0Z/0qhSbG1A==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.19.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.5.tgz", + "integrity": "sha512-kL2l+xScnAy/E/3119OggX8SrWyBEcqAh8aOY1gr4gPvw76la2GlD4Ymf832UCVbmuWeTf2adkZDK+h0Z/fB4g==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.19.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.5.tgz", + "integrity": "sha512-sPOfhtzFufQfTBgRnE1DIJjzsXukKSvZxloZbkJDG383q0awVAq600pc1nfqBcl0ice/WN9p4qLc39WhBShRTA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.19.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.5.tgz", + "integrity": "sha512-dGZkBXaafuKLpDSjKcB0ax0FL36YXCvJNnztjKV+6CO82tTYVDSH2lifitJ29jxRMoUhgkg9a+VA/B03WK5lcg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.19.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.5.tgz", + "integrity": "sha512-dWVjD9y03ilhdRQ6Xig1NWNgfLtf2o/STKTS+eZuF90fI2BhbwD6WlaiCGKptlqXlURVB5AUOxUj09LuwKGDTg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.19.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.5.tgz", + "integrity": "sha512-4liggWIA4oDgUxqpZwrDhmEfAH4d0iljanDOK7AnVU89T6CzHon/ony8C5LeOdfgx60x5cnQJFZwEydVlYx4iw==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.19.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.5.tgz", + "integrity": "sha512-czTrygUsB/jlM8qEW5MD8bgYU2Xg14lo6kBDXW6HdxKjh8M5PzETGiSHaz9MtbXBYDloHNUAUW2tMiKW4KM9Mw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@hono/node-server": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.3.1.tgz", + "integrity": "sha512-eQBCDbH1Vv/TiYXNP8aGfJTuXi9xGhEd/EZg9u6dhr7zC5/WKKztcBmbrOTtixVBvvV6bfcay6KEginwiqHyXg==", + "engines": { + "node": ">=18.14.1" + } + }, + "node_modules/@planetscale/database": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@planetscale/database/-/database-1.11.0.tgz", + "integrity": "sha512-aWbU+D/IRHoDE9975y+Q4c+EwwAWxCPwFId+N1AhQVFXzbeJMkj6KN2iQtoi03elcLMRdfT+V3i9Z4WRw+/oIA==", + "dev": true, + "engines": { + "node": ">=16" + } + }, + "node_modules/arakoo-jsonnet": { + "resolved": "../../types/jsonnet", + "link": true + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "node_modules/axios": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.2.tgz", + "integrity": "sha512-7i24Ri4pmDRfJTR7LDBhsOTtcm+9kjX5WiY1X3wIisx6G9So3pfMkEiU7emUBe46oceVImccTEM3k6C5dbVW8A==", + "dependencies": { + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/crypto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/crypto/-/crypto-1.0.1.tgz", + "integrity": "sha512-VxBKmeNcqQdiUQUW2Tzq0t377b54N2bMtXO/qiLa+6eRRmmC4qT3D4OnTGoT/U6O9aklQ/jTwbOtRMTTY8G0Ig==", + "deprecated": "This package is no longer supported. It's now a built-in Node module. If you've depended on crypto, you should switch to the one that's built-in." + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/emitter-component": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/emitter-component/-/emitter-component-1.1.2.tgz", + "integrity": "sha512-QdXO3nXOzZB4pAjM0n6ZE+R9/+kPpECA/XSELIcc54NeYVnBqIk+4DFiBgK+8QbV3mdvTG6nedl7dTYgO+5wDw==", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/esbuild": { + "version": "0.19.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.5.tgz", + "integrity": "sha512-bUxalY7b1g8vNhQKdB24QDmHeY4V4tw/s6Ak5z+jJX9laP5MoQseTOMemAr0gxssjNcH0MCViG8ONI2kksvfFQ==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/android-arm": "0.19.5", + "@esbuild/android-arm64": "0.19.5", + "@esbuild/android-x64": "0.19.5", + "@esbuild/darwin-arm64": "0.19.5", + "@esbuild/darwin-x64": "0.19.5", + "@esbuild/freebsd-arm64": "0.19.5", + "@esbuild/freebsd-x64": "0.19.5", + "@esbuild/linux-arm": "0.19.5", + "@esbuild/linux-arm64": "0.19.5", + "@esbuild/linux-ia32": "0.19.5", + "@esbuild/linux-loong64": "0.19.5", + "@esbuild/linux-mips64el": "0.19.5", + "@esbuild/linux-ppc64": "0.19.5", + "@esbuild/linux-riscv64": "0.19.5", + "@esbuild/linux-s390x": "0.19.5", + "@esbuild/linux-x64": "0.19.5", + "@esbuild/netbsd-x64": "0.19.5", + "@esbuild/openbsd-x64": "0.19.5", + "@esbuild/sunos-x64": "0.19.5", + "@esbuild/win32-arm64": "0.19.5", + "@esbuild/win32-ia32": "0.19.5", + "@esbuild/win32-x64": "0.19.5" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.3", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz", + "integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/hono": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/hono/-/hono-3.9.0.tgz", + "integrity": "sha512-MSGmerYD69jwDkBa631lY7y3xtEwbKFg2huFZ0TruzCdfJlmPd/rFzyvmMheePKsiA7CZp/KqL3mflBOzEmjLA==", + "dev": true, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/http": { + "version": "0.0.1-security", + "resolved": "https://registry.npmjs.org/http/-/http-0.0.1-security.tgz", + "integrity": "sha512-RnDvP10Ty9FxqOtPZuxtebw1j4L/WiqNMDtuc1YMH1XQm5TgDRaR1G9u8upL6KD1bXHSp9eSXo/ED+8Q7FAr+g==" + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, + "node_modules/stream": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stream/-/stream-0.0.2.tgz", + "integrity": "sha512-gCq3NDI2P35B2n6t76YJuOp7d6cN/C7Rt0577l91wllh0sY9ZBuw9KaSGqH/b0hzn3CWWJbpbW0W0WvQ1H/Q7g==", + "dependencies": { + "emitter-component": "^1.1.1" + } } + } } diff --git a/JS/wasm/examples/ec-wasmjs-hono/package.json b/JS/wasm/examples/ec-wasmjs-hono/package.json index 08f95e85d..ce2c2ffb2 100644 --- a/JS/wasm/examples/ec-wasmjs-hono/package.json +++ b/JS/wasm/examples/ec-wasmjs-hono/package.json @@ -1,21 +1,18 @@ { - "name": "hono", - "type": "module", - "main": "bin/[...app].js", - "scripts": { - "build": "node ./build.js" - }, - "devDependencies": { - "@planetscale/database": "^1.4.0", - "esbuild": "^0.19", - "hono": "^3.9" - }, - "dependencies": { - "@hono/node-server": "^1.3.1", - "axios": "^1.6.2", - "crypto": "^1.0.1", - "arakoo-jsonnet": "file:../../types/jsonnet", - "http": "^0.0.1-security", - "stream": "^0.0.2" - } -} + "name": "hono", + "type": "module", + "main": "bin/app.js", + "devDependencies": { + "@planetscale/database": "^1.4.0", + "esbuild": "^0.19", + "hono": "^3.9" + }, + "dependencies": { + "@hono/node-server": "^1.3.1", + "axios": "^1.6.2", + "crypto": "^1.0.1", + "arakoo-jsonnet": "file:../../types/jsonnet", + "http": "^0.0.1-security", + "stream": "^0.0.2" + } +} \ No newline at end of file diff --git a/JS/wasm/examples/ec-wasmjs-hono/src/index.js b/JS/wasm/examples/ec-wasmjs-hono/src/index.js index 730a495f8..6fbdb9e3b 100644 --- a/JS/wasm/examples/ec-wasmjs-hono/src/index.js +++ b/JS/wasm/examples/ec-wasmjs-hono/src/index.js @@ -1,62 +1,58 @@ import { Hono } from "hono"; import { connect } from "@planetscale/database"; -import { jsonnet, jsonnetExtVars } from "arakoo-jsonnet"; +import { html } from "hono/html"; +import Jsonnet from "arakoo-jsonnet"; -const app = new Hono(); +let jsonnet = new Jsonnet(); +const app = new Hono(); +const env = {}; app.get("/", (c) => { - const geo = c.req.raw.geo; - return c.text(`Your from ${geo.city}, ${geo.country_name}!`); -}); - -app.get("/jsonnet", async (c) => { - try { - const result = await jsonnet("test.jsonnet"); - return c.json(JSON.parse(result)); - } catch (error) { - console.log(JSON.stringify(error)); - c.text(error); - } + const code = ` + local username = std.extVar('name'); + local Person(name='Alice') = { + name: name, + welcome: 'Hello ' + name + '!', + }; + { + person1: Person(username), + person2: Person('Bob'), + }`; + let result = jsonnet.extString("name", "ll").evaluateSnippet(code); + return c.json(JSON.parse(result)); }); -app.get("/vars", async (c) => { - try { - const extVars = JSON.stringify({ - var1: "value1", - }); - const result = await jsonnetExtVars("test-vars.jsonnet", extVars); - return c.json(JSON.parse(result)); - } catch (error) { - console.log(JSON.stringify(error)); - c.text(error); - } +app.get("/:username", (c) => { + const { username } = c.req.param(); + // redirect to /hello/:username + return c.redirect(`/hello/${username}`); }); app.get("/hello/:name", async (c) => { - const name = c.req.param("name"); - return c.text(`Async Hello ${name}!`); + const name = c.req.param("name"); + return c.text(`Async Hello ${name}!`); }); app.get("/env/:key", async (c) => { - const key = c.req.param("key"); - return c.text(env[key]); + const key = c.req.param("key"); + return c.text(env[key]); }); const config = { - host: env["PLANETSCALE_HOST"], - username: env["PLANETSCALE_USERNAME"], - password: env["PLANETSCALE_PASSWORD"], + host: env["PLANETSCALE_HOST"], + username: env["PLANETSCALE_USERNAME"], + password: env["PLANETSCALE_PASSWORD"], }; const conn = connect(config); app.get("/db", async (c) => { - const result = await conn.execute("SHOW TABLES"); + const result = await conn.execute("SHOW TABLES"); - return c.json(result); + return c.json(result); }); app.notFound((c) => { - return c.text("404 not found", 404); + return c.text("404 not found", 404); }); -export default app; +app.fire(); diff --git a/JS/wasm/examples/nodejs-hono/package-lock.json b/JS/wasm/examples/nodejs-hono/package-lock.json new file mode 100644 index 000000000..769742f8f --- /dev/null +++ b/JS/wasm/examples/nodejs-hono/package-lock.json @@ -0,0 +1,580 @@ +{ + "name": "hono", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "hono", + "dependencies": { + "@hono/node-server": "^1.8.1", + "arakoo-jsonnet": "file:../../types/jsonnet", + "axios": "^1.6.2", + "crypto": "^1.0.1", + "http": "^0.0.1-security", + "stream": "^0.0.2" + }, + "devDependencies": { + "@planetscale/database": "^1.4.0", + "esbuild": "^0.19", + "hono": "^3.9" + } + }, + "../../types/jsonnet": { + "name": "arakoo-jsonnet", + "version": "0.1.1" + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz", + "integrity": "sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.12.tgz", + "integrity": "sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz", + "integrity": "sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.12.tgz", + "integrity": "sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz", + "integrity": "sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz", + "integrity": "sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz", + "integrity": "sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz", + "integrity": "sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz", + "integrity": "sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz", + "integrity": "sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz", + "integrity": "sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz", + "integrity": "sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz", + "integrity": "sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz", + "integrity": "sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz", + "integrity": "sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz", + "integrity": "sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.12.tgz", + "integrity": "sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz", + "integrity": "sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz", + "integrity": "sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz", + "integrity": "sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz", + "integrity": "sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz", + "integrity": "sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz", + "integrity": "sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@hono/node-server": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.8.1.tgz", + "integrity": "sha512-9ondWs/5EuyZOd/iyiRp0GQfMEq+IA+IbV8Wy2bgdr5+cC55I3xbQrqtXKprw7jJhfvq3IVw7ALiuvCEmLdCAA==", + "engines": { + "node": ">=18.14.1" + } + }, + "node_modules/@planetscale/database": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/@planetscale/database/-/database-1.16.0.tgz", + "integrity": "sha512-HNUrTqrd8aTRZYMDcsoZ62s36sIWkMMmKZBOehoCWR2WrfNPKq+Q1yQef5okl3pSVlldFnu2h/dbHjOsDTHXug==", + "dev": true, + "engines": { + "node": ">=16" + } + }, + "node_modules/arakoo-jsonnet": { + "resolved": "../../types/jsonnet", + "link": true + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "node_modules/axios": { + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.7.tgz", + "integrity": "sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==", + "dependencies": { + "follow-redirects": "^1.15.4", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/crypto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/crypto/-/crypto-1.0.1.tgz", + "integrity": "sha512-VxBKmeNcqQdiUQUW2Tzq0t377b54N2bMtXO/qiLa+6eRRmmC4qT3D4OnTGoT/U6O9aklQ/jTwbOtRMTTY8G0Ig==", + "deprecated": "This package is no longer supported. It's now a built-in Node module. If you've depended on crypto, you should switch to the one that's built-in." + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/emitter-component": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/emitter-component/-/emitter-component-1.1.2.tgz", + "integrity": "sha512-QdXO3nXOzZB4pAjM0n6ZE+R9/+kPpECA/XSELIcc54NeYVnBqIk+4DFiBgK+8QbV3mdvTG6nedl7dTYgO+5wDw==", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/esbuild": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.12.tgz", + "integrity": "sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.19.12", + "@esbuild/android-arm": "0.19.12", + "@esbuild/android-arm64": "0.19.12", + "@esbuild/android-x64": "0.19.12", + "@esbuild/darwin-arm64": "0.19.12", + "@esbuild/darwin-x64": "0.19.12", + "@esbuild/freebsd-arm64": "0.19.12", + "@esbuild/freebsd-x64": "0.19.12", + "@esbuild/linux-arm": "0.19.12", + "@esbuild/linux-arm64": "0.19.12", + "@esbuild/linux-ia32": "0.19.12", + "@esbuild/linux-loong64": "0.19.12", + "@esbuild/linux-mips64el": "0.19.12", + "@esbuild/linux-ppc64": "0.19.12", + "@esbuild/linux-riscv64": "0.19.12", + "@esbuild/linux-s390x": "0.19.12", + "@esbuild/linux-x64": "0.19.12", + "@esbuild/netbsd-x64": "0.19.12", + "@esbuild/openbsd-x64": "0.19.12", + "@esbuild/sunos-x64": "0.19.12", + "@esbuild/win32-arm64": "0.19.12", + "@esbuild/win32-ia32": "0.19.12", + "@esbuild/win32-x64": "0.19.12" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.5", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz", + "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/hono": { + "version": "3.12.12", + "resolved": "https://registry.npmjs.org/hono/-/hono-3.12.12.tgz", + "integrity": "sha512-5IAMJOXfpA5nT+K0MNjClchzz0IhBHs2Szl7WFAhrFOsbtQsYmNynFyJRg/a3IPsmCfxcrf8txUGiNShXpK5Rg==", + "dev": true, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/http": { + "version": "0.0.1-security", + "resolved": "https://registry.npmjs.org/http/-/http-0.0.1-security.tgz", + "integrity": "sha512-RnDvP10Ty9FxqOtPZuxtebw1j4L/WiqNMDtuc1YMH1XQm5TgDRaR1G9u8upL6KD1bXHSp9eSXo/ED+8Q7FAr+g==" + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, + "node_modules/stream": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stream/-/stream-0.0.2.tgz", + "integrity": "sha512-gCq3NDI2P35B2n6t76YJuOp7d6cN/C7Rt0577l91wllh0sY9ZBuw9KaSGqH/b0hzn3CWWJbpbW0W0WvQ1H/Q7g==", + "dependencies": { + "emitter-component": "^1.1.1" + } + } + } +} diff --git a/JS/wasm/examples/nodejs-hono/package.json b/JS/wasm/examples/nodejs-hono/package.json new file mode 100644 index 000000000..4f2cde4df --- /dev/null +++ b/JS/wasm/examples/nodejs-hono/package.json @@ -0,0 +1,21 @@ +{ + "name": "hono", + "type": "module", + "main": "bin/[...app].js", + "scripts": { + "build": "node ./build.js" + }, + "devDependencies": { + "@planetscale/database": "^1.4.0", + "esbuild": "^0.19", + "hono": "^3.9" + }, + "dependencies": { + "@hono/node-server": "^1.8.1", + "arakoo-jsonnet": "file:../../types/jsonnet", + "axios": "^1.6.2", + "crypto": "^1.0.1", + "http": "^0.0.1-security", + "stream": "^0.0.2" + } +} diff --git a/JS/wasm/examples/nodejs-hono/src/index.js b/JS/wasm/examples/nodejs-hono/src/index.js new file mode 100644 index 000000000..77c39186b --- /dev/null +++ b/JS/wasm/examples/nodejs-hono/src/index.js @@ -0,0 +1,63 @@ +import { Hono } from "hono"; +import { serve } from "@hono/node-server"; +import { connect } from "@planetscale/database"; + +import Jsonnet from "arakoo-jsonnet"; + +let jsonnet = new Jsonnet(); + +const app = new Hono(); +const env = {}; +app.get("/", (c) => { + const code = ` + local username = std.extVar('name'); + local Person(name='Alice') = { + name: name, + welcome: 'Hello ' + name + '!', + }; + { + person1: Person(username), + person2: Person('Bob'), + }`; + let result = jsonnet.extString("name", "ll").evaluateSnippet(code); + return c.json(JSON.parse(result)); +}); + +app.get("/:username", (c) => { + const { username } = c.req.param(); + // redirect to /hello/:username + return c.redirect(`/hello/${username}`); +}); + +app.get("/hello/:name", async (c) => { + const name = c.req.param("name"); + return c.text(`Async Hello ${name}!`); +}); + +app.get("/env/:key", async (c) => { + const key = c.req.param("key"); + return c.text(env[key]); +}); + +const config = { + host: env["PLANETSCALE_HOST"], + username: env["PLANETSCALE_USERNAME"], + password: env["PLANETSCALE_PASSWORD"], +}; +const conn = connect(config); + +app.get("/db", async (c) => { + const result = await conn.execute("SHOW TABLES"); + + return c.json(result); +}); + +app.notFound((c) => { + return c.text("404 not found", 404); +}); + +// app.fire(); + +serve(app, (info) => { + console.log(`Server started on http://localhost:${info.port}`); +}); \ No newline at end of file diff --git a/JS/wasm/types/jsonnet/.gitignore b/JS/wasm/types/jsonnet/.gitignore old mode 100644 new mode 100755 index 05dd501fb..9b621ca9d --- a/JS/wasm/types/jsonnet/.gitignore +++ b/JS/wasm/types/jsonnet/.gitignore @@ -1,5 +1,2 @@ -target -**/node_modules -**/.DS_Store -npm-debug.log* - +/target +node_modules/ diff --git a/JS/wasm/types/jsonnet/Cargo.lock b/JS/wasm/types/jsonnet/Cargo.lock old mode 100644 new mode 100755 index 6f64a6f41..42ffc6ad9 --- a/JS/wasm/types/jsonnet/Cargo.lock +++ b/JS/wasm/types/jsonnet/Cargo.lock @@ -3,23 +3,74 @@ version = 3 [[package]] -name = "arakoo-jsonnet" +name = "ahash" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77c3a9648d43b9cd48db467b3f87fdd6e146bcc88ab0180006cef2179fe11d01" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "annotate-snippets" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccaf7e9dfbb6ab22c82e473cd1a8a7bd313c19a5b7e40970f3d89ef5a5c9e81e" +dependencies = [ + "unicode-width", + "yansi-term", +] + +[[package]] +name = "arakoo" version = "0.1.0" dependencies = [ - "jsonnet-rs", - "neon", + "jrsonnet-evaluator", + "jrsonnet-gcmodule", + "jrsonnet-parser", + "jrsonnet-stdlib", + "serde", "serde_json", + "wasm-bindgen", + "wasm-bindgen-test", ] [[package]] -name = "cc" -version = "1.0.83" +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "base64" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "block-buffer" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" dependencies = [ - "libc", + "generic-array", ] +[[package]] +name = "bumpalo" +version = "3.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" + [[package]] name = "cfg-if" version = "1.0.0" @@ -27,93 +78,325 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] -name = "itoa" -version = "1.0.10" +name = "console_error_panic_hook" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" +checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" +dependencies = [ + "cfg-if", + "wasm-bindgen", +] [[package]] -name = "jsonnet-rs" -version = "0.17.0" +name = "cpufeatures" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82b396bdfc3ae94965555c9ec3efa2214e5f3921545a943ef9fc9873ff5e4723" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" dependencies = [ - "jsonnet-sys", "libc", ] [[package]] -name = "jsonnet-sys" -version = "0.17.0" +name = "crypto-common" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02347cbdf34234f30f0d92f0f8f678a15883bd5e1e4b3def4ed4a14f691d9add" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ - "cc", - "libc", + "generic-array", + "typenum", ] [[package]] -name = "libc" -version = "0.2.151" +name = "derivative" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] [[package]] -name = "libloading" -version = "0.6.7" +name = "digest" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "351a32417a12d5f7e82c368a66781e307834dae04c6ce0cd4456d52989229883" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "cfg-if", - "winapi", + "block-buffer", + "crypto-common", ] [[package]] -name = "neon" -version = "0.10.1" +name = "generic-array" +version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28e15415261d880aed48122e917a45e87bb82cf0260bb6db48bbab44b7464373" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ - "neon-build", - "neon-macros", - "neon-runtime", - "semver", - "smallvec", + "typenum", + "version_check", ] [[package]] -name = "neon-build" -version = "0.10.1" +name = "hashbrown" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bac98a702e71804af3dacfde41edde4a16076a7bbe889ae61e56e18c5b1c811" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] -name = "neon-macros" -version = "0.10.1" +name = "hashbrown" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7288eac8b54af7913c60e0eb0e2a7683020dffa342ab3fd15e28f035ba897cf" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" dependencies = [ + "ahash", +] + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", +] + +[[package]] +name = "itoa" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" + +[[package]] +name = "jrsonnet-evaluator" +version = "0.5.0-pre95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0951f206ee982ef3c61ed49c2779b3649858d2b7c6748943e4c7f36f6df55f9c" +dependencies = [ + "annotate-snippets", + "derivative", + "hashbrown 0.13.2", + "jrsonnet-gcmodule", + "jrsonnet-interner", + "jrsonnet-macros", + "jrsonnet-parser", + "jrsonnet-types", + "pathdiff", + "rustc-hash", + "serde", + "static_assertions", + "strsim", + "thiserror", +] + +[[package]] +name = "jrsonnet-gcmodule" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c11fb98940a7f8b419619e98ccbf2e094671a5fdd0e277f05acd373071186d57" +dependencies = [ + "jrsonnet-gcmodule-derive", + "parking_lot", +] + +[[package]] +name = "jrsonnet-gcmodule-derive" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bee774b7ba86fc86ee84482cd6732aa860ae3559f9827c65efd75c51e66ac76" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "jrsonnet-interner" +version = "0.5.0-pre95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d2332eb6c0bbd27e81ed8ad488a70e448437dd17b54e90cf3b8974b82c3c379" +dependencies = [ + "hashbrown 0.13.2", + "jrsonnet-gcmodule", + "rustc-hash", + "structdump", +] + +[[package]] +name = "jrsonnet-macros" +version = "0.5.0-pre95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4b4d289fa4d4992f0a791de2e9fbdae7100005d28fced76fc49a2d70b5737f5" +dependencies = [ + "proc-macro2", "quote", "syn 1.0.109", - "syn-mid", ] [[package]] -name = "neon-runtime" -version = "0.10.1" +name = "jrsonnet-parser" +version = "0.5.0-pre95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d403645f250bdc8f31a2a142ebd4608f9595bdad1a89db871ccdfe81c427957" +dependencies = [ + "jrsonnet-gcmodule", + "jrsonnet-interner", + "peg", + "static_assertions", + "structdump", +] + +[[package]] +name = "jrsonnet-stdlib" +version = "0.5.0-pre95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d7f31ed348ea5f7dfb379ddc65fe1773d82cab7698a8dbc4d2d72013795eba" +dependencies = [ + "base64", + "jrsonnet-evaluator", + "jrsonnet-gcmodule", + "jrsonnet-macros", + "jrsonnet-parser", + "md5", + "serde", + "serde_json", + "serde_yaml_with_quirks", + "sha1", + "sha2", + "sha3", + "structdump", +] + +[[package]] +name = "jrsonnet-types" +version = "0.5.0-pre95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68522259250172a8aa3714e2f99466641cc450b5c758fbdaa05265f86c1e0d97" +dependencies = [ + "jrsonnet-gcmodule", + "peg", +] + +[[package]] +name = "js-sys" +version = "0.3.67" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a1d36f1235bc969acba30b7f5990b864423a6068a10f7c90ae8f0112e3a59d1" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "keccak" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4676720fa8bb32c64c3d9f49c47a47289239ec46b4bdb66d0913cc512cb0daca" +checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "libc" +version = "0.2.152" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" + +[[package]] +name = "linked-hash-map" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" + +[[package]] +name = "lock_api" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" + +[[package]] +name = "md5" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771" + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" dependencies = [ "cfg-if", - "libloading", + "libc", + "redox_syscall", "smallvec", + "windows-targets", +] + +[[package]] +name = "pathdiff" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" + +[[package]] +name = "peg" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "400bcab7d219c38abf8bd7cc2054eb9bbbd4312d66f6a5557d572a203f646f61" +dependencies = [ + "peg-macros", + "peg-runtime", ] +[[package]] +name = "peg-macros" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46e61cce859b76d19090f62da50a9fe92bab7c2a5f09e183763559a2ac392c90" +dependencies = [ + "peg-runtime", + "proc-macro2", + "quote", +] + +[[package]] +name = "peg-runtime" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36bae92c60fa2398ce4678b98b2c4b5a7c61099961ca1fa305aec04a9ad28922" + [[package]] name = "proc-macro2" -version = "1.0.76" +version = "1.0.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c" +checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" dependencies = [ "unicode-ident", ] @@ -127,6 +410,21 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags", +] + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + [[package]] name = "ryu" version = "1.0.16" @@ -134,19 +432,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" [[package]] -name = "semver" -version = "0.9.0" +name = "scoped-tls" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" -dependencies = [ - "semver-parser", -] +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" [[package]] -name = "semver-parser" -version = "0.7.0" +name = "scopeguard" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "serde" @@ -179,11 +474,89 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_yaml_with_quirks" +version = "0.8.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47c5983eba86eae2d0058c35fb1065ccffb23af7f8965871069269088098321a" +dependencies = [ + "indexmap", + "ryu", + "serde", + "yaml-rust", +] + +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest", + "keccak", +] + [[package]] name = "smallvec" -version = "1.11.2" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" + +[[package]] +name = "static_assertions" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "structdump" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0570327507bf281d8a6e6b0d4c082b12cb6bcee27efce755aa5efacd44076c1" +dependencies = [ + "proc-macro2", + "quote", + "structdump-derive", +] + +[[package]] +name = "structdump-derive" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29cc0b59cfa11f1bceda09a9a7e37e6a6c3138575fd24ade8aa9af6d09aedf28" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] [[package]] name = "syn" @@ -208,22 +581,150 @@ dependencies = [ ] [[package]] -name = "syn-mid" -version = "0.5.4" +name = "thiserror" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fea305d57546cc8cd04feb14b62ec84bf17f50e3f7b12560d7bfa9265f39d9ed" +checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.48", ] +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + [[package]] name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +[[package]] +name = "unicode-width" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "wasm-bindgen" +version = "0.2.90" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1223296a201415c7fad14792dbefaace9bd52b62d33453ade1c5b5f07555406" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.90" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcdc935b63408d58a32f8cc9738a0bffd8f05cc7c002086c6ef20b7312ad9dcd" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.48", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bde2032aeb86bdfaecc8b261eef3cba735cc426c1f3a3416d1e0791be95fc461" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.90" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e4c238561b2d428924c49815533a8b9121c664599558a5d9ec51f8a1740a999" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.90" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bae1abb6806dc1ad9e560ed242107c0f6c84335f1749dd4e8ddb012ebd5e25a7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.90" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d91413b1c31d7539ba5ef2451af3f0b833a005eb27a631cec32bc0635a8602b" + +[[package]] +name = "wasm-bindgen-test" +version = "0.3.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "139bd73305d50e1c1c4333210c0db43d989395b64a237bd35c10ef3832a7f70c" +dependencies = [ + "console_error_panic_hook", + "js-sys", + "scoped-tls", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-bindgen-test-macro", +] + +[[package]] +name = "wasm-bindgen-test-macro" +version = "0.3.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70072aebfe5da66d2716002c729a14e4aec4da0e23cc2ea66323dac541c93928" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "web-sys" +version = "0.3.67" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58cd2333b6e0be7a39605f0e255892fd7418a682d8da8fe042fe25128794d2ed" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + [[package]] name = "winapi" version = "0.3.9" @@ -245,3 +746,98 @@ name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "yaml-rust" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" +dependencies = [ + "linked-hash-map", +] + +[[package]] +name = "yansi-term" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe5c30ade05e61656247b2e334a031dfd0cc466fadef865bdcdea8d537951bf1" +dependencies = [ + "winapi", +] + +[[package]] +name = "zerocopy" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] diff --git a/JS/wasm/types/jsonnet/Cargo.toml b/JS/wasm/types/jsonnet/Cargo.toml old mode 100644 new mode 100755 index ea90e9942..09083f47b --- a/JS/wasm/types/jsonnet/Cargo.toml +++ b/JS/wasm/types/jsonnet/Cargo.toml @@ -1,20 +1,22 @@ [package] -name = "arakoo-jsonnet" -version = "0.1.0" -license = "ISC" -edition = "2018" -exclude = ["index.node"] +name = "arakoo" +edition.workspace = true +version.workspace = true -[lib] -crate-type = ["cdylib"] -path = "src/lib.rs" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[lib] +crate-type = ["cdylib", "rlib"] + [dependencies] -jsonnet-rs = "0.17" +wasm-bindgen = "0.2.84" +jrsonnet-evaluator = { version = "0.5.0-pre95" } +jrsonnet-parser = { version = "0.5.0-pre95" } +jrsonnet-stdlib = { version = "0.5.0-pre95" } +jrsonnet-gcmodule = { version = "0.3.6" } +serde = "1.0.195" serde_json = "1.0.111" +wasm-bindgen-file-reader = "1" -[dependencies.neon] -version = "0.10" -default-features = false -features = ["napi-6"] +[dev-dependencies] +wasm-bindgen-test = "0.3.34" diff --git a/JS/wasm/types/jsonnet/README.md b/JS/wasm/types/jsonnet/README.md new file mode 100644 index 000000000..4e4dc44cc --- /dev/null +++ b/JS/wasm/types/jsonnet/README.md @@ -0,0 +1,51 @@ +# Jsonnet in Wasm +This project aim to running Jsonnet in Wasm. The code is written in Rust and compiled to Wasm using the `wasm32-unknown-unknown` target. The project is based on the [Jrsonnet](https://github.com/CertainLach/jrsonnet) project, which is a Rust implementation of Jsonnet. The project is still in early stage and have some limited support for Jsonnet. + +## Available features +- [x] Jsonnet Snippet evaluation +- [x] External variable support +- [ ] External function support +- [ ] Jsonnet file evaluation + +## Usage + +```bash +npm install arakoo-jsonnet +``` + +```javascript +import Jsonnet from "arakoo-jsonnet"; + +const jsonnet = new Jsonnet(); +let code = ` + local username = std.extVar('name'); + local Person(name='Alice') = { + name: name, + welcome: 'Hello ' + name + '!', + }; + { + person1: Person(username), + person2: Person('Bob'), + }`; +const result = jsonnet.extString('name', 'John').evaluateSnippet(code); +console.log(result); +``` +### Output +```json +{ + "person1": { + "name": "John", + "welcome": "Hello John!" + }, + "person2": { + "name": "Bob", + "welcome": "Hello Bob!" + } +} +``` + +## Build +```bash +./build.sh +``` + diff --git a/JS/wasm/types/jsonnet/build.sh b/JS/wasm/types/jsonnet/build.sh new file mode 100755 index 000000000..9990988f5 --- /dev/null +++ b/JS/wasm/types/jsonnet/build.sh @@ -0,0 +1,115 @@ +#!/bin/bash +# Call this script as `./build.sh ` eg. `./build.sh false` + +set -e + +# Remove older build +if [ "$1" != "false" ]; then + echo "Removing older build..." + # check if pkg folder exists + if [ -d "jsonnet" ]; then + echo "Removing pkg folder..." + rm -rf jsonnet + fi +fi +OUT_FOLDER="jsonnet" +OUT_JSON="${OUT_FOLDER}/package.json" +OUT_TARGET="bundler" +OUT_NPM_NAME="arakoo" +WASM_BUILD_PROFILE="release" + +echo "Using build profile: \"${WASM_BUILD_PROFILE}\"" + +# Check if wasm-pack is installed +if ! command -v wasm-pack &>/dev/null; then + echo "wasm-pack could not be found, installing now..." + curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh +fi + +echo "Building query-engine-wasm using $WASM_BUILD_PROFILE profile" +CARGO_PROFILE_RELEASE_OPT_LEVEL="z" wasm-pack build "--$WASM_BUILD_PROFILE" --target $OUT_TARGET --out-name jsonnet_wasm + +mv "pkg/" $OUT_FOLDER + +WASM_OPT_ARGS=( + "-Os" # execute size-focused optimization passes + "--vacuum" # removes obviously unneeded code + "--duplicate-function-elimination" # removes duplicate functions + "--duplicate-import-elimination" # removes duplicate imports + "--remove-unused-module-elements" # removes unused module elements + "--dae-optimizing" # removes arguments to calls in an lto-like manner + "--remove-unused-names" # removes names from location that are never branched to + "--rse" # removes redundant local.sets + "--gsi" # global struct inference, to optimize constant values + "--gufa-optimizing" # optimize the entire program using type monomorphization + "--strip-dwarf" # removes DWARF debug information + "--strip-producers" # removes the "producers" section + "--strip-target-features" # removes the "target_features" section +) +sleep 1 + +enable_cf_in_bindings() { + # Enable Cloudflare Workers in the generated JS bindings. + # The generated bindings are compatible with: + # - Node.js + # - Cloudflare Workers / Miniflare + + local FILE="$1" # e.g., `query_engine.js` + local BG_FILE="jsonnet_wasm_bg.js" + local OUTPUT_FILE="${OUT_FOLDER}/jsonnet_wasm.js" + + cat <"$OUTPUT_FILE" +import * as imports from "./${BG_FILE}"; + +// switch between both syntax for Node.js and for workers (Cloudflare Workers) +import * as wkmod from "./${BG_FILE%.js}.wasm"; +import * as nodemod from "./${BG_FILE%.js}.wasm"; +if ((typeof process !== 'undefined') && (process.release.name === 'node')) { + imports.__wbg_set_wasm(nodemod); +} else { + const instance = new WebAssembly.Instance(wkmod.default, { "./${BG_FILE}": imports }); + imports.__wbg_set_wasm(instance.exports); +} + +export * from "./${BG_FILE}"; +EOF + + cat <"$OUT_FOLDER/index.js" +import Jsonnet from "./jsonnet.js"; + +export default Jsonnet; +EOF + + cat <"$OUT_FOLDER/index.d.ts" +declare class Jsonnet { + constructor(); + evaluateSnippet(snippet: string): string; + destroy(): void; + extString(key: string, value: string): this; + evaluateFile(filename: string): string; +} + +export default Jsonnet; +EOF + +} + +update_package_json() { + local FILE="$1" # e.g., `index.js` + local OUTPUT_FILE="${OUT_FOLDER}/package.json" + jq '.module = "'${FILE}'"' "${OUT_JSON}" >temp.json + jq '.types = "'${FILE%.js}.d.ts'"' temp.json >temp2.json + jq '.files = ["'${FILE}'", "'${FILE%.js}.d.ts'"]' temp2.json >"${OUTPUT_FILE}" + rm temp.json temp2.json +} + +move_jsonnet_to_src() { + mv jsonnet/*.js jsonnet/*.wasm jsonnet/*.d.ts src/ + rm -rf src/snippets + mv jsonnet/snippets/ src/ + rm -rf jsonnet +} + +enable_cf_in_bindings "jsonnet_wasm_bg.js" +update_package_json "index.js" +move_jsonnet_to_src diff --git a/JS/wasm/types/jsonnet/dist/index.d.cts b/JS/wasm/types/jsonnet/dist/index.d.cts new file mode 100644 index 000000000..0006b466b --- /dev/null +++ b/JS/wasm/types/jsonnet/dist/index.d.cts @@ -0,0 +1,9 @@ +declare class Jsonnet { + constructor(); + evaluateSnippet(snippet: string): string; + destroy(): void; + extString(key: string, value: string): this; + evaluateFile(filename: string): string; +} + +export { Jsonnet as default }; diff --git a/JS/wasm/types/jsonnet/dist/index.d.ts b/JS/wasm/types/jsonnet/dist/index.d.ts new file mode 100644 index 000000000..0006b466b --- /dev/null +++ b/JS/wasm/types/jsonnet/dist/index.d.ts @@ -0,0 +1,9 @@ +declare class Jsonnet { + constructor(); + evaluateSnippet(snippet: string): string; + destroy(): void; + extString(key: string, value: string): this; + evaluateFile(filename: string): string; +} + +export { Jsonnet as default }; diff --git a/JS/wasm/types/jsonnet/example.js b/JS/wasm/types/jsonnet/example.js new file mode 100644 index 000000000..58743c292 --- /dev/null +++ b/JS/wasm/types/jsonnet/example.js @@ -0,0 +1,6 @@ +import Jsonnet from "./src/index.js" + +const jsonnet = new Jsonnet() + +const json = jsonnet.evaluateFile("./example.jsonnet") +console.log(json) // {"a":1,"b":2} \ No newline at end of file diff --git a/JS/wasm/types/jsonnet/example.jsonnet b/JS/wasm/types/jsonnet/example.jsonnet new file mode 100644 index 000000000..0c9d01ef7 --- /dev/null +++ b/JS/wasm/types/jsonnet/example.jsonnet @@ -0,0 +1,8 @@ +// Edit me! +{ + person1: { + name: 'Alice', + welcome: 'Hello ' + self.name + '!', + }, + person2: self.person1 { name: 'Bob' }, +} diff --git a/JS/wasm/types/jsonnet/index.node b/JS/wasm/types/jsonnet/index.node deleted file mode 100755 index e8b213e8b..000000000 Binary files a/JS/wasm/types/jsonnet/index.node and /dev/null differ diff --git a/JS/wasm/types/jsonnet/package-lock.json b/JS/wasm/types/jsonnet/package-lock.json index a8728d922..c06b4b88d 100644 --- a/JS/wasm/types/jsonnet/package-lock.json +++ b/JS/wasm/types/jsonnet/package-lock.json @@ -1,26 +1,1857 @@ { - "name": "arakoo-jsonnet", - "version": "0.1.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "arakoo-jsonnet", - "version": "0.1.0", - "hasInstallScript": true, - "license": "ISC", - "devDependencies": { - "cargo-cp-artifact": "^0.1" - } - }, - "node_modules/cargo-cp-artifact": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/cargo-cp-artifact/-/cargo-cp-artifact-0.1.8.tgz", - "integrity": "sha512-3j4DaoTrsCD1MRkTF2Soacii0Nx7UHCce0EwUf4fHnggwiE4fbmF2AbnfzayR36DF8KGadfh7M/Yfy625kgPlA==", - "dev": true, - "bin": { - "cargo-cp-artifact": "bin/cargo-cp-artifact.js" - } + "name": "@arakoodev/jsonnet", + "version": "0.1.1", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "@arakoodev/jsonnet", + "version": "0.1.1", + "dependencies": { + "tsup": "^8.0.2", + "typescript": "^4.9.4" + } + }, + "jsonnet": { + "name": "arakoo", + "version": "0.1.0", + "extraneous": true + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz", + "integrity": "sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.12.tgz", + "integrity": "sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz", + "integrity": "sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.12.tgz", + "integrity": "sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz", + "integrity": "sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz", + "integrity": "sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz", + "integrity": "sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz", + "integrity": "sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz", + "integrity": "sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz", + "integrity": "sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz", + "integrity": "sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz", + "integrity": "sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==", + "cpu": [ + "loong64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz", + "integrity": "sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==", + "cpu": [ + "mips64el" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz", + "integrity": "sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz", + "integrity": "sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==", + "cpu": [ + "riscv64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz", + "integrity": "sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==", + "cpu": [ + "s390x" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.12.tgz", + "integrity": "sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz", + "integrity": "sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz", + "integrity": "sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz", + "integrity": "sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz", + "integrity": "sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz", + "integrity": "sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz", + "integrity": "sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.4.tgz", + "integrity": "sha512-Oud2QPM5dHviZNn4y/WhhYKSXksv+1xLEIsNrAbGcFzUN3ubqWRFT5gwPchNc5NuzILOU4tPBDTZ4VwhL8Y7cw==", + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.23", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.23.tgz", + "integrity": "sha512-9/4foRoUKp8s96tSkh8DlAAc5A0Ty8vLXld+l9gjKKY6ckwI8G15f0hskGmuLZu78ZlGa1vtsfOa+lnB4vG6Jg==", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.12.0.tgz", + "integrity": "sha512-+ac02NL/2TCKRrJu2wffk1kZ+RyqxVUlbjSagNgPm94frxtr+XDL12E5Ll1enWskLrtrZ2r8L3wED1orIibV/w==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.12.0.tgz", + "integrity": "sha512-OBqcX2BMe6nvjQ0Nyp7cC90cnumt8PXmO7Dp3gfAju/6YwG0Tj74z1vKrfRz7qAv23nBcYM8BCbhrsWqO7PzQQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.12.0.tgz", + "integrity": "sha512-X64tZd8dRE/QTrBIEs63kaOBG0b5GVEd3ccoLtyf6IdXtHdh8h+I56C2yC3PtC9Ucnv0CpNFJLqKFVgCYe0lOQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.12.0.tgz", + "integrity": "sha512-cc71KUZoVbUJmGP2cOuiZ9HSOP14AzBAThn3OU+9LcA1+IUqswJyR1cAJj3Mg55HbjZP6OLAIscbQsQLrpgTOg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.12.0.tgz", + "integrity": "sha512-a6w/Y3hyyO6GlpKL2xJ4IOh/7d+APaqLYdMf86xnczU3nurFTaVN9s9jOXQg97BE4nYm/7Ga51rjec5nfRdrvA==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.12.0.tgz", + "integrity": "sha512-0fZBq27b+D7Ar5CQMofVN8sggOVhEtzFUwOwPppQt0k+VR+7UHMZZY4y+64WJ06XOhBTKXtQB/Sv0NwQMXyNAA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.12.0.tgz", + "integrity": "sha512-eTvzUS3hhhlgeAv6bfigekzWZjaEX9xP9HhxB0Dvrdbkk5w/b+1Sxct2ZuDxNJKzsRStSq1EaEkVSEe7A7ipgQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.12.0.tgz", + "integrity": "sha512-ix+qAB9qmrCRiaO71VFfY8rkiAZJL8zQRXveS27HS+pKdjwUfEhqo2+YF2oI+H/22Xsiski+qqwIBxVewLK7sw==", + "cpu": [ + "riscv64" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.12.0.tgz", + "integrity": "sha512-TenQhZVOtw/3qKOPa7d+QgkeM6xY0LtwzR8OplmyL5LrgTWIXpTQg2Q2ycBf8jm+SFW2Wt/DTn1gf7nFp3ssVA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.12.0.tgz", + "integrity": "sha512-LfFdRhNnW0zdMvdCb5FNuWlls2WbbSridJvxOvYWgSBOYZtgBfW9UGNJG//rwMqTX1xQE9BAodvMH9tAusKDUw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.12.0.tgz", + "integrity": "sha512-JPDxovheWNp6d7AHCgsUlkuCKvtu3RB55iNEkaQcf0ttsDU/JZF+iQnYcQJSk/7PtT4mjjVG8N1kpwnI9SLYaw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.12.0.tgz", + "integrity": "sha512-fjtuvMWRGJn1oZacG8IPnzIV6GF2/XG+h71FKn76OYFqySXInJtseAqdprVTDTyqPxQOG9Exak5/E9Z3+EJ8ZA==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.12.0.tgz", + "integrity": "sha512-ZYmr5mS2wd4Dew/JjT0Fqi2NPB/ZhZ2VvPp7SmvPZb4Y1CG/LRcS6tcRo2cYU7zLK5A7cdbhWnnWmUjoI4qapg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==" + }, + "node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==" + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "engines": { + "node": ">=8" + } + }, + "node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/bundle-require": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/bundle-require/-/bundle-require-4.0.2.tgz", + "integrity": "sha512-jwzPOChofl67PSTW2SGubV9HBQAhhR2i6nskiOThauo9dzwDUgOWQScFVaJkjEfYX+UXiD+LEx8EblQMc2wIag==", + "dependencies": { + "load-tsconfig": "^0.2.3" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "peerDependencies": { + "esbuild": ">=0.17" + } + }, + "node_modules/cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true } + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" + }, + "node_modules/esbuild": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.12.tgz", + "integrity": "sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==", + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.19.12", + "@esbuild/android-arm": "0.19.12", + "@esbuild/android-arm64": "0.19.12", + "@esbuild/android-x64": "0.19.12", + "@esbuild/darwin-arm64": "0.19.12", + "@esbuild/darwin-x64": "0.19.12", + "@esbuild/freebsd-arm64": "0.19.12", + "@esbuild/freebsd-x64": "0.19.12", + "@esbuild/linux-arm": "0.19.12", + "@esbuild/linux-arm64": "0.19.12", + "@esbuild/linux-ia32": "0.19.12", + "@esbuild/linux-loong64": "0.19.12", + "@esbuild/linux-mips64el": "0.19.12", + "@esbuild/linux-ppc64": "0.19.12", + "@esbuild/linux-riscv64": "0.19.12", + "@esbuild/linux-s390x": "0.19.12", + "@esbuild/linux-x64": "0.19.12", + "@esbuild/netbsd-x64": "0.19.12", + "@esbuild/openbsd-x64": "0.19.12", + "@esbuild/sunos-x64": "0.19.12", + "@esbuild/win32-arm64": "0.19.12", + "@esbuild/win32-ia32": "0.19.12", + "@esbuild/win32-x64": "0.19.12" + } + }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fastq": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/foreground-child": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", + "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/foreground-child/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/glob": { + "version": "10.3.10", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", + "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.3.5", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", + "path-scurry": "^1.10.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/ignore": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", + "engines": { + "node": ">= 4" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + }, + "node_modules/jackspeak": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", + "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/joycon": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/joycon/-/joycon-3.1.1.tgz", + "integrity": "sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==", + "engines": { + "node": ">=10" + } + }, + "node_modules/lilconfig": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.1.tgz", + "integrity": "sha512-O18pf7nyvHTckunPWCV1XUNXU1piu01y2b7ATJ0ppkUkk8ocqVWBrYjJBCwHDjD/ZWcfyrA0P4gKhzWGi5EINQ==", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" + }, + "node_modules/load-tsconfig": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/load-tsconfig/-/load-tsconfig-0.2.5.tgz", + "integrity": "sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==" + }, + "node_modules/lru-cache": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.0.tgz", + "integrity": "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==", + "engines": { + "node": "14 || >=16.14" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minipass": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-scurry": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", + "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", + "dependencies": { + "lru-cache": "^9.1.1 || ^10.0.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pirates": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", + "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/postcss-load-config": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz", + "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "lilconfig": "^3.0.0", + "yaml": "^2.3.4" + }, + "engines": { + "node": ">= 14" + }, + "peerDependencies": { + "postcss": ">=8.0.9", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "postcss": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rollup": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.12.0.tgz", + "integrity": "sha512-wz66wn4t1OHIJw3+XU7mJJQV/2NAfw5OAk6G6Hoo3zcvz/XOfQ52Vgi+AN4Uxoxi0KBBwk2g8zPrTDA4btSB/Q==", + "dependencies": { + "@types/estree": "1.0.5" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.12.0", + "@rollup/rollup-android-arm64": "4.12.0", + "@rollup/rollup-darwin-arm64": "4.12.0", + "@rollup/rollup-darwin-x64": "4.12.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.12.0", + "@rollup/rollup-linux-arm64-gnu": "4.12.0", + "@rollup/rollup-linux-arm64-musl": "4.12.0", + "@rollup/rollup-linux-riscv64-gnu": "4.12.0", + "@rollup/rollup-linux-x64-gnu": "4.12.0", + "@rollup/rollup-linux-x64-musl": "4.12.0", + "@rollup/rollup-win32-arm64-msvc": "4.12.0", + "@rollup/rollup-win32-ia32-msvc": "4.12.0", + "@rollup/rollup-win32-x64-msvc": "4.12.0", + "fsevents": "~2.3.2" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "engines": { + "node": ">=8" + } + }, + "node_modules/source-map": { + "version": "0.8.0-beta.0", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.8.0-beta.0.tgz", + "integrity": "sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==", + "dependencies": { + "whatwg-url": "^7.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/string-width-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/sucrase": { + "version": "3.35.0", + "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", + "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.2", + "commander": "^4.0.0", + "glob": "^10.3.10", + "lines-and-columns": "^1.1.6", + "mz": "^2.7.0", + "pirates": "^4.0.1", + "ts-interface-checker": "^0.1.9" + }, + "bin": { + "sucrase": "bin/sucrase", + "sucrase-node": "bin/sucrase-node" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/tr46": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", + "integrity": "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "bin": { + "tree-kill": "cli.js" + } + }, + "node_modules/ts-interface-checker": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==" + }, + "node_modules/tsup": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/tsup/-/tsup-8.0.2.tgz", + "integrity": "sha512-NY8xtQXdH7hDUAZwcQdY/Vzlw9johQsaqf7iwZ6g1DOUlFYQ5/AtVAjTvihhEyeRlGo4dLRVHtrRaL35M1daqQ==", + "dependencies": { + "bundle-require": "^4.0.0", + "cac": "^6.7.12", + "chokidar": "^3.5.1", + "debug": "^4.3.1", + "esbuild": "^0.19.2", + "execa": "^5.0.0", + "globby": "^11.0.3", + "joycon": "^3.0.1", + "postcss-load-config": "^4.0.1", + "resolve-from": "^5.0.0", + "rollup": "^4.0.2", + "source-map": "0.8.0-beta.0", + "sucrase": "^3.20.3", + "tree-kill": "^1.2.2" + }, + "bin": { + "tsup": "dist/cli-default.js", + "tsup-node": "dist/cli-node.js" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@microsoft/api-extractor": "^7.36.0", + "@swc/core": "^1", + "postcss": "^8.4.12", + "typescript": ">=4.5.0" + }, + "peerDependenciesMeta": { + "@microsoft/api-extractor": { + "optional": true + }, + "@swc/core": { + "optional": true + }, + "postcss": { + "optional": true + }, + "typescript": { + "optional": true + } + } + }, + "node_modules/typescript": { + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/webidl-conversions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==" + }, + "node_modules/whatwg-url": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", + "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", + "dependencies": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yaml": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.0.tgz", + "integrity": "sha512-j9iR8g+/t0lArF4V6NE/QCfT+CO7iLqrXAHZbJdo+LfjqP1vR8Fg5bSiaq6Q2lOD1AUEVrEVIgABvBFYojJVYQ==", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14" + } } + } } diff --git a/JS/wasm/types/jsonnet/package.json b/JS/wasm/types/jsonnet/package.json index d10be92fa..c8fcf94a2 100644 --- a/JS/wasm/types/jsonnet/package.json +++ b/JS/wasm/types/jsonnet/package.json @@ -1,25 +1,7 @@ { - "name": "arakoo-jsonnet", - "version": "0.1.0", - "description": "", - "main": "index.node", - "scripts": { - "build": "cargo-cp-artifact -nc index.node -- cargo build --message-format=json-render-diagnostics", - "build-debug": "npm run build --", - "build-release": "npm run build -- --release", - "test": "cargo test", - "preinstall": "npm install cargo-cp-artifact --no-save" - }, - "types": "src/index.d.ts", - "author": "", - "exports": { - ".": { - "require": "./src/index.js", - "default": "./src/module.mjs" - } - }, - "license": "ISC", - "devDependencies": { - "cargo-cp-artifact": "^0.1" - } -} + "name": "@arakoodev/jsonnet", + "version": "0.1.1", + "main": "src/index.js", + "type": "module", + "types": "src/index.d.ts" +} \ No newline at end of file diff --git a/JS/wasm/types/jsonnet/read-file.js b/JS/wasm/types/jsonnet/read-file.js new file mode 100644 index 000000000..8604e26db --- /dev/null +++ b/JS/wasm/types/jsonnet/read-file.js @@ -0,0 +1,5 @@ +import fs from "fs"; + +export function read_file(path) { + return fs.readFileSync(path, { encoding: "utf8" }); +} \ No newline at end of file diff --git a/JS/wasm/types/jsonnet/src/index.d.ts b/JS/wasm/types/jsonnet/src/index.d.ts index 188a9171f..f343ca278 100644 --- a/JS/wasm/types/jsonnet/src/index.d.ts +++ b/JS/wasm/types/jsonnet/src/index.d.ts @@ -1,11 +1,9 @@ -export function jsonnet(filename: string): Promise; +declare class Jsonnet { + constructor(); + evaluateSnippet(snippet: string): string; + destroy(): void; + extString(key: string, value: string): this; + evaluateFile(filename: string): string; +} -/** - * useage: - * const extVars = JSON.stringify({ - * a: 1, - * b: 2, - * }); - * await jsonnetExtVars(filename, extVars); - */ -export function jsonnetExtVars(filename: string, extVars: string): Promise; +export default Jsonnet; diff --git a/JS/wasm/types/jsonnet/src/index.js b/JS/wasm/types/jsonnet/src/index.js index 30b8d0a73..496a97213 100644 --- a/JS/wasm/types/jsonnet/src/index.js +++ b/JS/wasm/types/jsonnet/src/index.js @@ -1,6 +1,3 @@ -const { jsonnet, jsonnetExtVars } = require("../index.node"); +import Jsonnet from "./jsonnet"; -module.exports = { - jsonnet, - jsonnetExtVars, -}; +export default Jsonnet; diff --git a/JS/wasm/types/jsonnet/src/jsonnet.js b/JS/wasm/types/jsonnet/src/jsonnet.js new file mode 100644 index 000000000..a0b226b4c --- /dev/null +++ b/JS/wasm/types/jsonnet/src/jsonnet.js @@ -0,0 +1,50 @@ +const isArakoo = process.env.arakoo; + +let Jsonnet; + +if (!isArakoo) { + let module = import("./jsonnet_wasm.js"); + let { jsonnet_evaluate_snippet, jsonnet_destroy, jsonnet_make, ext_string, jsonnet_evaluate_file } = + await module; + Jsonnet = class Jsonnet { + constructor() { + this.vm = jsonnet_make(); + } + + evaluateSnippet(snippet) { + return jsonnet_evaluate_snippet(this.vm, "snippet", snippet); + } + + extString(key, value) { + ext_string(this.vm, key, value); + return this; + } + + evaluateFile(filename) { + return jsonnet_evaluate_file(this.vm, filename); + } + + destroy() { + jsonnet_destroy(this.vm); + } + }; +} else { + Jsonnet = class Jsonnet { + constructor() { + this.vars = {}; + } + + extString(key, value) { + this.vars[key] = value; + return this + } + evaluateSnippet(snippet) { + let vars = JSON.stringify(this.vars); + return __jsonnet_evaluate_snippet(vars, snippet); + } + + destroy() { } + }; +} + +export default Jsonnet; diff --git a/JS/wasm/types/jsonnet/src/jsonnet_wasm.d.ts b/JS/wasm/types/jsonnet/src/jsonnet_wasm.d.ts new file mode 100644 index 000000000..01f7635ab --- /dev/null +++ b/JS/wasm/types/jsonnet/src/jsonnet_wasm.d.ts @@ -0,0 +1,29 @@ +/* tslint:disable */ +/* eslint-disable */ +/** +* @returns {number} +*/ +export function jsonnet_make(): number; +/** +* @param {number} vm +*/ +export function jsonnet_destroy(vm: number): void; +/** +* @param {number} vm +* @param {string} filename +* @param {string} snippet +* @returns {string} +*/ +export function jsonnet_evaluate_snippet(vm: number, filename: string, snippet: string): string; +/** +* @param {number} vm +* @param {string} filename +* @returns {string} +*/ +export function jsonnet_evaluate_file(vm: number, filename: string): string; +/** +* @param {number} vm +* @param {string} key +* @param {string} value +*/ +export function ext_string(vm: number, key: string, value: string): void; diff --git a/JS/wasm/types/jsonnet/src/jsonnet_wasm.js b/JS/wasm/types/jsonnet/src/jsonnet_wasm.js new file mode 100644 index 000000000..e9cd70f58 --- /dev/null +++ b/JS/wasm/types/jsonnet/src/jsonnet_wasm.js @@ -0,0 +1,13 @@ +import * as imports from "./jsonnet_wasm_bg.js"; + +// switch between both syntax for Node.js and for workers (Cloudflare Workers) +import * as wkmod from "./jsonnet_wasm_bg.wasm"; +import * as nodemod from "./jsonnet_wasm_bg.wasm"; +if ((typeof process !== 'undefined') && (process.release.name === 'node')) { + imports.__wbg_set_wasm(nodemod); +} else { + const instance = new WebAssembly.Instance(wkmod.default, { "./jsonnet_wasm_bg.js": imports }); + imports.__wbg_set_wasm(instance.exports); +} + +export * from "./jsonnet_wasm_bg.js"; diff --git a/JS/wasm/types/jsonnet/src/jsonnet_wasm_bg.js b/JS/wasm/types/jsonnet/src/jsonnet_wasm_bg.js new file mode 100644 index 000000000..791211da0 --- /dev/null +++ b/JS/wasm/types/jsonnet/src/jsonnet_wasm_bg.js @@ -0,0 +1,235 @@ +import { read_file } from './snippets/arakoo-07ad5af4ed8e3fe0/read-file.js'; + +let wasm; +export function __wbg_set_wasm(val) { + wasm = val; +} + + +const heap = new Array(128).fill(undefined); + +heap.push(undefined, null, true, false); + +function getObject(idx) { return heap[idx]; } + +let WASM_VECTOR_LEN = 0; + +let cachedUint8Memory0 = null; + +function getUint8Memory0() { + if (cachedUint8Memory0 === null || cachedUint8Memory0.byteLength === 0) { + cachedUint8Memory0 = new Uint8Array(wasm.memory.buffer); + } + return cachedUint8Memory0; +} + +const lTextEncoder = typeof TextEncoder === 'undefined' ? (0, module.require)('util').TextEncoder : TextEncoder; + +let cachedTextEncoder = new lTextEncoder('utf-8'); + +const encodeString = (typeof cachedTextEncoder.encodeInto === 'function' + ? function (arg, view) { + return cachedTextEncoder.encodeInto(arg, view); +} + : function (arg, view) { + const buf = cachedTextEncoder.encode(arg); + view.set(buf); + return { + read: arg.length, + written: buf.length + }; +}); + +function passStringToWasm0(arg, malloc, realloc) { + + if (realloc === undefined) { + const buf = cachedTextEncoder.encode(arg); + const ptr = malloc(buf.length, 1) >>> 0; + getUint8Memory0().subarray(ptr, ptr + buf.length).set(buf); + WASM_VECTOR_LEN = buf.length; + return ptr; + } + + let len = arg.length; + let ptr = malloc(len, 1) >>> 0; + + const mem = getUint8Memory0(); + + let offset = 0; + + for (; offset < len; offset++) { + const code = arg.charCodeAt(offset); + if (code > 0x7F) break; + mem[ptr + offset] = code; + } + + if (offset !== len) { + if (offset !== 0) { + arg = arg.slice(offset); + } + ptr = realloc(ptr, len, len = offset + arg.length * 3, 1) >>> 0; + const view = getUint8Memory0().subarray(ptr + offset, ptr + len); + const ret = encodeString(arg, view); + + offset += ret.written; + ptr = realloc(ptr, len, offset, 1) >>> 0; + } + + WASM_VECTOR_LEN = offset; + return ptr; +} + +function isLikeNone(x) { + return x === undefined || x === null; +} + +let cachedInt32Memory0 = null; + +function getInt32Memory0() { + if (cachedInt32Memory0 === null || cachedInt32Memory0.byteLength === 0) { + cachedInt32Memory0 = new Int32Array(wasm.memory.buffer); + } + return cachedInt32Memory0; +} + +let heap_next = heap.length; + +function dropObject(idx) { + if (idx < 132) return; + heap[idx] = heap_next; + heap_next = idx; +} + +function takeObject(idx) { + const ret = getObject(idx); + dropObject(idx); + return ret; +} + +const lTextDecoder = typeof TextDecoder === 'undefined' ? (0, module.require)('util').TextDecoder : TextDecoder; + +let cachedTextDecoder = new lTextDecoder('utf-8', { ignoreBOM: true, fatal: true }); + +cachedTextDecoder.decode(); + +function getStringFromWasm0(ptr, len) { + ptr = ptr >>> 0; + return cachedTextDecoder.decode(getUint8Memory0().subarray(ptr, ptr + len)); +} + +function addHeapObject(obj) { + if (heap_next === heap.length) heap.push(heap.length + 1); + const idx = heap_next; + heap_next = heap[idx]; + + heap[idx] = obj; + return idx; +} + +function handleError(f, args) { + try { + return f.apply(this, args); + } catch (e) { + wasm.__wbindgen_exn_store(addHeapObject(e)); + } +} +/** +* @returns {number} +*/ +export function jsonnet_make() { + const ret = wasm.jsonnet_make(); + return ret >>> 0; +} + +/** +* @param {number} vm +*/ +export function jsonnet_destroy(vm) { + wasm.jsonnet_destroy(vm); +} + +/** +* @param {number} vm +* @param {string} filename +* @param {string} snippet +* @returns {string} +*/ +export function jsonnet_evaluate_snippet(vm, filename, snippet) { + let deferred3_0; + let deferred3_1; + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + const ptr0 = passStringToWasm0(filename, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len0 = WASM_VECTOR_LEN; + const ptr1 = passStringToWasm0(snippet, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len1 = WASM_VECTOR_LEN; + wasm.jsonnet_evaluate_snippet(retptr, vm, ptr0, len0, ptr1, len1); + var r0 = getInt32Memory0()[retptr / 4 + 0]; + var r1 = getInt32Memory0()[retptr / 4 + 1]; + deferred3_0 = r0; + deferred3_1 = r1; + return getStringFromWasm0(r0, r1); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + wasm.__wbindgen_free(deferred3_0, deferred3_1, 1); + } +} + +/** +* @param {number} vm +* @param {string} filename +* @returns {string} +*/ +export function jsonnet_evaluate_file(vm, filename) { + let deferred2_0; + let deferred2_1; + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + const ptr0 = passStringToWasm0(filename, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len0 = WASM_VECTOR_LEN; + wasm.jsonnet_evaluate_file(retptr, vm, ptr0, len0); + var r0 = getInt32Memory0()[retptr / 4 + 0]; + var r1 = getInt32Memory0()[retptr / 4 + 1]; + deferred2_0 = r0; + deferred2_1 = r1; + return getStringFromWasm0(r0, r1); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + wasm.__wbindgen_free(deferred2_0, deferred2_1, 1); + } +} + +/** +* @param {number} vm +* @param {string} key +* @param {string} value +*/ +export function ext_string(vm, key, value) { + const ptr0 = passStringToWasm0(key, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len0 = WASM_VECTOR_LEN; + const ptr1 = passStringToWasm0(value, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len1 = WASM_VECTOR_LEN; + wasm.ext_string(vm, ptr0, len0, ptr1, len1); +} + +export function __wbg_readfile_3df9f1d22ad880df() { return handleError(function (arg0, arg1, arg2) { + const ret = read_file(getStringFromWasm0(arg1, arg2)); + const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len1 = WASM_VECTOR_LEN; + getInt32Memory0()[arg0 / 4 + 1] = len1; + getInt32Memory0()[arg0 / 4 + 0] = ptr1; +}, arguments) }; + +export function __wbindgen_string_get(arg0, arg1) { + const obj = getObject(arg1); + const ret = typeof(obj) === 'string' ? obj : undefined; + var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + var len1 = WASM_VECTOR_LEN; + getInt32Memory0()[arg0 / 4 + 1] = len1; + getInt32Memory0()[arg0 / 4 + 0] = ptr1; +}; + +export function __wbindgen_object_drop_ref(arg0) { + takeObject(arg0); +}; + diff --git a/JS/wasm/types/jsonnet/src/jsonnet_wasm_bg.wasm b/JS/wasm/types/jsonnet/src/jsonnet_wasm_bg.wasm new file mode 100644 index 000000000..5e9876467 Binary files /dev/null and b/JS/wasm/types/jsonnet/src/jsonnet_wasm_bg.wasm differ diff --git a/JS/wasm/types/jsonnet/src/jsonnet_wasm_bg.wasm.d.ts b/JS/wasm/types/jsonnet/src/jsonnet_wasm_bg.wasm.d.ts new file mode 100644 index 000000000..c29cb9267 --- /dev/null +++ b/JS/wasm/types/jsonnet/src/jsonnet_wasm_bg.wasm.d.ts @@ -0,0 +1,13 @@ +/* tslint:disable */ +/* eslint-disable */ +export const memory: WebAssembly.Memory; +export function jsonnet_make(): number; +export function jsonnet_destroy(a: number): void; +export function jsonnet_evaluate_snippet(a: number, b: number, c: number, d: number, e: number, f: number): void; +export function jsonnet_evaluate_file(a: number, b: number, c: number, d: number): void; +export function ext_string(a: number, b: number, c: number, d: number, e: number): void; +export function __wbindgen_malloc(a: number, b: number): number; +export function __wbindgen_realloc(a: number, b: number, c: number, d: number): number; +export function __wbindgen_exn_store(a: number): void; +export function __wbindgen_add_to_stack_pointer(a: number): number; +export function __wbindgen_free(a: number, b: number, c: number): void; diff --git a/JS/wasm/types/jsonnet/src/lib.rs b/JS/wasm/types/jsonnet/src/lib.rs old mode 100644 new mode 100755 index 03867fd06..b29a94f17 --- a/JS/wasm/types/jsonnet/src/lib.rs +++ b/JS/wasm/types/jsonnet/src/lib.rs @@ -1,48 +1,101 @@ -use std::{collections::HashMap, fs}; +use jrsonnet_evaluator::{ + apply_tla, + function::TlaArg, + gc::GcHashMap, + manifest::{JsonFormat, ManifestFormat}, + tb, + trace::{CompactFormat, PathResolver, TraceFormat}, + FileImportResolver, State, Val, +}; +use jrsonnet_parser::IStr; +use wasm_bindgen::prelude::*; -use jsonnet::JsonnetVm; -use neon::prelude::*; -use serde_json::Value; +#[wasm_bindgen(module = "/read-file.js")] +extern "C" { + #[wasm_bindgen(catch)] + fn read_file(path: &str) -> Result; +} -pub fn jsonnet(mut cx: FunctionContext) -> JsResult { - let path: String = cx.argument::(0)?.value(&mut cx); - let mut vm = JsonnetVm::new(); - let snippet = fs::read_to_string(path).unwrap(); - let output = vm.evaluate_snippet("snippet", &snippet); - let output = match output { - Ok(output) => output, - Err(e) => { - return cx.throw_error(format!("Error: {}", e)); - } - }; - Ok(cx.string(output.to_string())) +pub struct VM { + state: State, + manifest_format: Box, + trace_format: Box, + tla_args: GcHashMap, } -pub fn jsonnet_ext_vars(mut cx: FunctionContext) -> JsResult { - let path: String = cx.argument::(0)?.value(&mut cx); - let ext_var: String = cx.argument::(1)?.value(&mut cx); - let mut vm = JsonnetVm::new(); - let ext_var_str = ext_var.as_str(); - let ext_vars: HashMap<&str, Value> = serde_json::from_str(ext_var_str).unwrap(); - for (key, value) in ext_vars { - vm.ext_var(key, value.as_str().unwrap()); +#[wasm_bindgen] +pub fn jsonnet_make() -> *mut VM { + let state = State::default(); + state.settings_mut().import_resolver = tb!(FileImportResolver::default()); + state.settings_mut().context_initializer = tb!(jrsonnet_stdlib::ContextInitializer::new( + state.clone(), + PathResolver::new_cwd_fallback(), + )); + Box::into_raw(Box::new(VM { + state, + manifest_format: Box::new(JsonFormat::default()), + trace_format: Box::new(CompactFormat::default()), + tla_args: GcHashMap::default(), + })) +} + +#[wasm_bindgen] +pub fn jsonnet_destroy(vm: *mut VM) { + unsafe { + let dloc_vm = Box::from_raw(vm); + drop(dloc_vm); } +} - let snippet = fs::read_to_string(path).unwrap(); +#[wasm_bindgen] +pub fn jsonnet_evaluate_snippet(vm: *mut VM, filename: &str, snippet: &str) -> String { + let vm = unsafe { &mut *vm }; + match vm + .state + .evaluate_snippet(filename, snippet) + .and_then(|val| apply_tla(vm.state.clone(), &vm.tla_args, val)) + .and_then(|val| val.manifest(&vm.manifest_format)) + { + Ok(v) => v, + Err(e) => { + let mut out = String::new(); + vm.trace_format.write_trace(&mut out, &e).unwrap(); + out + } + } +} - let output = vm.evaluate_snippet("snippet", &snippet); - let output = match output { - Ok(output) => output, +#[wasm_bindgen] +pub fn jsonnet_evaluate_file(vm: *mut VM, filename: &str) -> String { + let vm = unsafe { &mut *vm }; + match read_file(filename) { + Ok(content) => match vm + .state + .evaluate_snippet(filename, &content) + .and_then(|val| apply_tla(vm.state.clone(), &vm.tla_args, val)) + .and_then(|val| val.manifest(&vm.manifest_format)) + { + Ok(v) => v, + Err(e) => { + let mut out = String::new(); + vm.trace_format.write_trace(&mut out, &e).unwrap(); + out + } + }, Err(e) => { - return cx.throw_error(format!("{}", e)); + let out = String::from(e.as_string().unwrap()); + out } - }; - Ok(cx.string(output.to_string())) + } } -#[neon::main] -fn main(mut cx: ModuleContext) -> NeonResult<()> { - cx.export_function("jsonnet", jsonnet)?; - cx.export_function("jsonnetExtVars", jsonnet_ext_vars)?; - Ok(()) +#[wasm_bindgen] +pub fn ext_string(vm: *mut VM, key: &str, value: &str) { + let vm = unsafe { &mut *vm }; + let any_initializer = vm.state.context_initializer(); + any_initializer + .as_any() + .downcast_ref::() + .unwrap() + .add_ext_var(key.into(), Val::Str(value.into())); } diff --git a/JS/wasm/types/jsonnet/src/module.mjs b/JS/wasm/types/jsonnet/src/module.mjs deleted file mode 100644 index 962aaa90a..000000000 --- a/JS/wasm/types/jsonnet/src/module.mjs +++ /dev/null @@ -1,5 +0,0 @@ -import parseJson from "./index.js"; - -const { jsonnet, jsonnetExtVars } = parseJson; - -export { jsonnet, jsonnetExtVars }; diff --git a/JS/wasm/types/jsonnet/src/snippets/arakoo-07ad5af4ed8e3fe0/read-file.js b/JS/wasm/types/jsonnet/src/snippets/arakoo-07ad5af4ed8e3fe0/read-file.js new file mode 100644 index 000000000..8604e26db --- /dev/null +++ b/JS/wasm/types/jsonnet/src/snippets/arakoo-07ad5af4ed8e3fe0/read-file.js @@ -0,0 +1,5 @@ +import fs from "fs"; + +export function read_file(path) { + return fs.readFileSync(path, { encoding: "utf8" }); +} \ No newline at end of file diff --git a/JS/wasm/types/jsonnet/tsconfig.json b/JS/wasm/types/jsonnet/tsconfig.json index acbd9198e..c019db476 100644 --- a/JS/wasm/types/jsonnet/tsconfig.json +++ b/JS/wasm/types/jsonnet/tsconfig.json @@ -1,15 +1,27 @@ { - "compilerOptions": { - "module": "commonjs", - "lib": ["es6"], - "strict": true, - "baseUrl": ".", - "paths": { "arakoo-jsonnet": ["."] } + "compilerOptions": { + "module": "commonjs", + "lib": [ + "es6" + ], + "strict": true, + "baseUrl": ".", + "paths": { + "arakoo-jsonnet": [ + "." + ] }, - "typedocOptions": { - "entryPoints": ["index.d.ts"], - "out": "../docs", - "excludeExternals": true - }, - "include": ["."] + "noUncheckedIndexedAccess": true, + "noEmit": true + }, + "typedocOptions": { + "entryPoints": [ + "src/index.d.ts" + ], + "out": "../docs", + "excludeExternals": true + }, + "include": [ + "." + ] } diff --git a/JS/wasm/wit/arakoo.wit b/JS/wasm/wit/arakoo.wit new file mode 100644 index 000000000..f4ea1ddba --- /dev/null +++ b/JS/wasm/wit/arakoo.wit @@ -0,0 +1,5 @@ +use * from http-types + + +fetch-request: func(request: http-request) -> expected + diff --git a/JS/wasm/wit/http-types.wit b/JS/wasm/wit/http-types.wit new file mode 100644 index 000000000..168cafc4a --- /dev/null +++ b/JS/wasm/wit/http-types.wit @@ -0,0 +1,45 @@ + type uri = string + type http-status = u16 + type http-header = tuple + type http-headers = list + enum http-method { + get, + post, + put, + patch, + delete, + options, + head + } + type http-param = tuple + type http-params = list + type http-body = list + record http-request { + body: option, + headers: http-headers, + method: http-method, + params: http-params, + uri: uri, + } + record http-request-error { + error: http-error, + message: string + } + record http-response { + body: option, + headers: http-headers, + status: http-status, + } + enum http-error { + invalid-request, + invalid-request-body, + invalid-response-body, + not-allowed, + internal-error, + timeout, + redirect-loop, + } + enum file-error { + not-found, + invalid-path, + } diff --git a/Makefile b/Makefile new file mode 100644 index 000000000..236315871 --- /dev/null +++ b/Makefile @@ -0,0 +1,46 @@ +.PHONY: all +all: build-arakoo + +add: + @echo "Adding wasm32-wasi target" + @rustup target add wasm32-wasi + +clean-rm: clean-shims + @rm -rf target/ + +clean: + @cargo clean + +clean-shims: + @rm -rf dist/ node_modules/ + +build-arakoo: build-cors + @echo "Building arakoo cli" + @CARGO_PROFILE_RELEASE_LTO=off cargo build -p cli -r + +build-cors: build-shims + @echo "Building arakoo core" + @cargo build -p arakoo-core --target=wasm32-wasi -r --features experimental_event_loop + +build-shims: shims-install + @echo "Building shims" + @cd JS/wasm/crates/apis/src/http/shims && npm install + +shims-install: + @echo "Installing deps of shims" + @cd JS/wasm/crates/apis/src/http/shims && npm install + +compile: build-example + ./target/release/arakoo compile JS/wasm/examples/ec-wasmjs-hono/bin/app.js + +serve: + ./target/release/arakoo serve index.wasm + +build-example: + @cd /Users/rahulyadav/Documents/edgeCloud/EdgeChain/JS/wasm/examples/ec-wasmjs-hono && npm i && npm run build arakoo + +clean-example: + @rm -r JS/wasm/examples/ec-wasmjs-hono/node_modules/ JS/wasm/examples/ec-wasmjs-hono/bin/ + +build-jsonnet: + @cd JS/wasm/types/jsonnet && ./build.sh \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index b0580138d..00ac81eed 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,5 +1,5 @@ { - "name": "EdgeChains", + "name": "EdgeChain", "lockfileVersion": 3, "requires": true, "packages": { diff --git a/rust-toolchain.toml b/rust-toolchain.toml new file mode 100644 index 000000000..92e761c7f --- /dev/null +++ b/rust-toolchain.toml @@ -0,0 +1,5 @@ +[toolchain] +channel = "nightly" +components = ["clippy", "rustfmt"] +targets = ["wasm32-wasi"] +profile = "default"