Repository URL to install this package:
Version:
2.1.0-1 ▾
|
vending-mp-tcn-dep
/
usr
/
local
/
lib
/
vending
/
mp
/
tcn
/
node_modules
/
safe-stable-stringify
/
index.js
|
---|
'use strict'
const stringify = configure()
// @ts-expect-error
stringify.configure = configure
// @ts-expect-error
stringify.stringify = stringify
// @ts-expect-error
stringify.default = stringify
// @ts-expect-error used for named export
exports.stringify = stringify
// @ts-expect-error used for named export
exports.configure = configure
module.exports = stringify
// eslint-disable-next-line
const strEscapeSequencesRegExp = /[\u0000-\u001f\u0022\u005c\ud800-\udfff]|[\ud800-\udbff](?![\udc00-\udfff])|(?:[^\ud800-\udbff]|^)[\udc00-\udfff]/
// eslint-disable-next-line
const strEscapeSequencesReplacer = /[\u0000-\u001f\u0022\u005c\ud800-\udfff]|[\ud800-\udbff](?![\udc00-\udfff])|(?:[^\ud800-\udbff]|^)[\udc00-\udfff]/g
// Escaped special characters. Use empty strings to fill up unused entries.
const meta = [
'\\u0000', '\\u0001', '\\u0002', '\\u0003', '\\u0004',
'\\u0005', '\\u0006', '\\u0007', '\\b', '\\t',
'\\n', '\\u000b', '\\f', '\\r', '\\u000e',
'\\u000f', '\\u0010', '\\u0011', '\\u0012', '\\u0013',
'\\u0014', '\\u0015', '\\u0016', '\\u0017', '\\u0018',
'\\u0019', '\\u001a', '\\u001b', '\\u001c', '\\u001d',
'\\u001e', '\\u001f', '', '', '\\"',
'', '', '', '', '', '', '', '', '', '',
'', '', '', '', '', '', '', '', '', '',
'', '', '', '', '', '', '', '', '', '',
'', '', '', '', '', '', '', '', '', '',
'', '', '', '', '', '', '', '', '', '',
'', '', '', '', '', '', '', '\\\\'
]
function escapeFn (str) {
if (str.length === 2) {
const charCode = str.charCodeAt(1)
return `${str[0]}\\u${charCode.toString(16)}`
}
const charCode = str.charCodeAt(0)
return meta.length > charCode
? meta[charCode]
: `\\u${charCode.toString(16)}`
}
// Escape C0 control characters, double quotes, the backslash and every code
// unit with a numeric value in the inclusive range 0xD800 to 0xDFFF.
function strEscape (str) {
// Some magic numbers that worked out fine while benchmarking with v8 8.0
if (str.length < 5000 && !strEscapeSequencesRegExp.test(str)) {
return str
}
if (str.length > 100) {
return str.replace(strEscapeSequencesReplacer, escapeFn)
}
let result = ''
let last = 0
for (let i = 0; i < str.length; i++) {
const point = str.charCodeAt(i)
if (point === 34 || point === 92 || point < 32) {
result += `${str.slice(last, i)}${meta[point]}`
last = i + 1
} else if (point >= 0xd800 && point <= 0xdfff) {
if (point <= 0xdbff && i + 1 < str.length) {
const point = str.charCodeAt(i + 1)
if (point >= 0xdc00 && point <= 0xdfff) {
i++
continue
}
}
result += `${str.slice(last, i)}${`\\u${point.toString(16)}`}`
last = i + 1
}
}
result += str.slice(last)
return result
}
function insertSort (array) {
// Insertion sort is very efficient for small input sizes but it has a bad
// worst case complexity. Thus, use native array sort for bigger values.
if (array.length > 2e2) {
return array.sort()
}
for (let i = 1; i < array.length; i++) {
const currentValue = array[i]
let position = i
while (position !== 0 && array[position - 1] > currentValue) {
array[position] = array[position - 1]
position--
}
array[position] = currentValue
}
return array
}
const typedArrayPrototypeGetSymbolToStringTag =
Object.getOwnPropertyDescriptor(
Object.getPrototypeOf(
Object.getPrototypeOf(
new Uint8Array()
)
),
Symbol.toStringTag
).get
function isTypedArrayWithEntries (value) {
return typedArrayPrototypeGetSymbolToStringTag.call(value) !== undefined && value.length !== 0
}
function stringifyTypedArray (array, separator, maximumBreadth) {
if (array.length < maximumBreadth) {
maximumBreadth = array.length
}
const whitespace = separator === ',' ? '' : ' '
let res = `"0":${whitespace}${array[0]}`
for (let i = 1; i < maximumBreadth; i++) {
res += `${separator}"${i}":${whitespace}${array[i]}`
}
return res
}
function getCircularValueOption (options) {
if (options && Object.prototype.hasOwnProperty.call(options, 'circularValue')) {
var circularValue = options.circularValue
if (typeof circularValue === 'string') {
return `"${circularValue}"`
}
if (circularValue == null) {
return circularValue
}
if (circularValue === Error || circularValue === TypeError) {
return {
toString () {
throw new TypeError('Converting circular structure to JSON')
}
}
}
throw new TypeError('The "circularValue" argument must be of type string or the value null or undefined')
}
return '"[Circular]"'
}
function getBooleanOption (options, key) {
if (options && Object.prototype.hasOwnProperty.call(options, key)) {
var value = options[key]
if (typeof value !== 'boolean') {
throw new TypeError(`The "${key}" argument must be of type boolean`)
}
}
return value === undefined ? true : value
}
function getPositiveIntegerOption (options, key) {
if (options && Object.prototype.hasOwnProperty.call(options, key)) {
var value = options[key]
if (typeof value !== 'number') {
throw new TypeError(`The "${key}" argument must be of type number`)
}
if (!Number.isInteger(value)) {
throw new TypeError(`The "${key}" argument must be an integer`)
}
if (value < 1) {
throw new RangeError(`The "${key}" argument must be >= 1`)
}
}
return value === undefined ? Infinity : value
}
function getItemCount (number) {
if (number === 1) {
return '1 item'
}
return `${number} items`
}
function getUniqueReplacerSet (replacerArray) {
const replacerSet = new Set()
for (const value of replacerArray) {
if (typeof value === 'string') {
replacerSet.add(value)
} else if (typeof value === 'number') {
replacerSet.add(String(value))
}
}
return replacerSet
}
function configure (options) {
const circularValue = getCircularValueOption(options)
const bigint = getBooleanOption(options, 'bigint')
const deterministic = getBooleanOption(options, 'deterministic')
const maximumDepth = getPositiveIntegerOption(options, 'maximumDepth')
const maximumBreadth = getPositiveIntegerOption(options, 'maximumBreadth')
function stringifyFnReplacer (key, parent, stack, replacer, spacer, indentation) {
let value = parent[key]
if (typeof value === 'object' && value !== null && typeof value.toJSON === 'function') {
value = value.toJSON(key)
}
value = replacer.call(parent, key, value)
switch (typeof value) {
case 'string':
return `"${strEscape(value)}"`
case 'object': {
if (value === null) {
return 'null'
}
if (stack.indexOf(value) !== -1) {
return circularValue
}
let res = ''
let join = ','
const originalIndentation = indentation
if (Array.isArray(value)) {
if (value.length === 0) {
return '[]'
}
if (maximumDepth < stack.length + 1) {
return '"[Array]"'
}
stack.push(value)
if (spacer !== '') {
indentation += spacer
res += `\n${indentation}`
join = `,\n${indentation}`
}
const maximumValuesToStringify = Math.min(value.length, maximumBreadth)
let i = 0
for (; i < maximumValuesToStringify - 1; i++) {
const tmp = stringifyFnReplacer(i, value, stack, replacer, spacer, indentation)
res += tmp !== undefined ? tmp : 'null'
res += join
}
const tmp = stringifyFnReplacer(i, value, stack, replacer, spacer, indentation)
res += tmp !== undefined ? tmp : 'null'
if (value.length - 1 > maximumBreadth) {
const removedKeys = value.length - maximumBreadth - 1
res += `${join}"... ${getItemCount(removedKeys)} not stringified"`
}
if (spacer !== '') {
res += `\n${originalIndentation}`
}
stack.pop()
return `[${res}]`
}
let keys = Object.keys(value)
const keyLength = keys.length
if (keyLength === 0) {
return '{}'
}
if (maximumDepth < stack.length + 1) {
return '"[Object]"'
}
let whitespace = ''
let separator = ''
if (spacer !== '') {
indentation += spacer
join = `,\n${indentation}`
whitespace = ' '
}
let maximumPropertiesToStringify = Math.min(keyLength, maximumBreadth)
if (isTypedArrayWithEntries(value)) {
res += stringifyTypedArray(value, join, maximumBreadth)
keys = keys.slice(value.length)
maximumPropertiesToStringify -= value.length
separator = join
}
if (deterministic) {
keys = insertSort(keys)
}
stack.push(value)
for (let i = 0; i < maximumPropertiesToStringify; i++) {
const key = keys[i]
const tmp = stringifyFnReplacer(key, value, stack, replacer, spacer, indentation)
if (tmp !== undefined) {
res += `${separator}"${strEscape(key)}":${whitespace}${tmp}`
separator = join
}
}
if (keyLength > maximumBreadth) {
const removedKeys = keyLength - maximumBreadth
res += `${separator}"...":${whitespace}"${getItemCount(removedKeys)} not stringified"`
separator = join
}
if (spacer !== '' && separator.length > 1) {
res = `\n${indentation}${res}\n${originalIndentation}`
}
stack.pop()
return `{${res}}`
}
case 'number':
return isFinite(value) ? String(value) : 'null'
case 'boolean':
return value === true ? 'true' : 'false'
case 'bigint':
return bigint ? String(value) : undefined
}
}
function stringifyArrayReplacer (key, value, stack, replacer, spacer, indentation) {
if (typeof value === 'object' && value !== null && typeof value.toJSON === 'function') {
value = value.toJSON(key)
}
switch (typeof value) {
case 'string':
return `"${strEscape(value)}"`
case 'object': {
if (value === null) {
return 'null'
}
if (stack.indexOf(value) !== -1) {
return circularValue
}
const originalIndentation = indentation
let res = ''
let join = ','
if (Array.isArray(value)) {
if (value.length === 0) {
return '[]'
}
if (maximumDepth < stack.length + 1) {
return '"[Array]"'
}
stack.push(value)
if (spacer !== '') {
indentation += spacer
res += `\n${indentation}`
join = `,\n${indentation}`
}
const maximumValuesToStringify = Math.min(value.length, maximumBreadth)
let i = 0
for (; i < maximumValuesToStringify - 1; i++) {
const tmp = stringifyArrayReplacer(i, value[i], stack, replacer, spacer, indentation)
res += tmp !== undefined ? tmp : 'null'
res += join
}
const tmp = stringifyArrayReplacer(i, value[i], stack, replacer, spacer, indentation)
res += tmp !== undefined ? tmp : 'null'
if (value.length - 1 > maximumBreadth) {
const removedKeys = value.length - maximumBreadth - 1
res += `${join}"... ${getItemCount(removedKeys)} not stringified"`
}
if (spacer !== '') {
res += `\n${originalIndentation}`
}
stack.pop()
return `[${res}]`
}
if (replacer.size === 0) {
return '{}'
}
stack.push(value)
let whitespace = ''
if (spacer !== '') {
indentation += spacer
join = `,\n${indentation}`
whitespace = ' '
}
let separator = ''
for (const key of replacer) {
const tmp = stringifyArrayReplacer(key, value[key], stack, replacer, spacer, indentation)
if (tmp !== undefined) {
res += `${separator}"${strEscape(key)}":${whitespace}${tmp}`
separator = join
}
}
if (spacer !== '' && separator.length > 1) {
res = `\n${indentation}${res}\n${originalIndentation}`
}
stack.pop()
return `{${res}}`
}
case 'number':
return isFinite(value) ? String(value) : 'null'
case 'boolean':
return value === true ? 'true' : 'false'
case 'bigint':
return bigint ? String(value) : undefined
}
}
function stringifyIndent (key, value, stack, spacer, indentation) {
switch (typeof value) {
case 'string':
return `"${strEscape(value)}"`
case 'object': {
if (value === null) {
return 'null'
}
if (typeof value.toJSON === 'function') {
value = value.toJSON(key)
// Prevent calling `toJSON` again.
if (typeof value !== 'object') {
return stringifyIndent(key, value, stack, spacer, indentation)
}
if (value === null) {
return 'null'
}
}
if (stack.indexOf(value) !== -1) {
return circularValue
}
const originalIndentation = indentation
if (Array.isArray(value)) {
if (value.length === 0) {
return '[]'
}
if (maximumDepth < stack.length + 1) {
return '"[Array]"'
}
stack.push(value)
indentation += spacer
let res = `\n${indentation}`
const join = `,\n${indentation}`
const maximumValuesToStringify = Math.min(value.length, maximumBreadth)
let i = 0
for (; i < maximumValuesToStringify - 1; i++) {
const tmp = stringifyIndent(i, value[i], stack, spacer, indentation)
res += tmp !== undefined ? tmp : 'null'
res += join
}
const tmp = stringifyIndent(i, value[i], stack, spacer, indentation)
res += tmp !== undefined ? tmp : 'null'
if (value.length - 1 > maximumBreadth) {
const removedKeys = value.length - maximumBreadth - 1
res += `${join}"... ${getItemCount(removedKeys)} not stringified"`
}
res += `\n${originalIndentation}`
stack.pop()
return `[${res}]`
}
let keys = Object.keys(value)
const keyLength = keys.length
if (keyLength === 0) {
return '{}'
}
if (maximumDepth < stack.length + 1) {
return '"[Object]"'
}
indentation += spacer
const join = `,\n${indentation}`
let res = ''
let separator = ''
let maximumPropertiesToStringify = Math.min(keyLength, maximumBreadth)
if (isTypedArrayWithEntries(value)) {
res += stringifyTypedArray(value, join, maximumBreadth)
keys = keys.slice(value.length)
maximumPropertiesToStringify -= value.length
separator = join
}
if (deterministic) {
keys = insertSort(keys)
}
stack.push(value)
for (let i = 0; i < maximumPropertiesToStringify; i++) {
const key = keys[i]
const tmp = stringifyIndent(key, value[key], stack, spacer, indentation)
if (tmp !== undefined) {
res += `${separator}"${strEscape(key)}": ${tmp}`
separator = join
}
}
if (keyLength > maximumBreadth) {
const removedKeys = keyLength - maximumBreadth
res += `${separator}"...": "${getItemCount(removedKeys)} not stringified"`
separator = join
}
if (separator !== '') {
res = `\n${indentation}${res}\n${originalIndentation}`
}
stack.pop()
return `{${res}}`
}
case 'number':
return isFinite(value) ? String(value) : 'null'
case 'boolean':
return value === true ? 'true' : 'false'
case 'bigint':
return bigint ? String(value) : undefined
}
}
function stringifySimple (key, value, stack) {
switch (typeof value) {
case 'string':
return `"${strEscape(value)}"`
case 'object': {
if (value === null) {
return 'null'
}
if (typeof value.toJSON === 'function') {
value = value.toJSON(key)
// Prevent calling `toJSON` again
if (typeof value !== 'object') {
return stringifySimple(key, value, stack)
}
if (value === null) {
return 'null'
}
}
if (stack.indexOf(value) !== -1) {
return circularValue
}
let res = ''
if (Array.isArray(value)) {
if (value.length === 0) {
return '[]'
}
if (maximumDepth < stack.length + 1) {
return '"[Array]"'
}
stack.push(value)
const maximumValuesToStringify = Math.min(value.length, maximumBreadth)
let i = 0
for (; i < maximumValuesToStringify - 1; i++) {
const tmp = stringifySimple(i, value[i], stack)
res += tmp !== undefined ? tmp : 'null'
res += ','
}
const tmp = stringifySimple(i, value[i], stack)
res += tmp !== undefined ? tmp : 'null'
if (value.length - 1 > maximumBreadth) {
const removedKeys = value.length - maximumBreadth - 1
res += `,"... ${getItemCount(removedKeys)} not stringified"`
}
stack.pop()
return `[${res}]`
}
let keys = Object.keys(value)
const keyLength = keys.length
if (keyLength === 0) {
return '{}'
}
if (maximumDepth < stack.length + 1) {
return '"[Object]"'
}
let separator = ''
let maximumPropertiesToStringify = Math.min(keyLength, maximumBreadth)
if (isTypedArrayWithEntries(value)) {
res += stringifyTypedArray(value, ',', maximumBreadth)
keys = keys.slice(value.length)
maximumPropertiesToStringify -= value.length
separator = ','
}
if (deterministic) {
keys = insertSort(keys)
}
stack.push(value)
for (let i = 0; i < maximumPropertiesToStringify; i++) {
const key = keys[i]
const tmp = stringifySimple(key, value[key], stack)
if (tmp !== undefined) {
res += `${separator}"${strEscape(key)}":${tmp}`
separator = ','
}
}
if (keyLength > maximumBreadth) {
const removedKeys = keyLength - maximumBreadth
res += `${separator}"...":"${getItemCount(removedKeys)} not stringified"`
}
stack.pop()
return `{${res}}`
}
case 'number':
return isFinite(value) ? String(value) : 'null'
case 'boolean':
return value === true ? 'true' : 'false'
case 'bigint':
return bigint ? String(value) : undefined
}
}
function stringify (value, replacer, space) {
if (arguments.length > 1) {
let spacer = ''
if (typeof space === 'number') {
spacer = ' '.repeat(Math.min(space, 10))
} else if (typeof space === 'string') {
spacer = space.slice(0, 10)
}
if (replacer != null) {
if (typeof replacer === 'function') {
return stringifyFnReplacer('', { '': value }, [], replacer, spacer, '')
}
if (Array.isArray(replacer)) {
return stringifyArrayReplacer('', value, [], getUniqueReplacerSet(replacer), spacer, '')
}
}
if (spacer.length !== 0) {
return stringifyIndent('', value, [], spacer, '')
}
}
return stringifySimple('', value, [])
}
return stringify
}