qs 2.3.2 → 2.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.travis.yml +3 -1
- package/CHANGELOG.md +17 -5
- package/Makefile +4 -4
- package/README.md +13 -0
- package/index.js +1 -1
- package/lib/parse.js +2 -1
- package/lib/stringify.js +29 -9
- package/lib/utils.js +2 -2
- package/package.json +3 -2
- package/test/parse.js +25 -17
- package/test/stringify.js +33 -1
package/.travis.yml
CHANGED
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,19 @@
|
|
|
1
1
|
|
|
2
|
+
## [**2.4.1**](https://github.com/hapijs/qs/issues?milestone=20&state=closed)
|
|
3
|
+
- [**#73**](https://github.com/hapijs/qs/issues/73) Property 'hasOwnProperty' of object #<Object> is not a function
|
|
4
|
+
|
|
5
|
+
## [**2.4.0**](https://github.com/hapijs/qs/issues?milestone=19&state=closed)
|
|
6
|
+
- [**#70**](https://github.com/hapijs/qs/issues/70) Add arrayFormat option
|
|
7
|
+
|
|
8
|
+
## [**2.3.3**](https://github.com/hapijs/qs/issues?milestone=18&state=closed)
|
|
9
|
+
- [**#59**](https://github.com/hapijs/qs/issues/59) make sure array indexes are >= 0, closes #57
|
|
10
|
+
- [**#58**](https://github.com/hapijs/qs/issues/58) make qs usable for browser loader
|
|
11
|
+
|
|
12
|
+
## [**2.3.2**](https://github.com/hapijs/qs/issues?milestone=17&state=closed)
|
|
13
|
+
- [**#55**](https://github.com/hapijs/qs/issues/55) allow merging a string into an object
|
|
14
|
+
|
|
2
15
|
## [**2.3.1**](https://github.com/hapijs/qs/issues?milestone=16&state=closed)
|
|
3
|
-
- [**#52**](https://github.com/hapijs/qs/issues/52) Return
|
|
16
|
+
- [**#52**](https://github.com/hapijs/qs/issues/52) Return "undefined" and "false" instead of throwing "TypeError".
|
|
4
17
|
|
|
5
18
|
## [**2.3.0**](https://github.com/hapijs/qs/issues?milestone=15&state=closed)
|
|
6
19
|
- [**#50**](https://github.com/hapijs/qs/issues/50) add option to omit array indices, closes #46
|
|
@@ -27,9 +40,9 @@
|
|
|
27
40
|
- [**#31**](https://github.com/hapijs/qs/issues/31) qs.parse stackoverflow on circular objects
|
|
28
41
|
|
|
29
42
|
## [**2.2.0**](https://github.com/hapijs/qs/issues?milestone=9&state=closed)
|
|
30
|
-
- [**#26**](https://github.com/hapijs/qs/issues/26) Don
|
|
43
|
+
- [**#26**](https://github.com/hapijs/qs/issues/26) Don't use Buffer global if it's not present
|
|
31
44
|
- [**#30**](https://github.com/hapijs/qs/issues/30) Bug when merging non-object values into arrays
|
|
32
|
-
- [**#29**](https://github.com/hapijs/qs/issues/29) Don
|
|
45
|
+
- [**#29**](https://github.com/hapijs/qs/issues/29) Don't call Utils.clone at the top of Utils.merge
|
|
33
46
|
- [**#23**](https://github.com/hapijs/qs/issues/23) Ability to not limit parameters?
|
|
34
47
|
|
|
35
48
|
## [**2.1.0**](https://github.com/hapijs/qs/issues?milestone=8&state=closed)
|
|
@@ -41,7 +54,7 @@
|
|
|
41
54
|
- [**#21**](https://github.com/hapijs/qs/issues/21) make all limits optional, for #18, for #20
|
|
42
55
|
|
|
43
56
|
## [**1.2.2**](https://github.com/hapijs/qs/issues?milestone=6&state=closed)
|
|
44
|
-
- [**#19**](https://github.com/hapijs/qs/issues/19) Don
|
|
57
|
+
- [**#19**](https://github.com/hapijs/qs/issues/19) Don't overwrite null values
|
|
45
58
|
|
|
46
59
|
## [**1.2.1**](https://github.com/hapijs/qs/issues?milestone=5&state=closed)
|
|
47
60
|
- [**#16**](https://github.com/hapijs/qs/issues/16) ignore non-string delimiters
|
|
@@ -58,4 +71,3 @@
|
|
|
58
71
|
|
|
59
72
|
## [**1.0.2**](https://github.com/hapijs/qs/issues?milestone=2&state=closed)
|
|
60
73
|
- [**#5**](https://github.com/hapijs/qs/issues/5) array holes incorrectly copied into object on large index
|
|
61
|
-
|
package/Makefile
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
test:
|
|
2
|
-
@node node_modules/lab/bin/lab
|
|
2
|
+
@node node_modules/lab/bin/lab -a code -L
|
|
3
3
|
test-cov:
|
|
4
|
-
@node node_modules/lab/bin/lab -t 100
|
|
4
|
+
@node node_modules/lab/bin/lab -a code -t 100 -L
|
|
5
5
|
test-cov-html:
|
|
6
|
-
@node node_modules/lab/bin/lab -r html -o coverage.html
|
|
6
|
+
@node node_modules/lab/bin/lab -a code -L -r html -o coverage.html
|
|
7
7
|
|
|
8
|
-
.PHONY: test test-cov test-cov-html
|
|
8
|
+
.PHONY: test test-cov test-cov-html
|
package/README.md
CHANGED
|
@@ -153,6 +153,8 @@ Qs.parse('a[1]=b', { arrayLimit: 0 });
|
|
|
153
153
|
// { a: { '1': 'b' } }
|
|
154
154
|
```
|
|
155
155
|
|
|
156
|
+
To disable array parsing entirely, set `arrayLimit` to `-1`.
|
|
157
|
+
|
|
156
158
|
If you mix notations, **qs** will merge the two items into an object:
|
|
157
159
|
|
|
158
160
|
```javascript
|
|
@@ -198,6 +200,17 @@ Qs.stringify({ a: ['b', 'c', 'd'] }, { indices: false });
|
|
|
198
200
|
// 'a=b&a=c&a=d'
|
|
199
201
|
```
|
|
200
202
|
|
|
203
|
+
You may use the `arrayFormat` option to specify the format of the output array
|
|
204
|
+
|
|
205
|
+
```javascript
|
|
206
|
+
Qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'indices' })
|
|
207
|
+
// 'a[0]=b&a[1]=c'
|
|
208
|
+
Qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'brackets' })
|
|
209
|
+
// 'a[]=b&a[]=c'
|
|
210
|
+
Qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'repeat' })
|
|
211
|
+
// 'a=b&a=c'
|
|
212
|
+
```
|
|
213
|
+
|
|
201
214
|
Empty strings and null values will omit the value, but the equals sign (=) remains in place:
|
|
202
215
|
|
|
203
216
|
```javascript
|
package/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
module.exports = require('./lib');
|
|
1
|
+
module.exports = require('./lib/');
|
package/lib/parse.js
CHANGED
|
@@ -29,7 +29,7 @@ internals.parseValues = function (str, options) {
|
|
|
29
29
|
var key = Utils.decode(part.slice(0, pos));
|
|
30
30
|
var val = Utils.decode(part.slice(pos + 1));
|
|
31
31
|
|
|
32
|
-
if (!
|
|
32
|
+
if (!Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
33
33
|
obj[key] = val;
|
|
34
34
|
}
|
|
35
35
|
else {
|
|
@@ -62,6 +62,7 @@ internals.parseObject = function (chain, val, options) {
|
|
|
62
62
|
if (!isNaN(index) &&
|
|
63
63
|
root !== cleanRoot &&
|
|
64
64
|
indexString === cleanRoot &&
|
|
65
|
+
index >= 0 &&
|
|
65
66
|
index <= options.arrayLimit) {
|
|
66
67
|
|
|
67
68
|
obj = [];
|
package/lib/stringify.js
CHANGED
|
@@ -7,11 +7,21 @@ var Utils = require('./utils');
|
|
|
7
7
|
|
|
8
8
|
var internals = {
|
|
9
9
|
delimiter: '&',
|
|
10
|
-
|
|
10
|
+
arrayPrefixGenerators: {
|
|
11
|
+
brackets: function (prefix, key) {
|
|
12
|
+
return prefix + '[]';
|
|
13
|
+
},
|
|
14
|
+
indices: function (prefix, key) {
|
|
15
|
+
return prefix + '[' + key + ']';
|
|
16
|
+
},
|
|
17
|
+
repeat: function (prefix, key) {
|
|
18
|
+
return prefix;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
11
21
|
};
|
|
12
22
|
|
|
13
23
|
|
|
14
|
-
internals.stringify = function (obj, prefix,
|
|
24
|
+
internals.stringify = function (obj, prefix, generateArrayPrefix) {
|
|
15
25
|
|
|
16
26
|
if (Utils.isBuffer(obj)) {
|
|
17
27
|
obj = obj.toString();
|
|
@@ -39,13 +49,11 @@ internals.stringify = function (obj, prefix, options) {
|
|
|
39
49
|
var objKeys = Object.keys(obj);
|
|
40
50
|
for (var i = 0, il = objKeys.length; i < il; ++i) {
|
|
41
51
|
var key = objKeys[i];
|
|
42
|
-
if (
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
values = values.concat(internals.stringify(obj[key], prefix, options));
|
|
52
|
+
if (Array.isArray(obj)) {
|
|
53
|
+
values = values.concat(internals.stringify(obj[key], generateArrayPrefix(prefix, key), generateArrayPrefix));
|
|
46
54
|
}
|
|
47
55
|
else {
|
|
48
|
-
values = values.concat(internals.stringify(obj[key], prefix + '[' + key + ']',
|
|
56
|
+
values = values.concat(internals.stringify(obj[key], prefix + '[' + key + ']', generateArrayPrefix));
|
|
49
57
|
}
|
|
50
58
|
}
|
|
51
59
|
|
|
@@ -57,7 +65,6 @@ module.exports = function (obj, options) {
|
|
|
57
65
|
|
|
58
66
|
options = options || {};
|
|
59
67
|
var delimiter = typeof options.delimiter === 'undefined' ? internals.delimiter : options.delimiter;
|
|
60
|
-
options.indices = typeof options.indices === 'boolean' ? options.indices : internals.indices;
|
|
61
68
|
|
|
62
69
|
var keys = [];
|
|
63
70
|
|
|
@@ -67,10 +74,23 @@ module.exports = function (obj, options) {
|
|
|
67
74
|
return '';
|
|
68
75
|
}
|
|
69
76
|
|
|
77
|
+
var arrayFormat;
|
|
78
|
+
if (options.arrayFormat in internals.arrayPrefixGenerators) {
|
|
79
|
+
arrayFormat = options.arrayFormat;
|
|
80
|
+
}
|
|
81
|
+
else if ('indices' in options) {
|
|
82
|
+
arrayFormat = options.indices ? 'indices' : 'repeat';
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
arrayFormat = 'indices';
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
var generateArrayPrefix = internals.arrayPrefixGenerators[arrayFormat];
|
|
89
|
+
|
|
70
90
|
var objKeys = Object.keys(obj);
|
|
71
91
|
for (var i = 0, il = objKeys.length; i < il; ++i) {
|
|
72
92
|
var key = objKeys[i];
|
|
73
|
-
keys = keys.concat(internals.stringify(obj[key], key,
|
|
93
|
+
keys = keys.concat(internals.stringify(obj[key], key, generateArrayPrefix));
|
|
74
94
|
}
|
|
75
95
|
|
|
76
96
|
return keys.join(delimiter);
|
package/lib/utils.js
CHANGED
|
@@ -94,7 +94,7 @@ exports.compact = function (obj, refs) {
|
|
|
94
94
|
if (Array.isArray(obj)) {
|
|
95
95
|
var compacted = [];
|
|
96
96
|
|
|
97
|
-
for (var i = 0,
|
|
97
|
+
for (var i = 0, il = obj.length; i < il; ++i) {
|
|
98
98
|
if (typeof obj[i] !== 'undefined') {
|
|
99
99
|
compacted.push(obj[i]);
|
|
100
100
|
}
|
|
@@ -104,7 +104,7 @@ exports.compact = function (obj, refs) {
|
|
|
104
104
|
}
|
|
105
105
|
|
|
106
106
|
var keys = Object.keys(obj);
|
|
107
|
-
for (
|
|
107
|
+
for (i = 0, il = keys.length; i < il; ++i) {
|
|
108
108
|
var key = keys[i];
|
|
109
109
|
obj[key] = exports.compact(obj[key], refs);
|
|
110
110
|
}
|
package/package.json
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "qs",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.4.2",
|
|
4
4
|
"description": "A querystring parser that supports nesting and arrays, with a depth limit",
|
|
5
5
|
"homepage": "https://github.com/hapijs/qs",
|
|
6
6
|
"main": "index.js",
|
|
7
7
|
"dependencies": {},
|
|
8
8
|
"devDependencies": {
|
|
9
|
-
"
|
|
9
|
+
"code": "1.x.x",
|
|
10
|
+
"lab": "5.x.x"
|
|
10
11
|
},
|
|
11
12
|
"scripts": {
|
|
12
13
|
"test": "make test-cov"
|
package/test/parse.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
/* eslint no-extend-native:0 */
|
|
1
2
|
// Load modules
|
|
2
3
|
|
|
4
|
+
var Code = require('code');
|
|
3
5
|
var Lab = require('lab');
|
|
4
6
|
var Qs = require('../');
|
|
5
7
|
|
|
@@ -12,7 +14,7 @@ var internals = {};
|
|
|
12
14
|
// Test shortcuts
|
|
13
15
|
|
|
14
16
|
var lab = exports.lab = Lab.script();
|
|
15
|
-
var expect =
|
|
17
|
+
var expect = Code.expect;
|
|
16
18
|
var describe = lab.experiment;
|
|
17
19
|
var it = lab.test;
|
|
18
20
|
|
|
@@ -185,10 +187,11 @@ describe('parse()', function () {
|
|
|
185
187
|
|
|
186
188
|
it('cannot override prototypes', function (done) {
|
|
187
189
|
|
|
188
|
-
var obj = Qs.parse('toString=bad&bad[toString]=bad&constructor=bad');
|
|
190
|
+
var obj = Qs.parse('hasOwnProperty=bad&toString=bad&bad[toString]=bad&constructor=bad');
|
|
189
191
|
expect(typeof obj.toString).to.equal('function');
|
|
190
192
|
expect(typeof obj.bad.toString).to.equal('function');
|
|
191
193
|
expect(typeof obj.constructor).to.equal('function');
|
|
194
|
+
expect(typeof obj.hasOwnProperty).to.equal('function');
|
|
192
195
|
done();
|
|
193
196
|
});
|
|
194
197
|
|
|
@@ -302,6 +305,8 @@ describe('parse()', function () {
|
|
|
302
305
|
|
|
303
306
|
it('allows overriding array limit', function (done) {
|
|
304
307
|
|
|
308
|
+
expect(Qs.parse('a[0]=b', { arrayLimit: -1 })).to.deep.equal({ a: { '0': 'b' } });
|
|
309
|
+
expect(Qs.parse('a[-1]=b', { arrayLimit: -1 })).to.deep.equal({ a: { '-1': 'b' } });
|
|
305
310
|
expect(Qs.parse('a[0]=b&a[1]=c', { arrayLimit: 0 })).to.deep.equal({ a: { '0': 'b', '1': 'c' } });
|
|
306
311
|
done();
|
|
307
312
|
});
|
|
@@ -309,14 +314,14 @@ describe('parse()', function () {
|
|
|
309
314
|
it('parses an object', function (done) {
|
|
310
315
|
|
|
311
316
|
var input = {
|
|
312
|
-
|
|
313
|
-
|
|
317
|
+
'user[name]': {'pop[bob]': 3},
|
|
318
|
+
'user[email]': null
|
|
314
319
|
};
|
|
315
320
|
|
|
316
321
|
var expected = {
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
322
|
+
'user': {
|
|
323
|
+
'name': {'pop[bob]': 3},
|
|
324
|
+
'email': null
|
|
320
325
|
}
|
|
321
326
|
};
|
|
322
327
|
|
|
@@ -329,14 +334,14 @@ describe('parse()', function () {
|
|
|
329
334
|
it('parses an object and not child values', function (done) {
|
|
330
335
|
|
|
331
336
|
var input = {
|
|
332
|
-
|
|
333
|
-
|
|
337
|
+
'user[name]': {'pop[bob]': { 'test': 3 }},
|
|
338
|
+
'user[email]': null
|
|
334
339
|
};
|
|
335
340
|
|
|
336
341
|
var expected = {
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
342
|
+
'user': {
|
|
343
|
+
'name': {'pop[bob]': { 'test': 3 }},
|
|
344
|
+
'email': null
|
|
340
345
|
}
|
|
341
346
|
};
|
|
342
347
|
|
|
@@ -350,8 +355,9 @@ describe('parse()', function () {
|
|
|
350
355
|
|
|
351
356
|
var tempBuffer = global.Buffer;
|
|
352
357
|
delete global.Buffer;
|
|
353
|
-
|
|
358
|
+
var result = Qs.parse('a=b&c=d');
|
|
354
359
|
global.Buffer = tempBuffer;
|
|
360
|
+
expect(result).to.deep.equal({ a: 'b', c: 'd' });
|
|
355
361
|
done();
|
|
356
362
|
});
|
|
357
363
|
|
|
@@ -371,10 +377,10 @@ describe('parse()', function () {
|
|
|
371
377
|
expect(function () {
|
|
372
378
|
|
|
373
379
|
parsed = Qs.parse({ 'foo[bar]': 'baz', 'foo[baz]': a });
|
|
374
|
-
}).to.not.throw(
|
|
380
|
+
}).to.not.throw();
|
|
375
381
|
|
|
376
|
-
expect(parsed).to.
|
|
377
|
-
expect(parsed.foo).to.
|
|
382
|
+
expect(parsed).to.contain('foo');
|
|
383
|
+
expect(parsed.foo).to.contain('bar', 'baz');
|
|
378
384
|
expect(parsed.foo.bar).to.equal('baz');
|
|
379
385
|
expect(parsed.foo.baz).to.deep.equal(a);
|
|
380
386
|
done();
|
|
@@ -386,7 +392,9 @@ describe('parse()', function () {
|
|
|
386
392
|
a.b = 'c';
|
|
387
393
|
|
|
388
394
|
expect(Qs.parse(a)).to.deep.equal({ b: 'c' });
|
|
389
|
-
|
|
395
|
+
var result = Qs.parse({ a: a });
|
|
396
|
+
expect(result).to.contain('a');
|
|
397
|
+
expect(result.a).to.deep.equal(a);
|
|
390
398
|
done();
|
|
391
399
|
});
|
|
392
400
|
|
package/test/stringify.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
/* eslint no-extend-native:0 */
|
|
1
2
|
// Load modules
|
|
2
3
|
|
|
4
|
+
var Code = require('code');
|
|
3
5
|
var Lab = require('lab');
|
|
4
6
|
var Qs = require('../');
|
|
5
7
|
|
|
@@ -12,7 +14,7 @@ var internals = {};
|
|
|
12
14
|
// Test shortcuts
|
|
13
15
|
|
|
14
16
|
var lab = exports.lab = Lab.script();
|
|
15
|
-
var expect =
|
|
17
|
+
var expect = Code.expect;
|
|
16
18
|
var describe = lab.experiment;
|
|
17
19
|
var it = lab.test;
|
|
18
20
|
|
|
@@ -65,6 +67,36 @@ describe('stringify()', function () {
|
|
|
65
67
|
done();
|
|
66
68
|
});
|
|
67
69
|
|
|
70
|
+
it('uses indices notation for arrays when indices=true', function (done) {
|
|
71
|
+
|
|
72
|
+
expect(Qs.stringify({ a: ['b', 'c'] }, { indices: true })).to.equal('a%5B0%5D=b&a%5B1%5D=c');
|
|
73
|
+
done();
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
it('uses indices notation for arrays when no arrayFormat is specified', function (done) {
|
|
77
|
+
|
|
78
|
+
expect(Qs.stringify({ a: ['b', 'c'] })).to.equal('a%5B0%5D=b&a%5B1%5D=c');
|
|
79
|
+
done();
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
it('uses indices notation for arrays when no arrayFormat=indices', function (done) {
|
|
83
|
+
|
|
84
|
+
expect(Qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'indices' })).to.equal('a%5B0%5D=b&a%5B1%5D=c');
|
|
85
|
+
done();
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
it('uses repeat notation for arrays when no arrayFormat=repeat', function (done) {
|
|
89
|
+
|
|
90
|
+
expect(Qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'repeat' })).to.equal('a=b&a=c');
|
|
91
|
+
done();
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
it('uses brackets notation for arrays when no arrayFormat=brackets', function (done) {
|
|
95
|
+
|
|
96
|
+
expect(Qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'brackets' })).to.equal('a%5B%5D=b&a%5B%5D=c');
|
|
97
|
+
done();
|
|
98
|
+
});
|
|
99
|
+
|
|
68
100
|
it('stringifies a complicated object', function (done) {
|
|
69
101
|
|
|
70
102
|
expect(Qs.stringify({ a: { b: 'c', d: 'e' } })).to.equal('a%5Bb%5D=c&a%5Bd%5D=e');
|