Socket
Socket
Sign inDemoInstall

safe-stable-stringify

Package Overview
Dependencies
Maintainers
1
Versions
13
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

safe-stable-stringify - npm Package Compare versions

Comparing version 1.0.1 to 1.1.0

2

benchmark.js

@@ -5,3 +5,3 @@ 'use strict'

const suite = new Benchmark.Suite()
const stringify = require('fast-safe-stringify').stable
const stringify = require('.')

@@ -8,0 +8,0 @@ const array = new Array(10).fill(0).map((_, i) => i)

@@ -13,2 +13,3 @@ 'use strict'

'faster-stable-stringify': true,
'json-stringify-deterministic': true,
'fast-safe-stringify': 'stable',

@@ -15,0 +16,0 @@ 'this': require('.')

@@ -1,3 +0,4 @@

declare function stringify(data: any): string;
declare function stringify(value: any, replacer?: (key: string, value: any) => any, space?: string | number): string;
declare function stringify(value: any, replacer?: (number | string)[] | null, space?: string | number): string;
export default stringify;
{
"name": "safe-stable-stringify",
"version": "1.0.1",
"version": "1.1.0",
"description": "Deterministic and safely JSON.stringify to quickly serialize JavaScript objects",

@@ -23,3 +23,5 @@ "keywords": [

"benchmark": "node benchmark.js",
"compare": "node compare.js"
"compare": "node compare.js",
"coverage": "nyc --reporter=html --reporter=text npm test",
"lint": "standard . --fix"
},

@@ -32,11 +34,13 @@ "author": "Ruben Bridgewater",

"benchmark": "^2.1.4",
"clone": "^2.1.0",
"clone": "^2.1.2",
"fast-json-stable-stringify": "^2.0.0",
"fast-safe-stringify": "^2.0.2",
"fast-safe-stringify": "^2.0.6",
"fast-stable-stringify": "^1.0.0",
"faster-stable-stringify": "^1.0.0",
"json-stable-stringify": "^1.0.1",
"json-stringify-deterministic": "^1.0.1",
"json-stringify-safe": "^5.0.1",
"standard": "^11.0.0-beta.0",
"tap": "^11.0.0"
"nyc": "^13.0.1",
"standard": "^12.0.1",
"tap": "^12.0.1"
},

