qs 6.10.2 → 6.10.5

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/.editorconfig CHANGED
@@ -38,3 +38,6 @@ indent_size = off
38
38
  indent_style = off
39
39
  indent = off
40
40
  max_line_length = off
41
+
42
+ [.nycrc]
43
+ indent_style = tab
package/.eslintrc CHANGED
@@ -3,15 +3,19 @@
3
3
 
4
4
  "extends": "@ljharb",
5
5
 
6
+ "ignorePatterns": [
7
+ "dist/",
8
+ ],
9
+
6
10
  "rules": {
7
11
  "complexity": 0,
8
12
  "consistent-return": 1,
9
- "func-name-matching": 0,
13
+ "func-name-matching": 0,
10
14
  "id-length": [2, { "min": 1, "max": 25, "properties": "never" }],
11
15
  "indent": [2, 4],
12
16
  "max-lines-per-function": [2, { "max": 150 }],
13
17
  "max-params": [2, 15],
14
- "max-statements": [2, 52],
18
+ "max-statements": [2, 53],
15
19
  "multiline-comment-style": 0,
16
20
  "no-continue": 1,
17
21
  "no-magic-numbers": 0,
@@ -28,7 +32,7 @@
28
32
  "no-buffer-constructor": 0,
29
33
  "no-extend-native": 0,
30
34
  "no-throw-literal": 0,
31
- }
32
- }
33
- ]
35
+ },
36
+ },
37
+ ],
34
38
  }
