qs 6.7.0 → 6.8.0

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
@@ -12,6 +12,9 @@ max_line_length = 160
12
12
  [test/*]
13
13
  max_line_length = off
14
14
 
15
+ [LICENSE.md]
16
+ indent_size = off
17
+
15
18
  [*.md]
16
19
  max_line_length = off
17
20
 
@@ -0,0 +1,12 @@
1
+ # These are supported funding model platforms
2
+
3
+ github: [ljharb]
4
+ patreon: # Replace with a single Patreon username
5
+ open_collective: # Replace with a single Open Collective username
6
+ ko_fi: # Replace with a single Ko-fi username
7
+ tidelift: npm/qs
8
+ community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9
+ liberapay: # Replace with a single Liberapay username
10
+ issuehunt: # Replace with a single IssueHunt username
11
+ otechie: # Replace with a single Otechie username
12
+ custom: # Replace with a single custom sponsorship URL
package/CHANGELOG.md CHANGED
@@ -1,3 +1,17 @@
1
+ ## **6.8.0**
2
+ - [New] add `depth=false` to preserve the original key; [Fix] `depth=0` should preserve the original key (#326)
3
+ - [New] [Fix] stringify symbols and bigints
4
+ - [Fix] ensure node 0.12 can stringify Symbols
5
+ - [Fix] fix for an impossible situation: when the formatter is called with a non-string value
6
+ - [Refactor] `formats`: tiny bit of cleanup.
7
+ - [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `browserify`, `safe-publish-latest`, `iconv-lite`, `tape`
8
+ - [Tests] add tests for `depth=0` and `depth=false` behavior, both current and intuitive/intended (#326)
9
+ - [Tests] use `eclint` instead of `editorconfig-tools`
10
+ - [docs] readme: add security note
11
+ - [meta] add github sponsorship
12
+ - [meta] add FUNDING.yml
13
+ - [meta] Clean up license text so it’s properly detected as BSD-3-Clause
14
+
1
15
  ## **6.7.0**
2
16
  - [New] `stringify`/`parse`: add `comma` as an `arrayFormat` option (#276, #219)
3
17
  - [Fix] correctly parse nested arrays (#212)
package/LICENSE.md ADDED
@@ -0,0 +1,29 @@
1
+ BSD 3-Clause License
2
+
3
+ Copyright (c) 2014, Nathan LaFreniere and other [contributors](https://github.com/ljharb/qs/graphs/contributors)
4
+ All rights reserved.
5
+
6
+ Redistribution and use in source and binary forms, with or without
7
+ modification, are permitted provided that the following conditions are met:
8
+
9
+ 1. Redistributions of source code must retain the above copyright notice, this
10
+ list of conditions and the following disclaimer.
11
+
12
+ 2. Redistributions in binary form must reproduce the above copyright notice,
13
+ this list of conditions and the following disclaimer in the documentation
14
+ and/or other materials provided with the distribution.
15
+
16
+ 3. Neither the name of the copyright holder nor the names of its
17
+ contributors may be used to endorse or promote products derived from
18
+ this software without specific prior written permission.
19
+
20
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package/README.md CHANGED
@@ -553,6 +553,10 @@ assert.equal(qs.stringify({ a: 'b c' }, { format : 'RFC3986' }), 'a=b%20c');
553
553
  assert.equal(qs.stringify({ a: 'b c' }, { format : 'RFC1738' }), 'a=b+c');
554
554
  ```
555
555
 
556
+ ## Security
557
+
558
+ Please email [@ljharb](https://github.com/ljharb) or see https://tidelift.com/security if you have a potential security vulnerability to report.
559
+
556
560
  [1]: https://npmjs.org/package/qs
557
561
  [2]: http://versionbadg.es/ljharb/qs.svg
558
562
  [3]: https://api.travis-ci.org/ljharb/qs.svg
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');
@@ -181,7 +189,7 @@ var parseKeys = function parseQueryStringKeys(givenKey, val, options) {
181
189
 
182
190
  // Get the parent
183
191
 
184
- var segment = brackets.exec(key);
192
+ var segment = options.depth > 0 && brackets.exec(key);
185
193
  var parent = segment ? key.slice(0, segment.index) : key;
186
194
 
187
195
  // Stash the parent if it exists
@@ -201,7 +209,7 @@ var parseKeys = function parseQueryStringKeys(givenKey, val, options) {
201
209
  // Loop through children appending to the array until we hit depth
202
210
 
203
211
  var i = 0;
204
- while ((segment = child.exec(key)) !== null && i < options.depth) {
212
+ while (options.depth > 0 && (segment = child.exec(key)) !== null && i < options.depth) {
205
213
  i += 1;
206
214
  if (!options.plainObjects && has.call(Object.prototype, segment[1].slice(1, -1))) {
207
215
  if (!options.allowPrototypes) {
@@ -243,7 +251,8 @@ var normalizeParseOptions = function normalizeParseOptions(opts) {
243
251
  comma: typeof opts.comma === 'boolean' ? opts.comma : defaults.comma,
244
252
  decoder: typeof opts.decoder === 'function' ? opts.decoder : defaults.decoder,
245
253
  delimiter: typeof opts.delimiter === 'string' || utils.isRegExp(opts.delimiter) ? opts.delimiter : defaults.delimiter,
246
- depth: typeof opts.depth === 'number' ? opts.depth : defaults.depth,
254
+ // eslint-disable-next-line no-implicit-coercion, no-extra-parens
255
+ depth: (typeof opts.depth === 'number' || opts.depth === false) ? +opts.depth : defaults.depth,
247
256
  ignoreQueryPrefix: opts.ignoreQueryPrefix === true,
248
257
  interpretNumericEntities: typeof opts.interpretNumericEntities === 'boolean' ? opts.interpretNumericEntities : defaults.interpretNumericEntities,
249
258
  parameterLimit: typeof opts.parameterLimit === 'number' ? opts.parameterLimit : defaults.parameterLimit,
@@ -303,6 +312,7 @@ var pushToArray = function (arr, valueOrArray) {
303
312
 
304
313
  var toISO = Date.prototype.toISOString;
305
314
 
315
+ var defaultFormat = formats['default'];
306
316
  var defaults = {
307
317
  addQueryPrefix: false,
308
318
  allowDots: false,
@@ -312,7 +322,8 @@ var defaults = {
312
322
  encode: true,
313
323
  encoder: utils.encode,
314
324
  encodeValuesOnly: false,
315
- formatter: formats.formatters[formats['default']],
325
+ format: defaultFormat,
326
+ formatter: formats.formatters[defaultFormat],
316
327
  // deprecated
317
328
  indices: false,
318
329
  serializeDate: function serializeDate(date) { // eslint-disable-line func-name-matching
@@ -322,6 +333,14 @@ var defaults = {
322
333
  strictNullHandling: false
323
334
  };
324
335
 
336
+ var isNonNullishPrimitive = function isNonNullishPrimitive(v) { // eslint-disable-line func-name-matching
337
+ return typeof v === 'string'
338
+ || typeof v === 'number'
339
+ || typeof v === 'boolean'
340
+ || typeof v === 'symbol'
341
+ || typeof v === 'bigint'; // eslint-disable-line valid-typeof
342
+ };
343
+
325
344
  var stringify = function stringify( // eslint-disable-line func-name-matching
326
345
  object,
327
346
  prefix,
@@ -354,7 +373,7 @@ var stringify = function stringify( // eslint-disable-line func-name-matching
354
373
  obj = '';
355
374
  }
356
375
 
357
- if (typeof obj === 'string' || typeof obj === 'number' || typeof obj === 'boolean' || utils.isBuffer(obj)) {
376
+ if (isNonNullishPrimitive(obj) || utils.isBuffer(obj)) {
358
377
  if (encoder) {
359
378
  var keyValue = encodeValuesOnly ? prefix : encoder(prefix, defaults.encoder, charset);
360
379
  return [formatter(keyValue) + '=' + formatter(encoder(obj, defaults.encoder, charset))];
@@ -675,7 +694,12 @@ var encode = function encode(str, defaultEncoder, charset) {
675
694
  return str;
676
695
  }
677
696
 
678
- var string = typeof str === 'string' ? str : String(str);
697
+ var string = str;
698
+ if (typeof str === 'symbol') {
699
+ string = Symbol.prototype.toString.call(str);
700
+ } else if (typeof str !== 'string') {
701
+ string = String(str);
702
+ }
679
703
 
680
704
  if (charset === 'iso-8859-1') {
681
705
  return escape(string).replace(/%u[0-9a-f]{4}/gi, function ($0) {
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
@@ -147,7 +147,7 @@ var parseKeys = function parseQueryStringKeys(givenKey, val, options) {
147
147
 
148
148
  // Get the parent
149
149
 
150
- var segment = brackets.exec(key);
150
+ var segment = options.depth > 0 && brackets.exec(key);
151
151
  var parent = segment ? key.slice(0, segment.index) : key;
152
152
 
153
153
  // Stash the parent if it exists
@@ -167,7 +167,7 @@ var parseKeys = function parseQueryStringKeys(givenKey, val, options) {
167
167
  // Loop through children appending to the array until we hit depth
168
168
 
169
169
  var i = 0;
170
- while ((segment = child.exec(key)) !== null && i < options.depth) {
170
+ while (options.depth > 0 && (segment = child.exec(key)) !== null && i < options.depth) {
171
171
  i += 1;
172
172
  if (!options.plainObjects && has.call(Object.prototype, segment[1].slice(1, -1))) {
173
173
  if (!options.allowPrototypes) {
@@ -209,7 +209,8 @@ var normalizeParseOptions = function normalizeParseOptions(opts) {
209
209
  comma: typeof opts.comma === 'boolean' ? opts.comma : defaults.comma,
210
210
  decoder: typeof opts.decoder === 'function' ? opts.decoder : defaults.decoder,
211
211
  delimiter: typeof opts.delimiter === 'string' || utils.isRegExp(opts.delimiter) ? opts.delimiter : defaults.delimiter,
212
- depth: typeof opts.depth === 'number' ? opts.depth : defaults.depth,
212
+ // eslint-disable-next-line no-implicit-coercion, no-extra-parens
213
+ depth: (typeof opts.depth === 'number' || opts.depth === false) ? +opts.depth : defaults.depth,
213
214
  ignoreQueryPrefix: opts.ignoreQueryPrefix === true,
214
215
  interpretNumericEntities: typeof opts.interpretNumericEntities === 'boolean' ? opts.interpretNumericEntities : defaults.interpretNumericEntities,
215
216
  parameterLimit: typeof opts.parameterLimit === 'number' ? opts.parameterLimit : defaults.parameterLimit,
package/lib/stringify.js CHANGED
@@ -25,6 +25,7 @@ var pushToArray = function (arr, valueOrArray) {
25
25
 
26
26
  var toISO = Date.prototype.toISOString;
27
27
 
28
+ var defaultFormat = formats['default'];
28
29
  var defaults = {
29
30
  addQueryPrefix: false,
30
31
  allowDots: false,
@@ -34,7 +35,8 @@ var defaults = {
34
35
  encode: true,
35
36
  encoder: utils.encode,
36
37
  encodeValuesOnly: false,
37
- formatter: formats.formatters[formats['default']],
38
+ format: defaultFormat,
39
+ formatter: formats.formatters[defaultFormat],
38
40
  // deprecated
39
41
  indices: false,
40
42
  serializeDate: function serializeDate(date) { // eslint-disable-line func-name-matching
@@ -44,6 +46,14 @@ var defaults = {
44
46
  strictNullHandling: false
45
47
  };
46
48
 
49
+ var isNonNullishPrimitive = function isNonNullishPrimitive(v) { // eslint-disable-line func-name-matching
50
+ return typeof v === 'string'
51
+ || typeof v === 'number'
52
+ || typeof v === 'boolean'
53
+ || typeof v === 'symbol'
54
+ || typeof v === 'bigint'; // eslint-disable-line valid-typeof
55
+ };
56
+
47
57
  var stringify = function stringify( // eslint-disable-line func-name-matching
48
58
  object,
49
59
  prefix,
@@ -76,7 +86,7 @@ var stringify = function stringify( // eslint-disable-line func-name-matching
76
86
  obj = '';
77
87
  }
78
88
 
79
- if (typeof obj === 'string' || typeof obj === 'number' || typeof obj === 'boolean' || utils.isBuffer(obj)) {
89
+ if (isNonNullishPrimitive(obj) || utils.isBuffer(obj)) {
80
90
  if (encoder) {
81
91
  var keyValue = encodeValuesOnly ? prefix : encoder(prefix, defaults.encoder, charset);
82
92
  return [formatter(keyValue) + '=' + formatter(encoder(obj, defaults.encoder, charset))];
package/lib/utils.js CHANGED
@@ -126,7 +126,12 @@ var encode = function encode(str, defaultEncoder, charset) {
126
126
  return str;
127
127
  }
128
128
 
129
- var string = typeof str === 'string' ? str : String(str);
129
+ var string = str;
130
+ if (typeof str === 'symbol') {
131
+ string = Symbol.prototype.toString.call(str);
132
+ } else if (typeof str !== 'string') {
133
+ string = String(str);
134
+ }
130
135
 
131
136
  if (charset === 'iso-8859-1') {
132
137
  return escape(string).replace(/%u[0-9a-f]{4}/gi, function ($0) {
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.7.0",
5
+ "version": "6.8.0",
6
6
  "repository": {
7
7
  "type": "git",
8
8
  "url": "https://github.com/ljharb/qs.git"
@@ -28,20 +28,21 @@
28
28
  },
29
29
  "dependencies": {},
30
30
  "devDependencies": {
31
- "@ljharb/eslint-config": "^13.1.1",
32
- "browserify": "^16.2.3",
31
+ "@ljharb/eslint-config": "^14.0.2",
32
+ "browserify": "^16.5.0",
33
33
  "covert": "^1.1.1",
34
- "editorconfig-tools": "^0.1.1",
35
- "eslint": "^5.15.3",
34
+ "eclint": "^2.8.1",
35
+ "eslint": "^6.1.0",
36
36
  "evalmd": "^0.0.17",
37
37
  "for-each": "^0.3.3",
38
+ "has-symbols": "^1.0.0",
38
39
  "iconv-lite": "^0.4.24",
39
40
  "mkdirp": "^0.5.1",
40
41
  "object-inspect": "^1.6.0",
41
42
  "qs-iconv": "^1.0.4",
42
- "safe-publish-latest": "^1.1.2",
43
+ "safe-publish-latest": "^1.1.3",
43
44
  "safer-buffer": "^2.1.2",
44
- "tape": "^4.10.1"
45
+ "tape": "^4.11.0"
45
46
  },
46
47
  "scripts": {
47
48
  "prepublish": "safe-publish-latest && npm run dist",
@@ -49,7 +50,7 @@
49
50
  "test": "npm run --silent coverage",
50
51
  "tests-only": "node test",
51
52
  "readme": "evalmd README.md",
52
- "postlint": "editorconfig-tools check * lib/* test/*",
53
+ "postlint": "eclint check * lib/* test/*",
53
54
  "lint": "eslint lib/*.js test/*.js",
54
55
  "coverage": "covert test",
55
56
  "dist": "mkdirp dist && browserify --standalone Qs lib/index.js > dist/qs.js"
package/test/.eslintrc CHANGED
@@ -1,17 +1,17 @@
1
1
  {
2
2
  "rules": {
3
- "array-bracket-newline": 0,
4
- "array-element-newline": 0,
5
- "consistent-return": 2,
3
+ "array-bracket-newline": 0,
4
+ "array-element-newline": 0,
5
+ "consistent-return": 2,
6
6
  "function-paren-newline": 0,
7
7
  "max-lines": 0,
8
8
  "max-lines-per-function": 0,
9
9
  "max-nested-callbacks": [2, 3],
10
10
  "max-statements": 0,
11
- "no-buffer-constructor": 0,
11
+ "no-buffer-constructor": 0,
12
12
  "no-extend-native": 0,
13
13
  "no-magic-numbers": 0,
14
- "object-curly-newline": 0,
14
+ "object-curly-newline": 0,
15
15
  "sort-keys": 0
16
16
  }
17
17
  }
package/test/parse.js CHANGED
@@ -52,6 +52,18 @@ test('parse()', function (t) {
52
52
  st.end();
53
53
  });
54
54
 
55
+ t.test('uses original key when depth = 0', function (st) {
56
+ st.deepEqual(qs.parse('a[0]=b&a[1]=c', { depth: 0 }), { 'a[0]': 'b', 'a[1]': 'c' });
57
+ st.deepEqual(qs.parse('a[0][0]=b&a[0][1]=c&a[1]=d&e=2', { depth: 0 }), { 'a[0][0]': 'b', 'a[0][1]': 'c', 'a[1]': 'd', e: '2' });
58
+ st.end();
59
+ });
60
+
61
+ t.test('uses original key when depth = false', function (st) {
62
+ st.deepEqual(qs.parse('a[0]=b&a[1]=c', { depth: false }), { 'a[0]': 'b', 'a[1]': 'c' });
63
+ st.deepEqual(qs.parse('a[0][0]=b&a[0][1]=c&a[1]=d&e=2', { depth: false }), { 'a[0][0]': 'b', 'a[0][1]': 'c', 'a[1]': 'd', e: '2' });
64
+ st.end();
65
+ });
66
+
55
67
  t.deepEqual(qs.parse('a=b&a=c'), { a: ['b', 'c'] }, 'parses a simple array');
56
68
 
57
69
  t.test('parses an explicit array', function (st) {
@@ -617,6 +629,7 @@ test('parse()', function (t) {
617
629
  });
618
630
 
619
631
  t.test('prefers an iso-8859-1 charset specified by the utf8 sentinel to a default charset of utf-8', function (st) {
632
+ // eslint-disable-next-line quote-props
620
633
  st.deepEqual(qs.parse('utf8=' + urlEncodedNumCheckmark + '&' + urlEncodedOSlashInUtf8 + '=' + urlEncodedOSlashInUtf8, { charsetSentinel: true, charset: 'utf-8' }), { 'ø': 'ø' });
621
634
  st.end();
622
635
  });
@@ -637,6 +650,7 @@ test('parse()', function (t) {
637
650
  });
638
651
 
639
652
  t.test('uses the utf8 sentinel to switch to iso-8859-1 when no default charset is given', function (st) {
653
+ // eslint-disable-next-line quote-props
640
654
  st.deepEqual(qs.parse('utf8=' + urlEncodedNumCheckmark + '&' + urlEncodedOSlashInUtf8 + '=' + urlEncodedOSlashInUtf8, { charsetSentinel: true }), { 'ø': 'ø' });
641
655
  st.end();
642
656
  });
package/test/stringify.js CHANGED
@@ -5,6 +5,8 @@ var qs = require('../');
5
5
  var utils = require('../lib/utils');
6
6
  var iconv = require('iconv-lite');
7
7
  var SaferBuffer = require('safer-buffer').Buffer;
8
+ var hasSymbols = require('has-symbols');
9
+ var hasBigInt = typeof BigInt === 'function';
8
10
 
9
11
  test('stringify()', function (t) {
10
12
  t.test('stringifies a querystring object', function (st) {
@@ -28,6 +30,39 @@ test('stringify()', function (t) {
28
30
  st.end();
29
31
  });
30
32
 
33
+ t.test('stringifies symbols', { skip: !hasSymbols() }, function (st) {
34
+ st.equal(qs.stringify(Symbol.iterator), '');
35
+ st.equal(qs.stringify([Symbol.iterator]), '0=Symbol%28Symbol.iterator%29');
36
+ st.equal(qs.stringify({ a: Symbol.iterator }), 'a=Symbol%28Symbol.iterator%29');
37
+ st.equal(
38
+ qs.stringify({ a: [Symbol.iterator] }, { encodeValuesOnly: true, arrayFormat: 'brackets' }),
39
+ 'a[]=Symbol%28Symbol.iterator%29'
40
+ );
41
+ st.end();
42
+ });
43
+
44
+ t.test('stringifies bigints', { skip: !hasBigInt }, function (st) {
45
+ var three = BigInt(3); // eslint-disable-line new-cap
46
+ var encodeWithN = function (value, defaultEncoder, charset) {
47
+ var result = defaultEncoder(value, defaultEncoder, charset);
48
+ return typeof value === 'bigint' ? result + 'n' : result; // eslint-disable-line valid-typeof
49
+ };
50
+ st.equal(qs.stringify(three), '');
51
+ st.equal(qs.stringify([three]), '0=3');
52
+ st.equal(qs.stringify([three], { encoder: encodeWithN }), '0=3n');
53
+ st.equal(qs.stringify({ a: three }), 'a=3');
54
+ st.equal(qs.stringify({ a: three }, { encoder: encodeWithN }), 'a=3n');
55
+ st.equal(
56
+ qs.stringify({ a: [three] }, { encodeValuesOnly: true, arrayFormat: 'brackets' }),
57
+ 'a[]=3'
58
+ );
59
+ st.equal(
60
+ qs.stringify({ a: [three] }, { encodeValuesOnly: true, encoder: encodeWithN, arrayFormat: 'brackets' }),
61
+ 'a[]=3n'
62
+ );
63
+ st.end();
64
+ });
65
+
31
66
  t.test('adds query prefix', function (st) {
32
67
  st.equal(qs.stringify({ a: 'b' }, { addQueryPrefix: true }), '?a=b');
33
68
  st.end();
@@ -520,6 +555,12 @@ test('stringify()', function (t) {
520
555
  return String.fromCharCode(buffer.readUInt8(0) + 97);
521
556
  }
522
557
  }), 'a=b');
558
+
559
+ st.equal(qs.stringify({ a: SaferBuffer.from('a b') }, {
560
+ encoder: function (buffer) {
561
+ return buffer;
562
+ }
563
+ }), 'a=a b');
523
564
  st.end();
524
565
  });
525
566
 
@@ -560,17 +601,20 @@ test('stringify()', function (t) {
560
601
  t.test('RFC 1738 spaces serialization', function (st) {
561
602
  st.equal(qs.stringify({ a: 'b c' }, { format: qs.formats.RFC1738 }), 'a=b+c');
562
603
  st.equal(qs.stringify({ 'a b': 'c d' }, { format: qs.formats.RFC1738 }), 'a+b=c+d');
604
+ st.equal(qs.stringify({ 'a b': SaferBuffer.from('a b') }, { format: qs.formats.RFC1738 }), 'a+b=a+b');
563
605
  st.end();
564
606
  });
565
607
 
566
608
  t.test('RFC 3986 spaces serialization', function (st) {
567
609
  st.equal(qs.stringify({ a: 'b c' }, { format: qs.formats.RFC3986 }), 'a=b%20c');
568
610
  st.equal(qs.stringify({ 'a b': 'c d' }, { format: qs.formats.RFC3986 }), 'a%20b=c%20d');
611
+ st.equal(qs.stringify({ 'a b': SaferBuffer.from('a b') }, { format: qs.formats.RFC3986 }), 'a%20b=a%20b');
569
612
  st.end();
570
613
  });
571
614
 
572
615
  t.test('Backward compatibility to RFC 3986', function (st) {
573
616
  st.equal(qs.stringify({ a: 'b c' }), 'a=b%20c');
617
+ st.equal(qs.stringify({ 'a b': SaferBuffer.from('a b') }), 'a%20b=a%20b');
574
618
  st.end();
575
619
  });
576
620
 
package/LICENSE DELETED
@@ -1,28 +0,0 @@
1
- Copyright (c) 2014 Nathan LaFreniere and other contributors.
2
- All rights reserved.
3
-
4
- Redistribution and use in source and binary forms, with or without
5
- modification, are permitted provided that the following conditions are met:
6
- * Redistributions of source code must retain the above copyright
7
- notice, this list of conditions and the following disclaimer.
8
- * Redistributions in binary form must reproduce the above copyright
9
- notice, this list of conditions and the following disclaimer in the
10
- documentation and/or other materials provided with the distribution.
11
- * The names of any contributors may not be used to endorse or promote
12
- products derived from this software without specific prior written
13
- permission.
14
-
15
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16
- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18
- DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND CONTRIBUTORS BE LIABLE FOR ANY
19
- DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20
- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21
- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22
- ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
-
26
- * * *
27
-
28
- The complete list of contributors can be found at: https://github.com/hapijs/qs/graphs/contributors