qs 6.6.0 → 6.6.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/dist/qs.js CHANGED
@@ -4,21 +4,29 @@
4
4
  var replace = String.prototype.replace;
5
5
  var percentTwenties = /%20/g;
6
6
 
7
- module.exports = {
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
- },
7
+ var util = require('./utils');
8
+
9
+ var Format = {
17
10
  RFC1738: 'RFC1738',
18
11
  RFC3986: 'RFC3986'
19
12
  };
20
13
 
21
- },{}],2:[function(require,module,exports){
14
+ module.exports = util.assign(
15
+ {
16
+ 'default': Format.RFC3986,
17
+ formatters: {
18
+ RFC1738: function (value) {
19
+ return replace.call(value, percentTwenties, '+');
20
+ },
21
+ RFC3986: function (value) {
22
+ return String(value);
23
+ }
24
+ }
25
+ },
26
+ Format
27
+ );
28
+
29
+ },{"./utils":5}],2:[function(require,module,exports){
22
30
  'use strict';
23
31
 
24
32
  var stringify = require('./stringify');
@@ -74,7 +82,7 @@ var charsetSentinel = 'utf8=%E2%9C%93'; // encodeURIComponent('✓')
74
82
  var parseValues = function parseQueryStringValues(str, options) {
75
83
  var obj = {};
76
84
  var cleanStr = options.ignoreQueryPrefix ? str.replace(/^\?/, '') : str;
77
- var limit = options.parameterLimit === Infinity ? undefined : options.parameterLimit;
85
+ var limit = options.parameterLimit === Infinity ? void undefined : options.parameterLimit;
78
86
  var parts = cleanStr.split(options.delimiter, limit);
79
87
  var skipIndex = -1; // Keep track of where the utf8 sentinel was found
80
88
  var i;
@@ -149,7 +157,7 @@ var parseObject = function (chain, val, options) {
149
157
  ) {
150
158
  obj = [];
151
159
  obj[index] = leaf;
152
- } else {
160
+ } else if (cleanRoot !== '__proto__') {
153
161
  obj[cleanRoot] = leaf;
154
162
  }
155
163
  }
@@ -189,7 +197,7 @@ var parseKeys = function parseQueryStringKeys(givenKey, val, options) {
189
197
  }
190
198
  }
191
199
 
192
- keys.push(parent);
200
+ keys[keys.length] = parent;
193
201
  }
194
202
 
195
203
  // Loop through children appending to the array until we hit depth
@@ -202,43 +210,52 @@ var parseKeys = function parseQueryStringKeys(givenKey, val, options) {
202
210
  return;
203
211
  }
204
212
  }
205
- keys.push(segment[1]);
213
+ keys[keys.length] = segment[1];
206
214
  }
207
215
 
208
216
  // If there's a remainder, just add whatever is left
209
217
 
210
218
  if (segment) {
211
- keys.push('[' + key.slice(segment.index) + ']');
219
+ keys[keys.length] = '[' + key.slice(segment.index + ']');
212
220
  }
213
221
 
214
222
  return parseObject(keys, val, options);
215
223
  };
216
224
 
