qs 6.2.2 → 6.3.1

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/.eslintrc CHANGED
@@ -1,19 +1,19 @@
1
1
  {
2
- "root": true,
2
+ "root": true,
3
3
 
4
- "extends": "@ljharb",
4
+ "extends": "@ljharb",
5
5
 
6
- "rules": {
7
- "complexity": [2, 22],
8
- "consistent-return": [1],
9
- "id-length": [2, { "min": 1, "max": 25, "properties": "never" }],
10
- "indent": [2, 4],
11
- "max-params": [2, 9],
12
- "max-statements": [2, 36],
13
- "no-extra-parens": [1],
14
- "no-continue": [1],
15
- "no-magic-numbers": 0,
16
- "no-restricted-syntax": [2, "BreakStatement", "DebuggerStatement", "ForInStatement", "LabeledStatement", "WithStatement"],
17
- "operator-linebreak": 1
18
- }
6
+ "rules": {
7
+ "complexity": [2, 25],
8
+ "consistent-return": 1,
9
+ "id-length": [2, { "min": 1, "max": 25, "properties": "never" }],
10
+ "indent": [2, 4],
11
+ "max-params": [2, 11],
12
+ "max-statements": [2, 42],
13
+ "no-extra-parens": 1,
14
+ "no-continue": 1,
15
+ "no-magic-numbers": 0,
16
+ "no-restricted-syntax": [2, "BreakStatement", "DebuggerStatement", "ForInStatement", "LabeledStatement", "WithStatement"],
17
+ "operator-linebreak": 1
18
+ }
19
19
  }
