qs 2.2.5 → 2.3.3
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/CHANGELOG.md +18 -0
- package/Makefile +4 -4
- package/README.md +10 -1
- package/index.js +1 -1
- package/lib/parse.js +1 -0
- package/lib/stringify.js +19 -4
- package/lib/utils.js +9 -3
- package/package.json +3 -2
- package/test/parse.js +30 -17
- package/test/stringify.js +24 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,4 +1,22 @@
|
|
|
1
1
|
|
|
2
|
+
## [**2.3.3**](https://github.com/hapijs/qs/issues?milestone=18&state=open)
|
|
3
|
+
- [**#59**](https://github.com/hapijs/qs/issues/59) make sure array indexes are >= 0, closes #57
|
|
4
|
+
- [**#58**](https://github.com/hapijs/qs/issues/58) make qs usable for browser loader
|
|
5
|
+
|
|
6
|
+
## [**2.3.2**](https://github.com/hapijs/qs/issues?milestone=17&state=closed)
|
|
7
|
+
- [**#55**](https://github.com/hapijs/qs/issues/55) allow merging a string into an object
|
|
8
|
+
|
|
9
|
+
## [**2.3.1**](https://github.com/hapijs/qs/issues?milestone=16&state=closed)
|
|
10
|
+
- [**#52**](https://github.com/hapijs/qs/issues/52) Return "undefined" and "false" instead of throwing "TypeError".
|
|
11
|
+
|
|
12
|
+
## [**2.3.0**](https://github.com/hapijs/qs/issues?milestone=15&state=closed)
|
|
13
|
+
- [**#50**](https://github.com/hapijs/qs/issues/50) add option to omit array indices, closes #46
|
|
14
|
+
|
|
15
|
+
## [**2.2.5**](https://github.com/hapijs/qs/issues?milestone=14&state=closed)
|
|
16
|
+
- [**#39**](https://github.com/hapijs/qs/issues/39) Is there an alternative to Buffer.isBuffer?
|
|
17
|
+
- [**#49**](https://github.com/hapijs/qs/issues/49) refactor utils.merge, fixes #45
|
|
18
|
+
- [**#41**](https://github.com/hapijs/qs/issues/41) avoid browserifying Buffer, for #39
|
|
19
|
+
|
|
2
20
|
## [**2.2.4**](https://github.com/hapijs/qs/issues?milestone=13&state=closed)
|
|
3
21
|
- [**#38**](https://github.com/hapijs/qs/issues/38) how to handle object keys beginning with a number
|
|
4
22
|
|
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
|
|
@@ -184,13 +186,20 @@ Qs.stringify({ a: { b: 'c' } });
|
|
|
184
186
|
|
|
185
187
|
Examples beyond this point will be shown as though the output is not URI encoded for clarity. Please note that the return values in these cases *will* be URI encoded during real usage.
|
|
186
188
|
|
|
187
|
-
When arrays are stringified, they are
|
|
189
|
+
When arrays are stringified, by default they are given explicit indices:
|
|
188
190
|
|
|
189
191
|
```javascript
|
|
190
192
|
Qs.stringify({ a: ['b', 'c', 'd'] });
|
|
191
193
|
// 'a[0]=b&a[1]=c&a[2]=d'
|
|
192
194
|
```
|
|
193
195
|
|
|
196
|
+
You may override this by setting the `indices` option to `false`:
|
|
197
|
+
|
|
198
|
+
```javascript
|
|
199
|
+
Qs.stringify({ a: ['b', 'c', 'd'] }, { indices: false });
|
|
200
|
+
// 'a=b&a=c&a=d'
|
|
201
|
+
```
|
|
202
|
+
|
|
194
203
|
Empty strings and null values will omit the value, but the equals sign (=) remains in place:
|
|
195
204
|
|
|
196
205
|
```javascript
|
package/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
module.exports = require('./lib');
|
|
1
|
+
module.exports = require('./lib/');
|
package/lib/parse.js
CHANGED
package/lib/stringify.js
CHANGED
|
@@ -6,11 +6,12 @@ var Utils = require('./utils');
|
|
|
6
6
|
// Declare internals
|
|
7
7
|
|
|
8
8
|
var internals = {
|
|
9
|
-
delimiter: '&'
|
|
9
|
+
delimiter: '&',
|
|
10
|
+
indices: true
|
|
10
11
|
};
|
|
11
12
|
|
|
12
13
|
|
|
13
|
-
internals.stringify = function (obj, prefix) {
|
|
14
|
+
internals.stringify = function (obj, prefix, options) {
|
|
14
15
|
|
|
15
16
|
if (Utils.isBuffer(obj)) {
|
|
16
17
|
obj = obj.toString();
|
|
@@ -38,7 +39,14 @@ internals.stringify = function (obj, prefix) {
|
|
|
38
39
|
var objKeys = Object.keys(obj);
|
|
39
40
|
for (var i = 0, il = objKeys.length; i < il; ++i) {
|
|
40
41
|
var key = objKeys[i];
|
|
41
|
-
|
|
42
|
+
if (!options.indices &&
|
|
43
|
+
Array.isArray(obj)) {
|
|
44
|
+
|
|
45
|
+
values = values.concat(internals.stringify(obj[key], prefix, options));
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
values = values.concat(internals.stringify(obj[key], prefix + '[' + key + ']', options));
|
|
49
|
+
}
|
|
42
50
|
}
|
|
43
51
|
|
|
44
52
|
return values;
|
|
@@ -49,13 +57,20 @@ module.exports = function (obj, options) {
|
|
|
49
57
|
|
|
50
58
|
options = options || {};
|
|
51
59
|
var delimiter = typeof options.delimiter === 'undefined' ? internals.delimiter : options.delimiter;
|
|
60
|
+
options.indices = typeof options.indices === 'boolean' ? options.indices : internals.indices;
|
|
52
61
|
|
|
53
62
|
var keys = [];
|
|
54
63
|
|
|
64
|
+
if (typeof obj !== 'object' ||
|
|
65
|
+
obj === null) {
|
|
66
|
+
|
|
67
|
+
return '';
|
|
68
|
+
}
|
|
69
|
+
|
|
55
70
|
var objKeys = Object.keys(obj);
|
|
56
71
|
for (var i = 0, il = objKeys.length; i < il; ++i) {
|
|
57
72
|
var key = objKeys[i];
|
|
58
|
-
keys = keys.concat(internals.stringify(obj[key], key));
|
|
73
|
+
keys = keys.concat(internals.stringify(obj[key], key, options));
|
|
59
74
|
}
|
|
60
75
|
|
|
61
76
|
return keys.join(delimiter);
|
package/lib/utils.js
CHANGED
|
@@ -27,7 +27,13 @@ exports.merge = function (target, source) {
|
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
if (typeof source !== 'object') {
|
|
30
|
-
|
|
30
|
+
if (Array.isArray(target)) {
|
|
31
|
+
target.push(source);
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
target[source] = true;
|
|
35
|
+
}
|
|
36
|
+
|
|
31
37
|
return target;
|
|
32
38
|
}
|
|
33
39
|
|
|
@@ -88,7 +94,7 @@ exports.compact = function (obj, refs) {
|
|
|
88
94
|
if (Array.isArray(obj)) {
|
|
89
95
|
var compacted = [];
|
|
90
96
|
|
|
91
|
-
for (var i = 0,
|
|
97
|
+
for (var i = 0, il = obj.length; i < il; ++i) {
|
|
92
98
|
if (typeof obj[i] !== 'undefined') {
|
|
93
99
|
compacted.push(obj[i]);
|
|
94
100
|
}
|
|
@@ -98,7 +104,7 @@ exports.compact = function (obj, refs) {
|
|
|
98
104
|
}
|
|
99
105
|
|
|
100
106
|
var keys = Object.keys(obj);
|
|
101
|
-
for (
|
|
107
|
+
for (i = 0, il = keys.length; i < il; ++i) {
|
|
102
108
|
var key = keys[i];
|
|
103
109
|
obj[key] = exports.compact(obj[key], refs);
|
|
104
110
|
}
|
package/package.json
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "qs",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.3.3",
|
|
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
|
|
|
@@ -158,6 +160,12 @@ describe('parse()', function () {
|
|
|
158
160
|
done();
|
|
159
161
|
});
|
|
160
162
|
|
|
163
|
+
it('can add keys to objects', function (done) {
|
|
164
|
+
|
|
165
|
+
expect(Qs.parse('a[b]=c&a=d')).to.deep.equal({ a: { b: 'c', d: true } });
|
|
166
|
+
done();
|
|
167
|
+
});
|
|
168
|
+
|
|
161
169
|
it('correctly prunes undefined values when converting an array to an object', function (done) {
|
|
162
170
|
|
|
163
171
|
expect(Qs.parse('a[2]=b&a[99999999]=c')).to.deep.equal({ a: { '2': 'b', '99999999': 'c' } });
|
|
@@ -296,6 +304,8 @@ describe('parse()', function () {
|
|
|
296
304
|
|
|
297
305
|
it('allows overriding array limit', function (done) {
|
|
298
306
|
|
|
307
|
+
expect(Qs.parse('a[0]=b', { arrayLimit: -1 })).to.deep.equal({ a: { '0': 'b' } });
|
|
308
|
+
expect(Qs.parse('a[-1]=b', { arrayLimit: -1 })).to.deep.equal({ a: { '-1': 'b' } });
|
|
299
309
|
expect(Qs.parse('a[0]=b&a[1]=c', { arrayLimit: 0 })).to.deep.equal({ a: { '0': 'b', '1': 'c' } });
|
|
300
310
|
done();
|
|
301
311
|
});
|
|
@@ -303,14 +313,14 @@ describe('parse()', function () {
|
|
|
303
313
|
it('parses an object', function (done) {
|
|
304
314
|
|
|
305
315
|
var input = {
|
|
306
|
-
|
|
307
|
-
|
|
316
|
+
'user[name]': {'pop[bob]': 3},
|
|
317
|
+
'user[email]': null
|
|
308
318
|
};
|
|
309
319
|
|
|
310
320
|
var expected = {
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
321
|
+
'user': {
|
|
322
|
+
'name': {'pop[bob]': 3},
|
|
323
|
+
'email': null
|
|
314
324
|
}
|
|
315
325
|
};
|
|
316
326
|
|
|
@@ -323,14 +333,14 @@ describe('parse()', function () {
|
|
|
323
333
|
it('parses an object and not child values', function (done) {
|
|
324
334
|
|
|
325
335
|
var input = {
|
|
326
|
-
|
|
327
|
-
|
|
336
|
+
'user[name]': {'pop[bob]': { 'test': 3 }},
|
|
337
|
+
'user[email]': null
|
|
328
338
|
};
|
|
329
339
|
|
|
330
340
|
var expected = {
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
341
|
+
'user': {
|
|
342
|
+
'name': {'pop[bob]': { 'test': 3 }},
|
|
343
|
+
'email': null
|
|
334
344
|
}
|
|
335
345
|
};
|
|
336
346
|
|
|
@@ -344,8 +354,9 @@ describe('parse()', function () {
|
|
|
344
354
|
|
|
345
355
|
var tempBuffer = global.Buffer;
|
|
346
356
|
delete global.Buffer;
|
|
347
|
-
|
|
357
|
+
var result = Qs.parse('a=b&c=d');
|
|
348
358
|
global.Buffer = tempBuffer;
|
|
359
|
+
expect(result).to.deep.equal({ a: 'b', c: 'd' });
|
|
349
360
|
done();
|
|
350
361
|
});
|
|
351
362
|
|
|
@@ -365,10 +376,10 @@ describe('parse()', function () {
|
|
|
365
376
|
expect(function () {
|
|
366
377
|
|
|
367
378
|
parsed = Qs.parse({ 'foo[bar]': 'baz', 'foo[baz]': a });
|
|
368
|
-
}).to.not.throw(
|
|
379
|
+
}).to.not.throw();
|
|
369
380
|
|
|
370
|
-
expect(parsed).to.
|
|
371
|
-
expect(parsed.foo).to.
|
|
381
|
+
expect(parsed).to.contain('foo');
|
|
382
|
+
expect(parsed.foo).to.contain('bar', 'baz');
|
|
372
383
|
expect(parsed.foo.bar).to.equal('baz');
|
|
373
384
|
expect(parsed.foo.baz).to.deep.equal(a);
|
|
374
385
|
done();
|
|
@@ -378,9 +389,11 @@ describe('parse()', function () {
|
|
|
378
389
|
|
|
379
390
|
var a = Object.create(null);
|
|
380
391
|
a.b = 'c';
|
|
381
|
-
|
|
392
|
+
|
|
382
393
|
expect(Qs.parse(a)).to.deep.equal({ b: 'c' });
|
|
383
|
-
|
|
394
|
+
var result = Qs.parse({ a: a });
|
|
395
|
+
expect(result).to.contain('a');
|
|
396
|
+
expect(result.a).to.deep.equal(a);
|
|
384
397
|
done();
|
|
385
398
|
});
|
|
386
399
|
|
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
|
|
|
@@ -40,6 +42,12 @@ describe('stringify()', function () {
|
|
|
40
42
|
done();
|
|
41
43
|
});
|
|
42
44
|
|
|
45
|
+
it('omits array indices when asked', function (done) {
|
|
46
|
+
|
|
47
|
+
expect(Qs.stringify({ a: ['b', 'c', 'd'] }, { indices: false })).to.equal('a=b&a=c&a=d');
|
|
48
|
+
done();
|
|
49
|
+
});
|
|
50
|
+
|
|
43
51
|
it('stringifies a nested array value', function (done) {
|
|
44
52
|
|
|
45
53
|
expect(Qs.stringify({ a: { b: ['c', 'd'] } })).to.equal('a%5Bb%5D%5B0%5D=c&a%5Bb%5D%5B1%5D=d');
|
|
@@ -53,6 +61,12 @@ describe('stringify()', function () {
|
|
|
53
61
|
done();
|
|
54
62
|
});
|
|
55
63
|
|
|
64
|
+
it('does not omit object keys when indices = false', function (done) {
|
|
65
|
+
|
|
66
|
+
expect(Qs.stringify({ a: [{ b: 'c' }] }, { indices: false })).to.equal('a%5Bb%5D=c');
|
|
67
|
+
done();
|
|
68
|
+
});
|
|
69
|
+
|
|
56
70
|
it('stringifies a complicated object', function (done) {
|
|
57
71
|
|
|
58
72
|
expect(Qs.stringify({ a: { b: 'c', d: 'e' } })).to.equal('a%5Bb%5D=c&a%5Bd%5D=e');
|
|
@@ -76,6 +90,15 @@ describe('stringify()', function () {
|
|
|
76
90
|
done();
|
|
77
91
|
});
|
|
78
92
|
|
|
93
|
+
it('returns an empty string for invalid input', function (done) {
|
|
94
|
+
|
|
95
|
+
expect(Qs.stringify(undefined)).to.equal('');
|
|
96
|
+
expect(Qs.stringify(false)).to.equal('');
|
|
97
|
+
expect(Qs.stringify(null)).to.equal('');
|
|
98
|
+
expect(Qs.stringify('')).to.equal('');
|
|
99
|
+
done();
|
|
100
|
+
});
|
|
101
|
+
|
|
79
102
|
it('stringifies an object with an empty object as a child', function (done) {
|
|
80
103
|
|
|
81
104
|
var obj = {
|