217
- module.exports = function (str, opts) {
218
- var options = opts ? utils.assign({}, opts) : {};
225
+ var normalizeParseOptions = function normalizeParseOptions(opts) {
226
+ if (!opts) {
227
+ return defaults;
228
+ }
219
229
 
220
- if (options.decoder !== null && options.decoder !== undefined && typeof options.decoder !== 'function') {
230
+ if (opts.decoder !== null && opts.decoder !== undefined && typeof opts.decoder !== 'function') {
221
231
  throw new TypeError('Decoder has to be a function.');
222
232
  }
223
233
 
224
- options.ignoreQueryPrefix = options.ignoreQueryPrefix === true;
225
- options.delimiter = typeof options.delimiter === 'string' || utils.isRegExp(options.delimiter) ? options.delimiter : defaults.delimiter;
226
- options.depth = typeof options.depth === 'number' ? options.depth : defaults.depth;
227
- options.arrayLimit = typeof options.arrayLimit === 'number' ? options.arrayLimit : defaults.arrayLimit;
228
- options.parseArrays = options.parseArrays !== false;
229
- options.decoder = typeof options.decoder === 'function' ? options.decoder : defaults.decoder;
230
- options.allowDots = typeof options.allowDots === 'undefined' ? defaults.allowDots : !!options.allowDots;
231
- options.plainObjects = typeof options.plainObjects === 'boolean' ? options.plainObjects : defaults.plainObjects;
232
- options.allowPrototypes = typeof options.allowPrototypes === 'boolean' ? options.allowPrototypes : defaults.allowPrototypes;
233
- options.parameterLimit = typeof options.parameterLimit === 'number' ? options.parameterLimit : defaults.parameterLimit;
234
- options.strictNullHandling = typeof options.strictNullHandling === 'boolean' ? options.strictNullHandling : defaults.strictNullHandling;
235
-
236
- if (typeof options.charset !== 'undefined' && options.charset !== 'utf-8' && options.charset !== 'iso-8859-1') {
234
+ if (typeof opts.charset !== 'undefined' && opts.charset !== 'utf-8' && opts.charset !== 'iso-8859-1') {
237
235
  throw new Error('The charset option must be either utf-8, iso-8859-1, or undefined');
238
236
  }
239
- if (typeof options.charset === 'undefined') {
240
- options.charset = defaults.charset;
241
- }
237
+ var charset = typeof opts.charset === 'undefined' ? defaults.charset : opts.charset;
238
+
239
+ return {
240
+ allowDots: typeof opts.allowDots === 'undefined' ? defaults.allowDots : !!opts.allowDots,
241
+ allowPrototypes: typeof opts.allowPrototypes === 'boolean' ? opts.allowPrototypes : defaults.allowPrototypes,
242
+ arrayLimit: typeof opts.arrayLimit === 'number' ? opts.arrayLimit : defaults.arrayLimit,
243
+ charset: charset,
244
+ charsetSentinel: typeof opts.charsetSentinel === 'boolean' ? opts.charsetSentinel : defaults.charsetSentinel,
245
+ decoder: typeof opts.decoder === 'function' ? opts.decoder : defaults.decoder,
246
+ delimiter: typeof opts.delimiter === 'string' || utils.isRegExp(opts.delimiter) ? opts.delimiter : defaults.delimiter,
247
+ depth: typeof opts.depth === 'number' ? opts.depth : defaults.depth,
248
+ ignoreQueryPrefix: opts.ignoreQueryPrefix === true,
249
+ interpretNumericEntities: typeof opts.interpretNumericEntities === 'boolean' ? opts.interpretNumericEntities : defaults.interpretNumericEntities,
250
+ parameterLimit: typeof opts.parameterLimit === 'number' ? opts.parameterLimit : defaults.parameterLimit,
251
+ parseArrays: opts.parseArrays !== false,
252
+ plainObjects: typeof opts.plainObjects === 'boolean' ? opts.plainObjects : defaults.plainObjects,
253
+ strictNullHandling: typeof opts.strictNullHandling === 'boolean' ? opts.strictNullHandling : defaults.strictNullHandling
254
+ };
255
+ };
256
+
257
+ module.exports = function (str, opts) {
258
+ var options = normalizeParseOptions(opts);
242
259
 
243
260
  if (str === '' || str === null || typeof str === 'undefined') {
244
261
  return options.plainObjects ? Object.create(null) : {};
@@ -264,15 +281,16 @@ module.exports = function (str, opts) {
264
281
 
265
282
  var utils = require('./utils');
266
283
  var formats = require('./formats');
284
+ var has = Object.prototype.hasOwnProperty;
267
285
 
268
286
  var arrayPrefixGenerators = {
269
- brackets: function brackets(prefix) { // eslint-disable-line func-name-matching
287
+ brackets: function brackets(prefix) {
270
288
  return prefix + '[]';
271
289
  },
272
- indices: function indices(prefix, key) { // eslint-disable-line func-name-matching
290
+ indices: function indices(prefix, key) {
273
291
  return prefix + '[' + key + ']';
274
292
  },
275
- repeat: function repeat(prefix) { // eslint-disable-line func-name-matching
293
+ repeat: function repeat(prefix) {
276
294
  return prefix;
277
295
  }
278
296
  };
@@ -285,6 +303,7 @@ var pushToArray = function (arr, valueOrArray) {
285
303
 
286
304
  var toISO = Date.prototype.toISOString;
287
305
 
306
+ var defaultFormat = formats['default'];
288
307
  var defaults = {
289
308
  addQueryPrefix: false,
290
309
  allowDots: false,
@@ -294,16 +313,18 @@ var defaults = {
294
313
  encode: true,
295
314
  encoder: utils.encode,
296
315
  encodeValuesOnly: false,
316
+ format: defaultFormat,
317
+ formatter: formats.formatters[defaultFormat],
297
318
  // deprecated
298
319
  indices: false,
299
- serializeDate: function serializeDate(date) { // eslint-disable-line func-name-matching
320
+ serializeDate: function serializeDate(date) {
300
321
  return toISO.call(date);
301
322
  },
302
323
  skipNulls: false,
303
324
  strictNullHandling: false
304
325
  };
305
326
 
306
- var stringify = function stringify( // eslint-disable-line func-name-matching
327
+ var stringify = function stringify(
307
328
  object,
308
329
  prefix,
309
330
  generateArrayPrefix,
@@ -348,7 +369,7 @@ var stringify = function stringify( // eslint-disable-line func-name-matching
348
369
  }
349
370
 
350
371
  var objKeys;
351
- if (Array.isArray(filter)) {
372
+ if (isArray(filter)) {
352
373
  objKeys = filter;
353
374
  } else {
354
375
  var keys = Object.keys(obj);
@@ -362,7 +383,7 @@ var stringify = function stringify( // eslint-disable-line func-name-matching
362
383
  continue;
363
384
  }
364
385
 
365
- if (Array.isArray(obj)) {
386
+ if (isArray(obj)) {
366
387
  pushToArray(values, stringify(
367
388
  obj[key],
368
389
  generateArrayPrefix(prefix, key),
@@ -400,41 +421,63 @@ var stringify = function stringify( // eslint-disable-line func-name-matching
400
421
  return values;
401
422
  };
402
423
 
403
- module.exports = function (object, opts) {
404
- var obj = object;
405
- var options = opts ? utils.assign({}, opts) : {};
424
+ var normalizeStringifyOptions = function normalizeStringifyOptions(opts) {
425
+ if (!opts) {
426
+ return defaults;
427
+ }
406
428
 
407
- if (options.encoder !== null && options.encoder !== undefined && typeof options.encoder !== 'function') {
429
+ if (opts.encoder !== null && typeof opts.encoder !== 'undefined' && typeof opts.encoder !== 'function') {
408
430
  throw new TypeError('Encoder has to be a function.');
409
431
  }
410
432
 
411
- var delimiter = typeof options.delimiter === 'undefined' ? defaults.delimiter : options.delimiter;
412
- var strictNullHandling = typeof options.strictNullHandling === 'boolean' ? options.strictNullHandling : defaults.strictNullHandling;
413
- var skipNulls = typeof options.skipNulls === 'boolean' ? options.skipNulls : defaults.skipNulls;
414
- var encode = typeof options.encode === 'boolean' ? options.encode : defaults.encode;
415
- var encoder = typeof options.encoder === 'function' ? options.encoder : defaults.encoder;
416
- var sort = typeof options.sort === 'function' ? options.sort : null;
417
- var allowDots = typeof options.allowDots === 'undefined' ? defaults.allowDots : !!options.allowDots;
418
- var serializeDate = typeof options.serializeDate === 'function' ? options.serializeDate : defaults.serializeDate;
419
- var encodeValuesOnly = typeof options.encodeValuesOnly === 'boolean' ? options.encodeValuesOnly : defaults.encodeValuesOnly;
420
- var charset = options.charset || defaults.charset;
421
- if (typeof options.charset !== 'undefined' && options.charset !== 'utf-8' && options.charset !== 'iso-8859-1') {
422
- throw new Error('The charset option must be either utf-8, iso-8859-1, or undefined');
433
+ var charset = opts.charset || defaults.charset;
434
+ if (typeof opts.charset !== 'undefined' && opts.charset !== 'utf-8' && opts.charset !== 'iso-8859-1') {
435
+ throw new TypeError('The charset option must be either utf-8, iso-8859-1, or undefined');
423
436
  }
424
437
 
425
- if (typeof options.format === 'undefined') {
426
- options.format = formats['default'];
427
- } else if (!Object.prototype.hasOwnProperty.call(formats.formatters, options.format)) {
428
- throw new TypeError('Unknown format option provided.');
429
- }
430
- var formatter = formats.formatters[options.format];
438
+ var format = formats['default'];
439
+ if (typeof opts.format !== 'undefined') {
440
+ if (!has.call(formats.formatters, opts.format)) {
441
+ throw new TypeError('Unknown format option provided.');
442
+ }
443
+ format = opts.format;
444
+ }
445
+ var formatter = formats.formatters[format];
446
+
447
+ var filter = defaults.filter;
448
+ if (typeof opts.filter === 'function' || isArray(opts.filter)) {
449
+ filter = opts.filter;
450
+ }
451
+
452
+ return {
453
+ addQueryPrefix: typeof opts.addQueryPrefix === 'boolean' ? opts.addQueryPrefix : defaults.addQueryPrefix,
454
+ allowDots: typeof opts.allowDots === 'undefined' ? defaults.allowDots : !!opts.allowDots,
455
+ charset: charset,
456
+ charsetSentinel: typeof opts.charsetSentinel === 'boolean' ? opts.charsetSentinel : defaults.charsetSentinel,
457
+ delimiter: typeof opts.delimiter === 'undefined' ? defaults.delimiter : opts.delimiter,
458
+ encode: typeof opts.encode === 'boolean' ? opts.encode : defaults.encode,
459
+ encoder: typeof opts.encoder === 'function' ? opts.encoder : defaults.encoder,
460
+ encodeValuesOnly: typeof opts.encodeValuesOnly === 'boolean' ? opts.encodeValuesOnly : defaults.encodeValuesOnly,
461
+ filter: filter,
462
+ formatter: formatter,
463
+ serializeDate: typeof opts.serializeDate === 'function' ? opts.serializeDate : defaults.serializeDate,
464
+ skipNulls: typeof opts.skipNulls === 'boolean' ? opts.skipNulls : defaults.skipNulls,
465
+ sort: typeof opts.sort === 'function' ? opts.sort : null,
466
+ strictNullHandling: typeof opts.strictNullHandling === 'boolean' ? opts.strictNullHandling : defaults.strictNullHandling
467
+ };
468
+ };
469
+
470
+ module.exports = function (object, opts) {
471
+ var obj = object;
472
+ var options = normalizeStringifyOptions(opts);
473
+
431
474
  var objKeys;
432
475
  var filter;
433
476
 
434
477
  if (typeof options.filter === 'function') {
435
478
  filter = options.filter;
436
479
  obj = filter('', obj);
437
- } else if (Array.isArray(options.filter)) {
480
+ } else if (isArray(options.filter)) {
438
481
  filter = options.filter;
439
482
  objKeys = filter;
440
483
  }
@@ -446,10 +489,10 @@ module.exports = function (object, opts) {
446
489
  }
447
490
 
448
491
  var arrayFormat;
449
- if (options.arrayFormat in arrayPrefixGenerators) {
450
- arrayFormat = options.arrayFormat;
451
- } else if ('indices' in options) {
452
- arrayFormat = options.indices ? 'indices' : 'repeat';
492
+ if (opts && opts.arrayFormat in arrayPrefixGenerators) {
493
+ arrayFormat = opts.arrayFormat;
494
+ } else if (opts && 'indices' in opts) {
495
+ arrayFormat = opts.indices ? 'indices' : 'repeat';
453
496
  } else {
454
497
  arrayFormat = 'indices';
455
498
  }
@@ -460,38 +503,38 @@ module.exports = function (object, opts) {
460
503
  objKeys = Object.keys(obj);
461
504
  }
462
505
 
463
- if (sort) {
464
- objKeys.sort(sort);
506
+ if (options.sort) {
507
+ objKeys.sort(options.sort);
465
508
  }
466
509
 
467
510
  for (var i = 0; i < objKeys.length; ++i) {
468
511
  var key = objKeys[i];
469
512
 
470
- if (skipNulls && obj[key] === null) {
513
+ if (options.skipNulls && obj[key] === null) {
471
514
  continue;
472
515
  }
473
516
  pushToArray(keys, stringify(
474
517
  obj[key],
475
518
  key,
476
519
  generateArrayPrefix,
477
- strictNullHandling,
478
- skipNulls,
479
- encode ? encoder : null,
480
- filter,
481
- sort,
482
- allowDots,
483
- serializeDate,
484
- formatter,
485
- encodeValuesOnly,
486
- charset
520
+ options.strictNullHandling,
521
+ options.skipNulls,
522
+ options.encode ? options.encoder : null,
523
+ options.filter,
524
+ options.sort,
525
+ options.allowDots,
526
+ options.serializeDate,
527
+ options.formatter,
528
+ options.encodeValuesOnly,
529
+ options.charset
487
530
  ));
488
531
  }
489
532
 
490
- var joined = keys.join(delimiter);
533
+ var joined = keys.join(options.delimiter);
491
534
  var prefix = options.addQueryPrefix === true ? '?' : '';
492
535
 
493
536
  if (options.charsetSentinel) {
494
- if (charset === 'iso-8859-1') {
537
+ if (options.charset === 'iso-8859-1') {
495
538
  // encodeURIComponent('&#10003;'), the "numeric entity" representation of a checkmark
496
539
  prefix += 'utf8=%26%2310003%3B&';
497
540
  } else {
@@ -507,11 +550,12 @@ module.exports = function (object, opts) {
507
550
  'use strict';
508
551
 
509
552
  var has = Object.prototype.hasOwnProperty;
553
+ var isArray = Array.isArray;
510
554
 
511
555
  var hexTable = (function () {
512
556
  var array = [];
513
557
  for (var i = 0; i < 256; ++i) {
514
- array.push('%' + ((i < 16 ? '0' : '') + i.toString(16)).toUpperCase());
558
+ array[array.length] = '%' + ((i < 16 ? '0' : '' + i.toString(16)).toUpperCase());
515
559
  }
516
560
 
517
561
  return array;
@@ -522,12 +566,12 @@ var compactQueue = function compactQueue(queue) {
522
566
  var item = queue.pop();
523
567
  var obj = item.obj[item.prop];
524
568
 
525
- if (Array.isArray(obj)) {
569
+ if (isArray(obj)) {
526
570
  var compacted = [];
527
571
 
528
572
  for (var j = 0; j < obj.length; ++j) {
529
573
  if (typeof obj[j] !== 'undefined') {
530
- compacted.push(obj[j]);
574
+ compacted[compacted.length] = obj[j];
531
575
  }
532
576
  }
533
577
 
@@ -553,9 +597,9 @@ var merge = function merge(target, source, options) {
553
597
  }
554
598
 
555
599
  if (typeof source !== 'object') {
556
- if (Array.isArray(target)) {
557
- target.push(source);
558
- } else if (typeof target === 'object') {
600
+ if (isArray(target)) {
601
+ target[target.length] = source;
602
+ } else if (target && typeof target === 'object') {
559
603
  if ((options && (options.plainObjects || options.allowPrototypes)) || !has.call(Object.prototype, source)) {
560
604
  target[source] = true;
561
605
  }
@@ -566,22 +610,23 @@ var merge = function merge(target, source, options) {
566
610
  return target;
567
611
  }
568
612
 
569
- if (typeof target !== 'object') {
613
+ if (!target || typeof target !== 'object') {
570
614
  return [target].concat(source);
571
615
  }
572
616
 
573
617
  var mergeTarget = target;
574
- if (Array.isArray(target) && !Array.isArray(source)) {
618
+ if (isArray(target) && !isArray(source)) {
575
619
  mergeTarget = arrayToObject(target, options);
576
620
  }
577
621
 
578
- if (Array.isArray(target) && Array.isArray(source)) {
622
+ if (isArray(target) && isArray(source)) {
579
623
  source.forEach(function (item, i) {
580
624
  if (has.call(target, i)) {
581
- if (target[i] && typeof target[i] === 'object') {
582
- target[i] = merge(target[i], item, options);
625
+ var targetItem = target[i];
626
+ if (targetItem && typeof targetItem === 'object' && item && typeof item === 'object') {
627
+ target[i] = merge(targetItem, item, options);
583
628
  } else {
584
- target.push(item);
629
+ target[target.length] = item;
585
630
  }
586
631
  } else {
587
632
  target[i] = item;
@@ -694,8 +739,8 @@ var compact = function compact(value) {
694
739
  var key = keys[j];
695
740
  var val = obj[key];
696
741
  if (typeof val === 'object' && val !== null && refs.indexOf(val) === -1) {
697
- queue.push({ obj: obj, prop: key });
698
- refs.push(val);
742
+ queue[queue.length] = { obj: obj, prop: key };
743
+ refs[refs.length] = val;
699
744
  }
700
745
  }
701
746
  }
@@ -710,7 +755,7 @@ var isRegExp = function isRegExp(obj) {
710
755
  };
711
756
 
712
757
  var isBuffer = function isBuffer(obj) {
713
- if (obj === null || typeof obj === 'undefined') {
758
+ if (!obj || typeof obj !== 'object') {
714
759
  return false;
715
760
  }
716
761
 
package/lib/formats.js CHANGED
@@ -3,16 +3,24 @@
3
3
  var replace = String.prototype.replace;
4
4
  var percentTwenties = /%20/g;
5
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
- },
6
+ var util = require('./utils');
7
+
8
+ var Format = {
16
9
  RFC1738: 'RFC1738',
17
10
  RFC3986: 'RFC3986'
18
11
  };
12
+
13
+ module.exports = util.assign(
14
+ {
15
+ 'default': Format.RFC3986,
16
+ formatters: {
17
+ RFC1738: function (value) {
18
+ return replace.call(value, percentTwenties, '+');
19
+ },
20
+ RFC3986: function (value) {
21
+ return String(value);
22
+ }
23
+ }
24
+ },
25
+ Format
26
+ );
package/lib/parse.js CHANGED
@@ -40,7 +40,7 @@ var charsetSentinel = 'utf8=%E2%9C%93'; // encodeURIComponent('✓')
40
40
  var parseValues = function parseQueryStringValues(str, options) {
41
41
  var obj = {};
42
42
  var cleanStr = options.ignoreQueryPrefix ? str.replace(/^\?/, '') : str;
43
- var limit = options.parameterLimit === Infinity ? undefined : options.parameterLimit;
43
+ var limit = options.parameterLimit === Infinity ? void undefined : options.parameterLimit;
44
44
  var parts = cleanStr.split(options.delimiter, limit);
45
45
  var skipIndex = -1; // Keep track of where the utf8 sentinel was found
46
46
  var i;
@@ -115,7 +115,7 @@ var parseObject = function (chain, val, options) {
115
115
  ) {
116
116
  obj = [];
117
117
  obj[index] = leaf;
118
- } else {
118
+ } else if (cleanRoot !== '__proto__') {
119
119
  obj[cleanRoot] = leaf;
120
120
  }
121
121
  }
@@ -155,7 +155,7 @@ var parseKeys = function parseQueryStringKeys(givenKey, val, options) {
155
155
  }
156
156
  }
157
157
 
158
- keys.push(parent);
158
+ keys[keys.length] = parent;
159
159
  }
160
160
 
161
161
  // Loop through children appending to the array until we hit depth
@@ -168,43 +168,52 @@ var parseKeys = function parseQueryStringKeys(givenKey, val, options) {
168
168
  return;
169
169
  }
170
170
  }
171
- keys.push(segment[1]);
171
+ keys[keys.length] = segment[1];
172
172
  }
173
173
 
174
174
  // If there's a remainder, just add whatever is left
175
175
 
176
176
  if (segment) {
177
- keys.push('[' + key.slice(segment.index) + ']');
177
+ keys[keys.length] = '[' + key.slice(segment.index + ']');
178
178
  }
179
179
 
180
180
  return parseObject(keys, val, options);
181
181
  };
182
182
 
183
- module.exports = function (str, opts) {
184
- var options = opts ? utils.assign({}, opts) : {};
183
+ var normalizeParseOptions = function normalizeParseOptions(opts) {
184
+ if (!opts) {
185
+ return defaults;
186
+ }
185
187
 
186
- if (options.decoder !== null && options.decoder !== undefined && typeof options.decoder !== 'function') {
188
+ if (opts.decoder !== null && opts.decoder !== undefined && typeof opts.decoder !== 'function') {
187
189
  throw new TypeError('Decoder has to be a function.');
188
190
  }
189
191
 
190
- options.ignoreQueryPrefix = options.ignoreQueryPrefix === true;
191
- options.delimiter = typeof options.delimiter === 'string' || utils.isRegExp(options.delimiter) ? options.delimiter : defaults.delimiter;
192
- options.depth = typeof options.depth === 'number' ? options.depth : defaults.depth;
193
- options.arrayLimit = typeof options.arrayLimit === 'number' ? options.arrayLimit : defaults.arrayLimit;
194
- options.parseArrays = options.parseArrays !== false;
195
- options.decoder = typeof options.decoder === 'function' ? options.decoder : defaults.decoder;
196
- options.allowDots = typeof options.allowDots === 'undefined' ? defaults.allowDots : !!options.allowDots;
197
- options.plainObjects = typeof options.plainObjects === 'boolean' ? options.plainObjects : defaults.plainObjects;
198
- options.allowPrototypes = typeof options.allowPrototypes === 'boolean' ? options.allowPrototypes : defaults.allowPrototypes;
199
- options.parameterLimit = typeof options.parameterLimit === 'number' ? options.parameterLimit : defaults.parameterLimit;
200
- options.strictNullHandling = typeof options.strictNullHandling === 'boolean' ? options.strictNullHandling : defaults.strictNullHandling;
201
-
202
- if (typeof options.charset !== 'undefined' && options.charset !== 'utf-8' && options.charset !== 'iso-8859-1') {
192
+ if (typeof opts.charset !== 'undefined' && opts.charset !== 'utf-8' && opts.charset !== 'iso-8859-1') {
203
193
  throw new Error('The charset option must be either utf-8, iso-8859-1, or undefined');
204
194
  }
205
- if (typeof options.charset === 'undefined') {
206
- options.charset = defaults.charset;
207
- }
195
+ var charset = typeof opts.charset === 'undefined' ? defaults.charset : opts.charset;
196
+
197
+ return {
198
+ allowDots: typeof opts.allowDots === 'undefined' ? defaults.allowDots : !!opts.allowDots,
199
+ allowPrototypes: typeof opts.allowPrototypes === 'boolean' ? opts.allowPrototypes : defaults.allowPrototypes,
200
+ arrayLimit: typeof opts.arrayLimit === 'number' ? opts.arrayLimit : defaults.arrayLimit,
201
+ charset: charset,
202
+ charsetSentinel: typeof opts.charsetSentinel === 'boolean' ? opts.charsetSentinel : defaults.charsetSentinel,
203
+ decoder: typeof opts.decoder === 'function' ? opts.decoder : defaults.decoder,
204
+ delimiter: typeof opts.delimiter === 'string' || utils.isRegExp(opts.delimiter) ? opts.delimiter : defaults.delimiter,
205
+ depth: typeof opts.depth === 'number' ? opts.depth : defaults.depth,
206
+ ignoreQueryPrefix: opts.ignoreQueryPrefix === true,
207
+ interpretNumericEntities: typeof opts.interpretNumericEntities === 'boolean' ? opts.interpretNumericEntities : defaults.interpretNumericEntities,
208
+ parameterLimit: typeof opts.parameterLimit === 'number' ? opts.parameterLimit : defaults.parameterLimit,
209
+ parseArrays: opts.parseArrays !== false,
210
+ plainObjects: typeof opts.plainObjects === 'boolean' ? opts.plainObjects : defaults.plainObjects,
211
+ strictNullHandling: typeof opts.strictNullHandling === 'boolean' ? opts.strictNullHandling : defaults.strictNullHandling
212
+ };
213
+ };
214
+
215
+ module.exports = function (str, opts) {
216
+ var options = normalizeParseOptions(opts);
208
217
 
209
218
  if (str === '' || str === null || typeof str === 'undefined') {
210
219
  return options.plainObjects ? Object.create(null) : {};