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 +3 -0
- package/.github/FUNDING.yml +12 -0
- package/CHANGELOG.md +14 -0
- package/LICENSE.md +29 -0
- package/README.md +4 -0
- package/dist/qs.js +41 -17
- package/lib/formats.js +18 -10
- package/lib/parse.js +4 -3
- package/lib/stringify.js +12 -2
- package/lib/utils.js +6 -1
- package/package.json +9 -8
- package/test/.eslintrc +5 -5
- package/test/parse.js +14 -0
- package/test/stringify.js +44 -0
- package/LICENSE +0 -28
package/.editorconfig
CHANGED
|
@@ -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
|
-
|
|
8
|
-
|
|
9
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 (
|
|
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 =
|
|
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
|
-
|
|
7
|
-
|
|
8
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 (
|
|
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 =
|
|
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.
|
|
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": "^
|
|
32
|
-
"browserify": "^16.
|
|
31
|
+
"@ljharb/eslint-config": "^14.0.2",
|
|
32
|
+
"browserify": "^16.5.0",
|
|
33
33
|
"covert": "^1.1.1",
|
|
34
|
-
"
|
|
35
|
-
"eslint": "^
|
|
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.
|
|
43
|
+
"safe-publish-latest": "^1.1.3",
|
|
43
44
|
"safer-buffer": "^2.1.2",
|
|
44
|
-
"tape": "^4.
|
|
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": "
|
|
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
|
-
|
|
4
|
-
|
|
5
|
-
|
|
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
|
-
|
|
11
|
+
"no-buffer-constructor": 0,
|
|
12
12
|
"no-extend-native": 0,
|
|
13
13
|
"no-magic-numbers": 0,
|
|
14
|
-
|
|
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
|