qs 2.2.0 → 2.2.4
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 +47 -0
- package/lib/parse.js +10 -8
- package/lib/utils.js +26 -40
- package/package.json +2 -2
- package/test/parse.js +57 -6
- package/test/stringify.js +5 -4
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
|
|
2
|
+
## [**2.2.3**](https://github.com/hapijs/qs/issues?milestone=12&state=closed)
|
|
3
|
+
- [**#37**](https://github.com/hapijs/qs/issues/37) parser discards first empty value in array
|
|
4
|
+
- [**#36**](https://github.com/hapijs/qs/issues/36) Update to lab 4.x
|
|
5
|
+
|
|
6
|
+
## [**2.2.2**](https://github.com/hapijs/qs/issues?milestone=11&state=closed)
|
|
7
|
+
- [**#33**](https://github.com/hapijs/qs/issues/33) Error when plain object in a value
|
|
8
|
+
- [**#34**](https://github.com/hapijs/qs/issues/34) use Object.prototype.hasOwnProperty.call instead of obj.hasOwnProperty
|
|
9
|
+
- [**#24**](https://github.com/hapijs/qs/issues/24) Changelog? Semver?
|
|
10
|
+
|
|
11
|
+
## [**2.2.1**](https://github.com/hapijs/qs/issues?milestone=10&state=closed)
|
|
12
|
+
- [**#32**](https://github.com/hapijs/qs/issues/32) account for circular references properly, closes #31
|
|
13
|
+
- [**#31**](https://github.com/hapijs/qs/issues/31) qs.parse stackoverflow on circular objects
|
|
14
|
+
|
|
15
|
+
## [**2.2.0**](https://github.com/hapijs/qs/issues?milestone=9&state=closed)
|
|
16
|
+
- [**#26**](https://github.com/hapijs/qs/issues/26) Don't use Buffer global if it's not present
|
|
17
|
+
- [**#30**](https://github.com/hapijs/qs/issues/30) Bug when merging non-object values into arrays
|
|
18
|
+
- [**#29**](https://github.com/hapijs/qs/issues/29) Don't call Utils.clone at the top of Utils.merge
|
|
19
|
+
- [**#23**](https://github.com/hapijs/qs/issues/23) Ability to not limit parameters?
|
|
20
|
+
|
|
21
|
+
## [**2.1.0**](https://github.com/hapijs/qs/issues?milestone=8&state=closed)
|
|
22
|
+
- [**#22**](https://github.com/hapijs/qs/issues/22) Enable using a RegExp as delimiter
|
|
23
|
+
|
|
24
|
+
## [**2.0.0**](https://github.com/hapijs/qs/issues?milestone=7&state=closed)
|
|
25
|
+
- [**#18**](https://github.com/hapijs/qs/issues/18) Why is there arrayLimit?
|
|
26
|
+
- [**#20**](https://github.com/hapijs/qs/issues/20) Configurable parametersLimit
|
|
27
|
+
- [**#21**](https://github.com/hapijs/qs/issues/21) make all limits optional, for #18, for #20
|
|
28
|
+
|
|
29
|
+
## [**1.2.2**](https://github.com/hapijs/qs/issues?milestone=6&state=closed)
|
|
30
|
+
- [**#19**](https://github.com/hapijs/qs/issues/19) Don't overwrite null values
|
|
31
|
+
|
|
32
|
+
## [**1.2.1**](https://github.com/hapijs/qs/issues?milestone=5&state=closed)
|
|
33
|
+
- [**#16**](https://github.com/hapijs/qs/issues/16) ignore non-string delimiters
|
|
34
|
+
- [**#15**](https://github.com/hapijs/qs/issues/15) Close code block
|
|
35
|
+
|
|
36
|
+
## [**1.2.0**](https://github.com/hapijs/qs/issues?milestone=4&state=closed)
|
|
37
|
+
- [**#12**](https://github.com/hapijs/qs/issues/12) Add optional delim argument
|
|
38
|
+
- [**#13**](https://github.com/hapijs/qs/issues/13) fix #11: flattened keys in array are now correctly parsed
|
|
39
|
+
|
|
40
|
+
## [**1.1.0**](https://github.com/hapijs/qs/issues?milestone=3&state=closed)
|
|
41
|
+
- [**#7**](https://github.com/hapijs/qs/issues/7) Empty values of a POST array disappear after being submitted
|
|
42
|
+
- [**#9**](https://github.com/hapijs/qs/issues/9) Should not omit equals signs (=) when value is null
|
|
43
|
+
- [**#6**](https://github.com/hapijs/qs/issues/6) Minor grammar fix in README
|
|
44
|
+
|
|
45
|
+
## [**1.0.2**](https://github.com/hapijs/qs/issues?milestone=2&state=closed)
|
|
46
|
+
- [**#5**](https://github.com/hapijs/qs/issues/5) array holes incorrectly copied into object on large index
|
|
47
|
+
|
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 (!obj
|
|
32
|
+
if (!obj.hasOwnProperty(key)) {
|
|
33
33
|
obj[key] = val;
|
|
34
34
|
}
|
|
35
35
|
else {
|
|
@@ -58,8 +58,10 @@ internals.parseObject = function (chain, val, options) {
|
|
|
58
58
|
else {
|
|
59
59
|
var cleanRoot = root[0] === '[' && root[root.length - 1] === ']' ? root.slice(1, root.length - 1) : root;
|
|
60
60
|
var index = parseInt(cleanRoot, 10);
|
|
61
|
+
var indexString = '' + index;
|
|
61
62
|
if (!isNaN(index) &&
|
|
62
63
|
root !== cleanRoot &&
|
|
64
|
+
indexString === cleanRoot &&
|
|
63
65
|
index <= options.arrayLimit) {
|
|
64
66
|
|
|
65
67
|
obj = [];
|
|
@@ -138,16 +140,16 @@ module.exports = function (str, options) {
|
|
|
138
140
|
options.arrayLimit = typeof options.arrayLimit === 'number' ? options.arrayLimit : internals.arrayLimit;
|
|
139
141
|
options.parameterLimit = typeof options.parameterLimit === 'number' ? options.parameterLimit : internals.parameterLimit;
|
|
140
142
|
|
|
141
|
-
var tempObj = typeof str === 'string' ? internals.parseValues(str, options) :
|
|
143
|
+
var tempObj = typeof str === 'string' ? internals.parseValues(str, options) : str;
|
|
142
144
|
var obj = {};
|
|
143
145
|
|
|
144
146
|
// Iterate over the keys and setup the new object
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
147
|
+
|
|
148
|
+
var keys = Object.keys(tempObj);
|
|
149
|
+
for (var i = 0, il = keys.length; i < il; ++i) {
|
|
150
|
+
var key = keys[i];
|
|
151
|
+
var newObj = internals.parseKeys(key, tempObj[key], options);
|
|
152
|
+
obj = Utils.merge(obj, newObj);
|
|
151
153
|
}
|
|
152
154
|
|
|
153
155
|
return Utils.compact(obj);
|
package/lib/utils.js
CHANGED
|
@@ -20,29 +20,6 @@ exports.arrayToObject = function (source) {
|
|
|
20
20
|
};
|
|
21
21
|
|
|
22
22
|
|
|
23
|
-
exports.clone = function (source) {
|
|
24
|
-
|
|
25
|
-
if (typeof source !== 'object' ||
|
|
26
|
-
source === null) {
|
|
27
|
-
|
|
28
|
-
return source;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
if (exports.isBuffer(source)) {
|
|
32
|
-
return source.toString();
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
var obj = Array.isArray(source) ? [] : {};
|
|
36
|
-
for (var i in source) {
|
|
37
|
-
if (source.hasOwnProperty(i)) {
|
|
38
|
-
obj[i] = exports.clone(source[i]);
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
return obj;
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
|
|
46
23
|
exports.merge = function (target, source) {
|
|
47
24
|
|
|
48
25
|
if (!source) {
|
|
@@ -83,7 +60,7 @@ exports.merge = function (target, source) {
|
|
|
83
60
|
typeof value === 'object') {
|
|
84
61
|
|
|
85
62
|
if (!target[key]) {
|
|
86
|
-
target[key] =
|
|
63
|
+
target[key] = value;
|
|
87
64
|
}
|
|
88
65
|
else {
|
|
89
66
|
target[key] = exports.merge(target[key], value);
|
|
@@ -108,32 +85,41 @@ exports.decode = function (str) {
|
|
|
108
85
|
};
|
|
109
86
|
|
|
110
87
|
|
|
111
|
-
exports.compact = function (obj) {
|
|
88
|
+
exports.compact = function (obj, refs) {
|
|
89
|
+
|
|
90
|
+
if (typeof obj !== 'object' ||
|
|
91
|
+
obj === null) {
|
|
112
92
|
|
|
113
|
-
if (typeof obj !== 'object' || obj === null) {
|
|
114
93
|
return obj;
|
|
115
94
|
}
|
|
116
95
|
|
|
117
|
-
|
|
96
|
+
refs = refs || [];
|
|
97
|
+
var lookup = refs.indexOf(obj);
|
|
98
|
+
if (lookup !== -1) {
|
|
99
|
+
return refs[lookup];
|
|
100
|
+
}
|
|
118
101
|
|
|
119
|
-
|
|
120
|
-
if (obj.hasOwnProperty(key)) {
|
|
121
|
-
if (Array.isArray(obj[key])) {
|
|
122
|
-
compacted[key] = [];
|
|
102
|
+
refs.push(obj);
|
|
123
103
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
else {
|
|
131
|
-
compacted[key] = exports.compact(obj[key]);
|
|
104
|
+
if (Array.isArray(obj)) {
|
|
105
|
+
var compacted = [];
|
|
106
|
+
|
|
107
|
+
for (var i = 0, l = obj.length; i < l; ++i) {
|
|
108
|
+
if (typeof obj[i] !== 'undefined') {
|
|
109
|
+
compacted.push(obj[i]);
|
|
132
110
|
}
|
|
133
111
|
}
|
|
112
|
+
|
|
113
|
+
return compacted;
|
|
134
114
|
}
|
|
135
115
|
|
|
136
|
-
|
|
116
|
+
var keys = Object.keys(obj);
|
|
117
|
+
for (var i = 0, il = keys.length; i < il; ++i) {
|
|
118
|
+
var key = keys[i];
|
|
119
|
+
obj[key] = exports.compact(obj[key], refs);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return obj;
|
|
137
123
|
};
|
|
138
124
|
|
|
139
125
|
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "qs",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.4",
|
|
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
|
-
"lab": "
|
|
9
|
+
"lab": "4.x.x"
|
|
10
10
|
},
|
|
11
11
|
"scripts": {
|
|
12
12
|
"test": "make test-cov"
|
package/test/parse.js
CHANGED
|
@@ -11,11 +11,12 @@ var internals = {};
|
|
|
11
11
|
|
|
12
12
|
// Test shortcuts
|
|
13
13
|
|
|
14
|
+
var lab = exports.lab = Lab.script();
|
|
14
15
|
var expect = Lab.expect;
|
|
15
|
-
var before =
|
|
16
|
-
var after =
|
|
17
|
-
var describe =
|
|
18
|
-
var it =
|
|
16
|
+
var before = lab.before;
|
|
17
|
+
var after = lab.after;
|
|
18
|
+
var describe = lab.experiment;
|
|
19
|
+
var it = lab.test;
|
|
19
20
|
|
|
20
21
|
|
|
21
22
|
describe('#parse', function () {
|
|
@@ -103,6 +104,12 @@ describe('#parse', function () {
|
|
|
103
104
|
done();
|
|
104
105
|
});
|
|
105
106
|
|
|
107
|
+
it('supports keys that begin with a number', function (done) {
|
|
108
|
+
|
|
109
|
+
expect(Qs.parse('a[12b]=c')).to.deep.equal({ a: { '12b': 'c' } });
|
|
110
|
+
done();
|
|
111
|
+
});
|
|
112
|
+
|
|
106
113
|
it('supports encoded = signs', function (done) {
|
|
107
114
|
|
|
108
115
|
expect(Qs.parse('he%3Dllo=th%3Dere')).to.deep.equal({ 'he=llo': 'th=ere' });
|
|
@@ -189,6 +196,7 @@ describe('#parse', function () {
|
|
|
189
196
|
|
|
190
197
|
expect(Qs.parse('a[]=b&a[]=&a[]=c')).to.deep.equal({ a: ['b', '', 'c'] });
|
|
191
198
|
expect(Qs.parse('a[0]=b&a[1]=&a[2]=c&a[19]=')).to.deep.equal({ a: ['b', '', 'c', ''] });
|
|
199
|
+
expect(Qs.parse('a[]=&a[]=b&a[]=c')).to.deep.equal({ a: ['', 'b', 'c'] });
|
|
192
200
|
done();
|
|
193
201
|
});
|
|
194
202
|
|
|
@@ -205,10 +213,10 @@ describe('#parse', function () {
|
|
|
205
213
|
done();
|
|
206
214
|
});
|
|
207
215
|
|
|
208
|
-
it('parses buffers
|
|
216
|
+
it('parses buffers correctly', function (done) {
|
|
209
217
|
|
|
210
218
|
var b = new Buffer('test');
|
|
211
|
-
expect(Qs.parse({ a: b })).to.deep.equal({ a: b
|
|
219
|
+
expect(Qs.parse({ a: b })).to.deep.equal({ a: b });
|
|
212
220
|
done();
|
|
213
221
|
});
|
|
214
222
|
|
|
@@ -337,4 +345,47 @@ describe('#parse', function () {
|
|
|
337
345
|
expect(Qs.parse('roomInfoList[0].childrenAges[0]=15&roomInfoList[0].numberOfAdults=2')).to.deep.equal({ roomInfoList: [['15', '2']] });
|
|
338
346
|
done();
|
|
339
347
|
});
|
|
348
|
+
|
|
349
|
+
it('does not crash when parsing circular references', function (done) {
|
|
350
|
+
|
|
351
|
+
var a = {};
|
|
352
|
+
a.b = a;
|
|
353
|
+
|
|
354
|
+
var parsed;
|
|
355
|
+
|
|
356
|
+
expect(function () {
|
|
357
|
+
|
|
358
|
+
parsed = Qs.parse({ 'foo[bar]': 'baz', 'foo[baz]': a });
|
|
359
|
+
}).to.not.throw(Error);
|
|
360
|
+
|
|
361
|
+
expect(parsed).to.have.key('foo');
|
|
362
|
+
expect(parsed.foo).to.have.keys('bar', 'baz');
|
|
363
|
+
expect(parsed.foo.bar).to.equal('baz');
|
|
364
|
+
expect(parsed.foo.baz).to.deep.equal(a);
|
|
365
|
+
done();
|
|
366
|
+
});
|
|
367
|
+
|
|
368
|
+
it('parses plain objects correctly', function (done) {
|
|
369
|
+
|
|
370
|
+
var a = Object.create(null);
|
|
371
|
+
a.b = 'c';
|
|
372
|
+
|
|
373
|
+
expect(Qs.parse(a)).to.deep.equal({ b: 'c' });
|
|
374
|
+
expect(Qs.parse({ a: a })).to.deep.equal({ a: { b: 'c' } });
|
|
375
|
+
done();
|
|
376
|
+
});
|
|
377
|
+
|
|
378
|
+
it('parses dates correctly', function (done) {
|
|
379
|
+
|
|
380
|
+
var now = new Date();
|
|
381
|
+
expect(Qs.parse({ a: now })).to.deep.equal({ a: now });
|
|
382
|
+
done();
|
|
383
|
+
});
|
|
384
|
+
|
|
385
|
+
it('parses regular expressions correctly', function (done) {
|
|
386
|
+
|
|
387
|
+
var re = /^test$/;
|
|
388
|
+
expect(Qs.parse({ a: re })).to.deep.equal({ a: re });
|
|
389
|
+
done();
|
|
390
|
+
});
|
|
340
391
|
});
|
package/test/stringify.js
CHANGED
|
@@ -11,11 +11,12 @@ var internals = {};
|
|
|
11
11
|
|
|
12
12
|
// Test shortcuts
|
|
13
13
|
|
|
14
|
+
var lab = exports.lab = Lab.script();
|
|
14
15
|
var expect = Lab.expect;
|
|
15
|
-
var before =
|
|
16
|
-
var after =
|
|
17
|
-
var describe =
|
|
18
|
-
var it =
|
|
16
|
+
var before = lab.before;
|
|
17
|
+
var after = lab.after;
|
|
18
|
+
var describe = lab.experiment;
|
|
19
|
+
var it = lab.test;
|
|
19
20
|
|
|
20
21
|
|
|
21
22
|
describe('#stringify', function () {
|