package/CHANGELOG.md CHANGED
@@ -1,5 +1,28 @@
1
- ## **6.2.2**
2
- - [Fix] ensure that `allowPrototypes: false` does not ever shadow Object.prototype properties
1
+ ## **6.3.1**
2
+ - [Fix] ensure that `allowPrototypes: false` does not ever shadow Object.prototype properties (thanks, @snyk!)
3
+ - [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `browserify`, `iconv-lite`, `qs-iconv`, `tape`
4
+ - [Tests] on all node minors; improve test matrix
5
+ - [Docs] document stringify option `allowDots` (#195)
6
+ - [Docs] add empty object and array values example (#195)
7
+ - [Docs] Fix minor inconsistency/typo (#192)
8
+ - [Docs] document stringify option `sort` (#191)
9
+ - [Refactor] `stringify`: throw faster with an invalid encoder
10
+ - [Refactor] remove unnecessary escapes (#184)
11
+ - Remove contributing.md, since `qs` is no longer part of `hapi` (#183)
12
+
13
+ ## **6.3.0**
14
+ - [New] Add support for RFC 1738 (#174, #173)
15
+ - [New] `stringify`: Add `serializeDate` option to customize Date serialization (#159)
16
+ - [Fix] ensure `utils.merge` handles merging two arrays
17
+ - [Refactor] only constructors should be capitalized
18
+ - [Refactor] capitalized var names are for constructors only
19
+ - [Refactor] avoid using a sparse array
20
+ - [Robustness] `formats`: cache `String#replace`
21
+ - [Dev Deps] update `browserify`, `eslint`, `@ljharb/eslint-config`; add `safe-publish-latest`
22
+ - [Tests] up to `node` `v6.8`, `v4.6`; improve test matrix
23
+ - [Tests] flesh out arrayLimit/arrayFormat tests (#107)
24
+ - [Tests] skip Object.create tests when null objects are not available
25
+ - [Tests] Turn on eslint for test files (#175)
3
26
 
4
27
  ## **6.2.1**
5
28
  - [Fix] ensure `key[]=x&key[]&key[]=y` results in 3, not 2, values
package/README.md CHANGED
@@ -39,11 +39,11 @@ assert.deepEqual(qs.parse('foo[bar]=baz'), {
39
39
  });
40
40
  ```
41
41
 
42
- When using the `plainObjects` option the parsed value is returned as a plain object, created via `Object.create(null)` and as such you should be aware that prototype methods will not exist on it and a user may set those names to whatever value they like:
42
+ When using the `plainObjects` option the parsed value is returned as a null object, created via `Object.create(null)` and as such you should be aware that prototype methods will not exist on it and a user may set those names to whatever value they like:
43
43
 
44
44
  ```javascript
45
- var plainObject = qs.parse('a[hasOwnProperty]=b', { plainObjects: true });
46
- assert.deepEqual(plainObject, { a: { hasOwnProperty: 'b' } });
45
+ var nullObject = qs.parse('a[hasOwnProperty]=b', { plainObjects: true });
46
+ assert.deepEqual(nullObject, { a: { hasOwnProperty: 'b' } });
47
47
  ```
48
48
 
49
49
  By default parameters that would overwrite properties on the object prototype are ignored, if you wish to keep the data from those fields either use `plainObjects` as mentioned above, or set `allowPrototypes` to `true` which will allow user input to overwrite those properties. *WARNING* It is generally a bad idea to enable this option as it can cause problems when attempting to use the properties that have been overwritten. Always be careful with this option.
@@ -261,7 +261,7 @@ qs.stringify({ a: ['b', 'c', 'd'] }, { indices: false });
261
261
  // 'a=b&a=c&a=d'
262
262
  ```
263
263
 
264
- You may use the `arrayFormat` option to specify the format of the output array
264
+ You may use the `arrayFormat` option to specify the format of the output array:
265
265
 
266
266
  ```javascript
267
267
  qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'indices' })
@@ -272,12 +272,36 @@ qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'repeat' })
272
272
  // 'a=b&a=c'
273
273
  ```
274
274
 
275
+ When objects are stringified, by default they use bracket notation:
276
+
277
+ ```javascript
278
+ qs.stringify({ a: { b: { c: 'd', e: 'f' } } });
279
+ // 'a[b][c]=d&a[b][e]=f'
280
+ ```
281
+
282
+ You may override this to use dot notation by setting the `allowDots` option to `true`:
283
+
284
+ ```javascript
285
+ qs.stringify({ a: { b: { c: 'd', e: 'f' } } }, { allowDots: true });
286
+ // 'a.b.c=d&a.b.e=f'
287
+ ```
288
+
275
289
  Empty strings and null values will omit the value, but the equals sign (=) remains in place:
276
290
 
277
291
  ```javascript
278
292
  assert.equal(qs.stringify({ a: '' }), 'a=');
279
293
  ```
280
294
 
295
+ Key with no values (such as an empty object or array) will return nothing:
296
+
297
+ ```javascript
298
+ assert.equal(qs.stringify({ a: [] }), '');
299
+ assert.equal(qs.stringify({ a: {} }), '');
300
+ assert.equal(qs.stringify({ a: [{}] }), '');
301
+ assert.equal(qs.stringify({ a: { b: []} }), '');
302
+ assert.equal(qs.stringify({ a: { b: {}} }), '');
303
+ ```
304
+
281
305
  Properties that are set to `undefined` will be omitted entirely:
282
306
 
283
307
  ```javascript
@@ -290,6 +314,26 @@ The delimiter may be overridden with stringify as well:
290
314
  assert.equal(qs.stringify({ a: 'b', c: 'd' }, { delimiter: ';' }), 'a=b;c=d');
291
315
  ```
292
316
 
317
+ If you only want to override the serialization of `Date` objects, you can provide a `serializeDate` option:
318
+
319
+ ```javascript
320
+ var date = new Date(7);
321
+ assert.equal(qs.stringify({ a: date }), 'a=1970-01-01T00:00:00.007Z'.replace(/:/g, '%3A'));
322
+ assert.equal(
323
+ qs.stringify({ a: date }, { serializeDate: function (d) { return d.getTime(); } }),
324
+ 'a=7'
325
+ );
326
+ ```
327
+
328
+ You may use the `sort` option to affect the order of parameter keys:
329
+
330
+ ```javascript
331
+ function alphabeticalSort(a, b) {
332
+ return a.localeCompare(b);
333
+ }
334
+ assert.equal(qs.stringify({ a: 'c', z: 'y', b : 'f' }, { sort: alphabeticalSort }), 'a=c&b=f&z=y');
335
+ ```
336
+
293
337
  Finally, you can use the `filter` option to restrict which keys will be included in the stringified output.
294
338
  If you pass a function, it will be called for each key to obtain the replacement value. Otherwise, if you
295
339
  pass an array, it will be used to select properties and array indices for stringification:
@@ -374,3 +418,14 @@ var decoder = require('qs-iconv/decoder')('shift_jis');
374
418
  var obj = qs.parse('a=%82%B1%82%F1%82%C9%82%BF%82%CD%81I', { decoder: decoder });
375
419
  assert.deepEqual(obj, { a: 'こんにちは!' });
376
420
  ```
421
+
422
+ ### RFC 3986 and RFC 1738 space encoding
423
+
424
+ RFC3986 used as default option and encodes ' ' to *%20* which is backward compatible.
425
+ In the same time, output can be stringified as per RFC1738 with ' ' equal to '+'.
426
+
427
+ ```
428
+ assert.equal(qs.stringify({ a: 'b c' }), 'a=b%20c');
429
+ assert.equal(qs.stringify({ a: 'b c' }, { format : 'RFC3986' }), 'a=b%20c');
430
+ assert.equal(qs.stringify({ a: 'b c' }, { format : 'RFC1738' }), 'a=b+c');
431
+ ```
package/dist/qs.js CHANGED
@@ -1,34 +1,56 @@
1
1
  (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Qs = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
2
2
  'use strict';
3
3
 
4
- var Stringify = require('./stringify');
5
- var Parse = require('./parse');
4
+ var replace = String.prototype.replace;
5
+ var percentTwenties = /%20/g;
6
6
 
7
7
  module.exports = {
8
- stringify: Stringify,
9
- parse: Parse
8
+ 'default': 'RFC3986',
9
+ formatters: {
10
+ RFC1738: function (value) {
11
+ return replace.call(value, percentTwenties, '+');
12
+ },
13
+ RFC3986: function (value) {
14
+ return value;
15
+ }
16
+ },
17
+ RFC1738: 'RFC1738',
18
+ RFC3986: 'RFC3986'
19
+ };
20
+
21
+ },{}],2:[function(require,module,exports){
22
+ 'use strict';
23
+
24
+ var stringify = require('./stringify');
25
+ var parse = require('./parse');
26
+ var formats = require('./formats');
27
+
28
+ module.exports = {
29
+ formats: formats,
30
+ parse: parse,
31
+ stringify: stringify
10
32
  };
11
33
 
12
- },{"./parse":2,"./stringify":3}],2:[function(require,module,exports){
34
+ },{"./formats":1,"./parse":3,"./stringify":4}],3:[function(require,module,exports){
13
35
  'use strict';
14
36
 
15
- var Utils = require('./utils');
37
+ var utils = require('./utils');
16
38
 
17
39
  var has = Object.prototype.hasOwnProperty;
18
40
 
19
41
  var defaults = {
42
+ allowDots: false,
43
+ allowPrototypes: false,
44
+ arrayLimit: 20,
45
+ decoder: utils.decode,
20
46
  delimiter: '&',
21
47
  depth: 5,
22
- arrayLimit: 20,
23
48
  parameterLimit: 1000,
24
- strictNullHandling: false,
25
49
  plainObjects: false,
26
- allowPrototypes: false,
27
- allowDots: false,
28
- decoder: Utils.decode
50
+ strictNullHandling: false
29
51
  };
30
52
 
31
- var parseValues = function parseValues(str, options) {
53
+ var parseValues = function parseQueryStringValues(str, options) {
32
54
  var obj = {};
33
55
  var parts = str.split(options.delimiter, options.parameterLimit === Infinity ? undefined : options.parameterLimit);
34
56
 
@@ -54,7 +76,7 @@ var parseValues = function parseValues(str, options) {
54
76
  return obj;
55
77
  };
56
78
 
57
- var parseObject = function parseObject(chain, val, options) {
79
+ var parseObject = function parseObjectRecursive(chain, val, options) {
58
80
  if (!chain.length) {
59
81
  return val;
60
82
  }
@@ -86,7 +108,7 @@ var parseObject = function parseObject(chain, val, options) {
86
108
  return obj;
87
109
  };
88
110
 
89
- var parseKeys = function parseKeys(givenKey, val, options) {
111
+ var parseKeys = function parseQueryStringKeys(givenKey, val, options) {
90
112
  if (!givenKey) {
91
113
  return;
92
114
  }
@@ -147,7 +169,7 @@ module.exports = function (str, opts) {
147
169
  throw new TypeError('Decoder has to be a function.');
148
170
  }
149
171
 
150
- options.delimiter = typeof options.delimiter === 'string' || Utils.isRegExp(options.delimiter) ? options.delimiter : defaults.delimiter;
172
+ options.delimiter = typeof options.delimiter === 'string' || utils.isRegExp(options.delimiter) ? options.delimiter : defaults.delimiter;
151
173
  options.depth = typeof options.depth === 'number' ? options.depth : defaults.depth;
152
174
  options.arrayLimit = typeof options.arrayLimit === 'number' ? options.arrayLimit : defaults.arrayLimit;
153
175
  options.parseArrays = options.parseArrays !== false;
@@ -171,43 +193,61 @@ module.exports = function (str, opts) {
171
193
  for (var i = 0; i < keys.length; ++i) {
172
194
  var key = keys[i];
173
195
  var newObj = parseKeys(key, tempObj[key], options);
174
- obj = Utils.merge(obj, newObj, options);
196
+ obj = utils.merge(obj, newObj, options);
175
197
  }
176
198
 
177
- return Utils.compact(obj);
199
+ return utils.compact(obj);
178
200
  };
179
201
 
180
- },{"./utils":4}],3:[function(require,module,exports){
202
+ },{"./utils":5}],4:[function(require,module,exports){
181
203
  'use strict';
182
204
 
183
- var Utils = require('./utils');
205
+ var utils = require('./utils');
206
+ var formats = require('./formats');
184
207
 
185
208
  var arrayPrefixGenerators = {
186
- brackets: function brackets(prefix) {
209
+ brackets: function brackets(prefix) { // eslint-disable-line func-name-matching
187
210
  return prefix + '[]';
188
211
  },
189
- indices: function indices(prefix, key) {
212
+ indices: function indices(prefix, key) { // eslint-disable-line func-name-matching
190
213
  return prefix + '[' + key + ']';
191
214
  },
192
- repeat: function repeat(prefix) {
215
+ repeat: function repeat(prefix) { // eslint-disable-line func-name-matching
193
216
  return prefix;
194
217
  }
195
218
  };
196
219
 
220
+ var toISO = Date.prototype.toISOString;
221
+
197
222
  var defaults = {
198
223
  delimiter: '&',
199
- strictNullHandling: false,
200
- skipNulls: false,
201
224
  encode: true,
202
- encoder: Utils.encode
225
+ encoder: utils.encode,
226
+ serializeDate: function serializeDate(date) { // eslint-disable-line func-name-matching
227
+ return toISO.call(date);
228
+ },
229
+ skipNulls: false,
230
+ strictNullHandling: false
203
231
  };
204
232
 
205
- var stringify = function stringify(object, prefix, generateArrayPrefix, strictNullHandling, skipNulls, encoder, filter, sort, allowDots) {
233
+ var stringify = function stringify( // eslint-disable-line func-name-matching
234
+ object,
235
+ prefix,
236
+ generateArrayPrefix,
237
+ strictNullHandling,
238
+ skipNulls,
239
+ encoder,
240
+ filter,
241
+ sort,
242
+ allowDots,
243
+ serializeDate,
244
+ formatter
245
+ ) {
206
246
  var obj = object;
207
247
  if (typeof filter === 'function') {
208
248
  obj = filter(prefix, obj);
209
249
  } else if (obj instanceof Date) {
210
- obj = obj.toISOString();
250
+ obj = serializeDate(obj);
211
251
  } else if (obj === null) {
212
252
  if (strictNullHandling) {
213
253
  return encoder ? encoder(prefix) : prefix;
@@ -216,11 +256,11 @@ var stringify = function stringify(object, prefix, generateArrayPrefix, strictNu
216
256
  obj = '';
217
257
  }
218
258
 
219
- if (typeof obj === 'string' || typeof obj === 'number' || typeof obj === 'boolean' || Utils.isBuffer(obj)) {
259
+ if (typeof obj === 'string' || typeof obj === 'number' || typeof obj === 'boolean' || utils.isBuffer(obj)) {
220
260
  if (encoder) {
221
- return [encoder(prefix) + '=' + encoder(obj)];
261
+ return [formatter(encoder(prefix)) + '=' + formatter(encoder(obj))];
222
262
  }
223
- return [prefix + '=' + String(obj)];
263
+ return [formatter(prefix) + '=' + formatter(String(obj))];
224
264
  }
225
265
 
226
266
  var values = [];
@@ -245,9 +285,33 @@ var stringify = function stringify(object, prefix, generateArrayPrefix, strictNu
245
285
  }
246
286
 
247
287
  if (Array.isArray(obj)) {
248
- values = values.concat(stringify(obj[key], generateArrayPrefix(prefix, key), generateArrayPrefix, strictNullHandling, skipNulls, encoder, filter, sort, allowDots));
288
+ values = values.concat(stringify(
289
+ obj[key],
290
+ generateArrayPrefix(prefix, key),
291
+ generateArrayPrefix,
292
+ strictNullHandling,
293
+ skipNulls,
294
+ encoder,
295
+ filter,
296
+ sort,
297
+ allowDots,
298
+ serializeDate,
299
+ formatter
300
+ ));
249
301
  } else {
250
- values = values.concat(stringify(obj[key], prefix + (allowDots ? '.' + key : '[' + key + ']'), generateArrayPrefix, strictNullHandling, skipNulls, encoder, filter, sort, allowDots));
302
+ values = values.concat(stringify(
303
+ obj[key],
304
+ prefix + (allowDots ? '.' + key : '[' + key + ']'),
305
+ generateArrayPrefix,
306
+ strictNullHandling,
307
+ skipNulls,
308
+ encoder,
309
+ filter,
310
+ sort,
311
+ allowDots,
312
+ serializeDate,
313
+ formatter
314
+ ));
251
315
  }
252
316
  }
253
317
 
@@ -257,6 +321,11 @@ var stringify = function stringify(object, prefix, generateArrayPrefix, strictNu
257
321
  module.exports = function (object, opts) {
258
322
  var obj = object;
259
323
  var options = opts || {};
324
+
325
+ if (options.encoder !== null && options.encoder !== undefined && typeof options.encoder !== 'function') {
326
+ throw new TypeError('Encoder has to be a function.');
327
+ }
328
+
260
329
  var delimiter = typeof options.delimiter === 'undefined' ? defaults.delimiter : options.delimiter;
261
330
  var strictNullHandling = typeof options.strictNullHandling === 'boolean' ? options.strictNullHandling : defaults.strictNullHandling;
262
331
  var skipNulls = typeof options.skipNulls === 'boolean' ? options.skipNulls : defaults.skipNulls;
@@ -264,18 +333,22 @@ module.exports = function (object, opts) {
264
333
  var encoder = encode ? (typeof options.encoder === 'function' ? options.encoder : defaults.encoder) : null;
265
334
  var sort = typeof options.sort === 'function' ? options.sort : null;
266
335
  var allowDots = typeof options.allowDots === 'undefined' ? false : options.allowDots;
336
+ var serializeDate = typeof options.serializeDate === 'function' ? options.serializeDate : defaults.serializeDate;
337
+ if (typeof options.format === 'undefined') {
338
+ options.format = formats.default;
339
+ } else if (!Object.prototype.hasOwnProperty.call(formats.formatters, options.format)) {
340
+ throw new TypeError('Unknown format option provided.');
341
+ }
342
+ var formatter = formats.formatters[options.format];
267
343
  var objKeys;
268
344
  var filter;
269
345
 
270
- if (options.encoder !== null && options.encoder !== undefined && typeof options.encoder !== 'function') {
271
- throw new TypeError('Encoder has to be a function.');
272
- }
273
-
274
346
  if (typeof options.filter === 'function') {
275
347
  filter = options.filter;
276
348
  obj = filter('', obj);
277
349
  } else if (Array.isArray(options.filter)) {
278
- objKeys = filter = options.filter;
350
+ filter = options.filter;
351
+ objKeys = filter;
279
352
  }
280
353
 
281
354
  var keys = [];
@@ -310,26 +383,40 @@ module.exports = function (object, opts) {
310
383
  continue;
311
384
  }
312
385
 
313
- keys = keys.concat(stringify(obj[key], key, generateArrayPrefix, strictNullHandling, skipNulls, encoder, filter, sort, allowDots));
386
+ keys = keys.concat(stringify(
387
+ obj[key],
388
+ key,
389
+ generateArrayPrefix,
390
+ strictNullHandling,
391
+ skipNulls,
392
+ encoder,
393
+ filter,
394
+ sort,
395
+ allowDots,
396
+ serializeDate,
397
+ formatter
398
+ ));
314
399
  }
315
400
 
316
401
  return keys.join(delimiter);
317
402
  };
318
403
 
319
- },{"./utils":4}],4:[function(require,module,exports){
404
+ },{"./formats":1,"./utils":5}],5:[function(require,module,exports){
320
405
  'use strict';
321
406
 
407
+ var has = Object.prototype.hasOwnProperty;
408
+
322
409
  var hexTable = (function () {
323
- var array = new Array(256);
410
+ var array = [];
324
411
  for (var i = 0; i < 256; ++i) {
325
- array[i] = '%' + ((i < 16 ? '0' : '') + i.toString(16)).toUpperCase();
412
+ array.push('%' + ((i < 16 ? '0' : '') + i.toString(16)).toUpperCase());
326
413
  }
327
414
 
328
415
  return array;
329
416
  }());
330
417
 
331
418
  exports.arrayToObject = function (source, options) {
332
- var obj = options.plainObjects ? Object.create(null) : {};
419
+ var obj = options && options.plainObjects ? Object.create(null) : {};
333
420
  for (var i = 0; i < source.length; ++i) {
334
421
  if (typeof source[i] !== 'undefined') {
335
422
  obj[i] = source[i];
@@ -365,6 +452,21 @@ exports.merge = function (target, source, options) {
365
452
  mergeTarget = exports.arrayToObject(target, options);
366
453
  }
367
454
 
455
+ if (Array.isArray(target) && Array.isArray(source)) {
456
+ source.forEach(function (item, i) {
457
+ if (has.call(target, i)) {
458
+ if (target[i] && typeof target[i] === 'object') {
459
+ target[i] = exports.merge(target[i], item, options);
460
+ } else {
461
+ target.push(item);
462
+ }
463
+ } else {
464
+ target[i] = item;
465
+ }
466
+ });
467
+ return target;
468
+ }
469
+
368
470
  return Object.keys(source).reduce(function (acc, key) {
369
471
  var value = source[key];
370
472
 
@@ -428,7 +530,7 @@ exports.encode = function (str) {
428
530
 
429
531
  i += 1;
430
532
  c = 0x10000 + (((c & 0x3FF) << 10) | (string.charCodeAt(i) & 0x3FF));
431
- out += hexTable[0xF0 | (c >> 18)] + hexTable[0x80 | ((c >> 12) & 0x3F)] + hexTable[0x80 | ((c >> 6) & 0x3F)] + hexTable[0x80 | (c & 0x3F)];
533
+ out += hexTable[0xF0 | (c >> 18)] + hexTable[0x80 | ((c >> 12) & 0x3F)] + hexTable[0x80 | ((c >> 6) & 0x3F)] + hexTable[0x80 | (c & 0x3F)]; // eslint-disable-line max-len
432
534
  }
433
535
 
434
536
  return out;
@@ -462,10 +564,9 @@ exports.compact = function (obj, references) {
462
564
  }
463
565
 
464
566
  var keys = Object.keys(obj);
465
- for (var j = 0; j < keys.length; ++j) {
466
- var key = keys[j];
567
+ keys.forEach(function (key) {
467
568
  obj[key] = exports.compact(obj[key], refs);
468
- }
569
+ });
469
570
 
470
571
  return obj;
471
572
  };
@@ -482,5 +583,5 @@ exports.isBuffer = function (obj) {
482
583
  return !!(obj.constructor && obj.constructor.isBuffer && obj.constructor.isBuffer(obj));
483
584
  };
484
585
 
485
- },{}]},{},[1])(1)
586
+ },{}]},{},[2])(2)
486
587
  });
package/lib/formats.js ADDED
@@ -0,0 +1,18 @@
1
+ 'use strict';
2
+
3
+ var replace = String.prototype.replace;
4
+ var percentTwenties = /%20/g;
5
+
6
+ module.exports = {
7
+ 'default': 'RFC3986',
8
+ formatters: {
9
+ RFC1738: function (value) {
10
+ return replace.call(value, percentTwenties, '+');
11
+ },
12
+ RFC3986: function (value) {
13
+ return value;
14
+ }
15
+ },
16
+ RFC1738: 'RFC1738',
17
+ RFC3986: 'RFC3986'
18
+ };
package/lib/index.js CHANGED
@@ -1,9 +1,11 @@
1
1
  'use strict';
2
2
 
3
- var Stringify = require('./stringify');
4
- var Parse = require('./parse');
3
+ var stringify = require('./stringify');
4
+ var parse = require('./parse');
5
+ var formats = require('./formats');
5
6
 
6
7
  module.exports = {
7
- stringify: Stringify,
8
- parse: Parse
8
+ formats: formats,
9
+ parse: parse,
10
+ stringify: stringify
9
11
  };
package/lib/parse.js CHANGED
@@ -1,22 +1,22 @@
1
1
  'use strict';
2
2
 
3
- var Utils = require('./utils');
3
+ var utils = require('./utils');
4
4
 
5
5
  var has = Object.prototype.hasOwnProperty;
6
6
 
7
7
  var defaults = {
8
+ allowDots: false,
9
+ allowPrototypes: false,
10
+ arrayLimit: 20,
11
+ decoder: utils.decode,
8
12
  delimiter: '&',
9
13
  depth: 5,
10
- arrayLimit: 20,
11
14
  parameterLimit: 1000,
12
- strictNullHandling: false,
13
15
  plainObjects: false,
14
- allowPrototypes: false,
15
- allowDots: false,
16
- decoder: Utils.decode
16
+ strictNullHandling: false
17
17
  };
18
18
 
19
- var parseValues = function parseValues(str, options) {
19
+ var parseValues = function parseQueryStringValues(str, options) {
20
20
  var obj = {};
21
21
  var parts = str.split(options.delimiter, options.parameterLimit === Infinity ? undefined : options.parameterLimit);
22
22
 
@@ -42,7 +42,7 @@ var parseValues = function parseValues(str, options) {
42
42
  return obj;
43
43
  };
44
44
 
45
- var parseObject = function parseObject(chain, val, options) {
45
+ var parseObject = function parseObjectRecursive(chain, val, options) {
46
46
  if (!chain.length) {
47
47
  return val;
48
48
  }
@@ -74,7 +74,7 @@ var parseObject = function parseObject(chain, val, options) {
74
74
  return obj;
75
75
  };
76
76
 
77
- var parseKeys = function parseKeys(givenKey, val, options) {
77
+ var parseKeys = function parseQueryStringKeys(givenKey, val, options) {
78
78
  if (!givenKey) {
79
79
  return;
80
80
  }
@@ -135,7 +135,7 @@ module.exports = function (str, opts) {
135
135
  throw new TypeError('Decoder has to be a function.');
136
136
  }
137
137
 
138
- options.delimiter = typeof options.delimiter === 'string' || Utils.isRegExp(options.delimiter) ? options.delimiter : defaults.delimiter;
138
+ options.delimiter = typeof options.delimiter === 'string' || utils.isRegExp(options.delimiter) ? options.delimiter : defaults.delimiter;
139
139
  options.depth = typeof options.depth === 'number' ? options.depth : defaults.depth;
140
140
  options.arrayLimit = typeof options.arrayLimit === 'number' ? options.arrayLimit : defaults.arrayLimit;
141
141
  options.parseArrays = options.parseArrays !== false;
@@ -159,8 +159,8 @@ module.exports = function (str, opts) {
159
159
  for (var i = 0; i < keys.length; ++i) {
160
160
  var key = keys[i];
161
161
  var newObj = parseKeys(key, tempObj[key], options);
162
- obj = Utils.merge(obj, newObj, options);
162
+ obj = utils.merge(obj, newObj, options);
163
163
  }
164
164
 
165
- return Utils.compact(obj);
165
+ return utils.compact(obj);
166
166
  };