@@ -43,0 +47,0 @@ "repository": {

@@ -74,17 +74,2 @@ # safe-stable-stringify

array: deep circular x 1,400,577 ops/sec ±1.00% (92 runs sampled)
full replacer: simple object x 993,352 ops/sec ±1.49% (92 runs sampled)
full replacer: circular x 467,264 ops/sec ±0.68% (95 runs sampled)
full replacer: deep x 14,855 ops/sec ±0.82% (91 runs sampled)
full replacer: deep circular x 14,608 ops/sec ±1.68% (95 runs sampled)
full array: simple object x 1,233,430 ops/sec ±0.58% (92 runs sampled)
full array: circular x 1,205,360 ops/sec ±1.33% (90 runs sampled)
full array: deep x 1,175,758 ops/sec ±0.63% (92 runs sampled)
full array: deep circular x 1,171,813 ops/sec ±1.08% (92 runs sampled)
indentation: simple object x 1,385,853 ops/sec ±2.18% (94 runs sampled)
indentation: circular x 598,650 ops/sec ±1.26% (92 runs sampled)
indentation: deep x 16,060 ops/sec ±0.76% (93 runs sampled)
indentation: deep circular x 15,784 ops/sec ±1.31% (95 runs sampled)
```

@@ -95,8 +80,9 @@

```md
fast-json-stable-stringify x 8,906 ops/sec ±0.87% (91 runs sampled)
json-stable-stringify x 6,821 ops/sec ±2.93% (88 runs sampled)
fast-stable-stringify x 10,540 ops/sec ±0.51% (92 runs sampled)
faster-stable-stringify x 8,450 ops/sec ±1.62% (89 runs sampled)
fast-safe-stringify x 15,640 ops/sec ±0.51% (95 runs sampled)
this x 25,482 ops/sec ±1.59% (87 runs sampled)
fast-json-stable-stringify x 9,336 ops/sec ±0.64% (90 runs sampled)
json-stable-stringify x 7,512 ops/sec ±0.63% (91 runs sampled)
fast-stable-stringify x 11,674 ops/sec ±0.58% (92 runs sampled)
faster-stable-stringify x 8,893 ops/sec ±0.51% (92 runs sampled)
json-stringify-deterministic x 6,240 ops/sec ±0.68% (94 runs sampled)
fast-safe-stringify x 15,939 ops/sec ±0.42% (96 runs sampled)
this x 24,048 ops/sec ±0.44% (91 runs sampled)

@@ -106,2 +92,4 @@ The fastest is this

The `fast-safe-stringify` comparison uses the modules stable implementation.
## Acknowledgements

@@ -108,0 +96,0 @@

@@ -28,3 +28,5 @@ 'use strict'

const escapeFn = (str) => meta[str.charCodeAt(0)]
function escapeFn (str) {
return meta[str.charCodeAt(0)]
}

@@ -67,3 +69,3 @@ // Escape control characters, double quotes and the backslash.

var i, res, join
const mind = gap
const startGap = gap
var value = parent[key]

@@ -109,7 +111,7 @@

if (gap !== '') {
res += `\n${mind}`
res += `\n${startGap}`
}
res += ']'
stack.pop()
gap = mind
gap = startGap
return res

@@ -130,29 +132,15 @@ }

}
var last = false
for (i = 0; i < keys.length - 1; i++) {
var separator = ''
for (i = 0; i < keys.length; i++) {
key = keys[i]
const tmp = stringifyFullFn(key, value, stack, replacer, indent)
if (tmp !== undefined) {
if (last) {
res += join
}
res += `"${strEscape(key)}"${gap !== '' ? ': ' : ':'}${tmp}`
last = true
res += `${separator}"${strEscape(key)}"${gap !== '' ? ': ' : ':'}${tmp}`
separator = join
}
}
key = keys[i]
const tmp = stringifyFullFn(key, value, stack, replacer, indent)
if (tmp !== undefined) {
if (last) {
res += join
}
if (gap === '') {
res += `"${strEscape(key)}":${tmp}`
if (gap !== '') {
if (separator !== '') {
res += `\n${startGap}`
} else {
res += `"${strEscape(key)}": ${tmp}\n${mind}`
}
} else if (gap !== '') {
if (last) {
res += `\n${mind}`
} else {
res = '{'

@@ -163,3 +151,3 @@ }

stack.pop()
gap = mind
gap = startGap
return res

@@ -178,3 +166,3 @@ case 'string':

var i, res, join
const mind = gap
const startGap = gap

@@ -218,7 +206,7 @@ if (typeof value === 'object' && value !== null && typeof value.toJSON === 'function') {

if (gap !== '') {
res += `\n${mind}`
res += `\n${startGap}`
}
res += ']'
stack.pop()
gap = mind
gap = startGap
return res

@@ -238,3 +226,3 @@ }

}
var last = false
var separator = ''
for (i = 0; i < replacer.length; i++) {

@@ -245,7 +233,4 @@ if (typeof replacer[i] === 'string' || typeof replacer[i] === 'number') {

if (tmp !== undefined) {
if (last) {
res += join
}
res += `"${strEscape(key)}"${gap ? ': ' : ':'}${tmp}`
last = true
res += `${separator}"${strEscape(key)}"${gap ? ': ' : ':'}${tmp}`
separator = join
}

@@ -255,4 +240,4 @@ }

if (gap !== '') {
if (last) {
res += `\n${mind}`
if (separator !== '') {
res += `\n${startGap}`
} else {

@@ -264,3 +249,3 @@ res = '{'

stack.pop()
gap = mind
gap = startGap
return res

@@ -279,4 +264,4 @@ case 'string':

function stringifyIndent (key, value, stack, indent) {
var i, res, join, add
const mind = gap
var i, res, join
const startGap = gap

@@ -326,7 +311,7 @@ switch (typeof value) {

if (gap !== '') {
res += `\n${mind}`
res += `\n${startGap}`
}
res += ']'
stack.pop()
gap = mind
gap = startGap
return res

@@ -343,29 +328,25 @@ }

join = ','
add = ''
} else {
add = `\n${gap}`
res += `\n${gap}`
join = `,\n${gap}`
}
for (i = 0; i < keys.length - 1; i++) {
var separator = ''
for (i = 0; i < keys.length; i++) {
key = keys[i]
const tmp = stringifyIndent(key, value[key], stack, indent)
if (tmp !== undefined) {
add += `"${strEscape(key)}"${gap ? ': ' : ':'}${tmp}${join}`
res += `${separator}"${strEscape(key)}"${gap ? ': ' : ':'}${tmp}`
separator = join
}
}
key = keys[i]
const tmp = stringifyIndent(key, value[key], stack, indent)
if (tmp !== undefined) {
if (gap === '') {
add += `"${strEscape(key)}":${tmp}`
if (gap !== '') {
if (separator !== '') {
res += `\n${startGap}`
} else {
add += `"${strEscape(key)}": ${tmp}\n${mind}`
res = '{'
}
}
if (add.length > gap.length + 1) {
res += add
}
res += '}'
stack.pop()
gap = mind
gap = startGap
return res

@@ -424,3 +405,3 @@ case 'string':

res = '{'
var last = false
var separator = ''
for (i = 0; i < replacer.length; i++) {

@@ -431,7 +412,4 @@ if (typeof replacer[i] === 'string' || typeof replacer[i] === 'number') {

if (tmp !== undefined) {
if (last) {
res += ','
}
res += `"${strEscape(key)}":${tmp}`
last = true
res += `${separator}"${strEscape(key)}":${tmp}`
separator = ','
}

@@ -497,22 +475,11 @@ }

res = '{'
var last = false
for (i = 0; i < keys.length - 1; i++) {
var separator = ''
for (i = 0; i < keys.length; i++) {
key = keys[i]
const tmp = stringifyReplacerFn(key, value, stack, replacer)
if (tmp !== undefined) {
if (last === true) {
res += ','
}
res += `"${strEscape(key)}":${tmp}`
last = true
res += `${separator}"${strEscape(key)}":${tmp}`
separator = ','
}
}
key = keys[i]
const tmp = stringifyReplacerFn(key, value, stack, replacer)
if (tmp !== undefined) {
if (last === true) {
res += ','
}
res += `"${strEscape(key)}":${tmp}`
}
res += '}'

@@ -579,15 +546,12 @@ stack.pop()

stack.push(value)
var separator = ''
res = '{'
for (i = 0; i < keys.length - 1; i++) {
for (i = 0; i < keys.length; i++) {
key = keys[i]
const tmp = stringifySimple(key, value[key], stack)
if (tmp !== undefined) {
res += `"${strEscape(key)}":${tmp},`
res += `${separator}"${strEscape(key)}":${tmp}`
separator = ','
}
}
key = keys[i]
const tmp = stringifySimple(key, value[key], stack)
if (tmp !== undefined) {
res += `"${strEscape(key)}":${tmp}`
}
res += '}'

@@ -594,0 +558,0 @@ stack.pop()

@@ -17,6 +17,6 @@ const { test } = require('tap')

test('nested circular reference to root', function (assert) {
const fixture = { name: 'Tywin Lannister' }
const fixture = { name: 'Tywin\n\t"Lannister' }
fixture.id = { circle: fixture }
const expected = JSON.stringify(
{ id: { circle: '[Circular]' }, name: 'Tywin Lannister' }
{ id: { circle: '[Circular]' }, name: 'Tywin\n\t"Lannister' }
)

@@ -29,7 +29,7 @@ const actual = stringify(fixture)

test('child circular reference', function (assert) {
const fixture = { name: 'Tywin Lannister', child: { name: 'Tyrion Lannister' } }
const fixture = { name: 'Tywin Lannister', child: { name: 'Tyrion\n\t"Lannister'.repeat(20) } }
fixture.child.dinklage = fixture.child
const expected = JSON.stringify({
child: {
dinklage: '[Circular]', name: 'Tyrion Lannister'
dinklage: '[Circular]', name: 'Tyrion\n\t"Lannister'.repeat(20)
},

@@ -299,4 +299,4 @@ name: 'Tywin Lannister'

// The null element will be removed!
const expected = JSON.stringify({ f: null, null: true, 1: false }, replacer, 2)
const actual = stringify({ f: null, null: true, 1: false }, replacer, 2)
const expected = JSON.stringify({ f: null, null: true, 1: [false, -Infinity, 't'] }, replacer, 2)
const actual = stringify({ f: null, null: true, 1: [false, -Infinity, 't'] }, replacer, 2)
assert.is(actual, expected)

@@ -317,4 +317,4 @@ assert.end()

}
const expected = JSON.stringify({ f: 1 }, replacer, ' ')
const actual = stringify({ f: 1 }, replacer, ' ')
const expected = JSON.stringify({ f: 1, b: null, c: 't', d: Infinity, e: true }, replacer, ' ')
const actual = stringify({ f: 1, b: null, c: 't', d: Infinity, e: true }, replacer, ' ')
assert.is(actual, expected)

@@ -326,4 +326,4 @@ assert.end()

const replacer = ['']
const expected = JSON.stringify({ f: 1 }, replacer, ' ')
const actual = stringify({ f: 1 }, replacer, ' ')
const expected = JSON.stringify({ f: 1, b: null, c: 't', d: Infinity, e: true }, replacer, ' ')
const actual = stringify({ f: 1, b: null, c: 't', d: Infinity, e: true }, replacer, ' ')
assert.is(actual, expected)

@@ -348,4 +348,4 @@ assert.end()

test('array nulls, replacer and indentation', function (assert) {
const expected = JSON.stringify([null, null], (_, v) => v, 3)
const actual = stringify([null, null], (_, v) => v, 3)
const expected = JSON.stringify([null, Infinity, 5, true, false], (_, v) => v, 3)
const actual = stringify([null, Infinity, 5, true, false], (_, v) => v, 3)
assert.is(actual, expected)

@@ -355,2 +355,9 @@ assert.end()

test('array nulls and replacer', function (assert) {
const expected = JSON.stringify([null, Infinity, 5, true, false], (_, v) => v)
const actual = stringify([null, Infinity, 5, true, false], (_, v) => v)
assert.is(actual, expected)
assert.end()
})
test('array nulls, array replacer and indentation', function (assert) {

@@ -363,7 +370,46 @@ const expected = JSON.stringify([null, null], [false], 3)

test('array and array replacer', function (assert) {
const expected = JSON.stringify([null, null, 't', Infinity, true, false], [2])
const actual = stringify([null, null, 't', Infinity, true, false], [2])
assert.is(actual, expected)
assert.end()
})
test('indentation with elements', function (assert) {
const expected = JSON.stringify({ a: 1 }, null, 5)
const actual = stringify({ a: 1 }, null, 5)
const expected = JSON.stringify({ a: 1, b: [null, 't', Infinity, true] }, null, 5)
const actual = stringify({ a: 1, b: [null, 't', Infinity, true] }, null, 5)
assert.is(actual, expected)
assert.end()
})
test('object with undefined values', function (assert) {
let obj = { a: 1, c: undefined, b: 'hello' }
let expected = JSON.stringify(obj)
let actual = stringify(obj)
assert.is(actual, expected)
obj = { b: 'hello', a: undefined, c: 1 }
expected = JSON.stringify(obj)
actual = stringify(obj)
assert.is(actual, expected)
assert.end()
})
test('undefined values and indented', function (assert) {
let obj = { a: 1, c: undefined, b: 'hello' }
let expected = JSON.stringify(obj, null, 2)
let actual = stringify(obj, null, 2)
assert.is(actual, expected)
obj = { b: 'hello', a: undefined, c: 1 }
expected = JSON.stringify(obj)
actual = stringify(obj)
assert.is(actual, expected)
assert.end()
})

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc