| import * as assert from 'uvu/assert'; | ||
| import { suite } from 'uvu'; | ||
| import * as base64 from './base64.js'; | ||
| const strings = [ | ||
| '', | ||
| 'a', | ||
| 'ab', | ||
| 'abc', | ||
| 'a\r\nb', | ||
| '\xFF\xFE', | ||
| '\x00', | ||
| '\x00\x00\x00', | ||
| 'the quick brown fox etc', | ||
| 'é', | ||
| '中文', | ||
| '+/', | ||
| '😎' | ||
| ]; | ||
| const test = suite('base64_encode_decode'); | ||
| const encoder = new TextEncoder(); | ||
| const decoder = new TextDecoder(); | ||
| for (const string of strings) { | ||
| test(string, () => { | ||
| const data = encoder.encode(string); | ||
| const with_buffer = base64.encode_buffer(data); | ||
| const with_legacy = base64.encode_legacy(data); | ||
| assert.equal(with_buffer, with_legacy); | ||
| assert.equal(decoder.decode(base64.decode_buffer(with_buffer)), string); | ||
| assert.equal(decoder.decode(base64.decode_legacy(with_legacy)), string); | ||
| if (typeof Uint8Array.fromBase64 === 'function') { | ||
| const with_native = base64.encode_native(data); | ||
| assert.equal(decoder.decode(base64.decode_native(with_native)), string); | ||
| } | ||
| }); | ||
| } | ||
| test.run(); |
+5
-2
| { | ||
| "name": "devalue", | ||
| "description": "Gets the job done when JSON.stringify can't", | ||
| "version": "5.6.4", | ||
| "version": "5.7.0", | ||
| "repository": "sveltejs/devalue", | ||
@@ -23,2 +23,3 @@ "sideEffects": false, | ||
| "@js-temporal/polyfill": "^0.5.1", | ||
| "@types/node": "^24.12.0", | ||
| "dts-buddy": "^0.6.2", | ||
@@ -36,4 +37,6 @@ "publint": "^0.3.12", | ||
| "build": "dts-buddy", | ||
| "test": "uvu" | ||
| "test": "uvu", | ||
| "bench": "node --allow-natives-syntax ./benchmarking/run.js", | ||
| "bench:compare": "node --allow-natives-syntax ./benchmarking/compare/index.js" | ||
| } | ||
| } |
+46
-96
@@ -1,110 +0,60 @@ | ||
| /** | ||
| * Base64 Encodes an arraybuffer | ||
| * @param {ArrayBuffer} arraybuffer | ||
| * @returns {string} | ||
| */ | ||
| export function encode64(arraybuffer) { | ||
| const dv = new DataView(arraybuffer); | ||
| let binaryString = ""; | ||
| /* Baseline 2025 runtimes */ | ||
| for (let i = 0; i < arraybuffer.byteLength; i++) { | ||
| binaryString += String.fromCharCode(dv.getUint8(i)); | ||
| } | ||
| /** @type {(array_buffer: ArrayBuffer) => string} */ | ||
| export function encode_native(array_buffer) { | ||
| return new Uint8Array(array_buffer).toBase64(); | ||
| } | ||
| return binaryToAscii(binaryString); | ||
| /** @type {(base64: string) => ArrayBuffer} */ | ||
| export function decode_native(base64) { | ||
| return Uint8Array.fromBase64(base64).buffer; | ||
| } | ||
| /** | ||
| * Decodes a base64 string into an arraybuffer | ||
| * @param {string} string | ||
| * @returns {ArrayBuffer} | ||
| */ | ||
| export function decode64(string) { | ||
| const binaryString = asciiToBinary(string); | ||
| const arraybuffer = new ArrayBuffer(binaryString.length); | ||
| const dv = new DataView(arraybuffer); | ||
| /* Node-compatible runtimes */ | ||
| for (let i = 0; i < arraybuffer.byteLength; i++) { | ||
| dv.setUint8(i, binaryString.charCodeAt(i)); | ||
| } | ||
| /** @type {(array_buffer: ArrayBuffer) => string} */ | ||
| export function encode_buffer(array_buffer) { | ||
| return Buffer.from(array_buffer).toString('base64'); | ||
| } | ||
| return arraybuffer; | ||
| /** @type {(base64: string) => ArrayBuffer} */ | ||
| export function decode_buffer(base64) { | ||
| return Uint8Array.from(Buffer.from(base64, 'base64')).buffer; | ||
| } | ||
| const KEY_STRING = | ||
| "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; | ||
| /* Legacy runtimes */ | ||
| /** | ||
| * Substitute for atob since it's deprecated in node. | ||
| * Does not do any input validation. | ||
| * | ||
| * @see https://github.com/jsdom/abab/blob/master/lib/atob.js | ||
| * | ||
| * @param {string} data | ||
| * @returns {string} | ||
| */ | ||
| function asciiToBinary(data) { | ||
| if (data.length % 4 === 0) { | ||
| data = data.replace(/==?$/, ""); | ||
| } | ||
| /** @type {(array_buffer: ArrayBuffer) => string} */ | ||
| export function encode_legacy(array_buffer) { | ||
| const array = new Uint8Array(array_buffer); | ||
| let binary = ''; | ||
| let output = ""; | ||
| let buffer = 0; | ||
| let accumulatedBits = 0; | ||
| // the maximum number of arguments to String.fromCharCode.apply | ||
| // should be around 0xFFFF in modern engines | ||
| const chunk_size = 0x8000; | ||
| for (let i = 0; i < array.length; i += chunk_size) { | ||
| const chunk = array.subarray(i, i + chunk_size); | ||
| binary += String.fromCharCode.apply(null, chunk); | ||
| } | ||
| for (let i = 0; i < data.length; i++) { | ||
| buffer <<= 6; | ||
| buffer |= KEY_STRING.indexOf(data[i]); | ||
| accumulatedBits += 6; | ||
| if (accumulatedBits === 24) { | ||
| output += String.fromCharCode((buffer & 0xff0000) >> 16); | ||
| output += String.fromCharCode((buffer & 0xff00) >> 8); | ||
| output += String.fromCharCode(buffer & 0xff); | ||
| buffer = accumulatedBits = 0; | ||
| } | ||
| } | ||
| if (accumulatedBits === 12) { | ||
| buffer >>= 4; | ||
| output += String.fromCharCode(buffer); | ||
| } else if (accumulatedBits === 18) { | ||
| buffer >>= 2; | ||
| output += String.fromCharCode((buffer & 0xff00) >> 8); | ||
| output += String.fromCharCode(buffer & 0xff); | ||
| } | ||
| return output; | ||
| return btoa(binary); | ||
| } | ||
| /** | ||
| * Substitute for btoa since it's deprecated in node. | ||
| * Does not do any input validation. | ||
| * | ||
| * @see https://github.com/jsdom/abab/blob/master/lib/btoa.js | ||
| * | ||
| * @param {string} str | ||
| * @returns {string} | ||
| */ | ||
| function binaryToAscii(str) { | ||
| let out = ""; | ||
| for (let i = 0; i < str.length; i += 3) { | ||
| /** @type {[number, number, number, number]} */ | ||
| const groupsOfSix = [undefined, undefined, undefined, undefined]; | ||
| groupsOfSix[0] = str.charCodeAt(i) >> 2; | ||
| groupsOfSix[1] = (str.charCodeAt(i) & 0x03) << 4; | ||
| if (str.length > i + 1) { | ||
| groupsOfSix[1] |= str.charCodeAt(i + 1) >> 4; | ||
| groupsOfSix[2] = (str.charCodeAt(i + 1) & 0x0f) << 2; | ||
| } | ||
| if (str.length > i + 2) { | ||
| groupsOfSix[2] |= str.charCodeAt(i + 2) >> 6; | ||
| groupsOfSix[3] = str.charCodeAt(i + 2) & 0x3f; | ||
| } | ||
| for (let j = 0; j < groupsOfSix.length; j++) { | ||
| if (typeof groupsOfSix[j] === "undefined") { | ||
| out += "="; | ||
| } else { | ||
| out += KEY_STRING[groupsOfSix[j]]; | ||
| } | ||
| } | ||
| } | ||
| return out; | ||
| /** @type {(base64: string) => ArrayBuffer} */ | ||
| export function decode_legacy(base64) { | ||
| const binary_string = atob(base64); | ||
| const len = binary_string.length; | ||
| const array = new Uint8Array(len); | ||
| for (let i = 0; i < len; i++) { | ||
| array[i] = binary_string.charCodeAt(i); | ||
| } | ||
| return array.buffer; | ||
| } | ||
| const native = typeof Uint8Array.fromBase64 === 'function'; | ||
| const buffer = typeof process === 'object' && process.versions?.node !== undefined; | ||
| export const encode64 = native ? encode_native : buffer ? encode_buffer : encode_legacy; | ||
| export const decode64 = native ? decode_native : buffer ? decode_buffer : decode_legacy; |
+16
-13
@@ -69,6 +69,3 @@ import { decode64 } from './base64.js'; | ||
| const reviver = | ||
| revivers && Object.hasOwn(revivers, type) | ||
| ? revivers[type] | ||
| : undefined; | ||
| const reviver = revivers && Object.hasOwn(revivers, type) ? revivers[type] : undefined; | ||
@@ -121,11 +118,16 @@ if (reviver) { | ||
| case 'Object': | ||
| const object = Object(value[1]); | ||
| case 'Object': { | ||
| const wrapped_index = value[1]; | ||
| if (Object.hasOwn(object, '__proto__')) { | ||
| throw new Error('Cannot parse an object with a `__proto__` property'); | ||
| if ( | ||
| typeof values[wrapped_index] === 'object' && | ||
| values[wrapped_index][0] !== 'BigInt' | ||
| ) { | ||
| // avoid infinite recusion in case of malformed input | ||
| throw new Error('Invalid input'); | ||
| } | ||
| hydrated[index] = object; | ||
| hydrated[index] = Object(hydrate(wrapped_index)); | ||
| break; | ||
| } | ||
@@ -153,2 +155,3 @@ case 'BigInt': | ||
| case 'Uint16Array': | ||
| case 'Float16Array': | ||
| case 'Int32Array': | ||
@@ -159,3 +162,4 @@ case 'Uint32Array': | ||
| case 'BigInt64Array': | ||
| case 'BigUint64Array': { | ||
| case 'BigUint64Array': | ||
| case 'DataView': { | ||
| if (values[value[1]][0] !== 'ArrayBuffer') { | ||
@@ -170,8 +174,7 @@ // without this, if we receive malformed input we could | ||
| const buffer = hydrate(value[1]); | ||
| const typedArray = new TypedArrayConstructor(buffer); | ||
| hydrated[index] = | ||
| value[2] !== undefined | ||
| ? typedArray.subarray(value[2], value[3]) | ||
| : typedArray; | ||
| ? new TypedArrayConstructor(buffer, value[2], value[3]) | ||
| : new TypedArrayConstructor(buffer); | ||
@@ -178,0 +181,0 @@ break; |
+13
-28
@@ -55,3 +55,3 @@ import { | ||
| if (indexes.has(thing)) return indexes.get(thing); | ||
| if (indexes.has(thing)) return /** @type {number} */ (indexes.get(thing)); | ||
@@ -71,2 +71,4 @@ const index = p++; | ||
| throw new DevalueError(`Cannot stringify a function`, keys, thing, value); | ||
| } else if (typeof thing === 'symbol') { | ||
| throw new DevalueError(`Cannot stringify a Symbol primitive`, keys, thing, value); | ||
| } | ||
@@ -85,7 +87,4 @@ | ||
| case 'Boolean': | ||
| str = `["Object",${stringify_primitive(thing)}]`; | ||
| break; | ||
| case 'BigInt': | ||
| str = `["BigInt",${thing}]`; | ||
| str = `["Object",${flatten(thing.valueOf())}]`; | ||
| break; | ||
@@ -211,5 +210,3 @@ | ||
| for (const [key, value] of thing) { | ||
| keys.push( | ||
| `.get(${is_primitive(key) ? stringify_primitive(key) : '...'})` | ||
| ); | ||
| keys.push(`.get(${is_primitive(key) ? stringify_primitive(key) : '...'})`); | ||
| str += `,${flatten(key)},${flatten(value)}`; | ||
@@ -227,2 +224,3 @@ keys.pop(); | ||
| case 'Uint16Array': | ||
| case 'Float16Array': | ||
| case 'Int32Array': | ||
@@ -233,3 +231,4 @@ case 'Uint32Array': | ||
| case 'BigInt64Array': | ||
| case 'BigUint64Array': { | ||
| case 'BigUint64Array': | ||
| case 'DataView': { | ||
| /** @type {import("./types.js").TypedArray} */ | ||
@@ -239,9 +238,6 @@ const typedArray = thing; | ||
| const a = thing.byteOffset; | ||
| const b = a + thing.byteLength; | ||
| // handle subarrays | ||
| if (a > 0 || b !== typedArray.buffer.byteLength) { | ||
| const m = +/(\d+)/.exec(type)[1] / 8; | ||
| str += `,${a / m},${b / m}`; | ||
| if (typedArray.byteLength !== typedArray.buffer.byteLength) { | ||
| // to be used with `new TypedArray(buffer, byteOffset, length)` | ||
| str += `,${typedArray.byteOffset},${typedArray.length}`; | ||
| } | ||
@@ -275,17 +271,7 @@ | ||
| if (!is_plain_object(thing)) { | ||
| throw new DevalueError( | ||
| `Cannot stringify arbitrary non-POJOs`, | ||
| keys, | ||
| thing, | ||
| value | ||
| ); | ||
| throw new DevalueError(`Cannot stringify arbitrary non-POJOs`, keys, thing, value); | ||
| } | ||
| if (enumerable_symbols(thing).length > 0) { | ||
| throw new DevalueError( | ||
| `Cannot stringify POJOs with symbolic keys`, | ||
| keys, | ||
| thing, | ||
| value | ||
| ); | ||
| throw new DevalueError(`Cannot stringify POJOs with symbolic keys`, keys, thing, value); | ||
| } | ||
@@ -353,3 +339,2 @@ | ||
| if (type === 'string') return stringify_string(thing); | ||
| if (thing instanceof String) return stringify_string(thing.toString()); | ||
| if (thing === void 0) return UNDEFINED.toString(); | ||
@@ -356,0 +341,0 @@ if (thing === 0 && 1 / thing < 0) return NEGATIVE_ZERO.toString(); |
+13
-1
@@ -1,1 +0,13 @@ | ||
| export type TypedArray = Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array | BigInt64Array | BigUint64Array; | ||
| export type TypedArray = | ||
| | Int8Array | ||
| | Uint8Array | ||
| | Uint8ClampedArray | ||
| | Int16Array | ||
| | Uint16Array | ||
| | Float16Array | ||
| | Int32Array | ||
| | Uint32Array | ||
| | Float32Array | ||
| | Float64Array | ||
| | BigInt64Array | ||
| | BigUint64Array; |
+109
-54
@@ -81,5 +81,3 @@ import { | ||
| for (const [key, value] of thing) { | ||
| keys.push( | ||
| `.get(${is_primitive(key) ? stringify_primitive(key) : '...'})` | ||
| ); | ||
| keys.push(`.get(${is_primitive(key) ? stringify_primitive(key) : '...'})`); | ||
| walk(value); | ||
@@ -95,2 +93,3 @@ keys.pop(); | ||
| case 'Uint16Array': | ||
| case 'Float16Array': | ||
| case 'Int32Array': | ||
@@ -102,2 +101,3 @@ case 'Uint32Array': | ||
| case 'BigUint64Array': | ||
| case 'DataView': | ||
| walk(thing.buffer); | ||
@@ -121,17 +121,7 @@ return; | ||
| if (!is_plain_object(thing)) { | ||
| throw new DevalueError( | ||
| `Cannot stringify arbitrary non-POJOs`, | ||
| keys, | ||
| thing, | ||
| value | ||
| ); | ||
| throw new DevalueError(`Cannot stringify arbitrary non-POJOs`, keys, thing, value); | ||
| } | ||
| if (enumerable_symbols(thing).length > 0) { | ||
| throw new DevalueError( | ||
| `Cannot stringify POJOs with symbolic keys`, | ||
| keys, | ||
| thing, | ||
| value | ||
| ); | ||
| throw new DevalueError(`Cannot stringify POJOs with symbolic keys`, keys, thing, value); | ||
| } | ||
@@ -154,2 +144,4 @@ | ||
| } | ||
| } else if (typeof thing === 'symbol') { | ||
| throw new DevalueError(`Cannot stringify a Symbol primitive`, keys, thing, value); | ||
| } | ||
@@ -192,8 +184,7 @@ } | ||
| case 'Boolean': | ||
| case 'BigInt': | ||
| return `Object(${stringify(thing.valueOf())})`; | ||
| case 'RegExp': | ||
| return `new RegExp(${stringify_string(thing.source)}, "${ | ||
| thing.flags | ||
| }")`; | ||
| return `new RegExp(${stringify_string(thing.source)}, "${thing.flags}")`; | ||
@@ -268,8 +259,6 @@ case 'Date': | ||
| const hole_cost = thing.length + 2; | ||
| const sparse_cost = (25 + d) + population * (d + 2); | ||
| const sparse_cost = 25 + d + population * (d + 2); | ||
| if (hole_cost > sparse_cost) { | ||
| const entries = populated_keys | ||
| .map((k) => `${k}:${stringify(thing[k])}`) | ||
| .join(','); | ||
| const entries = populated_keys.map((k) => `${k}:${stringify(thing[k])}`).join(','); | ||
| return `Object.assign(Array(${thing.length}),{${entries}})`; | ||
@@ -299,2 +288,3 @@ } | ||
| case 'Uint16Array': | ||
| case 'Float16Array': | ||
| case 'Int32Array': | ||
@@ -308,16 +298,14 @@ case 'Uint32Array': | ||
| if (counts.get(thing.buffer) === 1) { | ||
| if (!names.has(thing.buffer)) { | ||
| const array = new thing.constructor(thing.buffer); | ||
| str += `([${array}])`; | ||
| } else { | ||
| str += `([${stringify(thing.buffer)}])`; | ||
| str += `(${stringify(thing.buffer)})`; | ||
| } | ||
| const a = thing.byteOffset; | ||
| const b = a + thing.byteLength; | ||
| // handle subarrays | ||
| if (a > 0 || b !== thing.buffer.byteLength) { | ||
| const m = +/(\d+)/.exec(type)[1] / 8; | ||
| str += `.subarray(${a / m},${b / m})`; | ||
| if (thing.byteLength !== thing.buffer.byteLength) { | ||
| const start = thing.byteOffset / thing.BYTES_PER_ELEMENT; | ||
| const end = start + thing.length; | ||
| str += `.subarray(${start},${end})`; | ||
| } | ||
@@ -328,2 +316,19 @@ | ||
| case 'DataView': { | ||
| let str = `new DataView`; | ||
| if (!names.has(thing.buffer)) { | ||
| str += `(new Uint8Array([${new Uint8Array(thing.buffer)}]).buffer`; | ||
| } else { | ||
| str += `(${stringify(thing.buffer)}`; | ||
| } | ||
| // handle subviews | ||
| if (thing.byteLength !== thing.buffer.byteLength) { | ||
| str += `,${thing.startOffset},${thing.byteLength}`; | ||
| } | ||
| return str + ')'; | ||
| } | ||
| case 'ArrayBuffer': { | ||
@@ -346,10 +351,6 @@ const ui8 = new Uint8Array(thing); | ||
| const keys = Object.keys(thing); | ||
| const obj = keys | ||
| .map((key) => `${safe_key(key)}:${stringify(thing[key])}`) | ||
| .join(','); | ||
| const obj = keys.map((key) => `${safe_key(key)}:${stringify(thing[key])}`).join(','); | ||
| const proto = Object.getPrototypeOf(thing); | ||
| if (proto === null) { | ||
| return keys.length > 0 | ||
| ? `{${obj},__proto__:null}` | ||
| : `{__proto__:null}`; | ||
| return keys.length > 0 ? `{${obj},__proto__:null}` : `{__proto__:null}`; | ||
| } | ||
@@ -392,2 +393,3 @@ | ||
| case 'Boolean': | ||
| case 'BigInt': | ||
| values.push(`Object(${stringify(thing.valueOf())})`); | ||
@@ -404,2 +406,10 @@ break; | ||
| case 'URL': | ||
| values.push(`new URL(${stringify_string(thing.toString())})`); | ||
| break; | ||
| case 'URLSearchParams': | ||
| values.push(`new URLSearchParams(${stringify_string(thing.toString())})`); | ||
| break; | ||
| case 'Array': | ||
@@ -430,16 +440,64 @@ values.push(`Array(${thing.length})`); | ||
| case 'Int8Array': | ||
| case 'Uint8Array': | ||
| case 'Uint8ClampedArray': | ||
| case 'Int16Array': | ||
| case 'Uint16Array': | ||
| case 'Float16Array': | ||
| case 'Int32Array': | ||
| case 'Uint32Array': | ||
| case 'Float32Array': | ||
| case 'Float64Array': | ||
| case 'BigInt64Array': | ||
| case 'BigUint64Array': { | ||
| let str = `new ${type}`; | ||
| if (!names.has(thing.buffer)) { | ||
| const array = new thing.constructor(thing.buffer); | ||
| str += `([${array}])`; | ||
| } else { | ||
| str += `(${stringify(thing.buffer)})`; | ||
| } | ||
| // handle subarrays | ||
| if (thing.byteLength !== thing.buffer.byteLength) { | ||
| const start = thing.byteOffset / thing.BYTES_PER_ELEMENT; | ||
| const end = start + thing.length; | ||
| str += `.subarray(${start},${end})`; | ||
| } | ||
| values.push(`{}`); | ||
| statements.push(`${name}=${str}`); | ||
| break; | ||
| } | ||
| case 'DataView': { | ||
| let str = `new DataView`; | ||
| if (!names.has(thing.buffer)) { | ||
| str += `(new Uint8Array([${new Uint8Array(thing.buffer)}]).buffer`; | ||
| } else { | ||
| str += `(${stringify(thing.buffer)}`; | ||
| } | ||
| // handle subviews | ||
| if (thing.byteLength !== thing.buffer.byteLength) { | ||
| str += `,${thing.byteOffset},${thing.byteLength}`; | ||
| } | ||
| str += ')'; | ||
| values.push(`{}`); | ||
| statements.push(`${name}=${str}`); | ||
| break; | ||
| } | ||
| case 'ArrayBuffer': | ||
| values.push( | ||
| `new Uint8Array([${new Uint8Array(thing).join(',')}]).buffer` | ||
| ); | ||
| values.push(`new Uint8Array([${new Uint8Array(thing)}]).buffer`); | ||
| break; | ||
| default: | ||
| values.push( | ||
| Object.getPrototypeOf(thing) === null ? 'Object.create(null)' : '{}' | ||
| ); | ||
| values.push(Object.getPrototypeOf(thing) === null ? 'Object.create(null)' : '{}'); | ||
| Object.keys(thing).forEach((key) => { | ||
| statements.push( | ||
| `${name}${safe_prop(key)}=${stringify(thing[key])}` | ||
| ); | ||
| statements.push(`${name}${safe_prop(key)}=${stringify(thing[key])}`); | ||
| }); | ||
@@ -451,5 +509,3 @@ } | ||
| return `(function(${params.join(',')}){${statements.join( | ||
| ';' | ||
| )}}(${values.join(',')}))`; | ||
| return `(function(${params.join(',')}){${statements.join(';')}}(${values.join(',')}))`; | ||
| } else { | ||
@@ -484,5 +540,3 @@ return str; | ||
| function safe_key(key) { | ||
| return /^[_$a-zA-Z][_$a-zA-Z0-9]*$/.test(key) | ||
| ? key | ||
| : escape_unsafe_chars(JSON.stringify(key)); | ||
| return /^[_$a-zA-Z][_$a-zA-Z0-9]*$/.test(key) ? key : escape_unsafe_chars(JSON.stringify(key)); | ||
| } | ||
@@ -499,9 +553,10 @@ | ||
| function stringify_primitive(thing) { | ||
| if (typeof thing === 'string') return stringify_string(thing); | ||
| const type = typeof thing; | ||
| if (type === 'string') return stringify_string(thing); | ||
| if (thing === void 0) return 'void 0'; | ||
| if (thing === 0 && 1 / thing < 0) return '-0'; | ||
| const str = String(thing); | ||
| if (typeof thing === 'number') return str.replace(/^(-)?0\./, '$1.'); | ||
| if (typeof thing === 'bigint') return thing + 'n'; | ||
| if (type === 'number') return str.replace(/^(-)?0\./, '$1.'); | ||
| if (type === 'bigint') return thing + 'n'; | ||
| return str; | ||
| } |
+3
-7
@@ -32,8 +32,6 @@ /** @type {Record<string, string>} */ | ||
| export function is_primitive(thing) { | ||
| return Object(thing) !== thing; | ||
| return thing === null || (typeof thing !== 'object' && typeof thing !== 'function'); | ||
| } | ||
| const object_proto_names = /* @__PURE__ */ Object.getOwnPropertyNames( | ||
| Object.prototype | ||
| ) | ||
| const object_proto_names = /* @__PURE__ */ Object.getOwnPropertyNames(Object.prototype) | ||
| .sort() | ||
@@ -83,5 +81,3 @@ .join('\0'); | ||
| default: | ||
| return char < ' ' | ||
| ? `\\u${char.charCodeAt(0).toString(16).padStart(4, '0')}` | ||
| : ''; | ||
| return char < ' ' ? `\\u${char.charCodeAt(0).toString(16).padStart(4, '0')}` : ''; | ||
| } | ||
@@ -88,0 +84,0 @@ } |
@@ -59,6 +59,6 @@ import * as assert from 'uvu/assert'; | ||
| arr[-1] = 'negative index'; | ||
| arr[2**32 - 1] = 'too large index'; | ||
| arr[2 ** 32 - 1] = 'too large index'; | ||
| assert.equal(valid_array_indices(arr), ['0', '1']); | ||
| }) | ||
| }); | ||
| test.run(); |
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
48542
4.63%15
7.14%1284
1.74%1
-66.67%7
16.67%