qs 6.8.1 → 6.9.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/CHANGELOG.md CHANGED
@@ -1,15 +1,17 @@
1
- ## **6.8.1**
2
- - [Fix] `parse`: Fix parsing array from object with `comma` true (#359)
3
- - [Fix] `parse`: throw a TypeError instead of an Error for bad charset (#349)
1
+ ## **6.9.1**
4
2
  - [Fix] `parse`: with comma true, handle field that holds an array of arrays (#335)
5
- - [fix] `parse`: with comma true, do not split non-string values (#334)
6
- - [meta] add tidelift marketing copy
3
+ - [Fix] `parse`: with comma true, do not split non-string values (#334)
7
4
  - [meta] add `funding` field
8
- - [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `tape`, `safe-publish-latest`, `evalmd`, `has-symbols`, `iconv-lite`, `mkdirp`, `object-inspect`
5
+ - [Dev Deps] update `eslint`, `@ljharb/eslint-config`
6
+ - [Tests] use shared travis-ci config
7
+
8
+ ## **6.9.0**
9
+ - [New] `parse`/`stringify`: Pass extra key/value argument to `decoder` (#333)
10
+ - [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `evalmd`
9
11
  - [Tests] `parse`: add passing `arrayFormat` tests
10
- - [Tests] use shared travis-ci configs
12
+ - [Tests] add `posttest` using `npx aud` to run `npm audit` without a lockfile
13
+ - [Tests] up to `node` `v12.10`, `v11.15`, `v10.16`, `v8.16`
11
14
  - [Tests] `Buffer.from` in node v5.0-v5.9 and v4.0-v4.4 requires a TypedArray
12
- - [actions] add automatic rebasing / merge commit blocking
13
15
 
14
16
  ## **6.8.0**
15
17
  - [New] add `depth=false` to preserve the original key; [Fix] `depth=0` should preserve the original key (#326)
package/README.md CHANGED
@@ -330,6 +330,30 @@ var decoded = qs.parse('x=z', { decoder: function (str) {
330
330
  }})
331
331
  ```
332
332
 
333
+ You can encode keys and values using different logic by using the type argument provided to the encoder:
334
+
335
+ ```javascript
336
+ var encoded = qs.stringify({ a: { b: 'c' } }, { encoder: function (str, defaultEncoder, charset, type) {
337
+ if (type === 'key') {
338
+ return // Encoded key
339
+ } else if (type === 'value') {
340
+ return // Encoded value
341
+ }
342
+ }})
343
+ ```
344
+
345
+ The type argument is also provided to the decoder:
346
+
347
+ ```javascript
348
+ var decoded = qs.parse('x=z', { decoder: function (str, defaultEncoder, charset, type) {
349
+ if (type === 'key') {
350
+ return // Decoded key
351
+ } else if (type === 'value') {
352
+ return // Decoded value
353
+ }
354
+ }})
355
+ ```
356
+
333
357
  Examples beyond this point will be shown as though the output is not URI encoded for clarity. Please note that the return values in these cases *will* be URI encoded during real usage.
334
358
 
335
359
  When arrays are stringified, by default they are given explicit indices:
@@ -557,12 +581,6 @@ assert.equal(qs.stringify({ a: 'b c' }, { format : 'RFC1738' }), 'a=b+c');
557
581
 
558
582
  Please email [@ljharb](https://github.com/ljharb) or see https://tidelift.com/security if you have a potential security vulnerability to report.
559
583
 
560
- ## qs for enterprise
561
-
562
- Available as part of the Tidelift Subscription
563
-
564
- The maintainers of qs and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use. [Learn more.](https://tidelift.com/subscription/pkg/npm-qs?utm_source=npm-qs&utm_medium=referral&utm_campaign=enterprise&utm_term=repo)
565
-
566
584
  [1]: https://npmjs.org/package/qs
567
585
  [2]: http://versionbadg.es/ljharb/qs.svg
568
586
  [3]: https://api.travis-ci.org/ljharb/qs.svg
package/dist/qs.js CHANGED
@@ -71,14 +71,6 @@ var interpretNumericEntities = function (str) {
71
71
  });
72
72
  };
73
73
 
74
- var parseArrayValue = function (val, options) {
75
- if (val && typeof val === 'string' && options.comma && val.indexOf(',') > -1) {
76
- return val.split(',');
77
- }
78
-
79
- return val;
80
- };
81
-
82
74
  // This is what browsers will submit when the ✓ character occurs in an
83
75
  // application/x-www-form-urlencoded body and the encoding of the page containing
84
76
  // the form is iso-8859-1, or when the submitted form has an accept-charset
@@ -123,18 +115,20 @@ var parseValues = function parseQueryStringValues(str, options) {
123
115
 
124
116
  var key, val;
125
117
  if (pos === -1) {
126
- key = options.decoder(part, defaults.decoder, charset);
118
+ key = options.decoder(part, defaults.decoder, charset, 'key');
127
119
  val = options.strictNullHandling ? null : '';
128
120
  } else {
129
- key = options.decoder(part.slice(0, pos), defaults.decoder, charset);
130
- val = options.decoder(part.slice(pos + 1), defaults.decoder, charset);
121
+ key = options.decoder(part.slice(0, pos), defaults.decoder, charset, 'key');
122
+ val = options.decoder(part.slice(pos + 1), defaults.decoder, charset, 'value');
131
123
  }
132
124
 
133
125
  if (val && options.interpretNumericEntities && charset === 'iso-8859-1') {
134
126
  val = interpretNumericEntities(val);
135
127
  }
136
128
 
137
- val = parseArrayValue(val, options);
129
+ if (val && typeof val === 'string' && options.comma && val.indexOf(',') > -1) {
130
+ val = val.split(',');
131
+ }
138
132
 
139
133
  if (part.indexOf('[]=') > -1) {
140
134
  val = isArray(val) ? [val] : val;
@@ -151,7 +145,7 @@ var parseValues = function parseQueryStringValues(str, options) {
151
145
  };
152
146
 
153
147
  var parseObject = function (chain, val, options) {
154
- var leaf = parseArrayValue(val, options);
148
+ var leaf = val;
155
149
 
156
150
  for (var i = chain.length - 1; i >= 0; --i) {
157
151
  var obj;
@@ -249,7 +243,7 @@ var normalizeParseOptions = function normalizeParseOptions(opts) {
249
243
  }
250
244
 
251
245
  if (typeof opts.charset !== 'undefined' && opts.charset !== 'utf-8' && opts.charset !== 'iso-8859-1') {
252
- throw new TypeError('The charset option must be either utf-8, iso-8859-1, or undefined');
246
+ throw new Error('The charset option must be either utf-8, iso-8859-1, or undefined');
253
247
  }
254
248
  var charset = typeof opts.charset === 'undefined' ? defaults.charset : opts.charset;
255
249
 
@@ -349,7 +343,7 @@ var isNonNullishPrimitive = function isNonNullishPrimitive(v) {
349
343
  || typeof v === 'number'
350
344
  || typeof v === 'boolean'
351
345
  || typeof v === 'symbol'
352
- || typeof v === 'bigint'; // eslint-disable-line valid-typeof
346
+ || typeof v === 'bigint';
353
347
  };
354
348
 
355
349
  var stringify = function stringify(
@@ -378,7 +372,7 @@ var stringify = function stringify(
378
372
 
379
373
  if (obj === null) {
380
374
  if (strictNullHandling) {
381
- return encoder && !encodeValuesOnly ? encoder(prefix, defaults.encoder, charset) : prefix;
375
+ return encoder && !encodeValuesOnly ? encoder(prefix, defaults.encoder, charset, 'key') : prefix;
382
376
  }
383
377
 
384
378
  obj = '';
@@ -386,8 +380,8 @@ var stringify = function stringify(
386
380
 
387
381
  if (isNonNullishPrimitive(obj) || utils.isBuffer(obj)) {
388
382
  if (encoder) {
389
- var keyValue = encodeValuesOnly ? prefix : encoder(prefix, defaults.encoder, charset);
390
- return [formatter(keyValue) + '=' + formatter(encoder(obj, defaults.encoder, charset))];
383
+ var keyValue = encodeValuesOnly ? prefix : encoder(prefix, defaults.encoder, charset, 'key');
384
+ return [formatter(keyValue) + '=' + formatter(encoder(obj, defaults.encoder, charset, 'value'))];
391
385
  }
392
386
  return [formatter(prefix) + '=' + formatter(String(obj))];
393
387
  }
@@ -622,6 +616,7 @@ var arrayToObject = function arrayToObject(source, options) {
622
616
  };
623
617
 
624
618
  var merge = function merge(target, source, options) {
619
+ /* eslint no-param-reassign: 0 */
625
620
  if (!source) {
626
621
  return target;
627
622
  }
@@ -631,7 +626,7 @@ var merge = function merge(target, source, options) {
631
626
  target.push(source);
632
627
  } else if (target && typeof target === 'object') {
633
628
  if ((options && (options.plainObjects || options.allowPrototypes)) || !has.call(Object.prototype, source)) {
634
- target[source] = true; // eslint-disable-line no-param-reassign
629
+ target[source] = true;
635
630
  }
636
631
  } else {
637
632
  return [target, source];
@@ -654,12 +649,12 @@ var merge = function merge(target, source, options) {
654
649
  if (has.call(target, i)) {
655
650
  var targetItem = target[i];
656
651
  if (targetItem && typeof targetItem === 'object' && item && typeof item === 'object') {
657
- target[i] = merge(targetItem, item, options); // eslint-disable-line no-param-reassign
652
+ target[i] = merge(targetItem, item, options);
658
653
  } else {
659
654
  target.push(item);
660
655
  }
661
656
  } else {
662
- target[i] = item; // eslint-disable-line no-param-reassign
657
+ target[i] = item;
663
658
  }
664
659
  });
665
660
  return target;
@@ -669,9 +664,9 @@ var merge = function merge(target, source, options) {
669
664
  var value = source[key];
670
665
 
671
666
  if (has.call(acc, key)) {
672
- acc[key] = merge(acc[key], value, options); // eslint-disable-line no-param-reassign
667
+ acc[key] = merge(acc[key], value, options);
673
668
  } else {
674
- acc[key] = value; // eslint-disable-line no-param-reassign
669
+ acc[key] = value;
675
670
  }
676
671
  return acc;
677
672
  }, mergeTarget);
@@ -679,7 +674,7 @@ var merge = function merge(target, source, options) {
679
674
 
680
675
  var assign = function assignSingleSource(target, source) {
681
676
  return Object.keys(source).reduce(function (acc, key) {
682
- acc[key] = source[key]; // eslint-disable-line no-param-reassign
677
+ acc[key] = source[key];
683
678
  return acc;
684
679
  }, target);
685
680
  };
package/lib/parse.js CHANGED
@@ -29,14 +29,6 @@ var interpretNumericEntities = function (str) {
29
29
  });
30
30
  };
31
31
 
32
- var parseArrayValue = function (val, options) {
33
- if (val && typeof val === 'string' && options.comma && val.indexOf(',') > -1) {
34
- return val.split(',');
35
- }
36
-
37
- return val;
38
- };
39
-
40
32
  // This is what browsers will submit when the ✓ character occurs in an
41
33
  // application/x-www-form-urlencoded body and the encoding of the page containing
42
34
  // the form is iso-8859-1, or when the submitted form has an accept-charset
@@ -81,18 +73,20 @@ var parseValues = function parseQueryStringValues(str, options) {
81
73
 
82
74
  var key, val;
83
75
  if (pos === -1) {
84
- key = options.decoder(part, defaults.decoder, charset);
76
+ key = options.decoder(part, defaults.decoder, charset, 'key');
85
77
  val = options.strictNullHandling ? null : '';
86
78
  } else {
87
- key = options.decoder(part.slice(0, pos), defaults.decoder, charset);
88
- val = options.decoder(part.slice(pos + 1), defaults.decoder, charset);
79
+ key = options.decoder(part.slice(0, pos), defaults.decoder, charset, 'key');
80
+ val = options.decoder(part.slice(pos + 1), defaults.decoder, charset, 'value');
89
81
  }
90
82
 
91
83
  if (val && options.interpretNumericEntities && charset === 'iso-8859-1') {
92
84
  val = interpretNumericEntities(val);
93
85
  }
94
86
 
95
- val = parseArrayValue(val, options);
87
+ if (val && typeof val === 'string' && options.comma && val.indexOf(',') > -1) {
88
+ val = val.split(',');
89
+ }
96
90
 
97
91
  if (part.indexOf('[]=') > -1) {
98
92
  val = isArray(val) ? [val] : val;
@@ -109,7 +103,7 @@ var parseValues = function parseQueryStringValues(str, options) {
109
103
  };
110
104
 
111
105
  var parseObject = function (chain, val, options) {
112
- var leaf = parseArrayValue(val, options);
106
+ var leaf = val;
113
107
 
114
108
  for (var i = chain.length - 1; i >= 0; --i) {
115
109
  var obj;
@@ -207,7 +201,7 @@ var normalizeParseOptions = function normalizeParseOptions(opts) {
207
201
  }
208
202
 
209
203
  if (typeof opts.charset !== 'undefined' && opts.charset !== 'utf-8' && opts.charset !== 'iso-8859-1') {
210
- throw new TypeError('The charset option must be either utf-8, iso-8859-1, or undefined');
204
+ throw new Error('The charset option must be either utf-8, iso-8859-1, or undefined');
211
205
  }
212
206
  var charset = typeof opts.charset === 'undefined' ? defaults.charset : opts.charset;
213
207
 
package/lib/stringify.js CHANGED
@@ -51,7 +51,7 @@ var isNonNullishPrimitive = function isNonNullishPrimitive(v) {
51
51
  || typeof v === 'number'
52
52
  || typeof v === 'boolean'
53
53
  || typeof v === 'symbol'
54
- || typeof v === 'bigint'; // eslint-disable-line valid-typeof
54
+ || typeof v === 'bigint';
55
55
  };
56
56
 
57
57
  var stringify = function stringify(
@@ -80,7 +80,7 @@ var stringify = function stringify(
80
80
 
81
81
  if (obj === null) {
82
82
  if (strictNullHandling) {
83
- return encoder && !encodeValuesOnly ? encoder(prefix, defaults.encoder, charset) : prefix;
83
+ return encoder && !encodeValuesOnly ? encoder(prefix, defaults.encoder, charset, 'key') : prefix;
84
84
  }
85
85
 
86
86
  obj = '';
@@ -88,8 +88,8 @@ var stringify = function stringify(
88
88
 
89
89
  if (isNonNullishPrimitive(obj) || utils.isBuffer(obj)) {
90
90
  if (encoder) {
91
- var keyValue = encodeValuesOnly ? prefix : encoder(prefix, defaults.encoder, charset);
92
- return [formatter(keyValue) + '=' + formatter(encoder(obj, defaults.encoder, charset))];
91
+ var keyValue = encodeValuesOnly ? prefix : encoder(prefix, defaults.encoder, charset, 'key');
92
+ return [formatter(keyValue) + '=' + formatter(encoder(obj, defaults.encoder, charset, 'value'))];
93
93
  }
94
94
  return [formatter(prefix) + '=' + formatter(String(obj))];
95
95
  }
package/lib/utils.js CHANGED
@@ -43,6 +43,7 @@ var arrayToObject = function arrayToObject(source, options) {
43
43
  };
44
44
 
45
45
  var merge = function merge(target, source, options) {
46
+ /* eslint no-param-reassign: 0 */
46
47
  if (!source) {
47
48
  return target;
48
49
  }
@@ -52,7 +53,7 @@ var merge = function merge(target, source, options) {
52
53
  target.push(source);
53
54
  } else if (target && typeof target === 'object') {
54
55
  if ((options && (options.plainObjects || options.allowPrototypes)) || !has.call(Object.prototype, source)) {
55
- target[source] = true; // eslint-disable-line no-param-reassign
56
+ target[source] = true;
56
57
  }
57
58
  } else {
58
59
  return [target, source];
@@ -75,12 +76,12 @@ var merge = function merge(target, source, options) {
75
76
  if (has.call(target, i)) {
76
77
  var targetItem = target[i];
77
78
  if (targetItem && typeof targetItem === 'object' && item && typeof item === 'object') {
78
- target[i] = merge(targetItem, item, options); // eslint-disable-line no-param-reassign
79
+ target[i] = merge(targetItem, item, options);
79
80
  } else {
80
81
  target.push(item);
81
82
  }
82
83
  } else {
83
- target[i] = item; // eslint-disable-line no-param-reassign
84
+ target[i] = item;
84
85
  }
85
86
  });
86
87
  return target;
@@ -90,9 +91,9 @@ var merge = function merge(target, source, options) {
90
91
  var value = source[key];
91
92
 
92
93
  if (has.call(acc, key)) {
93
- acc[key] = merge(acc[key], value, options); // eslint-disable-line no-param-reassign
94
+ acc[key] = merge(acc[key], value, options);
94
95
  } else {
95
- acc[key] = value; // eslint-disable-line no-param-reassign
96
+ acc[key] = value;
96
97
  }
97
98
  return acc;
98
99
  }, mergeTarget);
@@ -100,7 +101,7 @@ var merge = function merge(target, source, options) {
100
101
 
101
102
  var assign = function assignSingleSource(target, source) {
102
103
  return Object.keys(source).reduce(function (acc, key) {
103
- acc[key] = source[key]; // eslint-disable-line no-param-reassign
104
+ acc[key] = source[key];
104
105
  return acc;
105
106
  }, target);
106
107
  };
package/package.json CHANGED
@@ -2,14 +2,14 @@
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.8.1",
5
+ "version": "6.9.1",
6
6
  "repository": {
7
7
  "type": "git",
8
8
  "url": "https://github.com/ljharb/qs.git"
9
9
  },
10
- "funding": {
11
- "url": "https://github.com/sponsors/ljharb"
12
- },
10
+ "funding": {
11
+ "url": "https://github.com/sponsors/ljharb"
12
+ },
13
13
  "main": "lib/index.js",
14
14
  "contributors": [
15
15
  {
@@ -31,28 +31,28 @@
31
31
  },
32
32
  "dependencies": {},
33
33
  "devDependencies": {
34
- "@ljharb/eslint-config": "^16.0.0",
34
+ "@ljharb/eslint-config": "^15.0.0",
35
35
  "browserify": "^16.5.0",
36
36
  "covert": "^1.1.1",
37
37
  "eclint": "^2.8.1",
38
- "eslint": "^6.8.0",
38
+ "eslint": "^6.6.0",
39
39
  "evalmd": "^0.0.19",
40
40
  "for-each": "^0.3.3",
41
- "has-symbols": "^1.0.1",
42
- "iconv-lite": "^0.5.1",
43
- "mkdirp": "^0.5.4",
44
- "object-inspect": "^1.7.0",
41
+ "has-symbols": "^1.0.0",
42
+ "iconv-lite": "^0.4.24",
43
+ "mkdirp": "^0.5.1",
44
+ "object-inspect": "^1.6.0",
45
45
  "qs-iconv": "^1.0.4",
46
- "safe-publish-latest": "^1.1.4",
46
+ "safe-publish-latest": "^1.1.3",
47
47
  "safer-buffer": "^2.1.2",
48
- "tape": "^5.0.0-next.5"
48
+ "tape": "^4.11.0"
49
49
  },
50
50
  "scripts": {
51
51
  "prepublish": "safe-publish-latest && npm run dist",
52
52
  "pretest": "npm run --silent readme && npm run --silent lint",
53
53
  "test": "npm run --silent coverage",
54
54
  "tests-only": "node test",
55
- "posttest": "npx aud --production",
55
+ "posttest": "npx aud",
56
56
  "readme": "evalmd README.md",
57
57
  "postlint": "eclint check * lib/* test/*",
58
58
  "lint": "eslint lib/*.js test/*.js",
package/test/.eslintrc CHANGED
@@ -11,7 +11,8 @@
11
11
  "no-buffer-constructor": 0,
12
12
  "no-extend-native": 0,
13
13
  "no-magic-numbers": 0,
14
+ "no-throw-literal": 0,
14
15
  "object-curly-newline": 0,
15
- "sort-keys": 0
16
+ "sort-keys": 0,
16
17
  }
17
18
  }
package/test/parse.js CHANGED
@@ -400,12 +400,6 @@ test('parse()', function (t) {
400
400
  st.end();
401
401
  });
402
402
 
403
- t.test('parses values with comma as array divider', function (st) {
404
- st.deepEqual(qs.parse({ foo: 'bar,tee' }, { comma: false }), { foo: 'bar,tee' });
405
- st.deepEqual(qs.parse({ foo: 'bar,tee' }, { comma: true }), { foo: ['bar', 'tee'] });
406
- st.end();
407
- });
408
-
409
403
  t.test('use number decoder, parses string that has one number with comma option enabled', function (st) {
410
404
  var decoder = function (str, defaultDecoder, charset, type) {
411
405
  if (!isNaN(Number(str))) {
@@ -605,7 +599,7 @@ test('parse()', function (t) {
605
599
 
606
600
  st.deepEqual(
607
601
  qs.parse('a[b]=c&a=toString', { plainObjects: true }),
608
- { __proto__: null, a: { __proto__: null, b: 'c', toString: true } },
602
+ { a: { b: 'c', toString: true } },
609
603
  'can overwrite prototype with plainObjects true'
610
604
  );
611
605
 
@@ -745,5 +739,20 @@ test('parse()', function (t) {
745
739
  st.end();
746
740
  });
747
741
 
742
+ t.test('allows for decoding keys and values differently', function (st) {
743
+ var decoder = function (str, defaultDecoder, charset, type) {
744
+ if (type === 'key') {
745
+ return defaultDecoder(str, defaultDecoder, charset, type).toLowerCase();
746
+ }
747
+ if (type === 'value') {
748
+ return defaultDecoder(str, defaultDecoder, charset, type).toUpperCase();
749
+ }
750
+ throw 'this should never happen! type: ' + type;
751
+ };
752
+
753
+ st.deepEqual(qs.parse('KeY=vAlUe', { decoder: decoder }), { key: 'VALUE' });
754
+ st.end();
755
+ });
756
+
748
757
  t.end();
749
758
  });
package/test/stringify.js CHANGED
@@ -719,5 +719,20 @@ test('stringify()', function (t) {
719
719
  st.end();
720
720
  });
721
721
 
722
+ t.test('allows for encoding keys and values differently', function (st) {
723
+ var encoder = function (str, defaultEncoder, charset, type) {
724
+ if (type === 'key') {
725
+ return defaultEncoder(str, defaultEncoder, charset, type).toLowerCase();
726
+ }
727
+ if (type === 'value') {
728
+ return defaultEncoder(str, defaultEncoder, charset, type).toUpperCase();
729
+ }
730
+ throw 'this should never happen! type: ' + type;
731
+ };
732
+
733
+ st.deepEqual(qs.stringify({ KeY: 'vAlUe' }, { encoder: encoder }), 'key=VALUE');
734
+ st.end();
735
+ });
736
+
722
737
  t.end();
723
738
  });
@@ -1,15 +0,0 @@
1
- name: Automatic Rebase
2
-
3
- on: [pull_request]
4
-
5
- jobs:
6
- _:
7
- name: "Automatic Rebase"
8
-
9
- runs-on: ubuntu-latest
10
-
11
- steps:
12
- - uses: actions/checkout@v1
13
- - uses: ljharb/rebase@master
14
- env:
15
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}