http-querystring-stringify
Advanced tools
Comparing version 1.0.0 to 2.0.0
161
index.js
@@ -1,122 +0,105 @@ | ||
'use strict'; | ||
'use strict' | ||
toQuerystring.serialize = serialize; | ||
toQuerystring.shake = shake; | ||
toQuerystring.normalize = normalize; | ||
stringify.serialize = serialize | ||
stringify.shake = shake | ||
stringify.normalize = normalize | ||
module.exports = toQuerystring; | ||
module.exports = stringify | ||
function toQuerystring( i ){ | ||
var shaken = shake(normalize(i)); | ||
function stringify(i) { | ||
if (i === null || typeof i !== 'object' || Array.isArray(i)) { | ||
throw new Error('Only objects can be stringified') | ||
} | ||
if (shaken === undefined) | ||
return ''; | ||
const shaken = shake(normalize(i)) | ||
return serialize(shaken); | ||
if (shaken === undefined) return '' | ||
return serialize(shaken) | ||
} | ||
function serialize( i, prefix ){ | ||
function serialize(i, prefix) { | ||
if (Array.isArray(i)) { | ||
var hasComplex = i.some(isComplex); | ||
const hasComplex = i.some(isComplex) | ||
return i.map(function( i, idx ){ | ||
return serialize(i, prefix+(hasComplex | ||
? '['+idx+']' | ||
: '[]')); | ||
}).join('&'); | ||
return i | ||
.map((i, idx) => { | ||
return serialize( | ||
i, | ||
prefix + (hasComplex ? '[' + idx + ']' : '[]') | ||
) | ||
}) | ||
.join('&') | ||
} | ||
if (typeof i === 'object') | ||
return Object.keys(i).map(function( key ){ | ||
return serialize(i[key], prefix === undefined | ||
? encodeURIComponent(key) | ||
: prefix+'['+encodeURIComponent(key)+']'); | ||
}).join('&'); | ||
return prefix+'='+encodeURIComponent(i); | ||
if (typeof i === 'object') { | ||
return Object.keys(i) | ||
.map(key => { | ||
return serialize( | ||
i[key], | ||
prefix === undefined | ||
? encodeURIComponent(key) | ||
: prefix + '[' + encodeURIComponent(key) + ']' | ||
) | ||
}) | ||
.join('&') | ||
} | ||
return prefix + '=' + encodeURIComponent(i) | ||
} | ||
function shake( i ){ | ||
if (i === undefined) | ||
return; | ||
function shake(i) { | ||
if (i === undefined) return | ||
if (Array.isArray(i)) { | ||
var shaken = i.map(shake).filter(isDefined); | ||
const shaken = i.map(shake).filter(isDefined) | ||
if (shaken.length === 0) | ||
return; | ||
return shaken; | ||
if (shaken.length === 0) return | ||
return shaken | ||
} | ||
if (typeof i === 'object') { | ||
var empty = true; | ||
let empty = true | ||
const shaken = Object.keys(i).reduce((o, key) => { | ||
const shaken = shake(i[key]) | ||
var shaken = Object.keys(i).reduce(function( o, key ){ | ||
var shaken = shake(i[key]); | ||
if (shaken !== undefined) { | ||
empty = false; | ||
o[key] = shaken; | ||
empty = false | ||
o[key] = shaken | ||
} | ||
return o; | ||
}, {}); | ||
return o | ||
}, {}) | ||
if (empty) | ||
return; | ||
return shaken; | ||
if (empty) return | ||
return shaken | ||
} | ||
return i; | ||
return i | ||
} | ||
function normalize( i ){ | ||
if (i === undefined) | ||
return undefined; | ||
function normalize(i) { | ||
if (i === undefined) return undefined | ||
if (i === null) return '' | ||
if (i === true) return 'y' | ||
if (i === false) return 'n' | ||
if (typeof i.toJSON === 'function') return normalize(i.toJSON()) | ||
if (i === null) | ||
return ''; | ||
const type = typeof i | ||
if (i === true) | ||
return 'y'; | ||
if (type === 'string') return i | ||
if (Array.isArray(i)) return i.map(normalize) | ||
if (type === 'object') { | ||
return Object.keys(i).reduce((o, key) => { | ||
o[key] = normalize(i[key]) | ||
if (i === false) | ||
return 'n'; | ||
return o | ||
}, {}) | ||
} | ||
if (typeof i.toJSON === 'function') | ||
return normalize(i.toJSON()); | ||
var type = typeof i; | ||
if (type === 'string') | ||
return i; | ||
if (Array.isArray(i)) | ||
return i.map(normalize); | ||
if (type === 'object') | ||
return Object.keys(i).reduce(function( o, key ){ | ||
o[key] = normalize(i[key]); | ||
return o; | ||
}, {}); | ||
return i+''; | ||
return i + '' | ||
} | ||
function isDefined( i ){ | ||
return i !== undefined; | ||
function isDefined(i) { | ||
return i !== undefined | ||
} | ||
function isComplex( i ){ | ||
if (Array.isArray(i)) | ||
return true; | ||
if (typeof i === 'object') | ||
return true; | ||
return false; | ||
function isComplex(i) { | ||
if (Array.isArray(i)) return true | ||
if (typeof i === 'object') return true | ||
return false | ||
} |
{ | ||
"name": "http-querystring-stringify", | ||
"description": "Create querystrings", | ||
"version": "1.0.0", | ||
"version": "2.0.0", | ||
"repository": "srcagency/http-querystring-stringify", | ||
"scripts": { | ||
"test": "node test" | ||
"test": "node test", | ||
"format": "prettier --write ./*" | ||
}, | ||
"devDependencies": { | ||
"tape": "^4.6.3" | ||
"prettier": "^1.14.3", | ||
"tape": "^4.9.1" | ||
}, | ||
"prettier": { | ||
"semi": false, | ||
"singleQuote": true, | ||
"useTabs": true, | ||
"bracketSpacing": false, | ||
"trailingComma": "es5", | ||
"tabWidth": 4, | ||
"overrides": [ | ||
{ | ||
"files": "*.md", | ||
"options": { | ||
"tabWidth": 2 | ||
} | ||
} | ||
] | ||
}, | ||
"license": "MIT" | ||
} |
@@ -13,8 +13,8 @@ # http-querystring-stringify | ||
This package was written because serialization seems to happen most often on | ||
the client as a single operation and similar performance-focused libraries had | ||
This package was written because serialization seems to happen most often on the | ||
client as a single operation and similar performance-focused libraries had | ||
trade-offs and bugs while others carried huge dependencies. | ||
```js | ||
var stringify = require('http-querystring-stringify'); | ||
var stringify = require('http-querystring-stringify') | ||
@@ -24,15 +24,13 @@ stringify({ | ||
last: 'Wayne', | ||
}); | ||
}) | ||
// -> first=John&last=Wayne | ||
stringify({ | ||
brands: [ 'KitKat', 'Snickers', 'Bounty' ], | ||
}); | ||
brands: ['KitKat', 'Snickers', 'Bounty'], | ||
}) | ||
// -> brands[]=KitKat&brands[]=Snickers&brands[]=Bounty | ||
stringify({ | ||
sites: [ | ||
{ name: 'facebook', 'color': 'blue' }, | ||
], | ||
}); | ||
sites: [{name: 'facebook', color: 'blue'}], | ||
}) | ||
// -> sites[0][name]=facebook&sites[0][color]=blue | ||
@@ -44,3 +42,59 @@ ``` | ||
- `null` is represented by an empty string | ||
- `undefined` values will be skipped completely | ||
- `undefined` values will be skipped completely (like `JSON.stringify` does) | ||
- arrays will be numbered only if they contain arrays or objects themselves | ||
## Compatibility with parsers | ||
Generally there are two types of parsers: those supporting extended nesting and | ||
those that just support repeated keys. | ||
### Perfect support (extended nesting): | ||
- [querystringparser](https://github.com/petkaantonov/querystringparser) (read | ||
open issues) | ||
- [qs](https://github.com/ljharb/qs) | ||
```js | ||
var input = { | ||
a: '', | ||
b: 's', | ||
c: [ '1', '2', '3' ], | ||
d: '&=[]', | ||
e: [ '1', '2', [ '3', '4' ] ], | ||
f: [ '1', { a: '1' } ], | ||
} | ||
deepEqual(parse(stringify(input)), input); | ||
-> true; | ||
``` | ||
### Will flatten: | ||
- [Node.js built-in](https://nodejs.org/api/url.html) | ||
- [URI.js](https://github.com/medialize/URI.js) | ||
```js | ||
parse(stringify({ | ||
a: '', | ||
b: 's', | ||
c: [ '1', '2', '3' ], | ||
d: '&=[]', | ||
e: [ '1', '2', [ '3', '4' ] ], | ||
f: [ '1', { a: '1' } ], | ||
})); | ||
-> { | ||
a: '', | ||
b: 's', | ||
d: '&=[]', | ||
// expect arrays to be collapsed like this | ||
'c[]': [ '1', '2', '3' ], | ||
// expect objects and multi-level arrays to be flattened like this | ||
'e[0]': '1', | ||
'e[1]': '2', | ||
'e[2][]': [ '3', '4' ], | ||
'f[0]': '1', | ||
'f[1][a]': '1', | ||
}; | ||
``` |
719
test.js
@@ -1,124 +0,149 @@ | ||
'use strict'; | ||
'use strict' | ||
var test = require('tape'); | ||
var stringify = require('./'); | ||
const test = require('tape') | ||
const stringify = require('./') | ||
test('normalize', function( t ){ | ||
t.deepEqual(stringify.normalize([ | ||
undefined, | ||
null, | ||
true, | ||
false, | ||
1, | ||
'a', | ||
'', | ||
'&=[]', | ||
// parsers | ||
const nodejs = require('url').parse | ||
const querystringparser = require('querystringparser').parse | ||
const qs = require('qs').parse | ||
const urijs = require('urijs').parseQuery | ||
{ | ||
a: undefined, | ||
b: null, | ||
c: true, | ||
d: false, | ||
e: 'a', | ||
f: '', | ||
g: '&=[]', | ||
}, | ||
]), [ | ||
undefined, | ||
'', | ||
'y', | ||
'n', | ||
'1', | ||
'a', | ||
'', | ||
'&=[]', | ||
test('normalize', t => { | ||
t.deepEqual( | ||
stringify.normalize([ | ||
undefined, | ||
null, | ||
true, | ||
false, | ||
1, | ||
'a', | ||
'', | ||
'&=[]', | ||
{ | ||
a: undefined, | ||
b: '', | ||
c: 'y', | ||
d: 'n', | ||
e: 'a', | ||
f: '', | ||
g: '&=[]', | ||
}, | ||
]); | ||
{ | ||
a: undefined, | ||
b: null, | ||
c: true, | ||
d: false, | ||
e: 'a', | ||
f: '', | ||
g: '&=[]', | ||
}, | ||
]), | ||
[ | ||
undefined, | ||
'', | ||
'y', | ||
'n', | ||
'1', | ||
'a', | ||
'', | ||
'&=[]', | ||
t.deepEqual(stringify.normalize({}), {}); | ||
{ | ||
a: undefined, | ||
b: '', | ||
c: 'y', | ||
d: 'n', | ||
e: 'a', | ||
f: '', | ||
g: '&=[]', | ||
}, | ||
] | ||
) | ||
t.end(); | ||
}); | ||
t.deepEqual(stringify.normalize({}), {}) | ||
test('shake', function( t ){ | ||
t.deepEqual(stringify.shake([ | ||
undefined, | ||
'a', | ||
undefined, | ||
'', | ||
{}, | ||
{ a: undefined }, | ||
{ | ||
a: undefined, | ||
b: '', | ||
}, | ||
[], | ||
[ undefined ], | ||
[ undefined, '' ], | ||
]), [ | ||
'a', | ||
'', | ||
{ b: '' }, | ||
[ '' ] | ||
]); | ||
t.end() | ||
}) | ||
t.equal(stringify.shake({}), undefined); | ||
test('shake', t => { | ||
t.deepEqual( | ||
stringify.shake([ | ||
undefined, | ||
'a', | ||
undefined, | ||
'', | ||
{}, | ||
{a: undefined}, | ||
{ | ||
a: undefined, | ||
b: '', | ||
}, | ||
[], | ||
[undefined], | ||
[undefined, ''], | ||
]), | ||
['a', '', {b: ''}, ['']] | ||
) | ||
t.end(); | ||
}); | ||
t.equal(stringify.shake({}), undefined) | ||
test('serialize', function( t ){ | ||
t.equal(stringify.serialize({ | ||
a: '', | ||
b: 's', | ||
c: [ '1', '2', '3' ], | ||
d: '&=[]', | ||
e: [ '1', '2', [ '3', '4' ] ], | ||
f: [ '1', { a: 1 } ], | ||
}), 'a=&b=s&c[]=1&c[]=2&c[]=3&d=%26%3D%5B%5D&e[0]=1&e[1]=2&e[2][]=3&e[2][]=4&f[0]=1&f[1][a]=1'); | ||
t.end() | ||
}) | ||
t.deepEqual(stringify.serialize({}), ''); | ||
test('serialize', t => { | ||
t.equal( | ||
stringify.serialize({ | ||
a: '', | ||
b: 's', | ||
c: ['1', '2', '3'], | ||
d: '&=[]', | ||
e: ['1', '2', ['3', '4']], | ||
f: ['1', {a: 1}], | ||
}), | ||
'a=&b=s&c[]=1&c[]=2&c[]=3&d=%26%3D%5B%5D&e[0]=1&e[1]=2&e[2][]=3&e[2][]=4&f[0]=1&f[1][a]=1' | ||
) | ||
t.end(); | ||
}); | ||
t.deepEqual(stringify.serialize({}), '') | ||
test('stringify', function( t ){ | ||
t.equal(stringify({ | ||
// normalizes | ||
a: true, | ||
t.end() | ||
}) | ||
// shakes | ||
b: undefined, | ||
test('stringify', t => { | ||
t.throws(() => stringify(), /Only objects can be stringified/) | ||
t.throws(() => stringify(null), /Only objects can be stringified/) | ||
t.throws(() => stringify(''), /Only objects can be stringified/) | ||
t.throws(() => stringify(1), /Only objects can be stringified/) | ||
t.throws(() => stringify([]), /Only objects can be stringified/) | ||
// serializes | ||
c: '&=[]', | ||
}), 'a=y&c=%26%3D%5B%5D'); | ||
t.equal( | ||
stringify({ | ||
// normalizes | ||
a: true, | ||
t.equal(stringify({ | ||
at: new Date(0), | ||
}), 'at=1970-01-01T00%3A00%3A00.000Z'); | ||
// shakes | ||
b: undefined, | ||
// serializes | ||
c: '&=[]', | ||
}), | ||
'a=y&c=%26%3D%5B%5D' | ||
) | ||
t.equal( | ||
stringify({ | ||
at: new Date(0), | ||
}), | ||
'at=1970-01-01T00%3A00%3A00.000Z' | ||
) | ||
// https://github.com/petkaantonov/querystringparser/issues/3 | ||
t.equal(stringify({ | ||
a: { b: { c: true } }, | ||
d: true, | ||
}), 'a[b][c]=y&d=y'); | ||
t.equal( | ||
stringify({ | ||
a: {b: {c: true}}, | ||
d: true, | ||
}), | ||
'a[b][c]=y&d=y' | ||
) | ||
t.equal(stringify({}), ''); | ||
t.equal(stringify({}), '') | ||
t.equal(stringify({ code: 204 }), 'code=204'); | ||
t.equal(stringify({code: 204}), 'code=204') | ||
t.end(); | ||
}); | ||
t.end() | ||
}) | ||
test('serialize (from petkaantonov/querystringparser)', function( t ){ | ||
test('serialize (from petkaantonov/querystringparser)', t => { | ||
/* | ||
@@ -135,243 +160,295 @@ | ||
t.equal(stringify({ | ||
'foo': 'bar' | ||
}), 'foo=bar'); | ||
t.equal( | ||
stringify({ | ||
foo: 'bar', | ||
}), | ||
'foo=bar' | ||
) | ||
t.equal(stringify({ | ||
'foo': 'bar', | ||
'bar': 'baz' | ||
}), 'foo=bar&bar=baz'); | ||
t.equal( | ||
stringify({ | ||
foo: 'bar', | ||
bar: 'baz', | ||
}), | ||
'foo=bar&bar=baz' | ||
) | ||
t.equal(stringify({ | ||
'foo': '\"bar\"' | ||
}), 'foo=%22bar%22'); | ||
t.equal( | ||
stringify({ | ||
foo: '"bar"', | ||
}), | ||
'foo=%22bar%22' | ||
) | ||
t.equal(stringify({ | ||
foo: '' | ||
}), 'foo='); | ||
t.equal( | ||
stringify({ | ||
foo: '', | ||
}), | ||
'foo=' | ||
) | ||
t.equal(stringify({ | ||
'foo': '1', | ||
'bar': '2' | ||
}), 'foo=1&bar=2'); | ||
t.equal( | ||
stringify({ | ||
foo: '1', | ||
bar: '2', | ||
}), | ||
'foo=1&bar=2' | ||
) | ||
t.equal(stringify({ | ||
'my weird field': "q1!2\"'w$5&7/z8)?" | ||
}), 'my%20weird%20field=q1!2%22\'w%245%267%2Fz8)%3F'); | ||
t.equal( | ||
stringify({ | ||
'my weird field': 'q1!2"\'w$5&7/z8)?', | ||
}), | ||
"my%20weird%20field=q1!2%22'w%245%267%2Fz8)%3F" | ||
) | ||
t.equal(stringify({ | ||
'foo=baz': 'bar' | ||
}), 'foo%3Dbaz=bar'); | ||
t.equal( | ||
stringify({ | ||
'foo=baz': 'bar', | ||
}), | ||
'foo%3Dbaz=bar' | ||
) | ||
t.equal(stringify({ | ||
foo: 'bar', | ||
bar: 'baz' | ||
}), 'foo=bar&bar=baz'); | ||
t.equal( | ||
stringify({ | ||
foo: 'bar', | ||
bar: 'baz', | ||
}), | ||
'foo=bar&bar=baz' | ||
) | ||
t.equal(stringify({ | ||
foo: 'bar', | ||
baz: '', | ||
raz: '' | ||
}), 'foo=bar&baz=&raz='); | ||
t.equal( | ||
stringify({ | ||
foo: 'bar', | ||
baz: '', | ||
raz: '', | ||
}), | ||
'foo=bar&baz=&raz=' | ||
) | ||
// escaping | ||
t.equal(stringify({ | ||
foo: 'foo bar' | ||
}), 'foo=foo%20bar'); | ||
t.equal( | ||
stringify({ | ||
foo: 'foo bar', | ||
}), | ||
'foo=foo%20bar' | ||
) | ||
t.equal(stringify({ | ||
cht: 'p3', | ||
chd: 't:60,40', | ||
chs: '250x100', | ||
chl: 'Hello|World' | ||
}), 'cht=p3&chd=t%3A60%2C40&chs=250x100&chl=Hello%7CWorld'); | ||
t.equal( | ||
stringify({ | ||
cht: 'p3', | ||
chd: 't:60,40', | ||
chs: '250x100', | ||
chl: 'Hello|World', | ||
}), | ||
'cht=p3&chd=t%3A60%2C40&chs=250x100&chl=Hello%7CWorld' | ||
) | ||
// nested (some modified) | ||
// nested (some modified) | ||
var str, obj; | ||
let str, obj | ||
str = 'foo[]=bar'; | ||
str = 'foo[]=bar' | ||
obj = { | ||
'foo': ['bar'] | ||
}; | ||
t.equal(stringify(obj), str); | ||
foo: ['bar'], | ||
} | ||
t.equal(stringify(obj), str) | ||
str = 'foo[]=bar&foo[]=quux'; | ||
str = 'foo[]=bar&foo[]=quux' | ||
obj = { | ||
'foo': ['bar', 'quux'] | ||
}; | ||
t.equal(stringify(obj), str); | ||
foo: ['bar', 'quux'], | ||
} | ||
t.equal(stringify(obj), str) | ||
str = 'foo[]=0&foo[]=1'; | ||
str = 'foo[]=0&foo[]=1' | ||
obj = { | ||
'foo': ['0', '1'] | ||
}; | ||
t.equal(stringify(obj), str); | ||
foo: ['0', '1'], | ||
} | ||
t.equal(stringify(obj), str) | ||
str = 'foo=bar&baz[]=1&baz[]=2&baz[]=3'; | ||
str = 'foo=bar&baz[]=1&baz[]=2&baz[]=3' | ||
obj = { | ||
'foo': 'bar', | ||
'baz': ['1', '2', '3'] | ||
}; | ||
t.equal(stringify(obj), str); | ||
foo: 'bar', | ||
baz: ['1', '2', '3'], | ||
} | ||
t.equal(stringify(obj), str) | ||
str = 'foo[]=bar&baz[]=1&baz[]=2&baz[]=3'; | ||
str = 'foo[]=bar&baz[]=1&baz[]=2&baz[]=3' | ||
obj = { | ||
'foo': ['bar'], | ||
'baz': ['1', '2', '3'] | ||
}; | ||
t.equal(stringify(obj), str); | ||
foo: ['bar'], | ||
baz: ['1', '2', '3'], | ||
} | ||
t.equal(stringify(obj), str) | ||
str = 'foo[]=bar&baz[]=1&baz[]=2&baz[]=3'; | ||
str = 'foo[]=bar&baz[]=1&baz[]=2&baz[]=3' | ||
obj = { | ||
'foo': ['bar'], | ||
'baz': ['1', '2', '3'] | ||
}; | ||
t.equal(stringify(obj), str); | ||
foo: ['bar'], | ||
baz: ['1', '2', '3'], | ||
} | ||
t.equal(stringify(obj), str) | ||
str = 'x[y][z][]=1'; | ||
str = 'x[y][z][]=1' | ||
obj = { | ||
'x': { | ||
'y': { | ||
'z': ['1'] | ||
} | ||
} | ||
}; | ||
t.equal(stringify(obj), str); | ||
x: { | ||
y: { | ||
z: ['1'], | ||
}, | ||
}, | ||
} | ||
t.equal(stringify(obj), str) | ||
str = 'x[y][z]=1'; | ||
str = 'x[y][z]=1' | ||
obj = { | ||
'x': { | ||
'y': { | ||
'z': '1' | ||
} | ||
} | ||
}; | ||
t.equal(stringify(obj), str); | ||
x: { | ||
y: { | ||
z: '1', | ||
}, | ||
}, | ||
} | ||
t.equal(stringify(obj), str) | ||
str = 'x[y][z]=2'; | ||
str = 'x[y][z]=2' | ||
obj = { | ||
'x': { | ||
'y': { | ||
'z': '2' | ||
} | ||
} | ||
}; | ||
t.equal(stringify(obj), str); | ||
x: { | ||
y: { | ||
z: '2', | ||
}, | ||
}, | ||
} | ||
t.equal(stringify(obj), str) | ||
str = 'x[y][z][]=1&x[y][z][]=2'; | ||
str = 'x[y][z][]=1&x[y][z][]=2' | ||
obj = { | ||
'x': { | ||
'y': { | ||
'z': ['1', '2'] | ||
} | ||
} | ||
}; | ||
t.equal(stringify(obj), str); | ||
x: { | ||
y: { | ||
z: ['1', '2'], | ||
}, | ||
}, | ||
} | ||
t.equal(stringify(obj), str) | ||
str = 'x[y][0][z]=1'; | ||
str = 'x[y][0][z]=1' | ||
obj = { | ||
'x': { | ||
'y': [{ | ||
'z': '1' | ||
}] | ||
} | ||
}; | ||
t.equal(stringify(obj), str); | ||
x: { | ||
y: [ | ||
{ | ||
z: '1', | ||
}, | ||
], | ||
}, | ||
} | ||
t.equal(stringify(obj), str) | ||
str = 'x[y][0][z][]=1'; | ||
str = 'x[y][0][z][]=1' | ||
obj = { | ||
'x': { | ||
'y': [{ | ||
'z': ['1'] | ||
}] | ||
} | ||
}; | ||
t.equal(stringify(obj), str); | ||
x: { | ||
y: [ | ||
{ | ||
z: ['1'], | ||
}, | ||
], | ||
}, | ||
} | ||
t.equal(stringify(obj), str) | ||
str = 'x[y][0][z][]=1'; | ||
str = 'x[y][0][z][]=1' | ||
obj = { | ||
'x': { | ||
'y': [{ | ||
'z': ['1'] | ||
}] | ||
} | ||
}; | ||
t.equal(stringify(obj), str); | ||
x: { | ||
y: [ | ||
{ | ||
z: ['1'], | ||
}, | ||
], | ||
}, | ||
} | ||
t.equal(stringify(obj), str) | ||
str = 'x[y][0][z][]=1'; | ||
str = 'x[y][0][z][]=1' | ||
obj = { | ||
'x': { | ||
'y': [{ | ||
'z': ['1'] | ||
}] | ||
} | ||
}; | ||
t.equal(stringify(obj), str); | ||
x: { | ||
y: [ | ||
{ | ||
z: ['1'], | ||
}, | ||
], | ||
}, | ||
} | ||
t.equal(stringify(obj), str) | ||
str = 'x[y][0][z]=1&x[y][0][w]=2'; | ||
str = 'x[y][0][z]=1&x[y][0][w]=2' | ||
obj = { | ||
'x': { | ||
'y': [{ | ||
'z': '1', | ||
'w': '2' | ||
}] | ||
} | ||
}; | ||
t.equal(stringify(obj), str); | ||
x: { | ||
y: [ | ||
{ | ||
z: '1', | ||
w: '2', | ||
}, | ||
], | ||
}, | ||
} | ||
t.equal(stringify(obj), str) | ||
str = 'x[y][0][v][w]=1'; | ||
str = 'x[y][0][v][w]=1' | ||
obj = { | ||
'x': { | ||
'y': [{ | ||
'v': { | ||
'w': '1' | ||
} | ||
}] | ||
} | ||
}; | ||
t.equal(stringify(obj), str); | ||
x: { | ||
y: [ | ||
{ | ||
v: { | ||
w: '1', | ||
}, | ||
}, | ||
], | ||
}, | ||
} | ||
t.equal(stringify(obj), str) | ||
str = 'x[y][0][z]=1&x[y][0][v][w]=2'; | ||
str = 'x[y][0][z]=1&x[y][0][v][w]=2' | ||
obj = { | ||
'x': { | ||
'y': [{ | ||
'z': '1', | ||
'v': { | ||
'w': '2' | ||
} | ||
}] | ||
} | ||
}; | ||
t.equal(stringify(obj), str); | ||
x: { | ||
y: [ | ||
{ | ||
z: '1', | ||
v: { | ||
w: '2', | ||
}, | ||
}, | ||
], | ||
}, | ||
} | ||
t.equal(stringify(obj), str) | ||
str = 'x[y][0][z]=1&x[y][1][z]=2'; | ||
str = 'x[y][0][z]=1&x[y][1][z]=2' | ||
obj = { | ||
'x': { | ||
'y': [{ | ||
'z': '1' | ||
}, { | ||
'z': '2' | ||
}] | ||
} | ||
}; | ||
t.equal(stringify(obj), str); | ||
x: { | ||
y: [ | ||
{ | ||
z: '1', | ||
}, | ||
{ | ||
z: '2', | ||
}, | ||
], | ||
}, | ||
} | ||
t.equal(stringify(obj), str) | ||
str = 'x[y][0][z]=1&x[y][0][w]=a&x[y][1][z]=2&x[y][1][w]=3'; | ||
str = 'x[y][0][z]=1&x[y][0][w]=a&x[y][1][z]=2&x[y][1][w]=3' | ||
obj = { | ||
'x': { | ||
'y': [{ | ||
'z': '1', | ||
'w': 'a' | ||
}, { | ||
'z': '2', | ||
'w': '3' | ||
}] | ||
} | ||
}; | ||
t.equal(stringify(obj), str); | ||
x: { | ||
y: [ | ||
{ | ||
z: '1', | ||
w: 'a', | ||
}, | ||
{ | ||
z: '2', | ||
w: '3', | ||
}, | ||
], | ||
}, | ||
} | ||
t.equal(stringify(obj), str) | ||
str = 'user[name][first]=tj&user[name][last]=holowaychuk'; | ||
str = 'user[name][first]=tj&user[name][last]=holowaychuk' | ||
obj = { | ||
@@ -381,10 +458,60 @@ user: { | ||
first: 'tj', | ||
last: 'holowaychuk' | ||
} | ||
} | ||
}; | ||
t.equal(stringify(obj), str); | ||
last: 'holowaychuk', | ||
}, | ||
}, | ||
} | ||
t.equal(stringify(obj), str) | ||
t.end() | ||
}) | ||
t.end(); | ||
}); | ||
test('compatibility with parsers', t => { | ||
const subject = { | ||
a: '', | ||
b: 's', | ||
c: ['1', '2', '3'], | ||
d: '&=[]', | ||
e: ['1', '2', ['3', '4']], | ||
f: ['1', {a: '1'}], | ||
} | ||
const flattened = { | ||
a: '', | ||
b: 's', | ||
d: '&=[]', | ||
// expect arrays to be collapsed like this | ||
'c[]': ['1', '2', '3'], | ||
// expect objects and multi-level arrays to be flattened like this | ||
'e[0]': '1', | ||
'e[1]': '2', | ||
'e[2][]': ['3', '4'], | ||
'f[0]': '1', | ||
'f[1][a]': '1', | ||
} | ||
t.test('Node.js built-in (flat)', t => { | ||
t.plan(1) | ||
t.deepEqual(nodejs('?' + stringify(subject), true).query, flattened) | ||
}) | ||
t.test('querystringparser', t => { | ||
t.plan(1) | ||
t.deepEqual(querystringparser(stringify(subject)), subject) | ||
}) | ||
t.test('qs', t => { | ||
t.plan(1) | ||
t.deepEqual(qs(stringify(subject)), subject) | ||
}) | ||
t.test('urijs (flat)', t => { | ||
t.plan(1) | ||
t.deepEqual(urijs(stringify(subject)), flattened) | ||
}) | ||
}) |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
11847
527
98
2
4
1