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 CHANGED
@@ -1,4 +1,6 @@
1
1
  language: node_js
2
2
 
3
3
  node_js:
4
- - 0.10
4
+ - 0.10
5
+ - 0.12
6
+ - iojs
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 &quot;undefined&quot; and &quot;false&quot; instead of throwing &quot;TypeError&quot;.
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&#39;t use Buffer global if it&#39;s not present
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&#39;t call Utils.clone at the top of Utils.merge
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&#39;t overwrite null values
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 (!obj.hasOwnProperty(key)) {
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
- indices: true
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, options) {
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 (!options.indices &&
43
- Array.isArray(obj)) {
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 + ']', options));
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, options));
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, l = obj.length; i < l; ++i) {
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 (var i = 0, il = keys.length; i < il; ++i) {
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.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
- "lab": "4.x.x"
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 = Lab.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
- "user[name]": {"pop[bob]": 3},
313
- "user[email]": null
317
+ 'user[name]': {'pop[bob]': 3},
318
+ 'user[email]': null
314
319
  };
315
320
 
316
321
  var expected = {
317
- "user": {
318
- "name": {"pop[bob]": 3},
319
- "email": null
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
- "user[name]": {"pop[bob]": { "test": 3 }},
333
- "user[email]": null
337
+ 'user[name]': {'pop[bob]': { 'test': 3 }},
338
+ 'user[email]': null
334
339
  };
335
340
 
336
341
  var expected = {
337
- "user": {
338
- "name": {"pop[bob]": { "test": 3 }},
339
- "email": null
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
- expect(Qs.parse('a=b&c=d')).to.deep.equal({ a: 'b', c: 'd' });
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(Error);
380
+ }).to.not.throw();
375
381
 
376
- expect(parsed).to.have.key('foo');
377
- expect(parsed.foo).to.have.keys('bar', 'baz');
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
- expect(Qs.parse({ a: a })).to.deep.equal({ a: { b: 'c' } });
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 = Lab.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');