package/CHANGELOG.md CHANGED
@@ -1,3 +1,17 @@
1
+ ## **6.10.5**
2
+ - [Fix] `stringify`: with `arrayFormat: comma`, properly include an explicit `[]` on a single-item array (#434)
3
+
4
+ ## **6.10.4**
5
+ - [Fix] `stringify`: with `arrayFormat: comma`, include an explicit `[]` on a single-item array (#441)
6
+ - [meta] use `npmignore` to autogenerate an npmignore file
7
+ - [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `aud`, `has-symbol`, `object-inspect`, `tape`
8
+
9
+ ## **6.10.3**
10
+ - [Fix] `parse`: ignore `__proto__` keys (#428)
11
+ - [Robustness] `stringify`: avoid relying on a global `undefined` (#427)
12
+ - [actions] reuse common workflows
13
+ - [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `object-inspect`, `tape`
14
+
1
15
  ## **6.10.2**
2
16
  - [Fix] `stringify`: actually fix cyclic references (#426)
3
17
  - [Fix] `stringify`: avoid encoding arrayformat comma when `encodeValuesOnly = true` (#424)
@@ -21,6 +35,18 @@
21
35
  - [Tests] use `ljharb/actions/node/install` instead of `ljharb/actions/node/run`
22
36
  - [Tests] Revert "[meta] ignore eclint transitive audit warning"
23
37
 
38
+ ## **6.9.7**
39
+ - [Fix] `parse`: ignore `__proto__` keys (#428)
40
+ - [Fix] `stringify`: avoid encoding arrayformat comma when `encodeValuesOnly = true` (#424)
41
+ - [Robustness] `stringify`: avoid relying on a global `undefined` (#427)
42
+ - [readme] remove travis badge; add github actions/codecov badges; update URLs
43
+ - [Docs] add note and links for coercing primitive values (#408)
44
+ - [Tests] clean up stringify tests slightly
45
+ - [meta] fix README.md (#399)
46
+ - Revert "[meta] ignore eclint transitive audit warning"
47
+ - [actions] backport actions from main
48
+ - [Dev Deps] backport updates from main
49
+
24
50
  ## **6.9.6**
25
51
  - [Fix] restore `dist` dir; mistakenly removed in d4f6c32
26
52
 
@@ -69,6 +95,19 @@
69
95
  - [Tests] up to `node` `v12.10`, `v11.15`, `v10.16`, `v8.16`
70
96
  - [Tests] `Buffer.from` in node v5.0-v5.9 and v4.0-v4.4 requires a TypedArray
71
97
 
98
+ ## **6.8.3**
99
+ - [Fix] `parse`: ignore `__proto__` keys (#428)
100
+ - [Robustness] `stringify`: avoid relying on a global `undefined` (#427)
101
+ - [Fix] `stringify`: avoid encoding arrayformat comma when `encodeValuesOnly = true` (#424)
102
+ - [readme] remove travis badge; add github actions/codecov badges; update URLs
103
+ - [Tests] clean up stringify tests slightly
104
+ - [Docs] add note and links for coercing primitive values (#408)
105
+ - [meta] fix README.md (#399)
106
+ - [actions] backport actions from main
107
+ - [Dev Deps] backport updates from main
108
+ - [Refactor] `stringify`: reduce branching
109
+ - [meta] do not publish workflow files
110
+
72
111
  ## **6.8.2**
73
112
  - [Fix] proper comma parsing of URL-encoded commas (#361)
74
113
  - [Fix] parses comma delimited array while having percent-encoded comma treated as normal text (#336)
@@ -100,6 +139,19 @@
100
139
  - [meta] add FUNDING.yml
101
140
  - [meta] Clean up license text so it’s properly detected as BSD-3-Clause
102
141
 
142
+ ## **6.7.3**
143
+ - [Fix] `parse`: ignore `__proto__` keys (#428)
144
+ - [Fix] `stringify`: avoid encoding arrayformat comma when `encodeValuesOnly = true` (#424)
145
+ - [Robustness] `stringify`: avoid relying on a global `undefined` (#427)
146
+ - [readme] remove travis badge; add github actions/codecov badges; update URLs
147
+ - [Docs] add note and links for coercing primitive values (#408)
148
+ - [meta] fix README.md (#399)
149
+ - [meta] do not publish workflow files
150
+ - [actions] backport actions from main
151
+ - [Dev Deps] backport updates from main
152
+ - [Tests] use `nyc` for coverage
153
+ - [Tests] clean up stringify tests slightly
154
+
103
155
  ## **6.7.2**
104
156
  - [Fix] proper comma parsing of URL-encoded commas (#361)
105
157
  - [Fix] parses comma delimited array while having percent-encoded comma treated as normal text (#336)
@@ -138,6 +190,32 @@
138
190
  - [Tests] fix Buffer tests to work in node < 4.5 and node < 5.10
139
191
  - [Tests] temporarily allow coverage to fail
140
192
 
193
+ ## **6.6.1**
194
+ - [Fix] `parse`: ignore `__proto__` keys (#428)
195
+ - [Fix] fix for an impossible situation: when the formatter is called with a non-string value
196
+ - [Fix] `utils.merge`: avoid a crash with a null target and an array source
197
+ - [Fix] `utils.merge`: avoid a crash with a null target and a truthy non-array source
198
+ - [Fix] correctly parse nested arrays
199
+ - [Robustness] `stringify`: avoid relying on a global `undefined` (#427)
200
+ - [Robustness] `stringify`: cache `Object.prototype.hasOwnProperty`
201
+ - [Refactor] `formats`: tiny bit of cleanup.
202
+ - [Refactor] `utils`: `isBuffer`: small tweak; add tests
203
+ - [Refactor]: `stringify`/`utils`: cache `Array.isArray`
204
+ - [Refactor] `utils`: reduce observable [[Get]]s
205
+ - [Refactor] use cached `Array.isArray`
206
+ - [Refactor] `parse`/`stringify`: make a function to normalize the options
207
+ - [readme] remove travis badge; add github actions/codecov badges; update URLs
208
+ - [Docs] Clarify the need for "arrayLimit" option
209
+ - [meta] fix README.md (#399)
210
+ - [meta] do not publish workflow files
211
+ - [meta] Clean up license text so it’s properly detected as BSD-3-Clause
212
+ - [meta] add FUNDING.yml
213
+ - [meta] Fixes typo in CHANGELOG.md
214
+ - [actions] backport actions from main
215
+ - [Tests] fix Buffer tests to work in node < 4.5 and node < 5.10
216
+ - [Tests] always use `String(x)` over `x.toString()`
217
+ - [Dev Deps] backport from main
218
+
141
219
  ## **6.6.0**
142
220
  - [New] Add support for iso-8859-1, utf8 "sentinel" and numeric entities (#268)
143
221
  - [New] move two-value combine to a `utils` function (#189)
@@ -154,6 +232,30 @@
154
232
  - [Dev Deps] update `browserify`, `eslint`, `@ljharb/eslint-config`, `iconv-lite`, `safe-publish-latest`, `tape`
155
233
  - [Tests] up to `node` `v10.10`, `v9.11`, `v8.12`, `v6.14`, `v4.9`; pin included builds to LTS
156
234
 
235
+ ## **6.5.3**
236
+ - [Fix] `parse`: ignore `__proto__` keys (#428)
237
+ - [Fix]` `utils.merge`: avoid a crash with a null target and a truthy non-array source
238
+ - [Fix] correctly parse nested arrays
239
+ - [Fix] `stringify`: fix a crash with `strictNullHandling` and a custom `filter`/`serializeDate` (#279)
240
+ - [Fix] `utils`: `merge`: fix crash when `source` is a truthy primitive & no options are provided
241
+ - [Fix] when `parseArrays` is false, properly handle keys ending in `[]`
242
+ - [Fix] fix for an impossible situation: when the formatter is called with a non-string value
243
+ - [Fix] `utils.merge`: avoid a crash with a null target and an array source
244
+ - [Refactor] `utils`: reduce observable [[Get]]s
245
+ - [Refactor] use cached `Array.isArray`
246
+ - [Refactor] `stringify`: Avoid arr = arr.concat(...), push to the existing instance (#269)
247
+ - [Refactor] `parse`: only need to reassign the var once
248
+ - [Robustness] `stringify`: avoid relying on a global `undefined` (#427)
249
+ - [readme] remove travis badge; add github actions/codecov badges; update URLs
250
+ - [Docs] Clean up license text so it’s properly detected as BSD-3-Clause
251
+ - [Docs] Clarify the need for "arrayLimit" option
252
+ - [meta] fix README.md (#399)
253
+ - [meta] add FUNDING.yml
254
+ - [actions] backport actions from main
255
+ - [Tests] always use `String(x)` over `x.toString()`
256
+ - [Tests] remove nonexistent tape option
257
+ - [Dev Deps] backport from main
258
+
157
259
  ## **6.5.2**
158
260
  - [Fix] use `safer-buffer` instead of `Buffer` constructor
159
261
  - [Refactor] utils: `module.exports` one thing, instead of mutating `exports` (#230)
@@ -180,6 +282,27 @@
180
282
  - [Tests] up to `node` `v8.1`, `v7.10`, `v6.11`; npm v4.6 breaks on node < v1; npm v5+ breaks on node < v4
181
283
  - [Tests] add `editorconfig-tools`
182
284
 
285
+ ## **6.4.1**
286
+ - [Fix] `parse`: ignore `__proto__` keys (#428)
287
+ - [Fix] fix for an impossible situation: when the formatter is called with a non-string value
288
+ - [Fix] use `safer-buffer` instead of `Buffer` constructor
289
+ - [Fix] `utils.merge`: avoid a crash with a null target and an array source
290
+ - [Fix]` `utils.merge`: avoid a crash with a null target and a truthy non-array source
291
+ - [Fix] `stringify`: fix a crash with `strictNullHandling` and a custom `filter`/`serializeDate` (#279)
292
+ - [Fix] `utils`: `merge`: fix crash when `source` is a truthy primitive & no options are provided
293
+ - [Fix] when `parseArrays` is false, properly handle keys ending in `[]`
294
+ - [Robustness] `stringify`: avoid relying on a global `undefined` (#427)
295
+ - [Refactor] use cached `Array.isArray`
296
+ - [Refactor] `stringify`: Avoid arr = arr.concat(...), push to the existing instance (#269)
297
+ - [readme] remove travis badge; add github actions/codecov badges; update URLs
298
+ - [Docs] Clarify the need for "arrayLimit" option
299
+ - [meta] fix README.md (#399)
300
+ - [meta] Clean up license text so it’s properly detected as BSD-3-Clause
301
+ - [meta] add FUNDING.yml
302
+ - [actions] backport actions from main
303
+ - [Tests] remove nonexistent tape option
304
+ - [Dev Deps] backport from main
305
+
183
306
  ## **6.4.0**
184
307
  - [New] `qs.stringify`: add `encodeValuesOnly` option
185
308
  - [Fix] follow `allowPrototypes` option during merge (#201, #201)
@@ -189,6 +312,26 @@
189
312
  - [Tests] up to `node` `v7.7`, `v6.10`,` v4.8`; disable osx builds since they block linux builds
190
313
  - [eslint] reduce warnings
191
314
 
315
+ ## **6.3.3**
316
+ - [Fix] `parse`: ignore `__proto__` keys (#428)
317
+ - [Fix] fix for an impossible situation: when the formatter is called with a non-string value
318
+ - [Fix] `utils.merge`: avoid a crash with a null target and an array source
319
+ - [Fix]` `utils.merge`: avoid a crash with a null target and a truthy non-array source
320
+ - [Fix] `stringify`: fix a crash with `strictNullHandling` and a custom `filter`/`serializeDate` (#279)
321
+ - [Fix] `utils`: `merge`: fix crash when `source` is a truthy primitive & no options are provided
322
+ - [Fix] when `parseArrays` is false, properly handle keys ending in `[]`
323
+ - [Robustness] `stringify`: avoid relying on a global `undefined` (#427)
324
+ - [Refactor] use cached `Array.isArray`
325
+ - [Refactor] `stringify`: Avoid arr = arr.concat(...), push to the existing instance (#269)
326
+ - [Docs] Clarify the need for "arrayLimit" option
327
+ - [meta] fix README.md (#399)
328
+ - [meta] Clean up license text so it’s properly detected as BSD-3-Clause
329
+ - [meta] add FUNDING.yml
330
+ - [actions] backport actions from main
331
+ - [Tests] use `safer-buffer` instead of `Buffer` constructor
332
+ - [Tests] remove nonexistent tape option
333
+ - [Dev Deps] backport from main
334
+
192
335
  ## **6.3.2**
193
336
  - [Fix] follow `allowPrototypes` option during merge (#201, #200)
194
337
  - [Dev Deps] update `eslint`
@@ -222,6 +365,23 @@
222
365
  - [Tests] skip Object.create tests when null objects are not available
223
366
  - [Tests] Turn on eslint for test files (#175)
224
367
 
368
+ ## **6.2.4**
369
+ - [Fix] `parse`: ignore `__proto__` keys (#428)
370
+ - [Fix] `utils.merge`: avoid a crash with a null target and an array source
371
+ - [Fix] `utils.merge`: avoid a crash with a null target and a truthy non-array source
372
+ - [Fix] `utils`: `merge`: fix crash when `source` is a truthy primitive & no options are provided
373
+ - [Fix] when `parseArrays` is false, properly handle keys ending in `[]`
374
+ - [Robustness] `stringify`: avoid relying on a global `undefined` (#427)
375
+ - [Refactor] use cached `Array.isArray`
376
+ - [Docs] Clarify the need for "arrayLimit" option
377
+ - [meta] fix README.md (#399)
378
+ - [meta] Clean up license text so it’s properly detected as BSD-3-Clause
379
+ - [meta] add FUNDING.yml
380
+ - [actions] backport actions from main
381
+ - [Tests] use `safer-buffer` instead of `Buffer` constructor
382
+ - [Tests] remove nonexistent tape option
383
+ - [Dev Deps] backport from main
384
+
225
385
  ## **6.2.3**
226
386
  - [Fix] follow `allowPrototypes` option during merge (#201, #200)
227
387
  - [Fix] chmod a-x
package/dist/qs.js CHANGED
@@ -175,7 +175,7 @@ var parseObject = function (chain, val, options, valuesParsed) {
175
175
  ) {
176
176
  obj = [];
177
177
  obj[index] = leaf;
178
- } else {
178
+ } else if (cleanRoot !== '__proto__') {
179
179
  obj[cleanRoot] = leaf;
180
180
  }
181
181
  }
@@ -384,7 +384,7 @@ var stringify = function stringify(
384
384
  var tmpSc = sideChannel;
385
385
  var step = 0;
386
386
  var findFlag = false;
387
- while ((tmpSc = tmpSc.get(sentinel)) !== undefined && !findFlag) {
387
+ while ((tmpSc = tmpSc.get(sentinel)) !== void undefined && !findFlag) {
388
388
  // Where object last appeared in the ref tree
389
389
  var pos = tmpSc.get(object);
390
390
  step += 1;
@@ -430,7 +430,7 @@ var stringify = function stringify(
430
430
  for (var i = 0; i < valuesArray.length; ++i) {
431
431
  valuesJoined += (i === 0 ? '' : ',') + formatter(encoder(valuesArray[i], defaults.encoder, charset, 'value', format));
432
432
  }
433
- return [formatter(keyValue) + '=' + valuesJoined];
433
+ return [formatter(keyValue) + (isArray(obj) && valuesArray.length === 1 ? '[]' : '') + '=' + valuesJoined];
434
434
  }
435
435
  return [formatter(keyValue) + '=' + formatter(encoder(obj, defaults.encoder, charset, 'value', format))];
436
436
  }
@@ -446,7 +446,7 @@ var stringify = function stringify(
446
446
  var objKeys;
447
447
  if (generateArrayPrefix === 'comma' && isArray(obj)) {
448
448
  // we need to join elements in
449
- objKeys = [{ value: obj.length > 0 ? obj.join(',') || null : undefined }];
449
+ objKeys = [{ value: obj.length > 0 ? obj.join(',') || null : void undefined }];
450
450
  } else if (isArray(filter)) {
451
451
  objKeys = filter;
452
452
  } else {
@@ -454,17 +454,19 @@ var stringify = function stringify(
454
454
  objKeys = sort ? keys.sort(sort) : keys;
455
455
  }
456
456
 
457
+ var adjustedPrefix = generateArrayPrefix === 'comma' && isArray(obj) && obj.length === 1 ? prefix + '[]' : prefix;
458
+
457
459
  for (var j = 0; j < objKeys.length; ++j) {
458
460
  var key = objKeys[j];
459
- var value = typeof key === 'object' && key.value !== undefined ? key.value : obj[key];
461
+ var value = typeof key === 'object' && typeof key.value !== 'undefined' ? key.value : obj[key];
460
462
 
461
463
  if (skipNulls && value === null) {
462
464
  continue;
463
465
  }
464
466
 
465
467
  var keyPrefix = isArray(obj)
466
- ? typeof generateArrayPrefix === 'function' ? generateArrayPrefix(prefix, key) : prefix
467
- : prefix + (allowDots ? '.' + key : '[' + key + ']');
468
+ ? typeof generateArrayPrefix === 'function' ? generateArrayPrefix(adjustedPrefix, key) : adjustedPrefix
469
+ : adjustedPrefix + (allowDots ? '.' + key : '[' + key + ']');
468
470
 
469
471
  sideChannel.set(object, step);
470
472
  var valueSideChannel = getSideChannel();
@@ -496,7 +498,7 @@ var normalizeStringifyOptions = function normalizeStringifyOptions(opts) {
496
498
  return defaults;
497
499
  }
498
500
 
499
- if (opts.encoder !== null && opts.encoder !== undefined && typeof opts.encoder !== 'function') {
501
+ if (opts.encoder !== null && typeof opts.encoder !== 'undefined' && typeof opts.encoder !== 'function') {
500
502
  throw new TypeError('Encoder has to be a function.');
501
503
  }
502
504
 
@@ -1419,11 +1421,24 @@ var weakRefDeref = hasWeakRef ? WeakRef.prototype.deref : null;
1419
1421
  var booleanValueOf = Boolean.prototype.valueOf;
1420
1422
  var objectToString = Object.prototype.toString;
1421
1423
  var functionToString = Function.prototype.toString;
1422
- var match = String.prototype.match;
1424
+ var $match = String.prototype.match;
1425
+ var $slice = String.prototype.slice;
1426
+ var $replace = String.prototype.replace;
1427
+ var $toUpperCase = String.prototype.toUpperCase;
1428
+ var $toLowerCase = String.prototype.toLowerCase;
1429
+ var $test = RegExp.prototype.test;
1430
+ var $concat = Array.prototype.concat;
1431
+ var $join = Array.prototype.join;
1432
+ var $arrSlice = Array.prototype.slice;
1433
+ var $floor = Math.floor;
1423
1434
  var bigIntValueOf = typeof BigInt === 'function' ? BigInt.prototype.valueOf : null;
1424
1435
  var gOPS = Object.getOwnPropertySymbols;
1425
1436
  var symToString = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ? Symbol.prototype.toString : null;
1426
1437
  var hasShammedSymbols = typeof Symbol === 'function' && typeof Symbol.iterator === 'object';
1438
+ // ie, `has-tostringtag/shams
1439
+ var toStringTag = typeof Symbol === 'function' && Symbol.toStringTag && (typeof Symbol.toStringTag === hasShammedSymbols ? 'object' : 'symbol')
1440
+ ? Symbol.toStringTag
1441
+ : null;
1427
1442
  var isEnumerable = Object.prototype.propertyIsEnumerable;
1428
1443
 
1429
1444
  var gPO = (typeof Reflect === 'function' ? Reflect.getPrototypeOf : Object.getPrototypeOf) || (
@@ -1434,9 +1449,31 @@ var gPO = (typeof Reflect === 'function' ? Reflect.getPrototypeOf : Object.getPr
1434
1449
  : null
1435
1450
  );
1436
1451
 
1437
- var inspectCustom = require('./util.inspect').custom;
1438
- var inspectSymbol = inspectCustom && isSymbol(inspectCustom) ? inspectCustom : null;
1439
- var toStringTag = typeof Symbol === 'function' && typeof Symbol.toStringTag !== 'undefined' ? Symbol.toStringTag : null;
1452
+ function addNumericSeparator(num, str) {
1453
+ if (
1454
+ num === Infinity
1455
+ || num === -Infinity
1456
+ || num !== num
1457
+ || (num && num > -1000 && num < 1000)
1458
+ || $test.call(/e/, str)
1459
+ ) {
1460
+ return str;
1461
+ }
1462
+ var sepRegex = /[0-9](?=(?:[0-9]{3})+(?![0-9]))/g;
1463
+ if (typeof num === 'number') {
1464
+ var int = num < 0 ? -$floor(-num) : $floor(num); // trunc(num)
1465
+ if (int !== num) {
1466
+ var intStr = String(int);
1467
+ var dec = $slice.call(str, intStr.length + 1);
1468
+ return $replace.call(intStr, sepRegex, '$&_') + '.' + $replace.call($replace.call(dec, /([0-9]{3})/g, '$&_'), /_$/, '');
1469
+ }
1470
+ }
1471
+ return $replace.call(str, sepRegex, '$&_');
1472
+ }
1473
+
1474
+ var utilInspect = require('./util.inspect');
1475
+ var inspectCustom = utilInspect.custom;
1476
+ var inspectSymbol = isSymbol(inspectCustom) ? inspectCustom : null;
1440
1477
 
1441
1478
  module.exports = function inspect_(obj, options, depth, seen) {
1442
1479
  var opts = options || {};
@@ -1463,8 +1500,12 @@ module.exports = function inspect_(obj, options, depth, seen) {
1463
1500
  && opts.indent !== '\t'
1464
1501
  && !(parseInt(opts.indent, 10) === opts.indent && opts.indent > 0)
1465
1502
  ) {
1466
- throw new TypeError('options "indent" must be "\\t", an integer > 0, or `null`');
1503
+ throw new TypeError('option "indent" must be "\\t", an integer > 0, or `null`');
1504
+ }
1505
+ if (has(opts, 'numericSeparator') && typeof opts.numericSeparator !== 'boolean') {
1506
+ throw new TypeError('option "numericSeparator", if provided, must be `true` or `false`');
1467
1507
  }
1508
+ var numericSeparator = opts.numericSeparator;
1468
1509
 
1469
1510
  if (typeof obj === 'undefined') {
1470
1511
  return 'undefined';
@@ -1483,10 +1524,12 @@ module.exports = function inspect_(obj, options, depth, seen) {
1483
1524
  if (obj === 0) {
1484
1525
  return Infinity / obj > 0 ? '0' : '-0';
1485
1526
  }
1486
- return String(obj);
1527
+ var str = String(obj);
1528
+ return numericSeparator ? addNumericSeparator(obj, str) : str;
1487
1529
  }
1488
1530
  if (typeof obj === 'bigint') {
1489
- return String(obj) + 'n';
1531
+ var bigIntStr = String(obj) + 'n';
1532
+ return numericSeparator ? addNumericSeparator(obj, bigIntStr) : bigIntStr;
1490
1533
  }
1491
1534
 
1492
1535
  var maxDepth = typeof opts.depth === 'undefined' ? 5 : opts.depth;
@@ -1505,7 +1548,7 @@ module.exports = function inspect_(obj, options, depth, seen) {
1505
1548
 
1506
1549
  function inspect(value, from, noIndent) {
1507
1550
  if (from) {
1508
- seen = seen.slice();
1551
+ seen = $arrSlice.call(seen);
1509
1552
  seen.push(from);
1510
1553
  }
1511
1554
  if (noIndent) {
@@ -1520,24 +1563,24 @@ module.exports = function inspect_(obj, options, depth, seen) {
1520
1563
  return inspect_(value, opts, depth + 1, seen);
1521
1564
  }
1522
1565
 
1523
- if (typeof obj === 'function') {
1566
+ if (typeof obj === 'function' && !isRegExp(obj)) { // in older engines, regexes are callable
1524
1567
  var name = nameOf(obj);
1525
1568
  var keys = arrObjKeys(obj, inspect);
1526
- return '[Function' + (name ? ': ' + name : ' (anonymous)') + ']' + (keys.length > 0 ? ' { ' + keys.join(', ') + ' }' : '');
1569
+ return '[Function' + (name ? ': ' + name : ' (anonymous)') + ']' + (keys.length > 0 ? ' { ' + $join.call(keys, ', ') + ' }' : '');
1527
1570
  }
1528
1571
  if (isSymbol(obj)) {
1529
- var symString = hasShammedSymbols ? String(obj).replace(/^(Symbol\(.*\))_[^)]*$/, '$1') : symToString.call(obj);
1572
+ var symString = hasShammedSymbols ? $replace.call(String(obj), /^(Symbol\(.*\))_[^)]*$/, '$1') : symToString.call(obj);
1530
1573
  return typeof obj === 'object' && !hasShammedSymbols ? markBoxed(symString) : symString;
1531
1574
  }
1532
1575
  if (isElement(obj)) {
1533
- var s = '<' + String(obj.nodeName).toLowerCase();
1576
+ var s = '<' + $toLowerCase.call(String(obj.nodeName));
1534
1577
  var attrs = obj.attributes || [];
1535
1578
  for (var i = 0; i < attrs.length; i++) {
1536
1579
  s += ' ' + attrs[i].name + '=' + wrapQuotes(quote(attrs[i].value), 'double', opts);
1537
1580
  }
1538
1581
  s += '>';
1539
1582
  if (obj.childNodes && obj.childNodes.length) { s += '...'; }
1540
- s += '</' + String(obj.nodeName).toLowerCase() + '>';
1583
+ s += '</' + $toLowerCase.call(String(obj.nodeName)) + '>';
1541
1584
  return s;
1542
1585
  }
1543
1586
  if (isArray(obj)) {
@@ -1546,16 +1589,19 @@ module.exports = function inspect_(obj, options, depth, seen) {
1546
1589
  if (indent && !singleLineValues(xs)) {
1547
1590
  return '[' + indentedJoin(xs, indent) + ']';
1548
1591
  }
1549
- return '[ ' + xs.join(', ') + ' ]';
1592
+ return '[ ' + $join.call(xs, ', ') + ' ]';
1550
1593
  }
1551
1594
  if (isError(obj)) {
1552
1595
  var parts = arrObjKeys(obj, inspect);
1596
+ if (!('cause' in Error.prototype) && 'cause' in obj && !isEnumerable.call(obj, 'cause')) {
1597
+ return '{ [' + String(obj) + '] ' + $join.call($concat.call('[cause]: ' + inspect(obj.cause), parts), ', ') + ' }';
1598
+ }
1553
1599
  if (parts.length === 0) { return '[' + String(obj) + ']'; }
1554
- return '{ [' + String(obj) + '] ' + parts.join(', ') + ' }';
1600
+ return '{ [' + String(obj) + '] ' + $join.call(parts, ', ') + ' }';
1555
1601
  }
1556
1602
  if (typeof obj === 'object' && customInspect) {
1557
- if (inspectSymbol && typeof obj[inspectSymbol] === 'function') {
1558
- return obj[inspectSymbol]();
1603
+ if (inspectSymbol && typeof obj[inspectSymbol] === 'function' && utilInspect) {
1604
+ return utilInspect(obj, { depth: maxDepth - depth });
1559
1605
  } else if (customInspect !== 'symbol' && typeof obj.inspect === 'function') {
1560
1606
  return obj.inspect();
1561
1607
  }
@@ -1599,14 +1645,14 @@ module.exports = function inspect_(obj, options, depth, seen) {
1599
1645
  var ys = arrObjKeys(obj, inspect);
1600
1646
  var isPlainObject = gPO ? gPO(obj) === Object.prototype : obj instanceof Object || obj.constructor === Object;
1601
1647
  var protoTag = obj instanceof Object ? '' : 'null prototype';
1602
- var stringTag = !isPlainObject && toStringTag && Object(obj) === obj && toStringTag in obj ? toStr(obj).slice(8, -1) : protoTag ? 'Object' : '';
1648
+ var stringTag = !isPlainObject && toStringTag && Object(obj) === obj && toStringTag in obj ? $slice.call(toStr(obj), 8, -1) : protoTag ? 'Object' : '';
1603
1649
  var constructorTag = isPlainObject || typeof obj.constructor !== 'function' ? '' : obj.constructor.name ? obj.constructor.name + ' ' : '';
1604
- var tag = constructorTag + (stringTag || protoTag ? '[' + [].concat(stringTag || [], protoTag || []).join(': ') + '] ' : '');
1650
+ var tag = constructorTag + (stringTag || protoTag ? '[' + $join.call($concat.call([], stringTag || [], protoTag || []), ': ') + '] ' : '');
1605
1651
  if (ys.length === 0) { return tag + '{}'; }
1606
1652
  if (indent) {
1607
1653
  return tag + '{' + indentedJoin(ys, indent) + '}';
1608
1654
  }
1609
- return tag + '{ ' + ys.join(', ') + ' }';
1655
+ return tag + '{ ' + $join.call(ys, ', ') + ' }';
1610
1656
  }
1611
1657
  return String(obj);
1612
1658
  };
@@ -1617,7 +1663,7 @@ function wrapQuotes(s, defaultStyle, opts) {
1617
1663
  }
1618
1664
 
1619
1665
  function quote(s) {
1620
- return String(s).replace(/"/g, '&quot;');
1666
+ return $replace.call(String(s), /"/g, '&quot;');
1621
1667
  }
1622
1668
 
1623
1669
  function isArray(obj) { return toStr(obj) === '[object Array]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }
@@ -1668,7 +1714,7 @@ function toStr(obj) {
1668
1714
 
1669
1715
  function nameOf(f) {
1670
1716
  if (f.name) { return f.name; }
1671
- var m = match.call(functionToString.call(f), /^function\s*([\w$]+)/);
1717
+ var m = $match.call(functionToString.call(f), /^function\s*([\w$]+)/);
1672
1718
  if (m) { return m[1]; }
1673
1719
  return null;
1674
1720
  }
@@ -1768,10 +1814,10 @@ function inspectString(str, opts) {
1768
1814
  if (str.length > opts.maxStringLength) {
1769
1815
  var remaining = str.length - opts.maxStringLength;
1770
1816
  var trailer = '... ' + remaining + ' more character' + (remaining > 1 ? 's' : '');
1771
- return inspectString(str.slice(0, opts.maxStringLength), opts) + trailer;
1817
+ return inspectString($slice.call(str, 0, opts.maxStringLength), opts) + trailer;
1772
1818
  }
1773
1819
  // eslint-disable-next-line no-control-regex
1774
- var s = str.replace(/(['\\])/g, '\\$1').replace(/[\x00-\x1f]/g, lowbyte);
1820
+ var s = $replace.call($replace.call(str, /(['\\])/g, '\\$1'), /[\x00-\x1f]/g, lowbyte);
1775
1821
  return wrapQuotes(s, 'single', opts);
1776
1822
  }
1777
1823
 
@@ -1785,7 +1831,7 @@ function lowbyte(c) {
1785
1831
  13: 'r'
1786
1832
  }[n];
1787
1833
  if (x) { return '\\' + x; }
1788
- return '\\x' + (n < 0x10 ? '0' : '') + n.toString(16).toUpperCase();
1834
+ return '\\x' + (n < 0x10 ? '0' : '') + $toUpperCase.call(n.toString(16));
1789
1835
  }
1790
1836
 
1791
1837
  function markBoxed(str) {
@@ -1797,7 +1843,7 @@ function weakCollectionOf(type) {
1797
1843
  }
1798
1844
 
1799
1845
  function collectionOf(type, size, entries, indent) {
1800
- var joinedEntries = indent ? indentedJoin(entries, indent) : entries.join(', ');
1846
+ var joinedEntries = indent ? indentedJoin(entries, indent) : $join.call(entries, ', ');
1801
1847
  return type + ' (' + size + ') {' + joinedEntries + '}';
1802
1848
  }
1803
1849
 
@@ -1815,20 +1861,20 @@ function getIndent(opts, depth) {
1815
1861
  if (opts.indent === '\t') {
1816
1862
  baseIndent = '\t';
1817
1863
  } else if (typeof opts.indent === 'number' && opts.indent > 0) {
1818
- baseIndent = Array(opts.indent + 1).join(' ');
1864
+ baseIndent = $join.call(Array(opts.indent + 1), ' ');
1819
1865
  } else {
1820
1866
  return null;
1821
1867
  }
1822
1868
  return {
1823
1869
  base: baseIndent,
1824
- prev: Array(depth + 1).join(baseIndent)
1870
+ prev: $join.call(Array(depth + 1), baseIndent)
1825
1871
  };
1826
1872
  }
1827
1873
 
1828
1874
  function indentedJoin(xs, indent) {
1829
1875
  if (xs.length === 0) { return ''; }
1830
1876
  var lineJoiner = '\n' + indent.prev + indent.base;
1831
- return lineJoiner + xs.join(',' + lineJoiner) + '\n' + indent.prev;
1877
+ return lineJoiner + $join.call(xs, ',' + lineJoiner) + '\n' + indent.prev;
1832
1878
  }
1833
1879
 
1834
1880
  function arrObjKeys(obj, inspect) {
@@ -1855,7 +1901,7 @@ function arrObjKeys(obj, inspect) {
1855
1901
  if (hasShammedSymbols && symMap['$' + key] instanceof Symbol) {
1856
1902
  // this is to prevent shammed Symbols, which are stored as strings, from being included in the string key section
1857
1903
  continue; // eslint-disable-line no-restricted-syntax, no-continue
1858
- } else if ((/[^\w$]/).test(key)) {
1904
+ } else if ($test.call(/[^\w$]/, key)) {
1859
1905
  xs.push(inspect(key, obj) + ': ' + inspect(obj[key], obj));
1860
1906
  } else {
1861
1907
  xs.push(key + ': ' + inspect(obj[key], obj));
package/lib/parse.js CHANGED
@@ -136,7 +136,7 @@ var parseObject = function (chain, val, options, valuesParsed) {
136
136
  ) {
137
137
  obj = [];
138
138
  obj[index] = leaf;
139
- } else {
139
+ } else if (cleanRoot !== '__proto__') {
140
140
  obj[cleanRoot] = leaf;
141
141
  }
142
142
  }
package/lib/stringify.js CHANGED
@@ -80,7 +80,7 @@ var stringify = function stringify(
80
80
  var tmpSc = sideChannel;
81
81
  var step = 0;
82
82
  var findFlag = false;
83
- while ((tmpSc = tmpSc.get(sentinel)) !== undefined && !findFlag) {
83
+ while ((tmpSc = tmpSc.get(sentinel)) !== void undefined && !findFlag) {
84
84
  // Where object last appeared in the ref tree
85
85
  var pos = tmpSc.get(object);
86
86
  step += 1;
@@ -126,7 +126,7 @@ var stringify = function stringify(
126
126
  for (var i = 0; i < valuesArray.length; ++i) {
127
127
  valuesJoined += (i === 0 ? '' : ',') + formatter(encoder(valuesArray[i], defaults.encoder, charset, 'value', format));
128
128
  }
129
- return [formatter(keyValue) + '=' + valuesJoined];
129
+ return [formatter(keyValue) + (isArray(obj) && valuesArray.length === 1 ? '[]' : '') + '=' + valuesJoined];
130
130
  }
131
131
  return [formatter(keyValue) + '=' + formatter(encoder(obj, defaults.encoder, charset, 'value', format))];
132
132
  }
@@ -142,7 +142,7 @@ var stringify = function stringify(
142
142
  var objKeys;
143
143
  if (generateArrayPrefix === 'comma' && isArray(obj)) {
144
144
  // we need to join elements in
145
- objKeys = [{ value: obj.length > 0 ? obj.join(',') || null : undefined }];
145
+ objKeys = [{ value: obj.length > 0 ? obj.join(',') || null : void undefined }];
146
146
  } else if (isArray(filter)) {
147
147
  objKeys = filter;
148
148
  } else {
@@ -150,17 +150,19 @@ var stringify = function stringify(
150
150
  objKeys = sort ? keys.sort(sort) : keys;
151
151
  }
152
152
 
153
+ var adjustedPrefix = generateArrayPrefix === 'comma' && isArray(obj) && obj.length === 1 ? prefix + '[]' : prefix;
154
+
153
155
  for (var j = 0; j < objKeys.length; ++j) {
154
156
  var key = objKeys[j];
155
- var value = typeof key === 'object' && key.value !== undefined ? key.value : obj[key];
157
+ var value = typeof key === 'object' && typeof key.value !== 'undefined' ? key.value : obj[key];
156
158
 
157
159
  if (skipNulls && value === null) {
158
160
  continue;
159
161
  }
160
162
 
161
163
  var keyPrefix = isArray(obj)
162
- ? typeof generateArrayPrefix === 'function' ? generateArrayPrefix(prefix, key) : prefix
163
- : prefix + (allowDots ? '.' + key : '[' + key + ']');
164
+ ? typeof generateArrayPrefix === 'function' ? generateArrayPrefix(adjustedPrefix, key) : adjustedPrefix
165
+ : adjustedPrefix + (allowDots ? '.' + key : '[' + key + ']');
164
166
 
165
167
  sideChannel.set(object, step);
166
168
  var valueSideChannel = getSideChannel();
@@ -192,7 +194,7 @@ var normalizeStringifyOptions = function normalizeStringifyOptions(opts) {
192
194
  return defaults;
193
195
  }
194
196
 
195
- if (opts.encoder !== null && opts.encoder !== undefined && typeof opts.encoder !== 'function') {
197
+ if (opts.encoder !== null && typeof opts.encoder !== 'undefined' && typeof opts.encoder !== 'function') {
196
198
  throw new TypeError('Encoder has to be a function.');
197
199
  }
198
200
 
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "qs",
3
3
  "description": "A querystring parser that supports nesting and arrays, with a depth limit",
4
4
  "homepage": "https://github.com/ljharb/qs",
5
- "version": "6.10.2",
5
+ "version": "6.10.5",
6
6
  "repository": {
7
7
  "type": "git",
8
8
  "url": "https://github.com/ljharb/qs.git"
@@ -33,25 +33,27 @@
33
33
  "side-channel": "^1.0.4"
34
34
  },
35
35
  "devDependencies": {
36
- "@ljharb/eslint-config": "^20.0.0",
37
- "aud": "^1.1.5",
36
+ "@ljharb/eslint-config": "^21.0.0",
37
+ "aud": "^2.0.0",
38
38
  "browserify": "^16.5.2",
39
39
  "eclint": "^2.8.1",
40
- "eslint": "^8.4.0",
40
+ "eslint": "=8.8.0",
41
41
  "evalmd": "^0.0.19",
42
42
  "for-each": "^0.3.3",
43
- "has-symbols": "^1.0.2",
43
+ "has-symbols": "^1.0.3",
44
44
  "iconv-lite": "^0.5.1",
45
45
  "in-publish": "^2.0.1",
46
46
  "mkdirp": "^0.5.5",
47
+ "npmignore": "^0.3.0",
47
48
  "nyc": "^10.3.2",
48
- "object-inspect": "^1.11.0",
49
+ "object-inspect": "^1.12.2",
49
50
  "qs-iconv": "^1.0.4",
50
51
  "safe-publish-latest": "^2.0.0",
51
52
  "safer-buffer": "^2.1.2",
52
- "tape": "^5.3.2"
53
+ "tape": "^5.5.3"
53
54
  },
54
55
  "scripts": {
56
+ "prepack": "npmignore --auto --commentLines=autogenerated",
55
57
  "prepublishOnly": "safe-publish-latest && npm run dist",
56
58
  "prepublish": "not-in-publish || npm run prepublishOnly",
57
59
  "pretest": "npm run --silent readme && npm run --silent lint",
@@ -59,15 +61,17 @@
59
61
  "tests-only": "nyc tape 'test/**/*.js'",
60
62
  "posttest": "aud --production",
61
63
  "readme": "evalmd README.md",
62
- "postlint": "eclint check * lib/* test/* !dist/*",
63
- "lint": "eslint .",
64
+ "postlint": "eclint check $(git ls-files | xargs find 2> /dev/null | grep -vE 'node_modules|\\.git' | grep -v dist/)",
65
+ "lint": "eslint --ext=js,mjs .",
64
66
  "dist": "mkdirp dist && browserify --standalone Qs lib/index.js > dist/qs.js"
65
67
  },
66
68
  "license": "BSD-3-Clause",
67
- "greenkeeper": {
69
+ "publishConfig": {
68
70
  "ignore": [
69
- "iconv-lite",
70
- "mkdirp"
71
+ "!dist/*",
72
+ "bower.json",
73
+ "component.json",
74
+ ".github/workflows"
71
75
  ]
72
76
  }
73
77
  }
package/test/parse.js CHANGED
@@ -140,6 +140,9 @@ test('parse()', function (t) {
140
140
  t.test('limits specific array indices to arrayLimit', function (st) {
141
141
  st.deepEqual(qs.parse('a[20]=a', { arrayLimit: 20 }), { a: ['a'] });
142
142
  st.deepEqual(qs.parse('a[21]=a', { arrayLimit: 20 }), { a: { 21: 'a' } });
143
+
144
+ st.deepEqual(qs.parse('a[20]=a'), { a: ['a'] });
145
+ st.deepEqual(qs.parse('a[21]=a'), { a: { 21: 'a' } });
143
146
  st.end();
144
147
  });
145
148
 
@@ -378,6 +381,7 @@ test('parse()', function (t) {
378
381
  st.deepEqual(qs.parse('?foo=bar', { ignoreQueryPrefix: true }), { foo: 'bar' });
379
382
  st.deepEqual(qs.parse('foo=bar', { ignoreQueryPrefix: true }), { foo: 'bar' });
380
383
  st.deepEqual(qs.parse('?foo=bar', { ignoreQueryPrefix: false }), { '?foo': 'bar' });
384
+
381
385
  st.end();
382
386
  });
383
387
 
@@ -406,6 +410,16 @@ test('parse()', function (t) {
406
410
  st.deepEqual(qs.parse('foo=', { comma: true }), { foo: '' });
407
411
  st.deepEqual(qs.parse('foo', { comma: true }), { foo: '' });
408
412
  st.deepEqual(qs.parse('foo', { comma: true, strictNullHandling: true }), { foo: null });
413
+
414
+ // test cases inversed from from stringify tests
415
+ st.deepEqual(qs.parse('a[0]=c'), { a: ['c'] });
416
+ st.deepEqual(qs.parse('a[]=c'), { a: ['c'] });
417
+ st.deepEqual(qs.parse('a[]=c', { comma: true }), { a: ['c'] });
418
+
419
+ st.deepEqual(qs.parse('a[0]=c&a[1]=d'), { a: ['c', 'd'] });
420
+ st.deepEqual(qs.parse('a[]=c&a[]=d'), { a: ['c', 'd'] });
421
+ st.deepEqual(qs.parse('a=c,d', { comma: true }), { a: ['c', 'd'] });
422
+
409
423
  st.end();
410
424
  });
411
425
 
@@ -629,6 +643,66 @@ test('parse()', function (t) {
629
643
  st.end();
630
644
  });
631
645
 
646
+ t.test('dunder proto is ignored', function (st) {
647
+ var payload = 'categories[__proto__]=login&categories[__proto__]&categories[length]=42';
648
+ var result = qs.parse(payload, { allowPrototypes: true });
649
+
650
+ st.deepEqual(
651
+ result,
652
+ {
653
+ categories: {
654
+ length: '42'
655
+ }
656
+ },
657
+ 'silent [[Prototype]] payload'
658
+ );
659
+
660
+ var plainResult = qs.parse(payload, { allowPrototypes: true, plainObjects: true });
661
+
662
+ st.deepEqual(
663
+ plainResult,
664
+ {
665
+ __proto__: null,
666
+ categories: {
667
+ __proto__: null,
668
+ length: '42'
669
+ }
670
+ },
671
+ 'silent [[Prototype]] payload: plain objects'
672
+ );
673
+
674
+ var query = qs.parse('categories[__proto__]=cats&categories[__proto__]=dogs&categories[some][json]=toInject', { allowPrototypes: true });
675
+
676
+ st.notOk(Array.isArray(query.categories), 'is not an array');
677
+ st.notOk(query.categories instanceof Array, 'is not instanceof an array');
678
+ st.deepEqual(query.categories, { some: { json: 'toInject' } });
679
+ st.equal(JSON.stringify(query.categories), '{"some":{"json":"toInject"}}', 'stringifies as a non-array');
680
+
681
+ st.deepEqual(
682
+ qs.parse('foo[__proto__][hidden]=value&foo[bar]=stuffs', { allowPrototypes: true }),
683
+ {
684
+ foo: {
685
+ bar: 'stuffs'
686
+ }
687
+ },
688
+ 'hidden values'
689
+ );
690
+
691
+ st.deepEqual(
692
+ qs.parse('foo[__proto__][hidden]=value&foo[bar]=stuffs', { allowPrototypes: true, plainObjects: true }),
693
+ {
694
+ __proto__: null,
695
+ foo: {
696
+ __proto__: null,
697
+ bar: 'stuffs'
698
+ }
699
+ },
700
+ 'hidden values: plain objects'
701
+ );
702
+
703
+ st.end();
704
+ });
705
+
632
706
  t.test('can return null objects', { skip: !Object.create }, function (st) {
633
707
  var expected = Object.create(null);
634
708
  expected.a = Object.create(null);
package/test/stringify.js CHANGED
@@ -131,6 +131,37 @@ test('stringify()', function (t) {
131
131
  st.end();
132
132
  });
133
133
 
134
+ t.test('stringifies an array value with one item vs multiple items', function (st) {
135
+ st.test('non-array item', function (s2t) {
136
+ s2t.equal(qs.stringify({ a: 'c' }, { encodeValuesOnly: true, arrayFormat: 'indices' }), 'a=c');
137
+ s2t.equal(qs.stringify({ a: 'c' }, { encodeValuesOnly: true, arrayFormat: 'brackets' }), 'a=c');
138
+ s2t.equal(qs.stringify({ a: 'c' }, { encodeValuesOnly: true, arrayFormat: 'comma' }), 'a=c');
139
+ s2t.equal(qs.stringify({ a: 'c' }, { encodeValuesOnly: true }), 'a=c');
140
+
141
+ s2t.end();
142
+ });
143
+
144
+ st.test('array with a single item', function (s2t) {
145
+ s2t.equal(qs.stringify({ a: ['c'] }, { encodeValuesOnly: true, arrayFormat: 'indices' }), 'a[0]=c');
146
+ s2t.equal(qs.stringify({ a: ['c'] }, { encodeValuesOnly: true, arrayFormat: 'brackets' }), 'a[]=c');
147
+ s2t.equal(qs.stringify({ a: ['c'] }, { encodeValuesOnly: true, arrayFormat: 'comma' }), 'a[]=c'); // so it parses back as an array
148
+ s2t.equal(qs.stringify({ a: ['c'] }, { encodeValuesOnly: true }), 'a[0]=c');
149
+
150
+ s2t.end();
151
+ });
152
+
153
+ st.test('array with multiple items', function (s2t) {
154
+ s2t.equal(qs.stringify({ a: ['c', 'd'] }, { encodeValuesOnly: true, arrayFormat: 'indices' }), 'a[0]=c&a[1]=d');
155
+ s2t.equal(qs.stringify({ a: ['c', 'd'] }, { encodeValuesOnly: true, arrayFormat: 'brackets' }), 'a[]=c&a[]=d');
156
+ s2t.equal(qs.stringify({ a: ['c', 'd'] }, { encodeValuesOnly: true, arrayFormat: 'comma' }), 'a=c,d');
157
+ s2t.equal(qs.stringify({ a: ['c', 'd'] }, { encodeValuesOnly: true }), 'a[0]=c&a[1]=d');
158
+
159
+ s2t.end();
160
+ });
161
+
162
+ st.end();
163
+ });
164
+
134
165
  t.test('stringifies a nested array value', function (st) {
135
166
  st.equal(qs.stringify({ a: { b: ['c', 'd'] } }, { encodeValuesOnly: true, arrayFormat: 'indices' }), 'a[b][0]=c&a[b][1]=d');
136
167
  st.equal(qs.stringify({ a: { b: ['c', 'd'] } }, { encodeValuesOnly: true, arrayFormat: 'brackets' }), 'a[b][]=c&a[b][]=d');
@@ -348,12 +379,12 @@ test('stringify()', function (t) {
348
379
  st.equal(qs.stringify({ a: [], b: [null], c: 'c' }, { encode: false, arrayFormat: 'indices' }), 'b[0]=&c=c');
349
380
  st.equal(qs.stringify({ a: [], b: [null], c: 'c' }, { encode: false, arrayFormat: 'brackets' }), 'b[]=&c=c');
350
381
  st.equal(qs.stringify({ a: [], b: [null], c: 'c' }, { encode: false, arrayFormat: 'repeat' }), 'b=&c=c');
351
- st.equal(qs.stringify({ a: [], b: [null], c: 'c' }, { encode: false, arrayFormat: 'comma' }), 'b=&c=c');
382
+ st.equal(qs.stringify({ a: [], b: [null], c: 'c' }, { encode: false, arrayFormat: 'comma' }), 'b[]=&c=c');
352
383
  // with strictNullHandling
353
384
  st.equal(qs.stringify({ a: [], b: [null], c: 'c' }, { encode: false, arrayFormat: 'indices', strictNullHandling: true }), 'b[0]&c=c');
354
385
  st.equal(qs.stringify({ a: [], b: [null], c: 'c' }, { encode: false, arrayFormat: 'brackets', strictNullHandling: true }), 'b[]&c=c');
355
386
  st.equal(qs.stringify({ a: [], b: [null], c: 'c' }, { encode: false, arrayFormat: 'repeat', strictNullHandling: true }), 'b&c=c');
356
- st.equal(qs.stringify({ a: [], b: [null], c: 'c' }, { encode: false, arrayFormat: 'comma', strictNullHandling: true }), 'b&c=c');
387
+ st.equal(qs.stringify({ a: [], b: [null], c: 'c' }, { encode: false, arrayFormat: 'comma', strictNullHandling: true }), 'b[]&c=c');
357
388
  // with skipNulls
358
389
  st.equal(qs.stringify({ a: [], b: [null], c: 'c' }, { encode: false, arrayFormat: 'indices', skipNulls: true }), 'c=c');
359
390
  st.equal(qs.stringify({ a: [], b: [null], c: 'c' }, { encode: false, arrayFormat: 'brackets', skipNulls: true }), 'c=c');
@@ -681,7 +712,7 @@ test('stringify()', function (t) {
681
712
  arrayFormat: 'comma'
682
713
  }
683
714
  ),
684
- 'a=' + date.getTime(),
715
+ 'a%5B%5D=' + date.getTime(),
685
716
  'works with arrayFormat comma'
686
717
  );
687
718
 
@@ -714,16 +745,14 @@ test('stringify()', function (t) {
714
745
  });
715
746
 
716
747
  t.test('Edge cases and unknown formats', function (st) {
717
- ['UFO1234', false, 1234, null, {}, []].forEach(
718
- function (format) {
719
- st['throws'](
720
- function () {
721
- qs.stringify({ a: 'b c' }, { format: format });
722
- },
723
- new TypeError('Unknown format option provided.')
724
- );
725
- }
726
- );
748
+ ['UFO1234', false, 1234, null, {}, []].forEach(function (format) {
749
+ st['throws'](
750
+ function () {
751
+ qs.stringify({ a: 'b c' }, { format: format });
752
+ },
753
+ new TypeError('Unknown format option provided.')
754
+ );
755
+ });
727
756
  st.end();
728
757
  });
729
758
 
package/.eslintignore DELETED
@@ -1,2 +0,0 @@
1
- dist/
2
- coverage/