From f7cf6fc46b3a456ebb5cbeb059c95bc10dd43bf1 Mon Sep 17 00:00:00 2001 From: rahul007-bit Date: Wed, 27 Dec 2023 00:57:14 +0530 Subject: [PATCH] Fix formatting in JS/wasm files --- JS/wasm/crates/wasmjs-engine/shims/build.js | 102 +- .../wasmjs-engine/shims/src/arakoo-jsonnet.js | 6 +- .../crates/wasmjs-engine/shims/src/buffer.js | 13 +- .../crates/wasmjs-engine/shims/src/crypto.ts | 370 +- .../crates/wasmjs-engine/shims/src/events.ts | 9 +- .../crates/wasmjs-engine/shims/src/index.js | 154 +- .../shims/src/internal/async_hooks.d.ts | 24 +- .../shims/src/internal/async_hooks.ts | 8 +- .../shims/src/internal/buffer.d.ts | 48 +- .../shims/src/internal/buffer.ts | 850 +++-- .../shims/src/internal/constants.ts | 3 +- .../shims/src/internal/crypto.d.ts | 70 +- .../shims/src/internal/crypto.ts | 142 +- .../shims/src/internal/crypto_dh.ts | 292 +- .../shims/src/internal/crypto_hash.ts | 349 +- .../shims/src/internal/crypto_hkdf.ts | 202 +- .../shims/src/internal/crypto_keys.ts | 474 +-- .../shims/src/internal/crypto_pbkdf2.ts | 115 +- .../shims/src/internal/crypto_random.ts | 665 ++-- .../shims/src/internal/crypto_util.ts | 140 +- .../shims/src/internal/events.ts | 1382 ++++---- .../shims/src/internal/internal_buffer.ts | 1235 ++++--- .../shims/src/internal/internal_errors.ts | 63 +- .../shims/src/internal/internal_inspect.ts | 1396 +++++--- .../shims/src/internal/internal_path.ts | 583 ++-- .../src/internal/internal_stringdecoder.ts | 193 +- .../shims/src/internal/internal_types.ts | 3 +- .../shims/src/internal/internal_utils.ts | 53 +- .../shims/src/internal/process.ts | 111 +- .../shims/src/internal/streams_adapters.js | 1195 ++++--- .../shims/src/internal/streams_duplex.js | 828 +++-- .../shims/src/internal/streams_legacy.js | 130 +- .../shims/src/internal/streams_readable.js | 2978 +++++++++-------- .../shims/src/internal/streams_transform.d.ts | 640 ++-- .../shims/src/internal/streams_transform.js | 222 +- .../shims/src/internal/streams_util.js | 1668 ++++----- .../shims/src/internal/streams_writable.js | 1349 ++++---- .../shims/src/internal/util.d.ts | 11 +- .../wasmjs-engine/shims/src/internal/util.ts | 29 +- .../shims/src/internal/validators.ts | 50 +- .../crates/wasmjs-engine/shims/src/path.js | 11 +- .../wasmjs-engine/shims/src/path/posix.ts | 2 +- .../wasmjs-engine/shims/src/path/win32.ts | 2 +- JS/wasm/examples/ec-wasmjs-hono/build.js | 4 +- JS/wasm/types/jsonnet/src/index.js | 2 +- 45 files changed, 9237 insertions(+), 8939 deletions(-) diff --git a/JS/wasm/crates/wasmjs-engine/shims/build.js b/JS/wasm/crates/wasmjs-engine/shims/build.js index 87f18d436..ebfb9d72e 100644 --- a/JS/wasm/crates/wasmjs-engine/shims/build.js +++ b/JS/wasm/crates/wasmjs-engine/shims/build.js @@ -1,68 +1,68 @@ -import { build } from 'esbuild' +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 + 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) -}) + 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 + 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) -}) + 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 + 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) -}) + 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 + 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) -}) + 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 + 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) -}) + console.error(error); + process.exit(1); +}); diff --git a/JS/wasm/crates/wasmjs-engine/shims/src/arakoo-jsonnet.js b/JS/wasm/crates/wasmjs-engine/shims/src/arakoo-jsonnet.js index bbb4e9df9..b64160d75 100644 --- a/JS/wasm/crates/wasmjs-engine/shims/src/arakoo-jsonnet.js +++ b/JS/wasm/crates/wasmjs-engine/shims/src/arakoo-jsonnet.js @@ -1,5 +1,3 @@ -const parseJsonnet = globalThis.parseJsonnet +const parseJsonnet = globalThis.parseJsonnet; -export { - parseJsonnet, -} +export { parseJsonnet }; diff --git a/JS/wasm/crates/wasmjs-engine/shims/src/buffer.js b/JS/wasm/crates/wasmjs-engine/shims/src/buffer.js index 1dd28191f..5d9131bf5 100644 --- a/JS/wasm/crates/wasmjs-engine/shims/src/buffer.js +++ b/JS/wasm/crates/wasmjs-engine/shims/src/buffer.js @@ -1,19 +1,12 @@ - import { constants, kMaxLength, kStringMaxLength, Buffer, SlowBuffer, -} from './internal/internal_buffer'; +} from "./internal/internal_buffer"; -export { - constants, - kMaxLength, - kStringMaxLength, - Buffer, - SlowBuffer, -}; +export { constants, kMaxLength, kStringMaxLength, Buffer, SlowBuffer }; export default { constants, @@ -21,4 +14,4 @@ export default { kStringMaxLength, Buffer, SlowBuffer, -} \ No newline at end of file +}; diff --git a/JS/wasm/crates/wasmjs-engine/shims/src/crypto.ts b/JS/wasm/crates/wasmjs-engine/shims/src/crypto.ts index 0d504c138..f176cf637 100644 --- a/JS/wasm/crates/wasmjs-engine/shims/src/crypto.ts +++ b/JS/wasm/crates/wasmjs-engine/shims/src/crypto.ts @@ -1,6 +1,4 @@ -import { - ERR_METHOD_NOT_IMPLEMENTED -} from './internal/internal_errors'; +import { ERR_METHOD_NOT_IMPLEMENTED } from "./internal/internal_errors"; // export const getRandomValues = crypto.getRandomValues; // export const subtle = crypto.subtle; @@ -8,209 +6,236 @@ import { // export const webcrypto = crypto; import { - DiffieHellman, - DiffieHellmanGroup, - createDiffieHellman, - createDiffieHellmanGroup, - getDiffieHellman, -} from './internal/crypto_dh'; + 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'; + 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 { createHash, createHmac, Hash, HashOptions, Hmac } from "./internal/crypto_hash"; -import { - hkdf, - hkdfSync, -} from './internal/crypto_hkdf'; +import { hkdf, hkdfSync } from "./internal/crypto_hkdf"; -import { - pbkdf2, - pbkdf2Sync, - ArrayLike, -} from './internal/crypto_pbkdf2'; +import { pbkdf2, pbkdf2Sync, ArrayLike } from "./internal/crypto_pbkdf2"; import { - KeyObject, - PublicKeyObject, - PrivateKeyObject, - SecretKeyObject, - generateKey, - generateKeyPair, - generateKeyPairSync, - generateKeySync, - createPrivateKey, - createPublicKey, - createSecretKey, -} from './internal/crypto_keys'; + 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, -} + // 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"]; + 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']; + // 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']; + // 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, - } + 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'); +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'); + throw new ERR_METHOD_NOT_IMPLEMENTED("setFips"); } // We always run in FIPS mode. export const fips = true; -export function getFips() { return fips; } +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, + // 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 @@ -294,4 +319,3 @@ export default { // * 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 index 938ed3c44..77f7b3f46 100644 --- a/JS/wasm/crates/wasmjs-engine/shims/src/events.ts +++ b/JS/wasm/crates/wasmjs-engine/shims/src/events.ts @@ -1,7 +1,2 @@ -// Copyright (c) 2017-2022 Cloudflare, Inc. -// Licensed under the Apache 2.0 license found in the LICENSE file or at: -// https://opensource.org/licenses/Apache-2.0 -// - -export * from './internal/events'; -export { default } from './internal/events'; +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 index 9c29c339f..2fa1129e0 100644 --- a/JS/wasm/crates/wasmjs-engine/shims/src/index.js +++ b/JS/wasm/crates/wasmjs-engine/shims/src/index.js @@ -1,112 +1,110 @@ // 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'; +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 + 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) + this.url.set(key, value); } toString() { - return this.url.toString() + return this.url.toString(); } toJson() { - return this.url.toString() + return this.url.toString(); } - } class URLSearchParams { - queryParams = {} + queryParams = {}; constructor(val) { this.queryParams = { - ..._queryString.parse(val) - } + ..._queryString.parse(val), + }; } append(key, val) { - this.queryParams[key] = val + this.queryParams[key] = val; } delete(key) { - delete this.queryParams[key] + delete this.queryParams[key]; } entries() { - let arr = [] - Object.entries(this.queryParams).map(o => { + let arr = []; + Object.entries(this.queryParams).map((o) => { if (Array.isArray(o[1])) { - o[1].map(k => { - arr.push([o[0], k]) - }) + o[1].map((k) => { + arr.push([o[0], k]); + }); } else { - arr.push([o[0], o[1]]) + arr.push([o[0], o[1]]); } - }) - let iterLength = arr.length - let iterIndex = 0 + }); + let iterLength = arr.length; + let iterIndex = 0; return { next: function () { - return iterIndex < iterLength ? - { value: arr[iterIndex++], done: false } : - { done: true }; - } - } + return iterIndex < iterLength + ? { value: arr[iterIndex++], done: false } + : { done: true }; + }, + }; } get(key) { - let val = this.queryParams[key] + let val = this.queryParams[key]; if (val) { - if (typeof (val) == "object") { - return val[0] + if (typeof val == "object") { + return val[0]; } - return val + return val; } - return null + return null; } getAll(key) { - let val = this.queryParams[key] + let val = this.queryParams[key]; if (val) { - return val + return val; } - return null + return null; } has(key) { - return this.queryParams[key] != undefined ? true : false + return this.queryParams[key] != undefined ? true : false; } keys() { - return Object.keys(this.queryParams) + return Object.keys(this.queryParams); } set(key, val) { - this.queryParams[key] = val + this.queryParams[key] = val; } toString() { - return _queryString.stringify(this.queryParams) + return _queryString.stringify(this.queryParams); } values() { - return Object.keys(this.queryParams).map(k => this.queryParams[k]) + return Object.keys(this.queryParams).map((k) => this.queryParams[k]); } [Symbol.iterator]() { - return this.entries() + return this.entries(); } } @@ -114,11 +112,11 @@ globalThis.URL = URL; globalThis.URLSearchParams = URLSearchParams; function atob(b64) { - return Buffer.from(b64, "base64").toString() + return Buffer.from(b64, "base64").toString(); } function btoa(data) { - return Buffer.from(data).toString('base64') + return Buffer.from(data).toString("base64"); } globalThis.btoa = btoa; @@ -207,9 +205,9 @@ class Response { return new Response(`Redirecting to ${url}`, { status, headers: { - Location: url - } - }) + Location: url, + }, + }); } get ok() { @@ -280,14 +278,14 @@ class Response { method: "GET", headers: {}, body: null, - ...opts + ...opts, }; if (optsWithDefault.body !== null && typeof optsWithDefault.body !== "string") { try { optsWithDefault.body = new TextEncoder().encode(optsWithDefault.body); } catch (e) { - return Promise.reject(`err: ${e}`) + return Promise.reject(`err: ${e}`); } } @@ -299,12 +297,11 @@ class Response { let response = new Response(result.body, { headers: result.headers, status: result.status, - }) + }); return Promise.resolve(response); } - } - + }; globalThis.console = { error(msg) { @@ -324,8 +321,8 @@ class Response { }, trace(msg) { this.log(msg); - } - } + }, + }; Reflect.deleteProperty(globalThis, "__send_http_request"); Reflect.deleteProperty(globalThis, "__console_log"); @@ -340,28 +337,27 @@ globalThis.addEventListener = (_eventName, handler) => { handlerFunction = handler; }; -const requestToHandler = input => { +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, - }; - }) + Promise.resolve(event.response) + .then((res) => { + result = { + data: res.body, + headers: res.headers.headers, + status: res.status, + }; + }) .catch((err) => { error = `err: \n${err}`; }); @@ -372,4 +368,4 @@ const requestToHandler = input => { globalThis.entrypoint = requestToHandler; globalThis.result = {}; -globalThis.error = null +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 index 4e97d10a0..6f02fb827 100644 --- 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 @@ -1,22 +1,26 @@ // Type definitions for c++ implementation. export interface AsyncResourceOptions { - triggerAsyncId?: number; + triggerAsyncId?: number; } export class AsyncResource { - public constructor(type: string, options?: AsyncResourceOptions); - public runInAsyncScope(fn: (...args: unknown[]) => R, ...args: unknown[]): R; + public constructor(type: string, options?: AsyncResourceOptions); + public runInAsyncScope(fn: (...args: unknown[]) => R, ...args: unknown[]): R; - public bind unknown>( - fn: Func): Func & { asyncResource: AsyncResource; }; + public bind unknown>( + fn: Func + ): Func & { asyncResource: AsyncResource }; - public static bind unknown, ThisArg>( - fn: Func, type?: string, thisArg?: ThisArg): 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; + 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 index a78e2a726..968aa2fc3 100644 --- a/JS/wasm/crates/wasmjs-engine/shims/src/internal/async_hooks.ts +++ b/JS/wasm/crates/wasmjs-engine/shims/src/internal/async_hooks.ts @@ -9,11 +9,15 @@ export class AsyncResource { public runInAsyncScope(fn: (...args: unknown[]) => R, ...args: unknown[]): R; public bind unknown>( - fn: Func): Func & { asyncResource: AsyncResource; }; + fn: Func + ): Func & { asyncResource: AsyncResource }; // @ts-ignore public static bind unknown, ThisArg>( - fn: Func, type?: string, thisArg?: ThisArg): Func & { asyncResource: AsyncResource; }; + fn: Func, + type?: string, + thisArg?: ThisArg + ): Func & { asyncResource: AsyncResource }; } export class AsyncLocalStorage { 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 index d387b6aa6..6ba318865 100644 --- a/JS/wasm/crates/wasmjs-engine/shims/src/internal/buffer.d.ts +++ b/JS/wasm/crates/wasmjs-engine/shims/src/internal/buffer.d.ts @@ -1,9 +1,8 @@ - export interface CompareOptions { aStart?: number; aEnd?: number; bStart?: number; - bEnd?: number + bEnd?: number; } type BufferSource = ArrayBufferView | ArrayBuffer; @@ -12,25 +11,28 @@ 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 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; \ No newline at end of file +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 index 8ea27b939..21fde0761 100644 --- a/JS/wasm/crates/wasmjs-engine/shims/src/internal/buffer.ts +++ b/JS/wasm/crates/wasmjs-engine/shims/src/internal/buffer.ts @@ -1,539 +1,521 @@ -import {isInstance} from "./internal_buffer"; +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, + "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 + 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; } - 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; + 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; + 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; + 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 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--; + 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; + const encoder = new TextEncoder(); + return encoder.encode(value).buffer; } export function write( - buffer: Uint8Array, - value: string, - offset: number, - length: number, - encoding: string + 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; + 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 + 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]; + 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; + // 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; } - 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); - } + + // 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); } - return arrayIndexOf(buffer, [val], byteOffset, encoding, dir); - } - throw new TypeError("val must be string, number or Buffer"); + 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; + 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; - } + function read(buf, i) { + if (indexSize === 1) { + return buf[i]; + } else { + return buf.readUInt16BE(i * indexSize); + } } - } 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; + + 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; } - } - if (found) return i; } - } - return -1; + 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; + 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); } - // 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"); + } } - 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 - ); + return bytes; +} + +function hexWrite(buf, string, offset, length) { + offset = Number(offset) || 0; + const remaining = buf.length - offset; + if (!length) { + length = remaining; } else { - throw new Error("Invalid code point"); + length = Number(length); + if (length > remaining) { + length = remaining; + } } - } - return bytes; -} + const strLen = string.length; -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; + if (length > strLen / 2) { + length = strLen / 2; } - } - - 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; + 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; } - buf[offset + i] = (a << 4) | b; - } - return i; + return i; } function base64ToBytes(str) { - return base64.toByteArray(base64clean(str)); + return base64.toByteArray(base64clean(str)); } function utf8Write(buf, string, offset, length) { - return blitBuffer( - utf8ToBytes(string, buf.length - offset), - buf, - 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); + return blitBuffer(asciiToBytes(string), buf, offset, length); } function base64Write(buf, string, offset, length) { - return blitBuffer(base64ToBytes(string), buf, 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 - ); + 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; + 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; + 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; + // 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; + 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 + // 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); + // 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"); + 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; } - result += char; - } - return result; -} \ No newline at end of file + 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 index 88ec50573..2013d207f 100644 --- a/JS/wasm/crates/wasmjs-engine/shims/src/internal/constants.ts +++ b/JS/wasm/crates/wasmjs-engine/shims/src/internal/constants.ts @@ -1,4 +1,3 @@ - export const CHAR_UPPERCASE_A = 65; /* A */ export const CHAR_LOWERCASE_A = 97; /* a */ export const CHAR_UPPERCASE_Z = 90; /* Z */ @@ -42,4 +41,4 @@ 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 = '\;'; \ No newline at end of file +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 index 6fb967959..afab20186 100644 --- a/JS/wasm/crates/wasmjs-engine/shims/src/internal/crypto.d.ts +++ b/JS/wasm/crates/wasmjs-engine/shims/src/internal/crypto.d.ts @@ -1,35 +1,47 @@ -import { - Buffer, -} from './internal_buffer'; +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; +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; + 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 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; + 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; +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; +export function getPbkdf( + password: ArrayLike, + salt: ArrayLike, + iterations: number, + keylen: number, + digest: string +): ArrayBuffer; // Keys export function exportKey(key: CryptoKey, options?: InnerExportOptions): KeyExportResult; @@ -214,19 +226,21 @@ export type KeyData = string | ArrayBuffer | ArrayBufferView; // 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 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 computeSecret(key: ArrayBuffer | ArrayBufferView): ArrayBuffer; + public generateKeys(): ArrayBuffer; - public getVerifyError(): number; + 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 index 088a1d7db..12248fd6e 100644 --- a/JS/wasm/crates/wasmjs-engine/shims/src/internal/crypto.ts +++ b/JS/wasm/crates/wasmjs-engine/shims/src/internal/crypto.ts @@ -1,10 +1,9 @@ -import * as sjcl from 'sjcl'; -import {Buffer} from "./internal_buffer"; +import * as sjcl from "sjcl"; +import { Buffer } from "./internal_buffer"; -export type ArrayLike = ArrayBuffer|string|Buffer|ArrayBufferView; +export type ArrayLike = ArrayBuffer | string | Buffer | ArrayBufferView; export type KeyData = string | ArrayBuffer | ArrayBufferView; - /** * Checks if a number represented by an ArrayBufferView is prime. * @@ -37,11 +36,16 @@ export function checkPrimeSync(candidate: ArrayBufferView, num_checks: 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 { +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); + prime = Math.abs(prime) % 2 ** size; if (safe) { prime = 2 * prime + 1; } @@ -57,7 +61,13 @@ export function randomPrime(size: number, safe: boolean, add?: ArrayBufferView, } // hkdf -export function getHkdf(hash: string, key: ArrayLike, salt: ArrayLike, info: ArrayLike, length: number): ArrayBuffer { +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()); @@ -72,7 +82,13 @@ export function getHkdf(hash: string, key: ArrayLike, salt: ArrayLike, info: Arr } // pbkdf2 -export function getPbkdf(password: ArrayLike, salt: ArrayLike, iterations: number, keylen: number, digest: string): ArrayBuffer { +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()); @@ -85,19 +101,18 @@ export function getPbkdf(password: ArrayLike, salt: ArrayLike, iterations: numbe return sjcl.codec.arrayBuffer.fromBits(derivedKeyBits); } - export class HashHandle { private hash: sjcl.SjclHash; public constructor(algorithm: string, xofLen: number) { switch (algorithm) { - case 'sha1': + case "sha1": this.hash = new sjcl.hash.sha1(); break; - case 'sha256': + case "sha256": this.hash = new sjcl.hash.sha256(); break; - case 'sha512': + case "sha512": this.hash = new sjcl.hash.sha512(); break; default: @@ -121,23 +136,23 @@ export class HashHandle { } public copy(xofLen: number): HashHandle { - let algo =""; + let algo = ""; let hash = this.hash; switch (true) { case hash instanceof sjcl.hash.sha1: - algo = 'sha1'; + algo = "sha1"; break; case hash instanceof sjcl.hash.sha256: - algo = 'sha256'; + algo = "sha256"; break; case hash instanceof sjcl.hash.sha512: - algo = '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 + let copy = new HashHandle(algo, xofLen); // Replace 'sha256' with the actual algorithm + copy.hash = this.hash; return copy; } } @@ -148,13 +163,13 @@ export class HmacHandle { public constructor(algorithm: string, key: ArrayLike | CryptoKey) { let keyBits = sjcl.codec.utf8String.toBits(key.toString()); switch (algorithm) { - case 'sha1': + case "sha1": this.hmac = new sjcl.misc.hmac(keyBits, sjcl.hash.sha1); break; - case 'sha256': + case "sha256": this.hmac = new sjcl.misc.hmac(keyBits, sjcl.hash.sha256); break; - case 'sha512': + case "sha512": this.hmac = new sjcl.misc.hmac(keyBits, sjcl.hash.sha512); break; default: @@ -175,45 +190,46 @@ export class HmacHandle { } export interface RsaKeyAlgorithm { - name: 'rsa' | 'rsa-pss'; + name: "rsa" | "rsa-pss"; modulusLength: number; publicExponent: Uint8Array; hash?: string; } export interface EcKeyAlgorithm { - name: 'ec'; + name: "ec"; namedCurve: string; } export interface DhKeyAlgorithm { - name: 'dh'; + name: "dh"; prime: Uint8Array; generator: Uint8Array; } export interface DsaKeyAlgorithm { - name: 'dsa'; + name: "dsa"; prime: Uint8Array; divisorLength: number; } export interface HmacKeyAlgorithm { - name: 'hmac'; + name: "hmac"; hash: string; } export interface AesKeyAlgorithm { - name: 'aes'; + name: "aes"; length: number; } -export type KeyAlgorithm = RsaKeyAlgorithm | - EcKeyAlgorithm | - DhKeyAlgorithm | - DsaKeyAlgorithm | - HmacKeyAlgorithm | - AesKeyAlgorithm; +export type KeyAlgorithm = + | RsaKeyAlgorithm + | EcKeyAlgorithm + | DhKeyAlgorithm + | DsaKeyAlgorithm + | HmacKeyAlgorithm + | AesKeyAlgorithm; export interface CryptoKey { algorithm: KeyAlgorithm; @@ -254,17 +270,17 @@ export interface CryptoKeyPair { publicKey: CryptoKey; } -export type KeyObjectType = 'secret' | 'public' | 'private'; +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 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; @@ -290,13 +306,15 @@ export interface InnerPrivateKeyExportOptions { passphrase?: Uint8Array; } -export type ExportOptions = SecretKeyExportOptions | - PublicKeyExportOptions | - PrivateKeyExportOptions; +export type ExportOptions = + | SecretKeyExportOptions + | PublicKeyExportOptions + | PrivateKeyExportOptions; -export type InnerExportOptions = SecretKeyExportOptions | - PublicKeyExportOptions | - InnerPrivateKeyExportOptions; +export type InnerExportOptions = + | SecretKeyExportOptions + | PublicKeyExportOptions + | InnerPrivateKeyExportOptions; export interface AsymmetricKeyDetails { modulusLength?: number; @@ -329,7 +347,7 @@ export interface GenerateKeyOptions { export interface GenerateKeyPairOptions { modulusLength?: number; - publicExponent?: number|bigint; + publicExponent?: number | bigint; hashAlgorithm?: string; mgf1HashAlgorithm?: string; saltLength?: number; @@ -378,12 +396,12 @@ export function createSecretKey(key: ArrayBuffer | ArrayBufferView): CryptoKey { return { algorithm: { - name: 'aes', - length: key.byteLength * 8 + name: "aes", + length: key.byteLength * 8, }, extractable: true, - type: 'secret', - usages: ['encrypt', 'decrypt'] + type: "secret", + usages: ["encrypt", "decrypt"], }; } @@ -397,15 +415,16 @@ export function createPublicKey(key: InnerCreateAsymmetricKeyOptions): CryptoKey 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) { + 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()); @@ -441,7 +460,7 @@ export class DiffieHellmanHandle { return sjcl.codec.arrayBuffer.fromBits(this.prime.toBits()); } - public computeSecret(key: ArrayBuffer|ArrayBufferView): ArrayBuffer { + 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()); @@ -449,7 +468,7 @@ export class DiffieHellmanHandle { public generateKeys(): ArrayBuffer { // Generate a new private key - this.privateKey = sjcl.bn.random(this.prime.sub(2),10).add(1); + 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); @@ -463,13 +482,12 @@ export class DiffieHellmanHandle { } } - 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 }, + 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 }; 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 index 1ce519c6d..762f512f9 100644 --- a/JS/wasm/crates/wasmjs-engine/shims/src/internal/crypto_dh.ts +++ b/JS/wasm/crates/wasmjs-engine/shims/src/internal/crypto_dh.ts @@ -1,202 +1,198 @@ - /* eslint-disable */ -'use strict'; +"use strict"; -import { - Buffer, -} from './internal_buffer'; +import { Buffer } from "./internal_buffer"; -import * as cryptoImpl from './crypto'; +import * as cryptoImpl from "./crypto"; type ArrayLike = cryptoImpl.ArrayLike; -import { - ERR_CRYPTO_ECDH_INVALID_PUBLIC_KEY, - ERR_INVALID_ARG_TYPE, -} from './internal_errors'; +import { ERR_CRYPTO_ECDH_INVALID_PUBLIC_KEY, ERR_INVALID_ARG_TYPE } from "./internal_errors"; -import { - validateInt32, -} from './validators'; +import { validateInt32 } from "./validators"; -import { - isArrayBufferView, - isAnyArrayBuffer -} from './internal_types'; +import { isArrayBufferView, isAnyArrayBuffer } from "./internal_types"; -import { - getArrayBufferOrView, - toBuf, - kHandle, -} from './crypto_util'; +import { getArrayBufferOrView, toBuf, kHandle } from "./crypto_util"; const DH_GENERATOR = 2; interface DiffieHellman { - [kHandle]: cryptoImpl.DiffieHellmanHandle; + [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' && +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; }; + !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; + [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; +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; + dhComputeSecret; DiffieHellmanGroup.prototype.getPrime = DiffieHellman.prototype.getPrime = dhGetPrime; -DiffieHellmanGroup.prototype.getGenerator = DiffieHellman.prototype.getGenerator = - dhGetGenerator; -DiffieHellmanGroup.prototype.getPublicKey = DiffieHellman.prototype.getPublicKey = - dhGetPublicKey; +DiffieHellmanGroup.prototype.getGenerator = DiffieHellman.prototype.getGenerator = dhGetGenerator; +DiffieHellmanGroup.prototype.getPublicKey = DiffieHellman.prototype.getPublicKey = dhGetPublicKey; DiffieHellmanGroup.prototype.getPrivateKey = DiffieHellman.prototype.getPrivateKey = - dhGetPrivateKey; + dhGetPrivateKey; DiffieHellman.prototype.setPublicKey = dhSetPublicKey; DiffieHellman.prototype.setPrivateKey = dhSetPrivateKey; -export {DiffieHellman, DiffieHellmanGroup}; +export { DiffieHellman, DiffieHellmanGroup }; -type DHLike = DiffieHellman|DiffieHellmanGroup; -function dhGenerateKeys(this: DHLike, encoding?: string): Buffer|string { - const keys = this[kHandle].generateKeys(); - return encode(keys, encoding); +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 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 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 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 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 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; + 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; + 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); +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 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); + return new DiffieHellmanGroup(name); } export function getDiffieHellman(name: string): DiffieHellmanGroup { - return createDiffieHellmanGroup(name); + 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 index 160fd63a6..296bd2013 100644 --- a/JS/wasm/crates/wasmjs-engine/shims/src/internal/crypto_hash.ts +++ b/JS/wasm/crates/wasmjs-engine/shims/src/internal/crypto_hash.ts @@ -1,235 +1,230 @@ /* eslint-disable */ -import * as cryptoImpl from './crypto'; +import * as cryptoImpl from "./crypto"; type ArrayLike = cryptoImpl.ArrayLike; -import { - kFinalized, - kHandle, - kState, - getArrayBufferOrView, - getStringOption, -} from './crypto_util'; +import { kFinalized, kHandle, kState, getArrayBufferOrView, getStringOption } from "./crypto_util"; -import { - Buffer -} from './internal_buffer'; +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'; + 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 { validateEncoding, validateString, validateUint32 } from "./validators"; -import { - normalizeEncoding -} from './internal_utils'; +import { normalizeEncoding } from "./internal_utils"; -import { - isArrayBufferView, - isCryptoKey, - isAnyArrayBuffer, -} from './internal_types'; +import { isArrayBufferView, isCryptoKey, isAnyArrayBuffer } from "./internal_types"; -import { - Transform, - TransformOptions, - TransformCallback, -} from './streams_transform'; +import { Transform, TransformOptions, TransformCallback } from "./streams_transform"; -import { - KeyObject, -} from './crypto_keys'; +import { KeyObject } from "./crypto_keys"; export interface HashOptions extends TransformOptions { - outputLength?: number; + outputLength?: number; } interface _kState { - [kFinalized]: boolean; + [kFinalized]: boolean; } interface Hash extends Transform { - [kHandle]: cryptoImpl.HashHandle; - [kState]: _kState; + [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); + 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); +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, + }; - 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; }; + 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(); +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); -} + 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._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._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.update = function ( + this: Hash | Hmac, + data: string | Buffer | ArrayBufferView, + encoding?: string +): Hash | Hmac { + encoding ??= "utf8"; + if (encoding === "buffer") { + encoding = undefined; + } -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; - } -} + 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; + [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)) { +export function createHmac( + hmac: string, + key: ArrayLike | KeyObject | CryptoKey, + options?: TransformOptions +): 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'); +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); } - 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'); + 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[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; }; + + 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.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}; +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 index 3c48a2849..7196bea89 100644 --- a/JS/wasm/crates/wasmjs-engine/shims/src/internal/crypto_hkdf.ts +++ b/JS/wasm/crates/wasmjs-engine/shims/src/internal/crypto_hkdf.ts @@ -1,124 +1,110 @@ /* eslint-disable */ -'use strict'; +"use strict"; -import * as cryptoImpl from './crypto'; +import * as cryptoImpl from "./crypto"; -import { - validateFunction, - validateInteger, - validateString, -} from './validators'; +import { validateFunction, validateInteger, validateString } from "./validators"; -import { - KeyObject, -} from './crypto_keys'; +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, - }; +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; + 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 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); +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 index aa549f57d..488d7b8d6 100644 --- a/JS/wasm/crates/wasmjs-engine/shims/src/internal/crypto_keys.ts +++ b/JS/wasm/crates/wasmjs-engine/shims/src/internal/crypto_keys.ts @@ -1,205 +1,220 @@ /* 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 { 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 { - arrayBufferToUnsignedBigInt, - kHandle, -} from './crypto_util'; + isAnyArrayBuffer, + isArrayBuffer, + isArrayBufferView, + isUint8Array, + // TODO(soon): Uncomment these once createPrivateKey/createPublicKey are implemented. + // isSharedArrayBuffer, +} from "./internal_types"; import { - isAnyArrayBuffer, - isArrayBuffer, - isArrayBufferView, - isUint8Array, - // TODO(soon): Uncomment these once createPrivateKey/createPublicKey are implemented. - // isSharedArrayBuffer, -} from './internal_types'; + 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 { - 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'; +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); + [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"); } - } - - 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); + + static from(key: CryptoKey): KeyObject { + if (!(key instanceof CryptoKey)) { + throw new ERR_INVALID_ARG_TYPE("key", "CryptoKey", key); } - if (!isUint8Array(opts.passphrase)) { - throw new ERR_INVALID_ARG_TYPE('options.passphrase', [ - 'string', 'Uint8Array' - ], opts.passphrase); + 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 + ); } - } } - 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); + 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; } - 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); + + 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]); } - return cryptoImpl.equals(this[kHandle], otherKeyObject[kHandle]); - } - abstract get type() : KeyObjectType; + 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); + get asymmetricKeyDetails(): AsymmetricKeyDetails { + let detail = cryptoImpl.getAsymmetricKeyDetail(this[kHandle]); + if (isArrayBuffer(detail.publicExponent)) { + detail.publicExponent = arrayBufferToUnsignedBigInt(detail.publicExponent as any); + } + return detail; } - return detail; - } - get asymmetricKeyType() : AsymmetricKeyType { - return cryptoImpl.getAsymmetricKeyType(this[kHandle]); - } + get asymmetricKeyType(): AsymmetricKeyType { + return cryptoImpl.getAsymmetricKeyType(this[kHandle]); + } } export class PublicKeyObject extends AsymmetricKeyObject { - override export(options?: PublicKeyExportOptions) : KeyExportResult { - return super.export(options); - } + override export(options?: PublicKeyExportOptions): KeyExportResult { + return super.export(options); + } - get type() : KeyObjectType { return 'public'; } + get type(): KeyObjectType { + return "public"; + } } export class PrivateKeyObject extends AsymmetricKeyObject { - override export(options?: PrivateKeyExportOptions) : KeyExportResult { - return super.export(options); - } + override export(options?: PrivateKeyExportOptions): KeyExportResult { + return super.export(options); + } - get type() : KeyObjectType { return 'private'; } + get type(): KeyObjectType { + return "private"; + } } export class SecretKeyObject extends KeyObject { - get symmetricKeySize() : number { - return (this[kHandle].algorithm as any).length | 0 - } + get symmetricKeySize(): number { + return (this[kHandle].algorithm as any).length | 0; + } - override export(options?: SecretKeyExportOptions) : KeyExportResult { - return super.export(options); - } + override export(options?: SecretKeyExportOptions): KeyExportResult { + return super.export(options); + } - get type() : KeyObjectType { return 'secret'; } + get type(): KeyObjectType { + return "secret"; + } } type ValidateKeyDataOptions = { - allowObject?: boolean; + 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); - } +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; +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 @@ -294,40 +309,41 @@ export function createSecretKey(key: KeyData, encoding?: string) : SecretKeyObje // 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 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 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; } // ====================================================================================== @@ -335,50 +351,56 @@ export function createPublicKey(_key: CreateAsymmetricKeyOptions | KeyData | Cry 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 type GenerateKeyPairCallback = ( + err?: any, + publicKey?: PublicKeyResult, + privateKey?: PrivateKeyResult +) => void; export interface KeyObjectPair { - publicKey: PublicKeyResult; - privateKey: PrivateKeyResult; + 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 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 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, + _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')); + 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'); + _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 index 40772a90c..3d575b53a 100644 --- a/JS/wasm/crates/wasmjs-engine/shims/src/internal/crypto_pbkdf2.ts +++ b/JS/wasm/crates/wasmjs-engine/shims/src/internal/crypto_pbkdf2.ts @@ -1,64 +1,85 @@ /* eslint-disable */ -'use strict'; +"use strict"; -import * as cryptoImpl from './crypto'; +import * as cryptoImpl from "./crypto"; type ArrayLike = cryptoImpl.ArrayLike; -export {ArrayLike}; +export { ArrayLike }; -import { - Buffer, -} from './internal_buffer'; +import { Buffer } from "./internal_buffer"; -import { - validateInt32, - validateFunction, - validateString, -} from './validators'; +import { validateInt32, validateFunction, validateString } from "./validators"; -import { - getArrayBufferOrView, -} from './crypto_util'; +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)); +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); + 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); +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"); } - }).then((val) => callback(null, Buffer.from(val)), (err) => callback(err)); + 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'); +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); + 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 }; + 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 index 64c0a58a1..ac49474c8 100644 --- a/JS/wasm/crates/wasmjs-engine/shims/src/internal/crypto_random.ts +++ b/JS/wasm/crates/wasmjs-engine/shims/src/internal/crypto_random.ts @@ -1,127 +1,126 @@ /* eslint-disable */ -import * as cryptoImpl from './crypto'; +import * as cryptoImpl from "./crypto"; import { - validateObject, - validateBoolean, - validateFunction, - validateInt32, - validateInteger, -} from './validators'; + validateObject, + validateBoolean, + validateFunction, + validateInt32, + validateInteger, +} from "./validators"; -import { - isAnyArrayBuffer, - isArrayBufferView -} from './internal_types'; +import { isAnyArrayBuffer, isArrayBufferView } from "./internal_types"; -import { - ERR_INVALID_ARG_TYPE, - ERR_OUT_OF_RANGE, -} from './internal_errors'; +import { ERR_INVALID_ARG_TYPE, ERR_OUT_OF_RANGE } from "./internal_errors"; -import { - Buffer, - kMaxLength -} from './internal_buffer'; +import { Buffer, kMaxLength } from "./internal_buffer"; -import { - arrayBufferToUnsignedBigInt, -} from './crypto_util'; +import { arrayBufferToUnsignedBigInt } from "./crypto_util"; -export type RandomBytesCallback = (err: any|null, buffer: Uint8Array) => void; +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 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, + 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); + 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)); +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; +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); @@ -129,282 +128,266 @@ 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; + 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); } - const x = randomCache.readUIntBE(randomCacheOffset, 6); - randomCacheOffset += 6; - if (x < randLimit) { - const n = (x % range) + min; - return n; + // 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. + 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 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'); + // 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(); + return crypto.randomUUID(); } export type PrimeNum = ArrayBuffer | ArrayBufferView | Buffer | bigint; export interface GeneratePrimeOptions { - add?: PrimeNum; - rem?: PrimeNum; - safe?: boolean; - bigint?: boolean; + add?: PrimeNum; + rem?: PrimeNum; + safe?: boolean; + bigint?: boolean; } export interface CheckPrimeOptions { - checks?: number; + checks?: number; } -export type GeneratePrimeCallback = (err?: any, prime?: bigint|ArrayBuffer) => void; +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); +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); + + 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, - } + + 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; + 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); +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 = {}; } - }).then((val) => callback!(null, val), (err) => callback!(err)); + 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); - } + 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'); + 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 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; +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); + 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); +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 = {}; } - }).then((val) => callback!(null, val), (err) => callback!(err)); + 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 index 5f52cdedc..9b268df0b 100644 --- a/JS/wasm/crates/wasmjs-engine/shims/src/internal/crypto_util.ts +++ b/JS/wasm/crates/wasmjs-engine/shims/src/internal/crypto_util.ts @@ -1,61 +1,48 @@ /* eslint-disable */ -'use strict'; +"use strict"; -import { - Buffer, -} from './internal_buffer'; +import { Buffer } from "./internal_buffer"; -import { - isAnyArrayBuffer, - isArrayBufferView, -} from './internal_types'; +import { isAnyArrayBuffer, isArrayBufferView } from "./internal_types"; -import { - ERR_INVALID_ARG_TYPE, -} from './internal_errors'; +import { ERR_INVALID_ARG_TYPE } from "./internal_errors"; -import { - validateString, -} from './validators'; +import { validateString } from "./validators"; -import * as cryptoImpl from './crypto'; +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 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; + 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'; +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); } - return Buffer.from(buffer, encoding); - } - if (!isArrayBufferView(buffer)) { - throw new ERR_INVALID_ARG_TYPE( - name, - [ - 'string', - 'ArrayBuffer', - 'Buffer', - 'TypedArray', - 'DataView', - ], - buffer, - ); - } - return buffer; + if (!isArrayBufferView(buffer)) { + throw new ERR_INVALID_ARG_TYPE( + name, + ["string", "ArrayBuffer", "Buffer", "TypedArray", "DataView"], + buffer + ); + } + return buffer; } /** @@ -71,48 +58,45 @@ export const numberToHexCharCode = (number: number): number => (number < 10 ? 48 * @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); - } + 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)}`); + 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'; +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 Buffer.from(val, encoding); - } - return val; + return val; } -export function validateByteSource(val: ArrayLike, - name: string): Buffer|ArrayBuffer|ArrayBufferView { - val = toBuf(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); + 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 index f7b92a65d..83f86114d 100644 --- a/JS/wasm/crates/wasmjs-engine/shims/src/internal/events.ts +++ b/JS/wasm/crates/wasmjs-engine/shims/src/internal/events.ts @@ -1,17 +1,12 @@ import { - AbortError, - ERR_INVALID_ARG_TYPE, - ERR_INVALID_THIS, - ERR_OUT_OF_RANGE, - ERR_UNHANDLED_ERROR, + 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 { validateAbortSignal, validateBoolean, validateFunction } from "./validators"; import * as process from "./process"; @@ -28,78 +23,76 @@ const kErrorMonitor = Symbol("events.errorMonitor"); const kMaxEventTargetListeners = Symbol("events.maxEventTargetListeners"); const kMaxEventTargetListenersWarned = Symbol("events.maxEventTargetListenersWarned"); - export interface EventEmitterOptions { - captureRejections? : boolean; -}; + captureRejections?: boolean; +} -export type EventName = string|symbol; +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; -}; + 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; +declare var EventTarget: Function; -export function EventEmitter(this : EventEmitter, opts? : EventEmitterOptions) { - EventEmitter.init.call(this, opts); +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; - } + #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); - } + #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; @@ -119,786 +112,777 @@ export const errorMonitor = EventEmitter.errorMonitor; export let defaultMaxListeners = 10; Object.defineProperties(EventEmitter, { - captureRejections: { - get() { - return EventEmitter.prototype[kCapture]; + captureRejections: { + get() { + return EventEmitter.prototype[kCapture]; + }, + set(value) { + validateBoolean(value, "EventEmitter.captureRejections"); + + EventEmitter.prototype[kCapture] = value; + }, + enumerable: true, }, - set(value) { - validateBoolean(value, "EventEmitter.captureRejections"); - - EventEmitter.prototype[kCapture] = value; + 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; + }, }, - enumerable: true, - }, - defaultMaxListeners: { - enumerable: true, - get: function () { - return defaultMaxListeners; + kMaxEventTargetListeners: { + value: kMaxEventTargetListeners, + enumerable: false, + configurable: false, + writable: false, }, - 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; + kMaxEventTargetListenersWarned: { + value: kMaxEventTargetListenersWarned, + enumerable: false, + configurable: false, + writable: false, }, - }, - 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, + 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]; - } +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, - ); - } +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 addCatch(that: any, promise: Promise, type: string | symbol, args: any[]) { + if (!that[kCapture]) { + return; + } -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. + // Handle Promises/A+ spec, then could be a getter + // that throws on second use. try { - ee[kCapture] = false; - ee.emit("error", err); - } finally { - ee[kCapture] = prev; + 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; +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; +function _getMaxListeners(that: any) { + if (that._maxListeners === undefined) { + return (EventEmitter as any).defaultMaxListeners; + } + return that._maxListeners; } EventEmitter.prototype.getMaxListeners = function getMaxListeners() { - return _getMaxListeners(this); + return _getMaxListeners(this); }; -EventEmitter.prototype.emit = function emit(type : string | symbol, ...args: any[]) { - let doError = type === "error"; +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; + } - const events = this._events; - if (events !== undefined) { - if (doError && events[kErrorMonitor] !== undefined) { - this.emit(kErrorMonitor, ...args); + // 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 } - 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]; + const handler = events[type]; + + if (handler === undefined) { + return false; } - 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 + 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); + } + } } - 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; + 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); +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 { - 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; + 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.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, + type: string | symbol, + listener: unknown ) { - return _addListener(this, type, listener, true); + 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); + 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); } - 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; +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"); +EventEmitter.prototype.once = function once(type: string | symbol, listener: unknown) { + validateFunction(listener, "listener"); - this.on(type, _onceWrap(this, type, listener)); - return this; + this.on(type, _onceWrap(this, type, listener)); + return this; }; EventEmitter.prototype.prependOnceListener = function prependOnceListener( - type : string | symbol, - listener : unknown, + type: string | symbol, + listener: unknown ) { - validateFunction(listener, "listener"); + validateFunction(listener, "listener"); - this.prependListener(type, _onceWrap(this, type, listener)); - return this; + this.prependListener(type, _onceWrap(this, type, listener)); + return this; }; EventEmitter.prototype.removeListener = function removeListener( - type : string | symbol, - listener : unknown, + 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; - } + validateFunction(listener, "listener"); - 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); + const events = this._events; + if (events === undefined) { + return this; } - if (list.length === 1) { - events[type] = list[0]; + const list = events[type]; + if (list === undefined) { + return this; } - if (events.removeListener !== undefined) { - this.emit("removeListener", type, listener); + 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; + 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; - } +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]; - } + // 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; } - 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); + // 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; } - this.removeAllListeners("removeListener"); - this._events = Object.create(null); - this._eventsCount = 0; - return this; - } - const listeners = events[type]; + 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]); + 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; + return this; }; -function _listeners(target : any, type : string | symbol, unwrap : boolean) { - const events = target._events; +function _listeners(target: any, type: string | symbol, unwrap: boolean) { + const events = target._events; - if (events === undefined) { - return []; - } + if (events === undefined) { + return []; + } - const evlistener = events[type]; - if (evlistener === undefined) { - return []; - } + const evlistener = events[type]; + if (evlistener === undefined) { + return []; + } - if (typeof evlistener === "function") { - return unwrap ? [evlistener.listener || evlistener] : [evlistener]; - } + if (typeof evlistener === "function") { + return unwrap ? [evlistener.listener || evlistener] : [evlistener]; + } - return unwrap ? unwrapListeners(evlistener) : arrayClone(evlistener); + return unwrap ? unwrapListeners(evlistener) : arrayClone(evlistener); } -EventEmitter.prototype.listeners = function listeners(type : string | symbol) { - return _listeners(this, type, true); +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); +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; +const _listenerCount = function listenerCount(this: any, type: string | symbol) { + const events = this._events; - if (events !== undefined) { - const evlistener = events[type]; + if (events !== undefined) { + const evlistener = events[type]; - if (typeof evlistener === "function") { - return 1; - } else if (evlistener !== undefined) { - return evlistener.length; + if (typeof evlistener === "function") { + return 1; + } else if (evlistener !== undefined) { + return evlistener.length; + } } - } - return 0; + 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); +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) : []; + 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 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; +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; + 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 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; -}; + 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); +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(); } - function abortListener() { - eventTargetAgnosticRemoveListener(emitter, name, resolver); - eventTargetAgnosticRemoveListener(emitter, "error", errorListener); - reject(new AbortError()); - } - if (signal != null) { - eventTargetAgnosticAddListener( - signal, - "abort", - abortListener, - { once: true }, - ); - } - }); + 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, + Object.getPrototypeOf(async function* () {}).prototype ); function createIterResult(value: any, done: boolean) { - return { value, done }; + 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); - } +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; + 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); +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 { - 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); - } + throw new ERR_INVALID_ARG_TYPE("emitter", "EventEmitter", emitter); + } } interface OnOptions { - signal?: AbortSignal; + 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)); - } +export function on(emitter: any, event: string | symbol, options: OnOptions = {}) { + const signal = options?.signal; + validateAbortSignal(signal, "options.signal"); + if (signal?.aborted) { + throw new AbortError(); + } - return Promise.resolve(createIterResult(undefined, true)); - }, + 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 + ); - 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); - }, + eventTargetAgnosticAddListener(emitter, event, eventHandler); + if (event !== "error" && typeof emitter.on === "function") { + emitter.on("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 }, - ); - } + if (signal) { + eventTargetAgnosticAddListener(signal, "abort", abortListener, { once: true }); + } - return iterator; + return iterator; - function abortListener() { - errorHandler(new AbortError()); - } + 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 eventHandler(...args: any[]) { + const promise = unconsumedPromises.shift(); + if (promise) { + promise.resolve(createIterResult(args, false)); + } else { + unconsumedEvents.push(args); + } } - } - function errorHandler(err : any) { - finished = true; + function errorHandler(err: any) { + finished = true; - const toError = unconsumedPromises.shift(); + const toError = unconsumedPromises.shift(); - if (toError) { - toError.reject(err); - } else { - // The next time we call next() - error = err; - } + if (toError) { + toError.reject(err); + } else { + // The next time we call next() + error = err; + } - iterator.return(); - } + 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 index 1b3d68e8f..e2487edc5 100644 --- a/JS/wasm/crates/wasmjs-engine/shims/src/internal/internal_buffer.ts +++ b/JS/wasm/crates/wasmjs-engine/shims/src/internal/internal_buffer.ts @@ -1,4 +1,3 @@ - import { ERR_BUFFER_OUT_OF_BOUNDS, ERR_OUT_OF_RANGE, @@ -6,29 +5,18 @@ import { ERR_INVALID_ARG_VALUE, ERR_INVALID_BUFFER_SIZE, ERR_UNKNOWN_ENCODING, -} from './internal_errors'; +} from "./internal_errors"; -import * as bufferUtil from './buffer'; +import * as bufferUtil from "./buffer"; -import { - isAnyArrayBuffer, - isArrayBufferView, - isUint8Array, -} from './internal_types'; +import { isAnyArrayBuffer, isArrayBufferView, isUint8Array } from "./internal_types"; -import { - normalizeEncoding, -} from './internal_utils'; +import { normalizeEncoding } from "./internal_utils"; -import { - validateString, -} from './validators'; +import { validateString } from "./validators"; -import * as internalUtil from './util'; -import { - InspectOptionsStylized, - inspect as utilInspect, -} from './internal_inspect'; +import * as internalUtil from "./util"; +import { InspectOptionsStylized, inspect as utilInspect } from "./internal_inspect"; // Temporary buffers to convert numbers. const float32Array = new Float32Array(1); @@ -47,7 +35,7 @@ export const bigEndian = uInt8Float32Array[3] === 0; export const kMaxLength = 2147483647; export const kStringMaxLength = 536870888; const MAX_UINT32 = 2 ** 32; -const kIsBuffer = Symbol('kIsBuffer'); +const kIsBuffer = Symbol("kIsBuffer"); const customInspectSymbol = typeof Symbol === "function" && typeof Symbol["for"] === "function" @@ -61,34 +49,38 @@ export const constants = { MAX_STRING_LENGTH: kStringMaxLength, }; -function createBuffer(length: number) : Buffer { +function createBuffer(length: number): Buffer { if (length > kMaxLength) { - throw new ERR_OUT_OF_RANGE('The given length is invalid', `0 to ${kMaxLength}`, length); + 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; +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; + 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; @@ -106,32 +98,32 @@ export interface Buffer extends Uint8Array { 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; + 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[]}; + 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; @@ -158,26 +150,29 @@ export interface Buffer extends Uint8Array { 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 (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; +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 { +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); @@ -202,7 +197,7 @@ Object.defineProperties(Buffer, { enumerable: true, value: 0, writable: false, - } + }, }); Object.defineProperties(Buffer.prototype, { @@ -231,21 +226,26 @@ Object.defineProperties(Buffer.prototype, { }, }); -function _from(value: BufferSource, - encodingOrOffset? : string|number, - length?: number) : Buffer { +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; + 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")) { + if ( + valueOf != null && + valueOf !== value && + (typeof valueOf === "string" || typeof valueOf === "object") + ) { return _from(valueOf as BufferSource, encodingOrOffset, length); } @@ -279,23 +279,22 @@ function _from(value: BufferSource, "ArrayBuffer", "SharedArrayBuffer", "Array", - "Array-like Object" + "Array-like Object", ], - value, + 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) { +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 === "") { @@ -308,20 +307,21 @@ function fromString(string: StringLike, encoding?: string) { 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}`); + 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) { +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) { +function fromArrayBuffer(obj: ArrayBufferLike, byteOffset: number, length?: number) { // Convert byteOffset to integer if (byteOffset === undefined) { byteOffset = 0; @@ -361,17 +361,16 @@ 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]!; + 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 { +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); + throw new ERR_INVALID_ARG_VALUE.RangeError("size", size); } if (size >= kMaxLength) { throw new ERR_OUT_OF_RANGE("size", `0 to ${kMaxLength}`, size); @@ -380,7 +379,7 @@ function alloc(size: number, fill?: FillValue, encoding?: string) : Buffer { const buffer = createBuffer(size); if (fill !== undefined) { if (encoding !== undefined) { - validateString(encoding, 'encoding'); + validateString(encoding, "encoding"); } return buffer.fill(fill as any, encoding); } @@ -389,7 +388,7 @@ function alloc(size: number, fill?: FillValue, encoding?: string) : Buffer { Buffer.alloc = alloc; -function allocUnsafe(size: number) : Buffer { +function allocUnsafe(size: number): Buffer { return alloc(size); } @@ -407,7 +406,7 @@ 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) { +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); @@ -417,10 +416,10 @@ export function compare(a: Buffer|Uint8Array, b: Buffer|Uint8Array) { b = fromArrayBuffer(buf.buffer, buf.byteOffset, buf.byteLength); } if (!Buffer.isBuffer(a)) { - throw new ERR_INVALID_ARG_TYPE('a', ['Buffer', 'Uint8Array'], typeof 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); + throw new ERR_INVALID_ARG_TYPE("b", ["Buffer", "Uint8Array"], typeof b); } if (a === b) return 0; @@ -430,14 +429,16 @@ export function compare(a: Buffer|Uint8Array, b: Buffer|Uint8Array) { Buffer.compare = compare; export function isEncoding(encoding: unknown) { - return typeof encoding === "string" && + return ( + typeof encoding === "string" && encoding.length !== 0 && - normalizeEncoding(encoding) !== undefined; + normalizeEncoding(encoding) !== undefined + ); } Buffer.isEncoding = isEncoding; -Buffer.concat = function concat(list: (Buffer|Uint8Array)[], length?: number) { +Buffer.concat = function concat(list: (Buffer | Uint8Array)[], length?: number) { if (!Array.isArray(list)) { throw new ERR_INVALID_ARG_TYPE("list", "(Buffer|Uint8Array)[]", list); } @@ -450,7 +451,7 @@ Buffer.concat = function concat(list: (Buffer|Uint8Array)[], length?: number) { if (list[i]!.length !== undefined) { length += list[i]!.length; } else { - throw new ERR_INVALID_ARG_TYPE('list', '(Buffer|Uint8Array)[]', list[i]); + throw new ERR_INVALID_ARG_TYPE("list", "(Buffer|Uint8Array)[]", list[i]); } } } @@ -464,15 +465,17 @@ function base64ByteLength(str: string) { let len = str.length; if (str.charCodeAt(len - 1) === 0x3d) { len--; - } if (len > 1 && 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) { +function byteLength( + string: string | ArrayBufferView | ArrayBuffer | SharedArrayBuffer, + encoding?: string +) { if (typeof string !== "string") { if (isArrayBufferView(string) || isAnyArrayBuffer(string)) { return string.byteLength; @@ -488,19 +491,19 @@ function byteLength(string: string|ArrayBufferView|ArrayBuffer|SharedArrayBuffer } switch (normalizedEncoding) { - case 'ascii': + case "ascii": // Fall through - case 'latin1': + case "latin1": return (string as string).length; - case 'utf16le': + case "utf16le": return (string as string).length * 2; - case 'base64': + case "base64": // Fall through - case 'base64url': + case "base64url": return base64ByteLength(string as string); - case 'hex': + case "hex": return (string as string).length >>> 1; - case 'utf8': + case "utf8": // Fall-through default: return bufferUtil.byteLength(string as string, normalizedEncoding as string); @@ -536,10 +539,7 @@ Buffer.prototype.swap64 = function swap64() { return this; }; -Buffer.prototype.toString = function toString( - encoding?: string, - start?: number, - end?: number) { +Buffer.prototype.toString = function toString(encoding?: string, start?: number, end?: number) { if (arguments.length === 0) { return bufferUtil.toString(this, 0, this.length, "utf8"); } @@ -574,31 +574,31 @@ Buffer.prototype.toString = function toString( Buffer.prototype.toLocaleString = Buffer.prototype.toString; -Buffer.prototype.equals = function equals(b: Buffer|Uint8Array) { +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(); + 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' : ''}`; + 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]; - }); + internalUtil.getOwnNonIndexProperties(this, filter).forEach((key) => { + extras = true; + obj[key] = this[key]; + }); if (extras) { - if (this.length !== 0) - str += ', '; + if (this.length !== 0) str += ", "; // '[Object: null prototype] {'.length === 26 // This is guarded with a test. str += utilInspect(obj, { @@ -616,11 +616,11 @@ if (customInspectSymbol) { } Buffer.prototype.compare = function compare( - target: Buffer|Uint8Array, + target: Buffer | Uint8Array, start?: number, end?: number, thisStart?: number, - thisEnd?: number, + thisEnd?: number ) { if (isInstance(target, Uint8Array)) { target = fromArrayBuffer(target.buffer, target.byteOffset, target.byteLength); @@ -663,15 +663,15 @@ Buffer.prototype.compare = function compare( function includes( this: Buffer, - val: string|number|Buffer|Uint8Array, + val: string | number | Buffer | Uint8Array, byteOffset?: number, - encoding?: string) { + 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`. // @@ -683,32 +683,32 @@ Buffer.prototype.includes = includes; // - 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) { - + 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); + throw new ERR_INVALID_ARG_TYPE("val", ["string", "number", "Buffer", "Uint8Array"], val); } - if (typeof byteOffset === 'string') { + if (typeof byteOffset === "string") { encoding = byteOffset; byteOffset = undefined; - } else if (byteOffset as number > 0x7fffffff) { + } else if ((byteOffset as number) > 0x7fffffff) { byteOffset = 0x7fffffff; - } else if (byteOffset as number < -0x80000000) { + } 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); + byteOffset = dir ? 0 : buffer.length || buffer.byteLength; } - dir = !!dir; // Cast to bool. + dir = !!dir; // Cast to bool. - if (typeof val === 'number') { + if (typeof val === "number") { val = (val >>> 0) & 0xff; if (dir) { return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset); @@ -717,8 +717,8 @@ function bidirectionalIndexOf( } } - if (typeof val !== 'string' && !isUint8Array(val) && !Buffer.isBuffer(val)) { - throw new ERR_INVALID_ARG_TYPE('value', ['number', 'string', 'Buffer', 'Uint8Array'], val); + 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); @@ -731,160 +731,173 @@ function bidirectionalIndexOf( } Buffer.prototype.indexOf = function indexOf( - val: string|number|Buffer|Uint8Array, - byteOffset?: number|string, - encoding?: string) { + 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) { + 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'); + 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'); + 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'); + 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'); + return bufferUtil.toString(this, offset, offset + length, "hex"); }; -Buffer.prototype.latin1Slice = function latin1Slice(offset: number, - length: number) { +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'); + 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'); + 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'); + return bufferUtil.toString(this, offset, offset + length, "utf8"); }; -Buffer.prototype.asciiWrite = function asciiWrite(string: StringLike, - offset?: number, - length?: number) { +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'); + return bufferUtil.write(this, `${string}`, offset as number, length as number, "ascii"); }; -Buffer.prototype.base64Write = function base64Write(string: StringLike, - offset?: number, - length?: number) { +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'); + return bufferUtil.write(this, `${string}`, offset as number, length as number, "base64"); }; -Buffer.prototype.base64urlWrite = function base64urlWrite(string: StringLike, - offset?: number, - length?: number) { +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'); + return bufferUtil.write(this, `${string}`, offset as number, length as number, "base64url"); }; -Buffer.prototype.hexWrite = function hexWrite(string: StringLike, - offset: number, - length: number) { +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'); + return bufferUtil.write(this, `${string}`, offset as number, length as number, "hex"); }; -Buffer.prototype.latin1Write = function latin1Write(string: StringLike, - offset: number, - length: number) { +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'); + return bufferUtil.write(this, `${string}`, offset as number, length as number, "latin1"); }; -Buffer.prototype.ucs2Write = function ucs2Write(string: StringLike, - offset: number, - length: number) { +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'); + return bufferUtil.write(this, `${string}`, offset as number, length as number, "utf16le"); }; -Buffer.prototype.utf8Write = function utf8Write(string: StringLike, - offset: number, - length: number) { +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'); + 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) { +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') { + 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); + 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') { + } else if (typeof length === "string") { encoding = length; length = remaining; } else { - validateOffset(length, 'length', 0, this.length); + validateOffset(length, "length", 0, this.length); if (length > remaining) { length = remaining; } @@ -900,8 +913,13 @@ Buffer.prototype.write = function write(string: StringLike, throw new ERR_UNKNOWN_ENCODING(encoding as string); } - return bufferUtil.write(this, string as string, offset as number, length as number, - normalizedEncoding as string); + return bufferUtil.write( + this, + string as string, + offset as number, + length as number, + normalizedEncoding as string + ); }; Buffer.prototype.toJSON = function toJSON() { @@ -943,17 +961,24 @@ Buffer.prototype.slice = function slice(start: number, end?: number) { Buffer.prototype.readUintLE = Buffer.prototype.readUIntLE = function readUIntLE( offset: number, - byteLength: 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); + 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"); } @@ -961,24 +986,30 @@ Buffer.prototype.readUintLE = Buffer.prototype.readUIntLE = function readUIntLE( Buffer.prototype.readUintBE = Buffer.prototype.readUIntBE = function readUIntBE( offset: number, - byteLength: 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); + 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) { +Buffer.prototype.readUint8 = Buffer.prototype.readUInt8 = function readUInt8(offset: number = 0) { validateOffset(offset, "offset", 0, this.length); const val = this[offset]; if (val === undefined) { @@ -990,104 +1021,110 @@ Buffer.prototype.readUint8 = Buffer.prototype.readUInt8 = function readUInt8( 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); - } +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 + last * 2 ** 8; +}; - return first + - this[++offset]! * 2 ** 8 + - this[++offset]! * 2 ** 16 + - last * 2 ** 24; - }; +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, +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); + 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) { +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); + 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"); } @@ -1100,7 +1137,7 @@ Buffer.prototype.readInt8 = function readInt8(offset: number = 0) { boundsError(offset, this.length - 1); } - return val | (val & 2 ** 7) * 0x1fffffe; + return val | ((val & (2 ** 7)) * 0x1fffffe); }; Buffer.prototype.readInt16LE = function readInt16LE(offset: number = 0) { @@ -1112,7 +1149,7 @@ Buffer.prototype.readInt16LE = function readInt16LE(offset: number = 0) { } const val = first + last * 2 ** 8; - return val | (val & 2 ** 15) * 0x1fffe; + return val | ((val & (2 ** 15)) * 0x1fffe); }; Buffer.prototype.readInt16BE = function readInt16BE(offset: number = 0) { @@ -1124,7 +1161,7 @@ Buffer.prototype.readInt16BE = function readInt16BE(offset: number = 0) { } const val = first * 2 ** 8 + last; - return val | (val & 2 ** 15) * 0x1fffe; + return val | ((val & (2 ** 15)) * 0x1fffe); }; Buffer.prototype.readInt32LE = function readInt32LE(offset: number = 0) { @@ -1135,10 +1172,7 @@ Buffer.prototype.readInt32LE = function readInt32LE(offset: number = 0) { boundsError(offset, this.length - 4); } - return first + - this[++offset] * 2 ** 8 + - this[++offset] * 2 ** 16 + - (last << 24); // Overflow + return first + this[++offset] * 2 ** 8 + this[++offset] * 2 ** 16 + (last << 24); // Overflow }; Buffer.prototype.readInt32BE = function readInt32BE(offset: number = 0) { @@ -1149,10 +1183,12 @@ Buffer.prototype.readInt32BE = function readInt32BE(offset: number = 0) { boundsError(offset, this.length - 4); } - return (first << 24) + // Overflow + return ( + (first << 24) + // Overflow this[++offset] * 2 ** 16 + this[++offset] * 2 ** 8 + - last; + last + ); }; Buffer.prototype.readBigInt64LE = function readBigInt64LE(this: Buffer, offset: number = 0) { @@ -1163,13 +1199,14 @@ Buffer.prototype.readBigInt64LE = function readBigInt64LE(this: Buffer, offset: 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)) + + 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, - ); + first + this[++offset]! * 2 ** 8 + this[++offset]! * 2 ** 16 + this[++offset]! * 2 ** 24 + ) + ); }; Buffer.prototype.readBigInt64BE = function readBigInt64BE(this: Buffer, offset: number = 0) { @@ -1180,106 +1217,114 @@ Buffer.prototype.readBigInt64BE = function readBigInt64BE(this: Buffer, offset: 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)) + + 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, - ); + 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); + return bigEndian ? readFloatBackwards(this, offset) : readFloatForwards(this, offset); }; Buffer.prototype.readFloatBE = function readFloatBE(offset: number = 0) { - return bigEndian - ? readFloatForwards(this, offset) - : readFloatBackwards(this, offset); + return bigEndian ? readFloatForwards(this, offset) : readFloatBackwards(this, offset); }; Buffer.prototype.readDoubleLE = function readDoubleLE(offset: number = 0) { - return bigEndian - ? readDoubleBackwards(this, offset) - : readDoubleForwards(this, offset); + 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"); - } - }; + 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, + 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.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.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.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); - }; +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) { +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; @@ -1289,7 +1334,7 @@ function wrtBigUInt64LE( buf[offset++] = lo; lo = lo >> 8; buf[offset++] = lo; - let hi = Number(value >> BigInt(32) & BigInt(4294967295)); + let hi = Number((value >> BigInt(32)) & BigInt(4294967295)); buf[offset++] = hi; hi = hi >> 8; buf[offset++] = hi; @@ -1300,12 +1345,7 @@ function wrtBigUInt64LE( return offset; } -function wrtBigUInt64BE( - buf: Buffer, - value: bigint, - offset: number, - min: bigint, - max: bigint) { +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; @@ -1315,7 +1355,7 @@ function wrtBigUInt64BE( buf[offset + 5] = lo; lo = lo >> 8; buf[offset + 4] = lo; - let hi = Number(value >> BigInt(32) & BigInt(4294967295)); + let hi = Number((value >> BigInt(32)) & BigInt(4294967295)); buf[offset + 3] = hi; hi = hi >> 8; buf[offset + 2] = hi; @@ -1326,29 +1366,40 @@ function wrtBigUInt64BE( 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.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.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); + 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"); } @@ -1357,14 +1408,21 @@ Buffer.prototype.writeIntLE = function writeIntLE( 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); + 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"); } @@ -1378,10 +1436,7 @@ Buffer.prototype.writeInt16LE = function writeInt16LE(value: number, offset: num return writeU_Int16LE(this, value, offset, -0x8000, 0x7fff); }; -Buffer.prototype.writeInt16BE = function writeInt16BE( - value: number, - offset: number = 0, -) { +Buffer.prototype.writeInt16BE = function writeInt16BE(value: number, offset: number = 0) { return writeU_Int16BE(this, value, offset, -0x8000, 0x7fff); }; @@ -1393,57 +1448,51 @@ Buffer.prototype.writeInt32BE = function writeInt32BE(value: number, offset: num 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.writeBigInt64LE = function writeBigInt64LE( + this: Buffer, + value: bigint, + offset: number = 0 +) { + return wrtBigUInt64LE(this, value, offset, -0x8000000000000000n, 0x7fffffffffffffffn); +}; -Buffer.prototype.writeFloatLE = function writeFloatLE( - value: number, - offset: number, +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, -) { +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, -) { +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, -) { +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, + target: Buffer | Uint8Array, targetStart?: number, sourceStart?: number, - sourceEnd?: number, + sourceEnd?: number ) { if (!isUint8Array(target)) { throw new ERR_INVALID_ARG_TYPE("target", ["Buffer", "Uint8Array"], target); @@ -1505,11 +1554,12 @@ Buffer.prototype.copy = function copy( }; Buffer.prototype.fill = function fill( - val: string|number|Buffer|Uint8Array, - start?: number|string, + val: string | number | Buffer | Uint8Array, + start?: number | string, end?: number, - encoding?: string) { - let normalizedEncoding : string | undefined; + encoding?: string +) { + let normalizedEncoding: string | undefined; if (typeof val === "string") { if (typeof start === "string") { encoding = start; @@ -1525,24 +1575,24 @@ Buffer.prototype.fill = function fill( } if (val.length === 1) { const code = val.charCodeAt(0); - if (encoding === "utf8" && code < 128 || encoding === "latin1") { + if ((encoding === "utf8" && code < 128) || encoding === "latin1") { val = code; } } } if (start !== undefined) { - validateNumber(start, 'start'); + validateNumber(start, "start"); } if (end !== undefined) { - validateNumber(end, 'end'); + 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); + 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); + throw new ERR_OUT_OF_RANGE("start", "0 to end", start); } if ((end as number) <= (start as number)) { return this; @@ -1551,17 +1601,19 @@ Buffer.prototype.fill = function fill( end = end === void 0 ? this.length : end >>> 0; if (typeof val === "string") { - bufferUtil.fillImpl(this, + bufferUtil.fillImpl( + this, val as string, start as number, end as number, - normalizedEncoding); + normalizedEncoding + ); return this; } if (isArrayBufferView(val)) { if ((val as ArrayBufferView).byteLength === 0) { - throw new ERR_INVALID_ARG_VALUE('value', 'zero-length'); + throw new ERR_INVALID_ARG_VALUE("value", "zero-length"); } bufferUtil.fillImpl(this, val as ArrayBufferView, start as number, end as number); return this; @@ -1579,10 +1631,7 @@ Buffer.prototype.fill = function fill( return this; }; -function checkBounds( - buf: Buffer, - offset: number, - byteLength2: number) { +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)); @@ -1590,12 +1639,13 @@ function checkBounds( } function checkIntBI( - value: bigint|number, - min: bigint|number, - max: bigint|number, + value: bigint | number, + min: bigint | number, + max: bigint | number, buf: Buffer, offset: number, - byteLength2: number) { + byteLength2: number +) { if (value > max || value < min) { const n = typeof min === "bigint" ? "n" : ""; let range; @@ -1616,13 +1666,16 @@ function checkIntBI( } 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; + 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) { +function readUInt48LE(buf: Buffer | Uint8Array, offset: number = 0) { validateOffset(offset, "offset", 0, buf.length); const first = buf[offset]; const last = buf[offset + 5]; @@ -1630,14 +1683,16 @@ function readUInt48LE(buf: Buffer|Uint8Array, offset: number = 0) { boundsError(offset, buf.length - 6); } - return first + + return ( + first + buf[++offset]! * 2 ** 8 + buf[++offset]! * 2 ** 16 + buf[++offset]! * 2 ** 24 + - (buf[++offset]! + last * 2 ** 8) * 2 ** 32; + (buf[++offset]! + last * 2 ** 8) * 2 ** 32 + ); } -function readUInt40LE(buf: Buffer|Uint8Array, offset: number = 0) { +function readUInt40LE(buf: Buffer | Uint8Array, offset: number = 0) { validateOffset(offset, "offset", 0, buf.length); const first = buf[offset]; const last = buf[offset + 4]; @@ -1645,14 +1700,16 @@ function readUInt40LE(buf: Buffer|Uint8Array, offset: number = 0) { boundsError(offset, buf.length - 5); } - return first + + return ( + first + buf[++offset]! * 2 ** 8 + buf[++offset]! * 2 ** 16 + buf[++offset]! * 2 ** 24 + - last * 2 ** 32; + last * 2 ** 32 + ); } -function readUInt24LE(buf: Buffer|Uint8Array, offset: number = 0) { +function readUInt24LE(buf: Buffer | Uint8Array, offset: number = 0) { validateOffset(offset, "offset", 0, buf.length); const first = buf[offset]; const last = buf[offset + 2]; @@ -1663,7 +1720,7 @@ function readUInt24LE(buf: Buffer|Uint8Array, offset: number = 0) { return first + buf[++offset]! * 2 ** 8 + last * 2 ** 16; } -function readUInt48BE(buf: Buffer|Uint8Array, offset: number = 0) { +function readUInt48BE(buf: Buffer | Uint8Array, offset: number = 0) { validateOffset(offset, "offset", 0, buf.length); const first = buf[offset]; const last = buf[offset + 5]; @@ -1671,14 +1728,16 @@ function readUInt48BE(buf: Buffer|Uint8Array, offset: number = 0) { boundsError(offset, buf.length - 6); } - return (first * 2 ** 8 + buf[++offset]!) * 2 ** 32 + + return ( + (first * 2 ** 8 + buf[++offset]!) * 2 ** 32 + buf[++offset]! * 2 ** 24 + buf[++offset]! * 2 ** 16 + buf[++offset]! * 2 ** 8 + - last; + last + ); } -function readUInt40BE(buf: Buffer|Uint8Array, offset: number = 0) { +function readUInt40BE(buf: Buffer | Uint8Array, offset: number = 0) { validateOffset(offset, "offset", 0, buf.length); const first = buf[offset]; const last = buf[offset + 4]; @@ -1686,14 +1745,16 @@ function readUInt40BE(buf: Buffer|Uint8Array, offset: number = 0) { boundsError(offset, buf.length - 5); } - return first * 2 ** 32 + + return ( + first * 2 ** 32 + buf[++offset]! * 2 ** 24 + buf[++offset]! * 2 ** 16 + buf[++offset]! * 2 ** 8 + - last; + last + ); } -function readUInt24BE(buf: Buffer|Uint8Array, offset: number = 0) { +function readUInt24BE(buf: Buffer | Uint8Array, offset: number = 0) { validateOffset(offset, "offset", 0, buf.length); const first = buf[offset]; const last = buf[offset + 2]; @@ -1723,13 +1784,10 @@ function readUInt32BE(this: Buffer, offset: number = 0) { boundsError(offset, this.length - 4); } - return first * 2 ** 24 + - this[++offset]! * 2 ** 16 + - this[++offset]! * 2 ** 8 + - last; + return first * 2 ** 24 + this[++offset]! * 2 ** 16 + this[++offset]! * 2 ** 8 + last; } -function readDoubleBackwards(buffer: Buffer|Uint8Array, offset: number = 0) { +function readDoubleBackwards(buffer: Buffer | Uint8Array, offset: number = 0) { validateOffset(offset, "offset", 0, buffer.length); const first = buffer[offset]; const last = buffer[offset + 7]; @@ -1748,7 +1806,7 @@ function readDoubleBackwards(buffer: Buffer|Uint8Array, offset: number = 0) { return float64Array[0]; } -function readDoubleForwards(buffer: Buffer|Uint8Array, offset: number = 0) { +function readDoubleForwards(buffer: Buffer | Uint8Array, offset: number = 0) { validateOffset(offset, "offset", 0, buffer.length); const first = buffer[offset]; const last = buffer[offset + 7]; @@ -1767,7 +1825,7 @@ function readDoubleForwards(buffer: Buffer|Uint8Array, offset: number = 0) { return float64Array[0]; } -function writeDoubleForwards(buffer: Buffer|Uint8Array, val: number, offset: number = 0) { +function writeDoubleForwards(buffer: Buffer | Uint8Array, val: number, offset: number = 0) { val = +val; checkBounds(buffer as any, offset, 7); @@ -1783,7 +1841,7 @@ function writeDoubleForwards(buffer: Buffer|Uint8Array, val: number, offset: num return offset; } -function writeDoubleBackwards(buffer: Buffer|Uint8Array, val: number, offset: number = 0) { +function writeDoubleBackwards(buffer: Buffer | Uint8Array, val: number, offset: number = 0) { val = +val; checkBounds(buffer as any, offset, 7); @@ -1799,7 +1857,7 @@ function writeDoubleBackwards(buffer: Buffer|Uint8Array, val: number, offset: nu return offset; } -function readFloatBackwards(buffer: Buffer|Uint8Array, offset: number = 0) { +function readFloatBackwards(buffer: Buffer | Uint8Array, offset: number = 0) { validateOffset(offset, "offset", 0, buffer.length); const first = buffer[offset]; const last = buffer[offset + 3]; @@ -1814,7 +1872,7 @@ function readFloatBackwards(buffer: Buffer|Uint8Array, offset: number = 0) { return float32Array[0]; } -function readFloatForwards(buffer: Buffer|Uint8Array, offset: number = 0) { +function readFloatForwards(buffer: Buffer | Uint8Array, offset: number = 0) { validateOffset(offset, "offset", 0, buffer.length); const first = buffer[offset]; const last = buffer[offset + 3]; @@ -1829,7 +1887,7 @@ function readFloatForwards(buffer: Buffer|Uint8Array, offset: number = 0) { return float32Array[0]; } -function writeFloatForwards(buffer: Buffer|Uint8Array, val: number, offset: number = 0) { +function writeFloatForwards(buffer: Buffer | Uint8Array, val: number, offset: number = 0) { val = +val; checkBounds(buffer as any, offset, 3); @@ -1841,7 +1899,7 @@ function writeFloatForwards(buffer: Buffer|Uint8Array, val: number, offset: numb return offset; } -function writeFloatBackwards(buffer: Buffer|Uint8Array, val: number, offset: number = 0) { +function writeFloatBackwards(buffer: Buffer | Uint8Array, val: number, offset: number = 0) { val = +val; checkBounds(buffer as any, offset, 3); @@ -1853,7 +1911,7 @@ function writeFloatBackwards(buffer: Buffer|Uint8Array, val: number, offset: num return offset; } -function readInt24LE(buf: Buffer|Uint8Array, offset: number = 0) { +function readInt24LE(buf: Buffer | Uint8Array, offset: number = 0) { validateOffset(offset, "offset", 0, buf.length); const first = buf[offset]; const last = buf[offset + 2]; @@ -1862,10 +1920,10 @@ function readInt24LE(buf: Buffer|Uint8Array, offset: number = 0) { } const val = first + buf[++offset]! * 2 ** 8 + last * 2 ** 16; - return val | (val & 2 ** 23) * 0x1fe; + return val | ((val & (2 ** 23)) * 0x1fe); } -function readInt40LE(buf: Buffer|Uint8Array, offset: number = 0) { +function readInt40LE(buf: Buffer | Uint8Array, offset: number = 0) { validateOffset(offset, "offset", 0, buf.length); const first = buf[offset]; const last = buf[offset + 4]; @@ -1873,14 +1931,16 @@ function readInt40LE(buf: Buffer|Uint8Array, offset: number = 0) { boundsError(offset, buf.length - 5); } - return (last | (last & 2 ** 7) * 0x1fffffe) * 2 ** 32 + + return ( + (last | ((last & (2 ** 7)) * 0x1fffffe)) * 2 ** 32 + first + buf[++offset]! * 2 ** 8 + buf[++offset]! * 2 ** 16 + - buf[++offset]! * 2 ** 24; + buf[++offset]! * 2 ** 24 + ); } -function readInt48LE(buf: Buffer|Uint8Array, offset: number = 0) { +function readInt48LE(buf: Buffer | Uint8Array, offset: number = 0) { validateOffset(offset, "offset", 0, buf.length); const first = buf[offset]; const last = buf[offset + 5]; @@ -1889,14 +1949,16 @@ function readInt48LE(buf: Buffer|Uint8Array, offset: number = 0) { } const val = buf[offset + 4]! + last * 2 ** 8; - return (val | (val & 2 ** 15) * 0x1fffe) * 2 ** 32 + + return ( + (val | ((val & (2 ** 15)) * 0x1fffe)) * 2 ** 32 + first + buf[++offset]! * 2 ** 8 + buf[++offset]! * 2 ** 16 + - buf[++offset]! * 2 ** 24; + buf[++offset]! * 2 ** 24 + ); } -function readInt24BE(buf: Buffer|Uint8Array, offset: number = 0) { +function readInt24BE(buf: Buffer | Uint8Array, offset: number = 0) { validateOffset(offset, "offset", 0, buf.length); const first = buf[offset]; const last = buf[offset + 2]; @@ -1905,10 +1967,10 @@ function readInt24BE(buf: Buffer|Uint8Array, offset: number = 0) { } const val = first * 2 ** 16 + buf[++offset]! * 2 ** 8 + last; - return val | (val & 2 ** 23) * 0x1fe; + return val | ((val & (2 ** 23)) * 0x1fe); } -function readInt48BE(buf: Buffer|Uint8Array, offset: number = 0) { +function readInt48BE(buf: Buffer | Uint8Array, offset: number = 0) { validateOffset(offset, "offset", 0, buf.length); const first = buf[offset]; const last = buf[offset + 5]; @@ -1917,14 +1979,16 @@ function readInt48BE(buf: Buffer|Uint8Array, offset: number = 0) { } const val = buf[++offset]! + first * 2 ** 8; - return (val | (val & 2 ** 15) * 0x1fffe) * 2 ** 32 + + return ( + (val | ((val & (2 ** 15)) * 0x1fffe)) * 2 ** 32 + buf[++offset]! * 2 ** 24 + buf[++offset]! * 2 ** 16 + buf[++offset]! * 2 ** 8 + - last; + last + ); } -function readInt40BE(buf: Buffer|Uint8Array, offset: number = 0) { +function readInt40BE(buf: Buffer | Uint8Array, offset: number = 0) { validateOffset(offset, "offset", 0, buf.length); const first = buf[offset]; const last = buf[offset + 4]; @@ -1932,14 +1996,16 @@ function readInt40BE(buf: Buffer|Uint8Array, offset: number = 0) { boundsError(offset, buf.length - 5); } - return (first | (first & 2 ** 7) * 0x1fffffe) * 2 ** 32 + + return ( + (first | ((first & (2 ** 7)) * 0x1fffffe)) * 2 ** 32 + buf[++offset]! * 2 ** 24 + buf[++offset]! * 2 ** 16 + buf[++offset]! * 2 ** 8 + - last; + last + ); } -function boundsError(value: number, length: number, type?: string) : never { +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); } @@ -1948,11 +2014,7 @@ function boundsError(value: number, length: number, type?: string) : never { throw new ERR_BUFFER_OUT_OF_BOUNDS(); } - throw new ERR_OUT_OF_RANGE( - type || "offset", - `>= ${type ? 1 : 0} and <= ${length}`, - value, - ); + throw new ERR_OUT_OF_RANGE(type || "offset", `>= ${type ? 1 : 0} and <= ${length}`, value); } function validateNumber(value: unknown, name: string) { @@ -1962,12 +2024,13 @@ function validateNumber(value: unknown, name: string) { } function checkInt( - value: number|bigint, - min: number|bigint, - max: number|bigint, + value: number | bigint, + min: number | bigint, + max: number | bigint, buf: Buffer, offset: number, - byteLength: number) { + byteLength: number +) { if (value > max || value < min) { const n = typeof min === "bigint" ? "n" : ""; let range; @@ -1975,7 +2038,8 @@ function checkInt( 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 ` + + range = + `>= -(2${n} ** ${(byteLength + 1) * 8 - 1}${n}) and ` + `< 2${n} ** ${(byteLength + 1) * 8 - 1}${n}`; } } else { @@ -1986,25 +2050,16 @@ function checkInt( checkBounds(buf, offset, byteLength); } -function toInteger(n: number|undefined, defaultVal: number) { +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)); + 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) { +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) { @@ -2018,12 +2073,7 @@ function writeU_Int8( return offset + 1; } -function writeU_Int16BE( - buf: Buffer, - value: number, - offset: number, - min: number, - max: number) { +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); @@ -2033,12 +2083,7 @@ function writeU_Int16BE( return offset; } -function _writeUInt32LE( - buf: Buffer, - value: number, - offset: number, - min: number, - max: number) { +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); @@ -2053,12 +2098,7 @@ function _writeUInt32LE( return offset; } -function writeU_Int16LE( - buf: Buffer, - value: number, - offset: number, - min: number, - max: number) { +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); @@ -2068,12 +2108,7 @@ function writeU_Int16LE( return offset; } -function _writeUInt32BE( - buf: Buffer, - value: number, - offset: number, - min: number, - max: number) { +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); @@ -2088,12 +2123,7 @@ function _writeUInt32BE( return offset + 4; } -function writeU_Int48BE( - buf: Buffer, - value: number, - offset: number, - min: number, - max: number) { +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); @@ -2111,12 +2141,7 @@ function writeU_Int48BE( return offset + 4; } -function writeU_Int40BE( - buf: Buffer, - value: number, - offset: number, - min: number, - max: number) { +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); @@ -2132,12 +2157,7 @@ function writeU_Int40BE( return offset + 4; } -function writeU_Int32BE( - buf: Buffer, - value: number, - offset: number, - min: number, - max: number) { +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); @@ -2152,12 +2172,7 @@ function writeU_Int32BE( return offset + 4; } -function writeU_Int24BE( - buf: Buffer, - value: number, - offset: number, - min: number, - max: number) { +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); @@ -2174,7 +2189,7 @@ function validateOffset( value: number, name: string, min: number = 0, - max: number = Number.MAX_SAFE_INTEGER, + max: number = Number.MAX_SAFE_INTEGER ) { if (typeof value !== "number") { throw new ERR_INVALID_ARG_TYPE(name, "number", value); @@ -2187,12 +2202,7 @@ function validateOffset( } } -function writeU_Int48LE( - buf: Buffer, - value: number, - offset: number, - min: number, - max: number) { +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); @@ -2210,12 +2220,7 @@ function writeU_Int48LE( return offset; } -function writeU_Int40LE( - buf: Buffer, - value: number, - offset: number, - min: number, - max: number) { +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); @@ -2232,12 +2237,7 @@ function writeU_Int40LE( return offset; } -function writeU_Int32LE( - buf: Buffer, - value: number, - offset: number, - min: number, - max: number) { +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); @@ -2252,12 +2252,7 @@ function writeU_Int32LE( return offset; } -function writeU_Int24LE( - buf: Buffer, - value: number, - offset: number, - min: number, - max: number) { +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); 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 index 5a6b40f0c..ab8e66830 100644 --- a/JS/wasm/crates/wasmjs-engine/shims/src/internal/internal_errors.ts +++ b/JS/wasm/crates/wasmjs-engine/shims/src/internal/internal_errors.ts @@ -57,10 +57,7 @@ export class NodeTypeError extends NodeErrorAbstraction implements TypeError { } } -function createInvalidArgType( - name: string, - expected: string | string[], -): string { +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 "; @@ -199,7 +196,10 @@ export class ERR_CRYPTO_INCOMPATIBLE_KEY extends NodeError { 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}.`); + super( + "ERR_CRYPTO_INVALID_KEY_OBJECT_TYPE", + `Invalid key object type ${actual}, expected ${expected}.` + ); } } @@ -226,10 +226,7 @@ export class ERR_INVALID_ARG_VALUE_RANGE extends NodeRangeError { const type = name.includes(".") ? "property" : "argument"; const inspected = inspect(value); - super( - "ERR_INVALID_ARG_VALUE", - `The ${type} '${name}' ${reason}. Received ${inspected}`, - ); + super("ERR_INVALID_ARG_VALUE", `The ${type} '${name}' ${reason}. Received ${inspected}`); } } @@ -238,10 +235,7 @@ export class ERR_INVALID_ARG_VALUE extends NodeTypeError { const type = name.includes(".") ? "property" : "argument"; const inspected = inspect(value); - super( - "ERR_INVALID_ARG_VALUE", - `The ${type} '${name}' ${reason}. Received ${inspected}`, - ); + super("ERR_INVALID_ARG_VALUE", `The ${type} '${name}' ${reason}. Received ${inspected}`); } static RangeError = ERR_INVALID_ARG_VALUE_RANGE; @@ -250,16 +244,10 @@ export class ERR_INVALID_ARG_VALUE extends NodeTypeError { export class ERR_OUT_OF_RANGE extends RangeError { code = "ERR_OUT_OF_RANGE"; - constructor( - str: string, - range: string, - input: unknown, - replaceDefaultBoolean = false) { + 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 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)); @@ -304,17 +292,14 @@ export class ERR_BUFFER_OUT_OF_BOUNDS extends NodeRangeError { "ERR_BUFFER_OUT_OF_BOUNDS", name ? `"${name}" is outside of buffer bounds` - : "Attempt to access memory outside 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`, - ); + super("ERR_INVALID_BUFFER_SIZE", `Buffer size must be a multiple of ${size}-bits`); } } @@ -372,11 +357,9 @@ 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, - ) - }.`, + `Expected ${input} to be returned from the "${name}" function but got ${determineSpecificType( + value + )}.` ); } } @@ -395,9 +378,7 @@ export class ERR_MISSING_ARGS extends NodeTypeError { const wrap = (a: unknown) => `"${a}"`; - args = args.map((a) => - Array.isArray(a) ? a.map(wrap).join(" or ") : wrap(a) - ); + args = args.map((a) => (Array.isArray(a) ? a.map(wrap).join(" or ") : wrap(a))); switch (len) { case 1: @@ -425,8 +406,8 @@ export class ERR_FALSY_VALUE_REJECTION extends NodeError { } export class ERR_METHOD_NOT_IMPLEMENTED extends NodeError { - constructor(name: string|symbol) { - if (typeof name === 'symbol') { + constructor(name: string | symbol) { + if (typeof name === "symbol") { name = (name as symbol).description!; } super("ERR_METHOD_NOT_IMPLEMENTED", `The ${name} method is not implemented`); @@ -439,16 +420,16 @@ export class ERR_STREAM_CANNOT_PIPE extends NodeError { } } export class ERR_STREAM_DESTROYED extends NodeError { - constructor(name: string|symbol) { - if (typeof name === 'symbol') { + 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') { + 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`); @@ -488,5 +469,5 @@ export function aggregateTwoErrors(innerError: any, outerError: any) { (err as any).code = outerError.code; return err; } - return innerError || outerError + 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 index 99ac8ecbd..4e5c8c797 100644 --- a/JS/wasm/crates/wasmjs-engine/shims/src/internal/internal_inspect.ts +++ b/JS/wasm/crates/wasmjs-engine/shims/src/internal/internal_inspect.ts @@ -1,4 +1,3 @@ - import * as internal from "./util"; import { Buffer } from "./internal_buffer"; @@ -35,9 +34,9 @@ import { validateObject, validateString } from "./validators"; function assert(value: boolean, message = "Assertion failed"): asserts value { if (!value) throw new Error(message); } -assert.fail = function(message = "Assertion failed"): never { +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 @@ -47,18 +46,28 @@ function isError(e: unknown): e is 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!; +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(); } + function overflowStack() { + overflowStack(); + } overflowStack(); } catch (err) { assert(isError(err)); @@ -67,16 +76,15 @@ function isStackOverflowError(err: Error): boolean { } } - return err && err.name === maxStack_ErrorName && - err.message === maxStack_ErrorMessage; + return err && err.name === maxStack_ErrorName && err.message === maxStack_ErrorMessage; } -export const customInspectSymbol = Symbol.for('nodejs.util.inspect.custom'); +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, ''); + return str.replace(colorRegExp, ""); } export interface InspectOptions { @@ -180,12 +188,11 @@ export interface InspectOptionsStylized extends InspectOptions { } const builtInObjects = new Set( - Object.getOwnPropertyNames(globalThis).filter( - (e) => /^[A-Z][a-zA-Z0-9]+$/.exec(e) !== null) + 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; +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. @@ -208,10 +215,14 @@ 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'); +const ansiPattern = + "[\\u001B\\u009B][[\\]()#;?]*" + + "(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*" + + "|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)" + + "|(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))"; +const ansi = new RegExp(ansiPattern, "g"); interface Context extends Required { maxArrayLength: number; @@ -294,9 +452,11 @@ function getUserOptions(ctx: Context, isCrossContext: boolean): InspectOptionsSt // 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) { + 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]; } } @@ -308,7 +468,7 @@ function getUserOptions(ctx: Context, isCrossContext: boolean): InspectOptionsSt // Continue regardless of error. } - if (typeof stylized !== 'string') return value; + if (typeof stylized !== "string") return value; // `stylized` is a string as it should be, which is safe to pass along. return stylized; }, null); @@ -324,7 +484,12 @@ function getUserOptions(ctx: Context, isCrossContext: boolean): InspectOptionsSt * @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, + 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 @@ -358,7 +523,7 @@ export function inspect(value: unknown, opts?: Partial | } } // Set user-specified options - if (typeof opts === 'boolean') { + if (typeof opts === "boolean") { ctx.showHidden = opts; } else if (opts) { const optKeys = Object.keys(opts) as (keyof InspectOptionsStylized)[]; @@ -369,7 +534,8 @@ export function inspect(value: unknown, opts?: Partial | // functionality. if ( Object.prototype.hasOwnProperty.call(inspectDefaultOptions, key) || - key === 'stylize') { + key === "stylize" + ) { (ctx as Record)[key] = opts[key]; } else if (ctx.userOptions === undefined) { // This is required to pass through the actual user input. @@ -385,12 +551,12 @@ export function inspect(value: unknown, opts?: Partial | } inspect.custom = customInspectSymbol; -Object.defineProperty(inspect, 'defaultOptions', { +Object.defineProperty(inspect, "defaultOptions", { get() { return inspectDefaultOptions; }, set(options) { - validateObject(options, 'options'); + validateObject(options, "options"); return Object.assign(inspectDefaultOptions, options); }, }); @@ -462,36 +628,36 @@ function defineColorAlias(target: string, alias: string) { }); } -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'); +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', + 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', + regexp: "red", + module: "underline", }; function addQuotes(str: string, quotes: number): string { @@ -523,10 +689,9 @@ function strEscape(str: string): string { if (str.includes("'")) { // This invalidates the charCode and therefore can not be matched for // anymore. - if (!(str.includes('"'))) { + if (!str.includes('"')) { singleQuote = -1; - } else if (!str.includes('`') && - !str.includes('${')) { + } else if (!str.includes("`") && !str.includes("${")) { singleQuote = -2; } if (singleQuote !== 39) { @@ -536,21 +701,17 @@ function strEscape(str: string): string { } // 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 < 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 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 (point === singleQuote || point === 92 || point < 32 || (point > 126 && point < 160)) { if (last === i) { result += meta[point]; } else { @@ -580,8 +741,7 @@ 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`; + if (color !== undefined) return `\u001b[${color[0]}m${str}\u001b[${color[1]}m`; } return str; } @@ -603,20 +763,27 @@ function isInstanceof(object: unknown, proto: Function): boolean { } } -function getConstructorName(obj: object, ctx: Context, recurseTimes: number, protoProps?: string[]): string | null { +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); + 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); } @@ -637,8 +804,7 @@ function getConstructorName(obj: object, ctx: Context, recurseTimes: number, pro return `${res} `; } - const protoConstr = getConstructorName( - firstProto!, ctx, recurseTimes + 1, protoProps); + const protoConstr = getConstructorName(firstProto!, ctx, recurseTimes + 1, protoProps); if (protoConstr === null) { return `${res} <${inspect(firstProto, { @@ -654,7 +820,13 @@ function getConstructorName(obj: object, ctx: Context, recurseTimes: number, pro // 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 { +function addPrototypeProperties( + ctx: Context, + main: object, + obj: Object, + recurseTimes: number, + output: string[] +): void { let depth = 0; let keys: PropertyKey[] | undefined; let keySet: Set | undefined; @@ -666,10 +838,12 @@ function addPrototypeProperties(ctx: Context, main: object, obj: Object, recurse 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)) { + const descriptor = Object.getOwnPropertyDescriptor(obj, "constructor"); + if ( + descriptor !== undefined && + typeof descriptor.value === "function" && + builtInObjects.has(descriptor.value.name) + ) { return; } } @@ -684,17 +858,18 @@ function addPrototypeProperties(ctx: Context, main: object, obj: Object, recurse ctx.seen.push(main); for (const key of keys) { // Ignore the `constructor` property and keys that exist on layers above. - if (key === 'constructor' || + if ( + key === "constructor" || Object.prototype.hasOwnProperty.call(main, key) || - (depth !== 0 && keySet!.has(key))) { + (depth !== 0 && keySet!.has(key)) + ) { continue; } const desc = Object.getOwnPropertyDescriptor(obj, key); - if (typeof desc?.value === 'function') { + if (typeof desc?.value === "function") { continue; } - const value = formatProperty( - ctx, obj, recurseTimes, key, kObjectType, desc, main); + const value = formatProperty(ctx, obj, recurseTimes, key, kObjectType, desc, main); if (ctx.colors) { // Faint! output.push(`\u001b[2m${value}\u001b[22m`); @@ -709,15 +884,15 @@ function addPrototypeProperties(ctx: Context, main: object, obj: Object, recurse } while (++depth !== 3); } -function getPrefix(constructor: string | null, tag: string, fallback: string, size = ''): string { +function getPrefix(constructor: string | null, tag: string, fallback: string, size = ""): string { if (constructor === null) { - if (tag !== '' && fallback !== tag) { + if (tag !== "" && fallback !== tag) { return `[${fallback}${size}: null prototype] [${tag}] `; } return `[${fallback}${size}: null prototype] `; } - if (tag !== '' && constructor !== tag) { + if (tag !== "" && constructor !== tag) { return `${constructor}${size} [${tag}] `; } return `${constructor}${size} `; @@ -729,8 +904,7 @@ function getKeys(value: object, showHidden: boolean): PropertyKey[] { const symbols = Object.getOwnPropertySymbols(value); if (showHidden) { keys = Object.getOwnPropertyNames(value); - if (symbols.length !== 0) - keys.push(...symbols); + 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 @@ -740,12 +914,16 @@ function getKeys(value: object, showHidden: boolean): PropertyKey[] { try { keys = Object.keys(value); } catch (err: any) { - assert(isNativeError(err) && err.name === 'ReferenceError' && - isModuleNamespaceObject(value)); + 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); + const filter = (key: PropertyKey) => + Object.prototype.propertyIsEnumerable.call(value, key); keys.push(...symbols.filter(filter)); } } @@ -753,11 +931,11 @@ function getKeys(value: object, showHidden: boolean): PropertyKey[] { } function getCtxStyle(value: unknown, constructor: string | null, tag: string): string { - let fallback = ''; + let fallback = ""; if (constructor === null) { fallback = internal.getConstructorName(value); if (fallback === tag) { - fallback = 'Object'; + fallback = "Object"; } } return getPrefix(constructor, tag, fallback); @@ -765,7 +943,7 @@ function getCtxStyle(value: unknown, constructor: string | null, tag: string): s function formatProxy(ctx: Context, proxy: internal.ProxyDetails, recurseTimes: number): string { if (ctx.depth !== null && recurseTimes > ctx.depth) { - return ctx.stylize('Proxy [Array]', 'special'); + return ctx.stylize("Proxy [Array]", "special"); } recurseTimes += 1; ctx.indentationLvl += 2; @@ -774,22 +952,24 @@ function formatProxy(ctx: Context, proxy: internal.ProxyDetails, recurseTimes: n formatValue(ctx, proxy.handler, recurseTimes), ]; ctx.indentationLvl -= 2; - return reduceToSingleString( - ctx, res, '', ['Proxy [', ']'], kArrayExtrasType, recurseTimes); + 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 { +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)) { + 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'); + return ctx.stylize("null", "null"); } // Memorize the context for custom inspection on proxies. @@ -799,7 +979,7 @@ function formatValue(ctx: Context, value: unknown, recurseTimes: number, typedAr const proxy = internal.getProxyDetails(value); if (proxy !== undefined) { if (proxy === null || proxy.target === null) { - return ctx.stylize('', 'special'); + return ctx.stylize("", "special"); } if (ctx.showProxy) { return formatProxy(ctx, proxy, recurseTimes); @@ -813,7 +993,9 @@ function formatValue(ctx: Context, value: unknown, recurseTimes: number, typedAr 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]; + const maybeResourceTypeInspect = (value as Record)[ + internal.kResourceTypeInspect + ]; if (typeof maybeResourceTypeInspect === "object") { maybeCustom = formatJsgResourceType.bind( context as Record, @@ -821,30 +1003,31 @@ function formatValue(ctx: Context, value: unknown, recurseTimes: number, typedAr ); } - if (typeof maybeCustom === 'function' && + 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)) { + !((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 isCrossContext = proxy !== undefined || !(context instanceof Object); const ret = Function.prototype.call.call( maybeCustom, context, depth, getUserOptions(ctx, isCrossContext), - inspect, + inspect ); // If the custom inspection method returned `this`, don't go into // infinite recursion. if (ret !== context) { - if (typeof ret !== 'string') { + if (typeof ret !== "string") { return formatValue(ctx, ret, recurseTimes); } - return ret.replaceAll('\n', `\n${' '.repeat(ctx.indentationLvl)}`); + return ret.replaceAll("\n", `\n${" ".repeat(ctx.indentationLvl)}`); } } } @@ -863,13 +1046,18 @@ function formatValue(ctx: Context, value: unknown, recurseTimes: number, typedAr ctx.circular.set(value, index); } } - return ctx.stylize(`[Circular *${index}]`, 'special'); + return ctx.stylize(`[Circular *${index}]`, "special"); } return formatRaw(ctx, value, recurseTimes, typedArray); } -function formatRaw(ctx: Context, value: unknown, recurseTimes: number, typedArray: unknown): string { +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)) { @@ -885,16 +1073,19 @@ function formatRaw(ctx: Context, value: unknown, recurseTimes: number, typedArra 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; + 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; @@ -912,7 +1103,7 @@ function formatRaw(ctx: Context, value: unknown, recurseTimes: number, typedArra 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})`); + const prefix = getPrefix(constructor, tag, "Object", `(${size})`); keys = getKeys(value, ctx.showHidden); // Remove `kEntries` and `size` from keys @@ -921,66 +1112,70 @@ function formatRaw(ctx: Context, value: unknown, recurseTimes: number, typedArra 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}{`, '}']; + 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})`) : - ''; + const prefix = + constructor !== "Array" || tag !== "" + ? getPrefix(constructor, tag, "Array", `(${value.length})`) + : ""; keys = internal.getOwnNonIndexProperties(value, filter); - braces = [`${prefix}[`, ']']; + 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})`); + 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}{`, '}']; + 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})`); + 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}{`, '}']; + 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 = ''; + let fallback = ""; if (constructor === null) { fallback = typedArrayPrototypeToStringTag.call(value); // Reconstruct the array information. - bound = new (globalThis as unknown as Record)[fallback]!(value); + 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]}]`; + 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); + 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); + braces = getIteratorBraces("Set", tag); // Add braces to the formatter parameters. formatter = formatIterator.bind(null, braces); } else { @@ -989,77 +1184,73 @@ function formatRaw(ctx: Context, value: unknown, recurseTimes: number, typedArra } if (noIterator) { keys = getKeys(value as object, ctx.showHidden); - braces = ['{', '}']; - if (constructor === 'Object') { + braces = ["{", "}"]; + if (constructor === "Object") { if (isArgumentsObject(value)) { - braces[0] = '[Arguments] {'; - } else if (tag !== '') { - braces[0] = `${getPrefix(constructor, tag, 'Object')}{`; + 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') { + } else if (typeof value === "function") { base = getFunctionBase(value, constructor, tag); - if (keys.length === 0 && protoProps === undefined) - return ctx.stylize(base, 'special'); + 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'); + 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}`; + 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'); + return ctx.stylize(base, "date"); } } else if (isError(value)) { base = formatError(value, constructor, tag, ctx, keys); - if (keys.length === 0 && protoProps === undefined) - return base; + 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 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)} }`; + return ( + prefix + `{ byteLength: ${formatNumber(ctx.stylize, value.byteLength, false)} }` + ); } braces[0] = `${prefix}{`; - keys.unshift('byteLength'); + keys.unshift("byteLength"); } else if (isDataView(value)) { - braces[0] = `${getPrefix(constructor, tag, 'DataView')}{`; + braces[0] = `${getPrefix(constructor, tag, "DataView")}{`; // .buffer goes last, it's not a primitive like the others. - keys.unshift('byteLength', 'byteOffset', 'buffer'); + keys.unshift("byteLength", "byteOffset", "buffer"); } else if (isPromise(value)) { - braces[0] = `${getPrefix(constructor, tag, 'Promise')}{`; + braces[0] = `${getPrefix(constructor, tag, "Promise")}{`; formatter = formatPromise; } else if (isWeakSet(value)) { - braces[0] = `${getPrefix(constructor, tag, 'WeakSet')}{`; + braces[0] = `${getPrefix(constructor, tag, "WeakSet")}{`; formatter = ctx.showHidden ? formatWeakSet : formatWeakCollection; } else if (isWeakMap(value)) { - braces[0] = `${getPrefix(constructor, tag, 'WeakMap')}{`; + braces[0] = `${getPrefix(constructor, tag, "WeakMap")}{`; formatter = ctx.showHidden ? formatWeakMap : formatWeakCollection; } else if (isModuleNamespaceObject(value)) { - braces[0] = `${getPrefix(constructor, tag, 'Module')}{`; + braces[0] = `${getPrefix(constructor, tag, "Module")}{`; // Special handle keys for namespace objects. formatter = formatNamespaceObject.bind(null, keys); } else if (isBoxedPrimitive(value)) { @@ -1077,9 +1268,8 @@ function formatRaw(ctx: Context, value: unknown, recurseTimes: number, typedArra 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'); + if (constructor !== null) constructorName = `[${constructorName}]`; + return ctx.stylize(constructorName, "special"); } recurseTimes += 1; @@ -1090,9 +1280,7 @@ function formatRaw(ctx: Context, value: unknown, recurseTimes: number, typedArra try { output = formatter(ctx, value, recurseTimes); for (i = 0; i < keys!.length; i++) { - output.push( - formatProperty(ctx, value as object, recurseTimes, keys![i]!, extrasType), - ); + output.push(formatProperty(ctx, value as object, recurseTimes, keys![i]!, extrasType)); } if (protoProps !== undefined) { output.push(...protoProps); @@ -1104,10 +1292,10 @@ function formatRaw(ctx: Context, value: unknown, recurseTimes: number, typedArra if (ctx.circular !== undefined) { const index = ctx.circular.get(value); if (index !== undefined) { - const reference = ctx.stylize(``, 'special'); + const reference = ctx.stylize(``, "special"); // Add reference always to the very beginning of the output. if (ctx.compact !== true) { - base = base === '' ? reference : `${reference} ${base}`; + base = base === "" ? reference : `${reference} ${base}`; } else { braces![0] = `${reference} ${braces![0]}`; } @@ -1125,8 +1313,7 @@ function formatRaw(ctx: Context, value: unknown, recurseTimes: number, typedArra } } - const res = reduceToSingleString( - ctx, output, base, braces!, extrasType, recurseTimes, value); + 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; @@ -1145,61 +1332,65 @@ function formatRaw(ctx: Context, value: unknown, recurseTimes: number, typedArra function getIteratorBraces(type: string, tag: string): [string, string] { if (tag !== `${type} Iterator`) { - if (tag !== '') - tag += '] ['; + if (tag !== "") tag += "] ["; tag += `${type} Iterator`; } - return [`[${tag}] {`, '}']; + return [`[${tag}] {`, "}"]; } -function getBoxedBase(value: unknown, ctx: Context, keys: PropertyKey[], constructor: string | null, tag: string): string { +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'; + type = "Number"; } else if (isStringObject(value)) { fn = String.prototype.valueOf; - type = 'String'; + 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'; + type = "Boolean"; } else if (isBigIntObject(value)) { fn = BigInt.prototype.valueOf; - type = 'BigInt'; + type = "BigInt"; } else { fn = Symbol.prototype.valueOf; - type = 'Symbol'; + type = "Symbol"; } let base = `[${type}`; if (type !== constructor) { if (constructor === null) { - base += ' (null prototype)'; + base += " (null prototype)"; } else { base += ` (${constructor})`; } } base += `: ${formatPrimitive(stylizeNoColor, fn.call(value), ctx)}]`; - if (tag !== '' && tag !== constructor) { + if (tag !== "" && tag !== constructor) { base += ` [${tag}]`; } - if (keys.length !== 0 || ctx.stylize === stylizeNoColor) - return base; + 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)'; + const hasName = Object.prototype.hasOwnProperty.call(value, "name"); + const name = (hasName && value.name) || "(anonymous)"; let base = `class ${name}`; - if (constructor !== 'Function' && constructor !== null) { + if (constructor !== "Function" && constructor !== null) { base += ` [${constructor}]`; } - if (tag !== '' && constructor !== tag) { + if (tag !== "" && constructor !== tag) { base += ` [${tag}]`; } if (constructor !== null) { @@ -1208,25 +1399,26 @@ function getClassBase(value: any, constructor: string | null, tag: string): stri base += ` extends ${superName}`; } } else { - base += ' extends [null prototype]'; + 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('}')) { + if (stringified.startsWith("class") && stringified.endsWith("}")) { const slice = stringified.slice(5, -1); - const bracketIndex = slice.indexOf('{'); - if (bracketIndex !== -1 && - (!slice.slice(0, bracketIndex).includes('(') || + 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'; + let type = "Function"; if (isGeneratorFunction(value)) { type = `Generator${type}`; } @@ -1235,24 +1427,27 @@ function getFunctionBase(value: Function, constructor: string | null, tag: strin } let base = `[${type}`; if (constructor === null) { - base += ' (null prototype)'; + base += " (null prototype)"; } - if (value.name === '') { - base += ' (anonymous)'; + if (value.name === "") { + base += " (anonymous)"; } else { base += `: ${value.name}`; } - base += ']'; + base += "]"; if (constructor !== type && constructor !== null) { base += ` ${constructor}`; } - if (tag !== '' && constructor !== tag) { + if (tag !== "" && constructor !== tag) { base += ` [${tag}]`; } return base; } -export function identicalSequenceRange(a: unknown[], b: unknown[]): { len: number, offset: number } { +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]); @@ -1280,7 +1475,7 @@ function getStackString(error: Error): string { } function getStackFrames(ctx: Context, err: Error, stack: string): string[] { - const frames = stack.split('\n'); + const frames = stack.split("\n"); let cause; try { @@ -1292,36 +1487,44 @@ function getStackFrames(ctx: Context, err: Error, stack: string): string[] { // Remove stack frames identical to frames in cause. if (cause != null && isError(cause)) { const causeStack = getStackString(cause); - const causeStackStart = causeStack.indexOf('\n at'); + const causeStackStart = causeStack.indexOf("\n at"); if (causeStackStart !== -1) { - const causeFrames = causeStack.slice(causeStackStart + 1).split('\n'); + 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')); + frames.splice(offset + 1, skipped, ctx.stylize(msg, "undefined")); } } } return frames; } -function improveStack(stack: string, constructor: string | null, name: string, tag: string): string { +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') && + if ( + constructor === null || + (name.endsWith("Error") && stack.startsWith(name) && - (stack.length === len || stack[len] === ':' || stack[len] === '\n'))) { - let fallback = 'Error'; + (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) || + 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]) || ''; + fallback = (start && start[1]) || ""; len = fallback.length; - fallback = fallback || 'Error'; + fallback = fallback || "Error"; } const prefix = getPrefix(constructor, tag, fallback).slice(0, -1); if (name !== prefix) { @@ -1339,9 +1542,14 @@ function improveStack(stack: string, constructor: string | null, name: string, t return stack; } -function removeDuplicateErrorKeys(ctx: Context, keys: PropertyKey[], err: Error, stack: string): void { +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) { + 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]!)) { @@ -1352,13 +1560,13 @@ function removeDuplicateErrorKeys(ctx: Context, keys: PropertyKey[], err: Error, } function markNodeModules(ctx: Context, line: string): string { - let tempLine = ''; + 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'); + tempLine += ctx.stylize(nodeModule[1]!, "module"); pos = nodeModule.index + nodeModule[0].length; } if (pos !== 0) { @@ -1367,31 +1575,37 @@ function markNodeModules(ctx: Context, line: string): string { 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'; +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'); + 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'); + 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; + 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); + const stackStart = stack.indexOf("\n at", pos); if (stackStart === -1) { stack = `[${stack}]`; } else { @@ -1401,26 +1615,30 @@ function formatError(err: Error, constructor: string | null, tag: string, ctx: C if (ctx.colors) { // Highlight userland code and node modules. for (let line of lines) { - newStack += '\n'; + newStack += "\n"; line = markNodeModules(ctx, line); newStack += line; } } else { - newStack += `\n${lines.join('\n')}`; + 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}`); + const indentation = " ".repeat(ctx.indentationLvl); + stack = stack.replaceAll("\n", `\n${indentation}`); } return stack; } -function groupArrayElements(ctx: Context, output: string[], value: unknown[] | undefined): string[] { +function groupArrayElements( + ctx: Context, + output: string[], + value: unknown[] | undefined +): string[] { let totalLength = 0; let maxLength = 0; let i = 0; @@ -1438,8 +1656,7 @@ function groupArrayElements(ctx: Context, output: string[], value: unknown[] | u const len = getStringWidth(output[i]!, ctx.colors); dataLen[i] = len; totalLength += len + separatorSpace; - if (maxLength < len) - maxLength = len; + if (maxLength < len) maxLength = len; } // Add two to `maxLength` as we add a single whitespace character plus a comma // in-between two entries. @@ -1448,9 +1665,10 @@ function groupArrayElements(ctx: Context, output: string[], value: unknown[] | u // 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)) { - + 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); @@ -1461,18 +1679,18 @@ function groupArrayElements(ctx: Context, output: string[], value: unknown[] | u // 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, - ), + 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, + (ctx.compact === false + ? 0 + : ctx.compact === true + ? inspectDefaultOptions.compact + : ctx.compact) * 4, // Limit the columns to a maximum of fifteen. - 15, + 15 ); // Return with the original output if no grouping should happen. if (columns <= 1) { @@ -1483,8 +1701,7 @@ function groupArrayElements(ctx: Context, output: string[], value: unknown[] | u 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]; + if (dataLen[j] > lineMaxLength) lineMaxLength = dataLen[j]; } lineMaxLength += separatorSpace; maxLineLength[i] = lineMaxLength; @@ -1492,7 +1709,7 @@ function groupArrayElements(ctx: Context, output: string[], value: unknown[] | u 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') { + if (typeof value[i] !== "number" && typeof value[i] !== "bigint") { order = String.prototype.padEnd; break; } @@ -1502,21 +1719,19 @@ function groupArrayElements(ctx: Context, output: string[], value: unknown[] | u 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 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, ' '); + 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, ' '); + const padding = + maxLineLength[j - i]! + output[j]!.length - dataLen[j] - separatorSpace; + str += output[j]!.padStart(padding, " "); } else { str += output[j]; } @@ -1530,14 +1745,19 @@ function groupArrayElements(ctx: Context, output: string[], value: unknown[] | u return output; } -function handleMaxCallStackSize(ctx: Context, err: Error, constructorName: string, indentationLvl: number): string { +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', + "prematurely. Maximum call stack size exceeded.]", + "special" ); } /* c8 ignore next */ @@ -1545,119 +1765,129 @@ function handleMaxCallStackSize(ctx: Context, err: Error, constructorName: strin } function addNumericSeparator(integerString: string): string { - let result = ''; + let result = ""; let i = integerString.length; - const start = integerString.startsWith('-') ? 1 : 0; + 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}`; + return i === integerString.length ? integerString : `${integerString.slice(0, i)}${result}`; } function addNumericSeparatorEnd(integerString: string): string { - let result = ''; + 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)}`; + return i === 0 ? integerString : `${result}${integerString.slice(i)}`; } -const remainingText = (remaining: number) => `... ${remaining} more item${remaining > 1 ? 's' : ''}`; +const remainingText = (remaining: number) => + `... ${remaining} more item${remaining > 1 ? "s" : ""}`; -function formatNumber(fn: InspectOptionsStylized["stylize"], number: number, numericSeparator?: boolean): string { +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("-0", "number"); } - return fn(`${number}`, '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'); + if (!Number.isFinite(number) || string.includes("e")) { + return fn(string, "number"); } - return fn(`${addNumericSeparator(string)}`, 'number'); + return fn(`${addNumericSeparator(string)}`, "number"); } if (Number.isNaN(number)) { - return fn(string, 'number'); + return fn(string, "number"); } - return fn(`${ - addNumericSeparator(string) - }.${ - addNumericSeparatorEnd( - String(number).slice(string.length + 1), - ) - }`, 'number'); + return fn( + `${addNumericSeparator(string)}.${addNumericSeparatorEnd( + String(number).slice(string.length + 1) + )}`, + "number" + ); } -function formatBigInt(fn: InspectOptionsStylized["stylize"], bigint: bigint, numericSeparator?: boolean): string { +function formatBigInt( + fn: InspectOptionsStylized["stylize"], + bigint: bigint, + numericSeparator?: boolean +): string { const string = String(bigint); if (!numericSeparator) { - return fn(`${string}n`, 'bigint'); + return fn(`${string}n`, "bigint"); } - return fn(`${addNumericSeparator(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 = ''; +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' : ''}`; + trailer = `... ${remaining} more character${remaining > 1 ? "s" : ""}`; } - if (ctx.compact !== true && + 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 + 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'); + .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'); + return fn(Symbol.prototype.toString.call(value), "symbol"); } -function formatNamespaceObject(keys: PropertyKey[], ctx: Context, value: object, recurseTimes: number): string[] { +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); + output[i] = formatProperty(ctx, value, recurseTimes, keys[i]!, kObjectType); } catch (err) { - assert(isNativeError(err) && err.name === 'ReferenceError'); + 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]!]: '' }; + const tmp = { [keys[i]!]: "" }; output[i] = formatProperty(ctx, tmp, recurseTimes, keys[i]!, kObjectType); - const pos = output[i]!.lastIndexOf(' '); + 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'); + output[i] = output[i]!.slice(0, pos + 1) + ctx.stylize("", "special"); } } // Reset the keys to an empty array. This prevents duplicated inspection. @@ -1666,7 +1896,14 @@ function formatNamespaceObject(keys: PropertyKey[], ctx: Context, value: object, } // The array is sparse and/or has extra keys -function formatSpecialArray(ctx: Context, value: unknown[], recurseTimes: number, maxLength: number, output: string[], i: number): string[] { +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++) { @@ -1681,9 +1918,9 @@ function formatSpecialArray(ctx: Context, value: unknown[], recurseTimes: number break; } const emptyItems = tmp - index; - const ending = emptyItems > 1 ? 's' : ''; + const ending = emptyItems > 1 ? "s" : ""; const message = `<${emptyItems} empty item${ending}>`; - output.push(ctx.stylize(message, 'undefined')); + output.push(ctx.stylize(message, "undefined")); index = tmp; if (output.length === maxLength) { break; @@ -1695,9 +1932,9 @@ function formatSpecialArray(ctx: Context, value: unknown[], recurseTimes: number const remaining = value.length - index; if (output.length !== maxLength) { if (remaining > 0) { - const ending = remaining > 1 ? 's' : ''; + const ending = remaining > 1 ? "s" : ""; const message = `<${remaining} empty item${ending}>`; - output.push(ctx.stylize(message, 'undefined')); + output.push(ctx.stylize(message, "undefined")); } } else if (remaining > 0) { output.push(remainingText(remaining)); @@ -1710,16 +1947,16 @@ function formatArrayBuffer(ctx: Context, value: ArrayBuffer): string[] { try { buffer = new Uint8Array(value); } catch { - return [ctx.stylize('(detached)', 'special')]; + 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 ') + 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}>`]; + 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[] { @@ -1741,13 +1978,18 @@ function formatArray(ctx: Context, value: unknown[], recurseTimes: number): stri return output; } -function formatTypedArray(value: internal.TypedArray, length: number, ctx: Context, _ignored: unknown, recurseTimes: number): string[] { +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; + 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); @@ -1760,11 +2002,11 @@ function formatTypedArray(value: internal.TypedArray, length: number, ctx: Conte // All besides `BYTES_PER_ELEMENT` are actually getters. ctx.indentationLvl += 2; for (const key of [ - 'BYTES_PER_ELEMENT', - 'length', - 'byteLength', - 'byteOffset', - 'buffer', + "BYTES_PER_ELEMENT", + "length", + "byteLength", + "byteOffset", + "buffer", ] as const) { const str = formatValue(ctx, value[key], recurseTimes, true); output.push(`[${key}]: ${str}`); @@ -1774,7 +2016,12 @@ function formatTypedArray(value: internal.TypedArray, length: number, ctx: Conte return output; } -function formatSet(value: Set | IterableIterator, ctx: Context, _ignored: unknown, recurseTimes: number): string[] { +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; @@ -1793,7 +2040,12 @@ function formatSet(value: Set | IterableIterator, ctx: Context return output; } -function formatMap(value: Map | IterableIterator<[unknown, unknown]>, ctx: Context, _ignored: unknown, recurseTimes: number): string[] { +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; @@ -1802,9 +2054,7 @@ function formatMap(value: Map | IterableIterator<[unknown, unk 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)}` - ); + output.push(`${formatValue(ctx, k, recurseTimes)} => ${formatValue(ctx, v, recurseTimes)}`); i++; } if (remaining > 0) { @@ -1814,7 +2064,12 @@ function formatMap(value: Map | IterableIterator<[unknown, unk return output; } -function formatSetIterInner(ctx: Context, recurseTimes: number, entries: unknown[], state: number): string[] { +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); @@ -1836,7 +2091,12 @@ function formatSetIterInner(ctx: Context, recurseTimes: number, entries: unknown return output; } -function formatMapIterInner(ctx: Context, recurseTimes: number, entries: unknown[], state: number): string[] { +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; @@ -1848,14 +2108,16 @@ function formatMapIterInner(ctx: Context, recurseTimes: number, entries: unknown if (state === kWeak) { for (; i < maxLength; i++) { const pos = i * 2; - output[i] = - `${formatValue(ctx, entries[pos], recurseTimes)} => ${formatValue(ctx, entries[pos + 1], recurseTimes)}`; + 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(); + if (!ctx.sorted) output.sort(); } else { for (; i < maxLength; i++) { const pos = i * 2; @@ -1864,7 +2126,13 @@ function formatMapIterInner(ctx: Context, recurseTimes: number, entries: unknown formatValue(ctx, entries[pos + 1], recurseTimes), ]; output[i] = reduceToSingleString( - ctx, res, '', ['[', ']'], kArrayExtrasType, recurseTimes); + ctx, + res, + "", + ["[", "]"], + kArrayExtrasType, + recurseTimes + ); } } ctx.indentationLvl -= 2; @@ -1875,7 +2143,7 @@ function formatMapIterInner(ctx: Context, recurseTimes: number, entries: unknown } function formatWeakCollection(ctx: Context): string[] { - return [ctx.stylize('', 'special')]; + return [ctx.stylize("", "special")]; } function formatWeakSet(ctx: Context, value: WeakSet, recurseTimes: number): string[] { @@ -1888,11 +2156,16 @@ function formatWeakMap(ctx: Context, value: WeakMap, recurseTimes: return formatMapIterInner(ctx, recurseTimes, entries, kWeak); } -function formatIterator(braces: [string, string], ctx: Context, value: Iterator, recurseTimes: number): string[] { +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] {'); + braces[0] = braces[0].replace(/ Iterator] {$/, " Entries] {"); return formatMapIterInner(ctx, recurseTimes, entries, kMapEntries); } @@ -1903,80 +2176,93 @@ function formatPromise(ctx: Context, value: Promise, recurseTimes: numb let output: string[]; const { state, result } = internal.getPromiseDetails(value)!; if (state === internal.kPending) { - output = [ctx.stylize('', 'special')]; + 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, + 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 { +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 }; + 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; + 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)}`; + extra = `\n${" ".repeat(ctx.indentationLvl)}`; } ctx.indentationLvl -= diff; } else if (desc.get !== undefined) { - const label = desc.set !== undefined ? 'Getter/Setter' : 'Getter'; + 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))) { + 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)} ${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)}`; + str = `${s(`[${label}:`, sp)} ${primitive}${s("]", sp)}`; } ctx.indentationLvl -= 2; } catch (err) { const message = ``; - str = `${s(`[${label}:`, sp)} ${message}${s(']', sp)}`; + str = `${s(`[${label}:`, sp)} ${message}${s("]", sp)}`; } } else { str = ctx.stylize(`[${label}]`, sp); } } else if (desc.set !== undefined) { - str = ctx.stylize('[Setter]', 'special'); + str = ctx.stylize("[Setter]", "special"); } else { - str = ctx.stylize('undefined', 'undefined'); + 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__') { + 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'); + name = ctx.stylize(String(key), "name"); } else { - name = ctx.stylize(strEscape(String(key)), 'string'); + name = ctx.stylize(strEscape(String(key)), "string"); } return `${name}:${extra}${str}`; } @@ -1989,8 +2275,7 @@ function isBelowBreakLength(ctx: Context, output: string[], start: number, base: // 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; + if (totalLength + output.length > ctx.breakLength) return false; for (let i = 0; i < output.length; i++) { if (ctx.colors) { totalLength += removeColors(output[i]!).length; @@ -2002,13 +2287,20 @@ function isBelowBreakLength(ctx: Context, output: string[], start: number, base: } } // Do not line up properties on the same line if `base` contains line breaks. - return base === '' || !base.includes('\n'); + return base === "" || !base.includes("\n"); } function reduceToSingleString( - ctx: Context, output: string[], base: string, braces: [string, string], extrasType: number, recurseTimes: number, value?: unknown): string { + 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) { + 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; @@ -2031,39 +2323,41 @@ function reduceToSingleString( // 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) { + 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; + 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]}`; + 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]}`; + 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]; + return `${braces[0]}${base ? ` ${base}` : ""} ${output.join(", ")} ` + braces[1]; } - const indentation = ' '.repeat(ctx.indentationLvl); + 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} `; + 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]}`; } @@ -2079,12 +2373,12 @@ function hasBuiltInToString(value: object): boolean { } // Count objects that have no `toString` function as built-in. - if (typeof value?.toString !== 'function') { + 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')) { + if (Object.prototype.hasOwnProperty.call(value, "toString")) { return false; } @@ -2093,16 +2387,19 @@ function hasBuiltInToString(value: object): boolean { let pointer = value; do { pointer = Object.getPrototypeOf(pointer); - } while (!Object.prototype.hasOwnProperty.call(pointer, 'toString')); + } 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 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]; +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 { @@ -2118,9 +2415,14 @@ function tryStringify(arg: unknown): string { CIRCULAR_ERROR_MESSAGE = firstErrorLine(circularError); } } - if (typeof err === "object" && err !== null && "name" in err && err.name === 'TypeError' && - firstErrorLine(err) === CIRCULAR_ERROR_MESSAGE) { - return '[Circular]'; + if ( + typeof err === "object" && + err !== null && + "name" in err && + err.name === "TypeError" && + firstErrorLine(err) === CIRCULAR_ERROR_MESSAGE + ) { + return "[Circular]"; } throw err; } @@ -2131,7 +2433,7 @@ export function format(...args: unknown[]): string { } export function formatWithOptions(inspectOptions: InspectOptions, ...args: unknown[]): string { - validateObject(inspectOptions, 'inspectOptions', { allowArray: true }); + validateObject(inspectOptions, "inspectOptions", { allowArray: true }); return formatWithOptionsInternal(inspectOptions, args); } @@ -2139,7 +2441,7 @@ function formatNumberNoColor(number: number, options?: InspectOptions): string { return formatNumber( stylizeNoColor, number, - options?.numericSeparator ?? inspectDefaultOptions.numericSeparator, + options?.numericSeparator ?? inspectDefaultOptions.numericSeparator ); } @@ -2147,17 +2449,20 @@ function formatBigIntNoColor(bigint: bigint, options?: InspectOptions): string { return formatBigInt( stylizeNoColor, bigint, - options?.numericSeparator ?? inspectDefaultOptions.numericSeparator, + options?.numericSeparator ?? inspectDefaultOptions.numericSeparator ); } -function formatWithOptionsInternal(inspectOptions: InspectOptions | undefined, args: unknown[]): string { +function formatWithOptionsInternal( + inspectOptions: InspectOptions | undefined, + args: unknown[] +): string { const first = args[0]; let a = 0; - let str = ''; - let join = ''; + let str = ""; + let join = ""; - if (typeof first === 'string') { + if (typeof first === "string") { if (args.length === 1) { return first; } @@ -2165,19 +2470,23 @@ function formatWithOptionsInternal(inspectOptions: InspectOptions | undefined, a let lastPos = 0; for (let i = 0; i < first.length - 1; i++) { - if (first.charCodeAt(i) === 37) { // '%' + if (first.charCodeAt(i) === 37) { + // '%' const nextChar = first.charCodeAt(++i); if (a + 1 !== args.length) { switch (nextChar) { - case 115: { // 's' + case 115: { + // 's' const tempArg = args[++a]; - if (typeof tempArg === 'number') { + if (typeof tempArg === "number") { tempStr = formatNumberNoColor(tempArg, inspectOptions); - } else if (typeof tempArg === 'bigint') { + } else if (typeof tempArg === "bigint") { tempStr = formatBigIntNoColor(tempArg, inspectOptions); - } else if (typeof tempArg !== 'object' || + } else if ( + typeof tempArg !== "object" || tempArg === null || - !hasBuiltInToString(tempArg)) { + !hasBuiltInToString(tempArg) + ) { tempStr = String(tempArg); } else { tempStr = inspect(tempArg, { @@ -2192,12 +2501,13 @@ function formatWithOptionsInternal(inspectOptions: InspectOptions | undefined, a case 106: // 'j' tempStr = tryStringify(args[++a]); break; - case 100: { // 'd' + case 100: { + // 'd' const tempNum = args[++a]; - if (typeof tempNum === 'bigint') { + if (typeof tempNum === "bigint") { tempStr = formatBigIntNoColor(tempNum, inspectOptions); - } else if (typeof tempNum === 'symbol') { - tempStr = 'NaN'; + } else if (typeof tempNum === "symbol") { + tempStr = "NaN"; } else { tempStr = formatNumberNoColor(Number(tempNum), inspectOptions); } @@ -2214,31 +2524,37 @@ function formatWithOptionsInternal(inspectOptions: InspectOptions | undefined, a depth: 4, }); break; - case 105: { // 'i' + case 105: { + // 'i' const tempInteger = args[++a]; - if (typeof tempInteger === 'bigint') { + if (typeof tempInteger === "bigint") { tempStr = formatBigIntNoColor(tempInteger, inspectOptions); - } else if (typeof tempInteger === 'symbol') { - tempStr = 'NaN'; + } else if (typeof tempInteger === "symbol") { + tempStr = "NaN"; } else { tempStr = formatNumberNoColor( - Number.parseInt(tempInteger as unknown as string), inspectOptions); + Number.parseInt(tempInteger as unknown as string), + inspectOptions + ); } break; } - case 102: { // 'f' + case 102: { + // 'f' const tempFloat = args[++a]; - if (typeof tempFloat === 'symbol') { - tempStr = 'NaN'; + if (typeof tempFloat === "symbol") { + tempStr = "NaN"; } else { tempStr = formatNumberNoColor( - Number.parseFloat(tempFloat as unknown as string), inspectOptions); + Number.parseFloat(tempFloat as unknown as string), + inspectOptions + ); } break; } case 99: // 'c' a += 1; - tempStr = ''; + tempStr = ""; break; case 37: // '%' str += first.slice(lastPos, i); @@ -2260,7 +2576,7 @@ function formatWithOptionsInternal(inspectOptions: InspectOptions | undefined, a } if (lastPos !== 0) { a++; - join = ' '; + join = " "; if (lastPos < first.length) { str += first.slice(lastPos); } @@ -2270,23 +2586,25 @@ function formatWithOptionsInternal(inspectOptions: InspectOptions | undefined, a while (a < args.length) { const value = args[a]; str += join; - str += typeof value !== 'string' ? inspect(value, inspectOptions) : value; - 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 + 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 + (code >= 0x20d0 && code <= 0x20ff) || + (code >= 0xfe00 && code <= 0xfe0f) || // Variation Selectors + (code >= 0xfe20 && code <= 0xfe2f) || // Combining Half Marks + (code >= 0xe0100 && code <= 0xe01ef) + ); // Variation Selectors } /** @@ -2295,9 +2613,8 @@ export function isZeroWidthCodePoint(code: number): boolean { export function getStringWidth(str: string, removeControlChars = true): number { let width = 0; - if (removeControlChars) - str = stripVTControlCharacters(str); - str = str.normalize('NFC'); + if (removeControlChars) str = stripVTControlCharacters(str); + str = str.normalize("NFC"); for (const char of str) { const code = char.codePointAt(0)!; if (isFullWidthCodePoint(code)) { @@ -2308,7 +2625,7 @@ export function getStringWidth(str: string, removeControlChars = true): number { } return width; -}; +} /** * Returns true if the character represented by a given @@ -2317,38 +2634,39 @@ export function getStringWidth(str: string, removeControlChars = true): number { 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) + 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)) ); }; @@ -2356,9 +2674,9 @@ const isFullWidthCodePoint = (code: number) => { * Remove all VT control characters. Use to estimate displayed string width. */ export function stripVTControlCharacters(str: string): string { - validateString(str, 'str'); + validateString(str, "str"); - return str.replace(ansi, ''); + return str.replace(ansi, ""); } // ================================================================================================ @@ -2376,7 +2694,7 @@ export function formatLog(...args: [...values: unknown[], colors: boolean]): str function isBuiltinPrototype(proto: unknown) { if (proto === null) return true; - const descriptor = Object.getOwnPropertyDescriptor(proto, 'constructor'); + const descriptor = Object.getOwnPropertyDescriptor(proto, "constructor"); return ( descriptor !== undefined && typeof descriptor.value === "function" && @@ -2411,7 +2729,7 @@ function formatJsgResourceType( options: InspectOptionsStylized ): unknown { const name = this.constructor.name; - if (depth < 0) return options.stylize(`[${name}]`, 'special'); + 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 @@ -2430,7 +2748,7 @@ function formatJsgResourceType( if (typeof value === "function" || this.constructor.propertyIsEnumerable(key)) continue; record[key] = value; } - } while (!isBuiltinPrototype(current = Object.getPrototypeOf(current))); + } 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)) { @@ -2451,4 +2769,4 @@ function formatJsgResourceType( // something like `Headers(1) { 'a' => '1' }`. return `${name}${inspected.replace("Object", "")}`; } -} \ No newline at end of file +} 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 index 88659773c..174193c23 100644 --- a/JS/wasm/crates/wasmjs-engine/shims/src/internal/internal_path.ts +++ b/JS/wasm/crates/wasmjs-engine/shims/src/internal/internal_path.ts @@ -1,54 +1,52 @@ -import { - CHAR_DOT, - CHAR_FORWARD_SLASH, -} from './constants'; +import { CHAR_DOT, CHAR_FORWARD_SLASH } from "./constants"; -import { - validateObject, - validateString, -} from './validators'; +import { validateObject, validateString } from "./validators"; -function isPosixPathSeparator(code : number) { +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 = ''; +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 (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 || + if ( + res.length < 2 || + lastSegmentLength !== 2 || res.charCodeAt(res.length - 1) !== CHAR_DOT || - res.charCodeAt(res.length - 2) !== CHAR_DOT) { + res.charCodeAt(res.length - 2) !== CHAR_DOT + ) { if (res.length > 2) { const lastSlashIndex = res.lastIndexOf(separator); if (lastSlashIndex === -1) { - res = ''; + res = ""; lastSegmentLength = 0; } else { res = res.slice(0, lastSlashIndex); - lastSegmentLength = - res.length - 1 - res.lastIndexOf(separator); + lastSegmentLength = res.length - 1 - res.lastIndexOf(separator); } lastSlash = i; dots = 0; continue; } else if (res.length !== 0) { - res = ''; + res = ""; lastSegmentLength = 0; lastSlash = i; dots = 0; @@ -56,14 +54,12 @@ function normalizeString(path: string, allowAboveRoot: boolean, separator: strin } } if (allowAboveRoot) { - res += res.length > 0 ? `${separator}..` : '..'; + 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); + if (res.length > 0) res += `${separator}${path.slice(lastSlash + 1, i)}`; + else res = path.slice(lastSlash + 1, i); lastSegmentLength = i - lastSlash - 1; } lastSlash = i; @@ -77,8 +73,8 @@ function normalizeString(path: string, allowAboveRoot: boolean, separator: strin return res; } -function formatExt(ext : string) { - return ext ? `${ext[0] === '.' ? '' : '.'}${ext}` : ''; +function formatExt(ext: string) { + return ext ? `${ext[0] === "." ? "" : "."}${ext}` : ""; } /** @@ -101,11 +97,10 @@ type PathObject = { ext?: string; }; -function _format(sep : string, pathObject : PathObject) { - validateObject(pathObject, 'pathObject', {}); +function _format(sep: string, pathObject: PathObject) { + validateObject(pathObject, "pathObject", {}); const dir = pathObject.dir || pathObject.root; - const base = pathObject.base || - `${pathObject.name || ''}${formatExt(pathObject.ext!)}`; + const base = pathObject.base || `${pathObject.name || ""}${formatExt(pathObject.ext!)}`; if (!dir) { return base; } @@ -115,53 +110,53 @@ function _format(sep : string, pathObject : PathObject) { // We currently do not implement the path.win32 subset. const win32 = { resolve(..._: [string[], string]) { - throw new Error('path.win32.resolve() is not implemented.'); + throw new Error("path.win32.resolve() is not implemented."); }, - normalize(_ : string) { - throw new Error('path.win32.normalize() 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.'); + isAbsolute(_: string) { + throw new Error("path.win32.isAbsolute() is not implemented."); }, - join(..._ : string[]) { - throw new Error('path.win32.join() 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.'); + 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.'); + toNamespacedPath(_: string) { + throw new Error("path.win32.toNamedspacedPath() is not implemented."); }, - dirname(_ : string) { - throw new Error('path.win32.dirname() 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.'); -}, + 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.'); -}, + extname(_: string) { + throw new Error("path.win32.extname() is not implemented."); + }, -format(_ : PathObject) { - throw new Error('path.win32.format() 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.'); -}, + parse(_: string) { + throw new Error("path.win32.parse() is not implemented."); + }, -sep: '\\', - delimiter: ';', - win32: null as Object|null, - posix: null as Object|null, + sep: "\\", + delimiter: ";", + win32: null as Object | null, + posix: null as Object | null, }; const posix = { @@ -171,13 +166,13 @@ const posix = { * @returns {string} */ resolve(...args: string[]) { - let resolvedPath = ''; + let resolvedPath = ""; let resolvedAbsolute = false; for (let i = args.length - 1; i >= -1 && !resolvedAbsolute; i--) { - const path = i >= 0 ? args[i] : '/'; + const path = i >= 0 ? args[i] : "/"; - validateString(path, 'path'); + validateString(path, "path"); // Skip empty entries if (path!.length === 0) { @@ -192,38 +187,34 @@ const posix = { // handle relative paths to be safe (might happen when process.cwd() fails) // Normalize the path - resolvedPath = normalizeString(resolvedPath, !resolvedAbsolute, '/', - isPosixPathSeparator); + resolvedPath = normalizeString(resolvedPath, !resolvedAbsolute, "/", isPosixPathSeparator); if (resolvedAbsolute) { return `/${resolvedPath}`; } - return resolvedPath.length > 0 ? resolvedPath : '.'; + return resolvedPath.length > 0 ? resolvedPath : "."; }, /** * @param {string} path * @returns {string} */ - normalize(path : string) { - validateString(path, 'path'); + normalize(path: string) { + validateString(path, "path"); - if (path.length === 0) - return '.'; + 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); + path = normalizeString(path, !isAbsolute, "/", isPosixPathSeparator); if (path.length === 0) { - if (isAbsolute) - return '/'; - return trailingSeparator ? './' : '.'; + if (isAbsolute) return "/"; + return trailingSeparator ? "./" : "."; } - if (trailingSeparator) - path += '/'; + if (trailingSeparator) path += "/"; return isAbsolute ? `/${path}` : path; }, @@ -232,8 +223,8 @@ const posix = { * @param {string} path * @returns {boolean} */ - isAbsolute(path : string) { - validateString(path, 'path'); + isAbsolute(path: string) { + validateString(path, "path"); return path.length > 0 && path.charCodeAt(0) === CHAR_FORWARD_SLASH; }, @@ -241,22 +232,18 @@ const posix = { * @param {...string} args * @returns {string} */ - join(...args : string[]) { - if (args.length === 0) - return '.'; + 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'); + validateString(arg, "path"); if (arg!.length > 0) { - if (joined === undefined) - joined = arg; - else - joined += `/${arg}`; + if (joined === undefined) joined = arg; + else joined += `/${arg}`; } } - if (joined === undefined) - return '.'; + if (joined === undefined) return "."; return posix.normalize(joined); }, @@ -265,19 +252,17 @@ const posix = { * @param {string} to * @returns {string} */ - relative(from: string, to : string) { - validateString(from, 'from'); - validateString(to, 'to'); + relative(from: string, to: string) { + validateString(from, "from"); + validateString(to, "to"); - if (from === to) - return ''; + if (from === to) return ""; // Trim leading forward slashes. from = posix.resolve(from); to = posix.resolve(to); - if (from === to) - return ''; + if (from === to) return ""; const fromStart = 1; const fromEnd = from.length; @@ -286,15 +271,13 @@ const posix = { const toLen = to.length - toStart; // Compare paths to find the longest common path from root - const length = (fromLen < toLen ? fromLen : toLen); + 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 (fromCode !== to.charCodeAt(toStart + i)) break; + else if (fromCode === CHAR_FORWARD_SLASH) lastCommonSep = i; } if (i === length) { if (toLen > length) { @@ -321,12 +304,12 @@ const posix = { } } - let out = ''; + 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 ? '..' : '/..'; + out += out.length === 0 ? ".." : "/.."; } } @@ -339,7 +322,7 @@ const posix = { * @param {string} path * @returns {string} */ - toNamespacedPath(path : string) { + toNamespacedPath(path: string) { // Non-op on posix systems return path; }, @@ -348,10 +331,9 @@ const posix = { * @param {string} path * @returns {string} */ - dirname(path : string) { - validateString(path, 'path'); - if (path.length === 0) - return '.'; + 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; @@ -367,10 +349,8 @@ const posix = { } } - if (end === -1) - return hasRoot ? '/' : '.'; - if (hasRoot && end === 1) - return '//'; + if (end === -1) return hasRoot ? "/" : "."; + if (hasRoot && end === 1) return "//"; return path.slice(0, end); }, @@ -379,138 +359,131 @@ const posix = { * @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; + 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) { - const code = path.charCodeAt(i); - if (code === CHAR_FORWARD_SLASH) { + 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 (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; - } - } + } 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 (start === end) - end = firstNonSlashEnd; - else if (end === -1) - end = path.length; + if (end === -1) return ""; 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; + /** + * @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; } - 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); -}, + 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, '/'), + format: _format.bind(null, "/"), /** * @param {string} path @@ -522,95 +495,89 @@ format: _format.bind(null, '/'), * ext: string; * }} */ - parse(path: string) : PathObject { - validateString(path, 'path'); + 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; + 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; } - 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; + 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 (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 = '/'; + if (startPart > 0) ret.dir = path.slice(0, startPart - 1); + else if (isAbsolute) ret.dir = "/"; - return ret; -}, + return ret; + }, -sep: '/', - delimiter: ':', - win32: null as Object|null, - posix: null as Object|null, + 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 }; \ No newline at end of file +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 index 63474c628..0ed5a1db5 100644 --- a/JS/wasm/crates/wasmjs-engine/shims/src/internal/internal_stringdecoder.ts +++ b/JS/wasm/crates/wasmjs-engine/shims/src/internal/internal_stringdecoder.ts @@ -1,13 +1,8 @@ +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 { 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'; +import * as bufferUtil from "./buffer"; const kIncompleteCharactersStart = 0; const kIncompleteCharactersEnd = 4; @@ -16,81 +11,83 @@ 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 encodings: Record = { + ascii: 0, + latin1: 1, + utf8: 2, + utf16le: 3, + base64: 4, + base64url: 5, + hex: 6, }; -const kNativeDecoder = Symbol('kNativeDecoder'); +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; + 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; + [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!; +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 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 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)); +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; @@ -98,37 +95,41 @@ 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; + 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]!; + 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]!; + 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 + 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 index 5fb614dff..5fd751258 100644 --- a/JS/wasm/crates/wasmjs-engine/shims/src/internal/internal_types.ts +++ b/JS/wasm/crates/wasmjs-engine/shims/src/internal/internal_types.ts @@ -1,4 +1,3 @@ - import * as internal from "./util"; export function isCryptoKey(value: unknown): boolean { @@ -94,4 +93,4 @@ export default { isUint16Array, isUint32Array, // TODO(soon): isExternal -}; \ No newline at end of file +}; 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 index a75b67790..6cf8b3848 100644 --- a/JS/wasm/crates/wasmjs-engine/shims/src/internal/internal_utils.ts +++ b/JS/wasm/crates/wasmjs-engine/shims/src/internal/internal_utils.ts @@ -1,14 +1,10 @@ - -export function normalizeEncoding(enc?: string) : string | undefined { - if (enc == null || - enc === "utf8" || - enc === "utf-8" || - enc === "UTF8" || - enc === "UTF-8") return "utf8"; +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 { +export function slowCases(enc: string): string | undefined { switch (enc.length) { case 4: if (enc === "UTF8") return "utf8"; @@ -18,10 +14,7 @@ export function slowCases(enc: string) : string | undefined { if (enc === "ucs2") return "utf16le"; break; case 3: - if ( - enc === "hex" || enc === "HEX" || - `${enc}`.toLowerCase() === "hex" - ) { + if (enc === "hex" || enc === "HEX" || `${enc}`.toLowerCase() === "hex") { return "hex"; } break; @@ -46,24 +39,19 @@ export function slowCases(enc: string) : string | undefined { if (enc === "latin1" || enc === "binary") return "latin1"; break; case 7: - if ( - enc === "utf16le" || enc === "UTF16LE" || - `${enc}`.toLowerCase() === "utf16le" - ) { + if (enc === "utf16le" || enc === "UTF16LE" || `${enc}`.toLowerCase() === "utf16le") { return "utf16le"; } break; case 8: - if ( - enc === "utf-16le" || enc === "UTF-16LE" || - `${enc}`.toLowerCase() === "utf-16le" - ) { + if (enc === "utf-16le" || enc === "UTF-16LE" || `${enc}`.toLowerCase() === "utf-16le") { return "utf16le"; } break; case 9: if ( - enc === "base64url" || enc === "BASE64URL" || + enc === "base64url" || + enc === "BASE64URL" || `${enc}`.toLowerCase() === "base64url" ) { return "base64url"; @@ -75,7 +63,7 @@ export function slowCases(enc: string) : string | undefined { return undefined; } -export function spliceOne(list: (string|undefined)[], index: number) { +export function spliceOne(list: (string | undefined)[], index: number) { for (; index + 1 < list.length; index++) list[index] = list[index + 1]; list.pop(); } @@ -100,20 +88,21 @@ export function isArrayIndex(value: unknown): value is number | string { } const length = value.length; if (length === 0) { - return isNumericLookup[value] = false; + 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 */ + (i === 0 && ch === 0x30 && length > 1) /* must not start with 0 */ || + ch < 0x30 /* 0 */ || + ch > 0x39 /* 9 */ ) { - return isNumericLookup[value] = false; + return (isNumericLookup[value] = false); } } - return isNumericLookup[value] = true; + return (isNumericLookup[value] = true); } default: return false; @@ -123,12 +112,9 @@ export function isArrayIndex(value: unknown): value is number | string { export function getOwnNonIndexProperties( // deno-lint-ignore ban-types obj: object, - filter: number, + filter: number ): (string | symbol)[] { - let allProperties = [ - ...Object.getOwnPropertyNames(obj), - ...Object.getOwnPropertySymbols(obj), - ]; + let allProperties = [...Object.getOwnPropertyNames(obj), ...Object.getOwnPropertySymbols(obj)]; if (Array.isArray(obj)) { allProperties = allProperties.filter((k) => !isArrayIndex(k)); @@ -172,11 +158,10 @@ export function createDeferredPromise() { 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 index d72466f2c..522a74ecd 100644 --- a/JS/wasm/crates/wasmjs-engine/shims/src/internal/process.ts +++ b/JS/wasm/crates/wasmjs-engine/shims/src/internal/process.ts @@ -1,14 +1,12 @@ -import { - validateObject, -} from './validators'; +import { validateObject } from "./validators"; -import { - ERR_INVALID_ARG_VALUE, -} from './internal_errors' +import { ERR_INVALID_ARG_VALUE } from "./internal_errors"; export function nextTick(cb: Function, ...args: unknown[]) { - queueMicrotask(() => { cb(...args); }); -}; + 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 @@ -16,50 +14,67 @@ export function nextTick(cb: Function, ...args: unknown[]) { // 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') +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); + }, } - 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 const platform = "wasm"; export default { - nextTick, - env, - argv, - platform, + 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 index ad3aadfed..819808333 100644 --- a/JS/wasm/crates/wasmjs-engine/shims/src/internal/streams_adapters.js +++ b/JS/wasm/crates/wasmjs-engine/shims/src/internal/streams_adapters.js @@ -1,49 +1,35 @@ /* eslint-disable */ -import { - Readable, -} from './streams_readable'; +import { Readable } from "./streams_readable"; import { TextEncoder, TextDecoder } from "@sinonjs/text-encoding"; -import { - Writable, -} from './streams_writable'; +import { Writable } from "./streams_writable"; -import { - Duplex, -} from './streams_duplex'; +import { Duplex } from "./streams_duplex"; import { - destroy, - eos as finished, - isDestroyed, - isReadable, - isWritable, - isWritableEnded, -} from './streams_util'; + destroy, + eos as finished, + isDestroyed, + isReadable, + isWritable, + isWritableEnded, +} from "./streams_util"; -import { - Buffer, -} from './internal_buffer'; +import { Buffer } from "./internal_buffer"; import { - ERR_INVALID_ARG_TYPE, - ERR_INVALID_ARG_VALUE, - ERR_STREAM_PREMATURE_CLOSE, - AbortError, -} from './internal_errors'; + ERR_INVALID_ARG_TYPE, + ERR_INVALID_ARG_VALUE, + ERR_STREAM_PREMATURE_CLOSE, + AbortError, +} from "./internal_errors"; -import { - createDeferredPromise, - normalizeEncoding, -} from './internal_utils'; +import { createDeferredPromise, normalizeEncoding } from "./internal_utils"; -import { - validateBoolean, - validateObject, -} from './validators'; +import { validateBoolean, validateObject } from "./validators"; -import * as process from './process'; +import * as process from "./process"; const encoder = new TextEncoder(); @@ -52,107 +38,105 @@ const encoder = new TextEncoder(); * @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; + // 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); } - 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 (isDestroyed(streamWritable) || !isWritable(streamWritable)) { + const writable = new WritableStream(); + writable.close(); + return writable; } - if (closed !== undefined) { - closed.resolve(); - closed = undefined; - return; + 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(); } - 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); + + 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 + ); } /** @@ -166,146 +150,134 @@ export function newWritableStreamFromStreamWritable(streamWritable) { * @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 - ); - } - } + if (!(writableStream instanceof WritableStream)) { + throw new ERR_INVALID_ARG_TYPE("writableStream", "WritableStream", writableStream); + } - function done(error) { - try { - callback(error); - } catch (error) { - destroy(writable, error); + 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); } - } - - 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; + return writable; } /** @@ -317,85 +289,85 @@ export function newStreamWritableFromWritableStream(writableStream, 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 }); + // 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); } - // 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 }; - }; + if (isDestroyed(streamReadable) || !isReadable(streamReadable)) { + const readable = new ReadableStream(); + readable.cancel(); + return readable; + } - const strategy = evaluateStrategyOrFallback(options?.strategy); + const objectMode = streamReadable.readableObjectMode; + const highWaterMark = streamReadable.readableHighWaterMark; - let controller; + const evaluateStrategyOrFallback = (strategy) => { + // If there is a strategy available, use it + if (strategy) return strategy; - 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(); - } + if (objectMode) { + // When running in objectMode explicitly but no strategy, we just fall + // back to CountQueuingStrategy + return new CountQueuingStrategy({ highWaterMark }); + } - streamReadable.pause(); + // 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 cleanup = finished(streamReadable, (error) => { - if (error?.code === 'ERR_STREAM_PREMATURE_CLOSE') { - const err = new AbortError(undefined, { cause: error }); - error = err; - } + const strategy = evaluateStrategyOrFallback(options?.strategy); - 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(); - }); + let controller; - streamReadable.on('data', onData); + 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(); + } - return new ReadableStream({ - start(c) { controller = c; }, + streamReadable.pause(); - pull() { streamReadable.resume(); }, + const cleanup = finished(streamReadable, (error) => { + if (error?.code === "ERR_STREAM_PREMATURE_CLOSE") { + const err = new AbortError(undefined, { cause: error }); + error = err; + } - cancel(reason) { - destroy(streamReadable, reason); - }, - }, strategy); + 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 + ); } /** @@ -409,77 +381,75 @@ export function newReadableStreamFromStreamReadable(streamReadable, 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 (!(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); } - } - - if (!closed) { - reader.cancel(error).then(done, done); - return; - } - done(); - }, - }); - - reader.closed.then(() => { - closed = true; - }, - (error) => { - closed = true; - destroy(readable, error); - }); - - return readable; + ); + + return readable; } /** @@ -493,42 +463,37 @@ export function newStreamReadableFromReadableStream(readableStream, options = {} * @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 }; + // 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 }; } /** @@ -544,187 +509,179 @@ export function newReadableWritablePairFromDuplex(duplex) { * @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 - ); - } - } + validateObject(pair, "pair"); + const { readable: readableStream, writable: writableStream } = pair; - 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); + 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); } - }, - (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; }); + ); + + reader.closed.then( + () => { + readableClosed = true; + }, + (error) => { + writableClosed = true; + readableClosed = true; + destroy(duplex, 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; + ); + + 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 index 7b2b286c7..61439b173 100644 --- a/JS/wasm/crates/wasmjs-engine/shims/src/internal/streams_duplex.js +++ b/JS/wasm/crates/wasmjs-engine/shims/src/internal/streams_duplex.js @@ -1,479 +1,475 @@ -import { - Readable, - from, -} from './streams_readable'; +import { Readable, from } from "./streams_readable"; -import { - Writable, -} from './streams_writable'; +import { Writable } from "./streams_writable"; import { - newStreamDuplexFromReadableWritablePair, - newReadableWritablePairFromDuplex, -} from './streams_adapters'; + newStreamDuplexFromReadableWritablePair, + newReadableWritablePairFromDuplex, +} from "./streams_adapters"; -import { - createDeferredPromise, -} from './internal_utils'; +import { createDeferredPromise } from "./internal_utils"; -import * as process from './process'; +import * as process from "./process"; import { - destroyer, - eos, - isReadable, - isWritable, - isIterable, - isNodeStream, - isReadableNodeStream, - isWritableNodeStream, - isDuplexNodeStream, -} from './streams_util'; + 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'; +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]; - } + 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; + 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; + 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; } - } 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 + 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; + } + }, }, - 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) -} + return newStreamDuplexFromReadableWritablePair(pair, options); +}; Duplex.toWeb = function (duplex) { - return newReadableWritablePairFromDuplex(duplex) -} + return newReadableWritablePairFromDuplex(duplex); +}; // ====================================================================================== Duplex.from = function (body) { - return duplexify(body, 'body') -} + return duplexify(body, "body"); +}; function isBlob(b) { - return b instanceof Blob; + 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 +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; + 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 - }); - } + 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 (isReadableStream(body)) { + // return _duplexify({ readable: Readable.fromWeb(body) }); + // } - // TODO: Webstreams - // if (isWritableStream(body)) { - // return _duplexify({ writable: Writable.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) + 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 - })); + 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, + }); } - 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); - // } + // 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); - } - ]); + 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 - ) + 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); - } - } + 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() + 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); + // 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, }); - 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; + 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; - 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; + if (onclose === null) { + callback(err); + } else { + onclose = callback; + destroyer(w, err); + destroyer(r, err); } - } }; - } - 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; + 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 index f0b4473df..1f859aae7 100644 --- a/JS/wasm/crates/wasmjs-engine/shims/src/internal/streams_legacy.js +++ b/JS/wasm/crates/wasmjs-engine/shims/src/internal/streams_legacy.js @@ -1,87 +1,83 @@ +import EventEmitter from "./events"; -import - EventEmitter from './events'; - -import { - Buffer, -} from './internal_buffer'; +import { Buffer } from "./internal_buffer"; export function Stream(opts) { - EventEmitter.call(this, 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(); + 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(); + source.on("data", ondata); + function ondrain() { + if (source.readable && source.resume) { + source.resume(); + } } - } - dest.on('drain', ondrain); + 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(); - } + // 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); + // 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); + 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); + // 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; -} + // Allow for unix-like usage: A.pipe(B).pipe(C) + return dest; +}; // Backwards-compat with node 0.4.x -Stream.Stream = Stream +Stream.Stream = Stream; Stream._isUint8Array = function isUint8Array(value) { - return value instanceof Uint8Array; -} + return value instanceof Uint8Array; +}; Stream._uint8ArrayToBuffer = function _uint8ArrayToBuffer(chunk) { - return Buffer.from(chunk.buffer, chunk.byteOffset, chunk.byteLength); -} + 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 index 0066ff927..af1d687b6 100644 --- a/JS/wasm/crates/wasmjs-engine/shims/src/internal/streams_readable.js +++ b/JS/wasm/crates/wasmjs-engine/shims/src/internal/streams_readable.js @@ -1,157 +1,149 @@ /* 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'; + 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 { - Stream, -} from './streams_legacy'; + newStreamReadableFromReadableStream, + newReadableStreamFromStreamReadable, +} from "./streams_adapters"; -import { - newStreamReadableFromReadableStream, - newReadableStreamFromStreamReadable, -} from './streams_adapters'; +import { Buffer } from "./internal_buffer"; import { - Buffer, -} from './internal_buffer'; + 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 { - 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 { - validateObject, - validateAbortSignal, - validateInteger, -} from './validators'; +import { StringDecoder } from "./internal_stringdecoder"; -import { StringDecoder } from './internal_stringdecoder'; - -import { isDuplexInstance } from './streams_duplex'; +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; - } + // 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; + } } // ====================================================================================== @@ -163,355 +155,357 @@ 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); - } - }); + 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 = destroy; +Readable.prototype._undestroy = undestroy; Readable.prototype._destroy = function (err, cb) { - if (cb) cb(err); -} + if (cb) cb(err); +}; Readable.prototype[EventEmitter.captureRejectionSymbol] = function (err) { - this.destroy(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); -} + 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); -} + 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); + 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 { - chunk = Buffer.from(chunk, encoding); - encoding = ''; + 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 (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); - } + } 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); + // 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(); + 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 { - 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); + // 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; -} + 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; -} + 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; + 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; + 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(); + // 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.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 -} + 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); - } + 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); - } + 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); + 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, @@ -521,48 +515,48 @@ function emitReadable_(stream) { // 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); - } + 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; + // 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. @@ -570,1183 +564,1200 @@ function maybeReadMore_(stream, state) { // 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()'); -} + 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; -} + 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(); - } - } + 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 - }) + 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; - } - - // 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 + 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 + 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; -} + 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; - } + 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); + 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; -} + 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); - } + 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); + 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; -} + 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); + 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; -} + 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); -} + return streamToAsyncIterator(this); +}; Readable.prototype.iterator = function (options) { - if (options !== undefined) { - validateObject(options, 'options', options); - } - return streamToAsyncIterator(this, 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; + 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) { + 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; - } 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(); + } 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; + 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; + }, }, - 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); + readableAborted: { + enumerable: false, + get: function () { + return !!( + this._readableState?.readable !== false && + (this._readableState?.destroyed || this._readableState?.errored) && + !this._readableState?.endEmitted + ); + }, }, - 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); + 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; + }, }, - 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 + // 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; + }, }, - set(value) { - this[kPaused] = !!value - } - } }); // Exposed for testing purposes only. -Readable._fromList = fromList +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 + // 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); - } + 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() - } - } - } + // 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() - } + const writable = stream.writable && !stream.writableEnded && !stream.destroyed; + if (writable) { + stream.end(); + } } Readable.fromWeb = function (readableStream, options) { - return newStreamReadableFromReadableStream(readableStream, options) -} + return newStreamReadableFromReadableStream(readableStream, options); +}; Readable.toWeb = function (streamReadable, options) { - return newReadableStreamFromStreamReadable(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); + 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) + 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 - } + 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; } - } catch (err) { - readable.destroy(err) - } - break } - } - return readable + return readable; } // ====================================================================================== // Operators -const kWeakHandler = Symbol('kWeak') -const kEmpty = Symbol('kEmpty') -const kEof = Symbol('kEof') +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; + 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$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; - } + ? 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; } - await new Promise((resolve) => { - next = resolve - }); - } - } finally { - ac.abort(); - done = true; - if (resume) { - resume(); - resume = null; - } - } - }.call(this); + 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]; + if (options != null) { + validateObject(options, "options", options); + } + if ((options === null || options === undefined ? undefined : options.signal) != null) { + validateAbortSignal(options.signal, "options.signal"); } - }.call(this); + 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; + 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 - )); + 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; + 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)); + 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) + 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' - } + 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 ( + 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$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 + (_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); } - if (!gotAnyItemFromStream && !hasInitialValue) { - throw new ReduceAwareErrMissingArgs(); + 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(); } - } finally { - ac.abort(); - } - return initialValue; + 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 - }); + 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); } - result.push(val); - } - return result; + 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) + 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 + // 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(); + if (options != null) { + validateObject(options, "options", options); } - 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); + 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(); + if (options != null) { + validateObject(options, "options", options); } - 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); + 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.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.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.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.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.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.take = function (number, options) { + return from(Readable, take.call(this, number, options)); +}; Readable.prototype.every = every; Readable.prototype.forEach = forEach; @@ -1754,4 +1765,3 @@ 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 index 127ce7887..7add11339 100644 --- 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 @@ -1,344 +1,392 @@ -import EventEmitter from './events'; +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; + 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; + pipe( + destination: T, + options?: { end?: boolean | undefined } + ): T; } export class Stream extends internal { - constructor(opts?: ReadableOptions); + 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; + 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; + 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; + 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; + 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; + 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; + 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; + 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; + 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; + 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; + 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; + [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; + 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; + 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; + 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; + 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; + 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; + 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; + 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; + 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; + 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; + 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; + 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; + 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 index 3abb6ddca..213c21c61 100644 --- a/JS/wasm/crates/wasmjs-engine/shims/src/internal/streams_transform.js +++ b/JS/wasm/crates/wasmjs-engine/shims/src/internal/streams_transform.js @@ -1,147 +1,143 @@ -'use strict' +"use strict"; -import { - ERR_METHOD_NOT_IMPLEMENTED -} from './internal_errors'; +import { ERR_METHOD_NOT_IMPLEMENTED } from "./internal_errors"; -import { - Duplex, -} from './streams_duplex'; +import { Duplex } from "./streams_duplex"; -import { - getHighWaterMark, -} from './streams_util'; +import { getHighWaterMark } from "./streams_util"; Object.setPrototypeOf(Transform.prototype, Duplex.prototype); Object.setPrototypeOf(Transform, Duplex); -const kCallback = Symbol('kCallback'); +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); + 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 (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(er); - } else { - this.destroy(er); + cb(); } - 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); - } + if (this._final !== final) { + final.call(this); + } } Transform.prototype._final = final; Transform.prototype._transform = function () { - throw new ERR_METHOD_NOT_IMPLEMENTED('_transform()') -} + 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; - } - }) -} + 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(); - } -} + 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, - }); + 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); -} + 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 index e9c50973b..91949bd71 100644 --- a/JS/wasm/crates/wasmjs-engine/shims/src/internal/streams_util.js +++ b/JS/wasm/crates/wasmjs-engine/shims/src/internal/streams_util.js @@ -1,723 +1,767 @@ -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'); +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'; + 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 * as process from "./process"; -import { Buffer } from './internal_buffer'; +import { Buffer } from "./internal_buffer"; -import { - validateAbortSignal, - validateFunction, - validateObject, -} from './validators'; +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. - ); + 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 - ); + 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' - ); + 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')) - ); + 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'; + 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)); + 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; + 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)); + 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; + 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)); + 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); + 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); + 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)) { + 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; - } - 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; + 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; + 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 + 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' - ); + 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); + 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 - ); + 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) - ); + 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) - ); + 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) - ) + 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) - } + 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 + return options.highWaterMark != null + ? options.highWaterMark + : isDuplex + ? options[duplexKey] + : null; } export function getDefaultHighWaterMark(objectMode = false) { - return objectMode ? 16 : 16 * 1024 + 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); + 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); } - return Math.floor(hwm); - } - // Default value - return getDefaultHighWaterMark(state.objectMode) + // 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; + 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); + 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; } - break; - } - ++c - } while ((p = p.next) !== null); - this.length -= c; - return ret; - } + } + + _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' + 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); + let _options$readable, _options$writable; + if (arguments.length === 2) { + callback = options; + options = {}; + } else if (options == null) { + options = {}; } else { - const originalCallback = callback; - callback = once((...args) => { - options.signal.removeEventListener('abort', abort) - originalCallback.apply(stream, args); - }); - options.signal.addEventListener('abort', abort); + 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); } - } - return cleanup; + + // 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(); - } - }) - }); + return new Promise((resolve, reject) => { + eos(stream, opts, (err) => { + if (err) { + reject(err); + } else { + resolve(); + } + }); + }); } eos.finished = finished; @@ -726,272 +770,274 @@ 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 (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 (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(); + 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; } - 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; + // 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.closed = true; + w.destroyed = true; } if (r) { - r.closed = true; - } - if (typeof cb === 'function') { - cb(err); + r.destroyed = true; } - if (err) { - process.nextTick(emitErrorCloseNT, self, err); + + // If still constructing then defer calling _destroy. + if (!s.constructed) { + this.once(kDestroy, function (er) { + _destroy(this, aggregateTwoErrors(er, err), cb); + }); } else { - process.nextTick(emitCloseNT, self); + _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); } - } - try { - self._destroy(err || null, onDestroy); - } catch (err) { - onDestroy(err); - } } function emitErrorCloseNT(self, err) { - emitErrorNT(self, err); - emitCloseNT(self); + 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'); - } + 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); + 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; - } + 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) + // 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 -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); + 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); + } + } } -function constructNT(stream) { - let called = false; - function onConstruct(err) { - if (called) { - errorOrDestroy(stream, err !== null && err !== undefined ? err : new ERR_MULTIPLE_CALLBACK()); - return; +export function construct(stream, cb) { + if (typeof stream._construct !== "function") { + return; } - called = true; const r = stream._readableState; const w = stream._writableState; - const s = w || r; if (r) { - r.constructed = true; + r.constructed = false; } if (w) { - w.constructed = true; + w.constructed = false; } - if (s.destroyed) { - stream.emit(kDestroy, err); - } else if (err) { - errorOrDestroy(stream, err, true); - } else { - process.nextTick(emitConstructNT, stream); + 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); } - } - try { - stream._construct(onConstruct); - } catch (err) { - onConstruct(err); - } } function emitConstructNT(stream) { - stream.emit(kConstruct); + stream.emit(kConstruct); } function emitCloseLegacy(stream) { - stream.emit('close'); + stream.emit("close"); } function emitErrorCloseLegacy(stream, err) { - stream.emit('error', err); - process.nextTick(emitCloseLegacy, stream); + 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; - } -} + 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 index f356c6794..6a288b6d6 100644 --- a/JS/wasm/crates/wasmjs-engine/shims/src/internal/streams_writable.js +++ b/JS/wasm/crates/wasmjs-engine/shims/src/internal/streams_writable.js @@ -1,185 +1,179 @@ -import - EventEmitter - from './events'; +import EventEmitter from "./events"; -import { - Stream -} from './streams_legacy'; +import { Stream } from "./streams_legacy"; -import { - Buffer, -} from './internal_buffer'; +import { Buffer } from "./internal_buffer"; -import * as process from './process'; +import * as process from "./process"; import { - nop, - kOnFinished, - getHighWaterMark, - getDefaultHighWaterMark, - addAbortSignal, - construct, - destroy, - undestroy, - errorOrDestroy, -} from './streams_util'; + nop, + kOnFinished, + getHighWaterMark, + getDefaultHighWaterMark, + addAbortSignal, + construct, + destroy, + undestroy, + errorOrDestroy, +} from "./streams_util"; import { - newStreamWritableFromWritableStream, - newWritableStreamFromStreamWritable, -} from './streams_adapters'; + 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'; + 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] = []; + // 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; + state.buffered = []; + state.bufferedIndex = 0; + state.allBuffers = true; + state.allNoop = true; } WritableState.prototype.getBuffer = function getBuffer() { - return this.buffered.slice(this.bufferedIndex); -} + return this.buffered.slice(this.bufferedIndex); +}; -Object.defineProperty(WritableState.prototype, 'bufferedRequestCount', { - get() { - return this.buffered.length - this.bufferedIndex; - } +Object.defineProperty(WritableState.prototype, "bufferedRequestCount", { + get() { + return this.buffered.length - this.bufferedIndex; + }, }); // ====================================================================================== @@ -191,117 +185,117 @@ 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); + // 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); } - finishMaybe(this, state); - }) + 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; - } -}) + 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()); -} + 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'; + const state = stream._writableState; + if (typeof encoding === "function") { + cb = encoding; + encoding = state.defaultEncoding; } else { - throw new ERR_INVALID_ARG_TYPE('chunk', ['string', 'Buffer', 'Uint8Array'], chunk); + 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; } - } - 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); + state.pendingcb++; + return writeOrBuffer(stream, state, chunk, encoding, cb); } function write(chunk, encoding, cb) { - return _write(this, chunk, encoding, cb) === true; + return _write(this, chunk, encoding, cb) === true; } Writable.prototype.write = write; Writable.prototype.cork = function () { - this._writableState.corked++; -} + this._writableState.corked++; +}; Writable.prototype.uncork = function () { - const state = this._writableState; - if (state.corked) { - state.corked--; - if (!state.writing) clearBuffer(this, state); - } -} + 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; + 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; @@ -310,506 +304,513 @@ Writable.prototype.setDefaultEncoding = setDefaultEncoding; // 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; + 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; } - } 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; + // 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; + 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); + --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; + 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); - } + // 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 { - afterWrite(stream, state, 1, cb); + 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); + 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); + 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 (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; + 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 { - state.bufferedIndex = i; + 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; + 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()'); - } -} + 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; + const state = this._writableState; + if (typeof chunk === "function") { + cb = chunk; + chunk = null; + encoding = null; + } else if (typeof encoding === "function") { + cb = encoding; + encoding = null; } - } - - // .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); + 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"); } - } - return this; + 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 - ); + 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; + 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); + } } - 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 = true; - state.pendingcb++; - try { - stream._final(onFinish); - } catch (err) { - onFinish(err); - } - state.sync = false; + 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'); + 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--; + 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); } - })(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(); + 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); + closed: { + get() { + return !!this._writableState?.closed; + }, }, - 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; + 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 + ); + }, }, - 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; -} + 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._undestroy = undestroy; Writable.prototype._destroy = function (err, cb) { - if (cb) cb(err); -} + if (cb) cb(err); +}; Writable.prototype[EventEmitter.captureRejectionSymbol] = function (err) { - this.destroy(err); -} + this.destroy(err); +}; Writable.fromWeb = function (writableStream, options) { - return newStreamWritableFromWritableStream(writableStream, options) -} + return newStreamWritableFromWritableStream(writableStream, options); +}; Writable.toWeb = function (streamWritable) { - return newWritableStreamFromStreamWritable(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 index 400179abc..d97761026 100644 --- a/JS/wasm/crates/wasmjs-engine/shims/src/internal/util.d.ts +++ b/JS/wasm/crates/wasmjs-engine/shims/src/internal/util.d.ts @@ -11,7 +11,7 @@ export abstract class MIMEType { export abstract class MIMEParams { public constructor(); public delete(name: string): void; - public get(name: string): string|undefined; + public get(name: string): string | undefined; public has(name: string): boolean; public set(name: string, value: string): void; public entries(): Iterable; @@ -23,7 +23,10 @@ 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 function getOwnNonIndexProperties( + value: unknown, + filter: typeof ALL_PROPERTIES | typeof ONLY_ENUMERABLE +): PropertyKey[]; export const kPending: 0; export const kFulfilled: 1; @@ -99,4 +102,6 @@ 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; +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 index 2821fd065..13f506b0b 100644 --- a/JS/wasm/crates/wasmjs-engine/shims/src/internal/util.ts +++ b/JS/wasm/crates/wasmjs-engine/shims/src/internal/util.ts @@ -1,7 +1,15 @@ -import { ALL_PROPERTIES as A_PROPERTIES, ONLY_CONFIGURABLE, ONLY_ENUMERABLE as O_ENUMERABLE, ONLY_WRITABLE, SKIP_STRINGS, SKIP_SYMBOLS, isArrayIndex } from "./internal_utils"; +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 kFulfilled = 1; export const kRejected = 2; export const kResourceTypeInspect: unique symbol = Symbol.for("nodejs.util.inspect.custom"); @@ -36,12 +44,9 @@ export interface ProxyDetails { export function getOwnNonIndexProperties( // deno-lint-ignore ban-types obj: object, - filter: number, + filter: number ): (string | symbol)[] { - let allProperties = [ - ...Object.getOwnPropertyNames(obj), - ...Object.getOwnPropertySymbols(obj), - ]; + let allProperties = [...Object.getOwnPropertyNames(obj), ...Object.getOwnPropertySymbols(obj)]; if (Array.isArray(obj)) { allProperties = allProperties.filter((k) => !isArrayIndex(k)); @@ -233,17 +238,18 @@ export function isAnyArrayBuffer(value: unknown): value is ArrayBuffer | SharedA return false; } -export function isBoxedPrimitive(value: unknown): value is Number | String | Boolean | BigInt | Symbol { +export function isBoxedPrimitive( + value: unknown +): value is Number | String | Boolean | BigInt | Symbol { return false; } - export function getPromiseDetails(value: unknown): PromiseDetails | undefined { - return undefined + return undefined; } export function getProxyDetails(value: unknown): ProxyDetails | undefined { - return undefined + return undefined; } export function previewEntries(value: unknown): PreviewedEntries | undefined { @@ -253,4 +259,3 @@ export function previewEntries(value: unknown): PreviewedEntries | 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 index 58985a377..f34d63533 100644 --- a/JS/wasm/crates/wasmjs-engine/shims/src/internal/validators.ts +++ b/JS/wasm/crates/wasmjs-engine/shims/src/internal/validators.ts @@ -1,31 +1,24 @@ 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"; +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 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, - ); + 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) { + max = Number.MAX_SAFE_INTEGER +) { if (typeof value !== "number") { throw new ERR_INVALID_ARG_TYPE(name, "number", value); } @@ -41,7 +34,7 @@ export interface ValidateObjectOptions { allowArray?: boolean; allowFunction?: boolean; nullable?: boolean; -}; +} export function validateObject(value: unknown, name: string, options?: ValidateObjectOptions) { const useDefaultOptions = options == null; @@ -51,13 +44,11 @@ export function validateObject(value: unknown, name: string, options?: ValidateO if ( (!nullable && value === null) || (!allowArray && Array.isArray(value)) || - (typeof value !== "object" && ( - !allowFunction || typeof value !== "function" - )) + (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)) { @@ -87,11 +78,7 @@ export function validateUint32(value: unknown, name: string, positive?: boolean) } const min = positive ? 1 : 0; // 2 ** 32 === 4294967296 - throw new ERR_OUT_OF_RANGE( - name, - `>= ${min} && < 4294967296`, - value, - ); + throw new ERR_OUT_OF_RANGE(name, `>= ${min} && < 4294967296`, value); } if (positive && value === 0) { throw new ERR_OUT_OF_RANGE(name, ">= 1 && < 4294967296", value); @@ -119,11 +106,8 @@ export function validateBoolean(value: unknown, name: string) { 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)), - ), - ", ", + Array.prototype.map.call(oneOf, (v) => (typeof v === "string" ? `'${v}'` : String(v))), + ", " ); const reason = "must be one of: " + allowed; @@ -139,7 +123,7 @@ export function validateEncoding(data: unknown, encoding: string): void { throw new ERR_INVALID_ARG_VALUE( "encoding", encoding, - `is invalid for data of length ${length}`, + `is invalid for data of length ${length}` ); } } @@ -147,13 +131,11 @@ export function validateEncoding(data: unknown, encoding: string): void { export function validateAbortSignal(signal: unknown, name: string) { if ( signal !== undefined && - (signal === null || - typeof signal !== "object" || - !("aborted" in signal)) + (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") { @@ -186,4 +168,4 @@ export default { validateOneOf, validateString, validateUint32, -}; \ No newline at end of file +}; diff --git a/JS/wasm/crates/wasmjs-engine/shims/src/path.js b/JS/wasm/crates/wasmjs-engine/shims/src/path.js index 08cce9319..f5f64f2c4 100644 --- a/JS/wasm/crates/wasmjs-engine/shims/src/path.js +++ b/JS/wasm/crates/wasmjs-engine/shims/src/path.js @@ -1,7 +1,4 @@ -import { - posix, - win32, -} from './internal/internal_path'; +import { posix, win32 } from "./internal/internal_path"; const { resolve, @@ -37,8 +34,8 @@ export { win32, }; -export { default } from './internal/internal_path' -import process from './internal/process'; +export { default } from "./internal/internal_path"; +import process from "./internal/process"; globalThis.process = process; @@ -58,4 +55,4 @@ globalThis.path = { 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 index 03168d917..7a16fe830 100644 --- a/JS/wasm/crates/wasmjs-engine/shims/src/path/posix.ts +++ b/JS/wasm/crates/wasmjs-engine/shims/src/path/posix.ts @@ -1,3 +1,3 @@ -import { posix } from '../internal/internal_path'; +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 index 440107305..f67ec9e71 100644 --- a/JS/wasm/crates/wasmjs-engine/shims/src/path/win32.ts +++ b/JS/wasm/crates/wasmjs-engine/shims/src/path/win32.ts @@ -1,3 +1,3 @@ -import { win32 } from '../internal/internal_path'; +import { win32 } from "../internal/internal_path"; export default win32; diff --git a/JS/wasm/examples/ec-wasmjs-hono/build.js b/JS/wasm/examples/ec-wasmjs-hono/build.js index 64bbadaec..83f669710 100644 --- a/JS/wasm/examples/ec-wasmjs-hono/build.js +++ b/JS/wasm/examples/ec-wasmjs-hono/build.js @@ -8,9 +8,7 @@ build({ format: "esm", target: "esnext", platform: "node", - external:[ - "arakoo-jsonnet" - ] + external: ["arakoo-jsonnet"], }).catch((error) => { console.error(error); process.exit(1); diff --git a/JS/wasm/types/jsonnet/src/index.js b/JS/wasm/types/jsonnet/src/index.js index 057355a78..66874ec6c 100644 --- a/JS/wasm/types/jsonnet/src/index.js +++ b/JS/wasm/types/jsonnet/src/index.js @@ -1,4 +1,4 @@ -const {parseJsonnet} = require("../index.node") +const { parseJsonnet } = require("../index.node"); module.exports = { parseJsonnet,