qs 6.10.1 → 6.10.4
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 +4 -0
- package/.eslintrc +8 -5
- package/CHANGELOG.md +167 -0
- package/README.md +30 -18
- package/dist/qs.js +196 -54
- package/lib/parse.js +1 -1
- package/lib/stringify.js +35 -8
- package/lib/utils.js +1 -0
- package/package.json +19 -14
- package/test/parse.js +74 -0
- package/test/stringify.js +53 -24
- package/.eslintignore +0 -2
package/.editorconfig
CHANGED
|
@@ -8,6 +8,7 @@ charset = utf-8
|
|
|
8
8
|
trim_trailing_whitespace = true
|
|
9
9
|
insert_final_newline = true
|
|
10
10
|
max_line_length = 160
|
|
11
|
+
quote_type = single
|
|
11
12
|
|
|
12
13
|
[test/*]
|
|
13
14
|
max_line_length = off
|
|
@@ -37,3 +38,6 @@ indent_size = off
|
|
|
37
38
|
indent_style = off
|
|
38
39
|
indent = off
|
|
39
40
|
max_line_length = off
|
|
41
|
+
|
|
42
|
+
[.nycrc]
|
|
43
|
+
indent_style = tab
|
package/.eslintrc
CHANGED
|
@@ -3,10 +3,14 @@
|
|
|
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
|
-
|
|
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 }],
|
|
@@ -16,7 +20,6 @@
|
|
|
16
20
|
"no-continue": 1,
|
|
17
21
|
"no-magic-numbers": 0,
|
|
18
22
|
"no-restricted-syntax": [2, "BreakStatement", "DebuggerStatement", "ForInStatement", "LabeledStatement", "WithStatement"],
|
|
19
|
-
"operator-linebreak": [2, "before"],
|
|
20
23
|
},
|
|
21
24
|
|
|
22
25
|
"overrides": [
|
|
@@ -29,7 +32,7 @@
|
|
|
29
32
|
"no-buffer-constructor": 0,
|
|
30
33
|
"no-extend-native": 0,
|
|
31
34
|
"no-throw-literal": 0,
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
]
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
],
|
|
35
38
|
}
|
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,24 @@
|
|
|
1
|
+
## **6.10.4**
|
|
2
|
+
- [Fix] `stringify`: with `arrayFormat: comma`, include an explicit `[]` on a single-item array (#441)
|
|
3
|
+
- [meta] use `npmignore` to autogenerate an npmignore file
|
|
4
|
+
- [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `aud`, `has-symbol`, `object-inspect`, `tape`
|
|
5
|
+
|
|
6
|
+
## **6.10.3**
|
|
7
|
+
- [Fix] `parse`: ignore `__proto__` keys (#428)
|
|
8
|
+
- [Robustness] `stringify`: avoid relying on a global `undefined` (#427)
|
|
9
|
+
- [actions] reuse common workflows
|
|
10
|
+
- [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `object-inspect`, `tape`
|
|
11
|
+
|
|
12
|
+
## **6.10.2**
|
|
13
|
+
- [Fix] `stringify`: actually fix cyclic references (#426)
|
|
14
|
+
- [Fix] `stringify`: avoid encoding arrayformat comma when `encodeValuesOnly = true` (#424)
|
|
15
|
+
- [readme] remove travis badge; add github actions/codecov badges; update URLs
|
|
16
|
+
- [Docs] add note and links for coercing primitive values (#408)
|
|
17
|
+
- [actions] update codecov uploader
|
|
18
|
+
- [actions] update workflows
|
|
19
|
+
- [Tests] clean up stringify tests slightly
|
|
20
|
+
- [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `aud`, `object-inspect`, `safe-publish-latest`, `tape`
|
|
21
|
+
|
|
1
22
|
## **6.10.1**
|
|
2
23
|
- [Fix] `stringify`: avoid exception on repeated object values (#402)
|
|
3
24
|
|
|
@@ -11,6 +32,18 @@
|
|
|
11
32
|
- [Tests] use `ljharb/actions/node/install` instead of `ljharb/actions/node/run`
|
|
12
33
|
- [Tests] Revert "[meta] ignore eclint transitive audit warning"
|
|
13
34
|
|
|
35
|
+
## **6.9.7**
|
|
36
|
+
- [Fix] `parse`: ignore `__proto__` keys (#428)
|
|
37
|
+
- [Fix] `stringify`: avoid encoding arrayformat comma when `encodeValuesOnly = true` (#424)
|
|
38
|
+
- [Robustness] `stringify`: avoid relying on a global `undefined` (#427)
|
|
39
|
+
- [readme] remove travis badge; add github actions/codecov badges; update URLs
|
|
40
|
+
- [Docs] add note and links for coercing primitive values (#408)
|
|
41
|
+
- [Tests] clean up stringify tests slightly
|
|
42
|
+
- [meta] fix README.md (#399)
|
|
43
|
+
- Revert "[meta] ignore eclint transitive audit warning"
|
|
44
|
+
- [actions] backport actions from main
|
|
45
|
+
- [Dev Deps] backport updates from main
|
|
46
|
+
|
|
14
47
|
## **6.9.6**
|
|
15
48
|
- [Fix] restore `dist` dir; mistakenly removed in d4f6c32
|
|
16
49
|
|
|
@@ -59,6 +92,19 @@
|
|
|
59
92
|
- [Tests] up to `node` `v12.10`, `v11.15`, `v10.16`, `v8.16`
|
|
60
93
|
- [Tests] `Buffer.from` in node v5.0-v5.9 and v4.0-v4.4 requires a TypedArray
|
|
61
94
|
|
|
95
|
+
## **6.8.3**
|
|
96
|
+
- [Fix] `parse`: ignore `__proto__` keys (#428)
|
|
97
|
+
- [Robustness] `stringify`: avoid relying on a global `undefined` (#427)
|
|
98
|
+
- [Fix] `stringify`: avoid encoding arrayformat comma when `encodeValuesOnly = true` (#424)
|
|
99
|
+
- [readme] remove travis badge; add github actions/codecov badges; update URLs
|
|
100
|
+
- [Tests] clean up stringify tests slightly
|
|
101
|
+
- [Docs] add note and links for coercing primitive values (#408)
|
|
102
|
+
- [meta] fix README.md (#399)
|
|
103
|
+
- [actions] backport actions from main
|
|
104
|
+
- [Dev Deps] backport updates from main
|
|
105
|
+
- [Refactor] `stringify`: reduce branching
|
|
106
|
+
- [meta] do not publish workflow files
|
|
107
|
+
|
|
62
108
|
## **6.8.2**
|
|
63
109
|
- [Fix] proper comma parsing of URL-encoded commas (#361)
|
|
64
110
|
- [Fix] parses comma delimited array while having percent-encoded comma treated as normal text (#336)
|
|
@@ -90,6 +136,19 @@
|
|
|
90
136
|
- [meta] add FUNDING.yml
|
|
91
137
|
- [meta] Clean up license text so it’s properly detected as BSD-3-Clause
|
|
92
138
|
|
|
139
|
+
## **6.7.3**
|
|
140
|
+
- [Fix] `parse`: ignore `__proto__` keys (#428)
|
|
141
|
+
- [Fix] `stringify`: avoid encoding arrayformat comma when `encodeValuesOnly = true` (#424)
|
|
142
|
+
- [Robustness] `stringify`: avoid relying on a global `undefined` (#427)
|
|
143
|
+
- [readme] remove travis badge; add github actions/codecov badges; update URLs
|
|
144
|
+
- [Docs] add note and links for coercing primitive values (#408)
|
|
145
|
+
- [meta] fix README.md (#399)
|
|
146
|
+
- [meta] do not publish workflow files
|
|
147
|
+
- [actions] backport actions from main
|
|
148
|
+
- [Dev Deps] backport updates from main
|
|
149
|
+
- [Tests] use `nyc` for coverage
|
|
150
|
+
- [Tests] clean up stringify tests slightly
|
|
151
|
+
|
|
93
152
|
## **6.7.2**
|
|
94
153
|
- [Fix] proper comma parsing of URL-encoded commas (#361)
|
|
95
154
|
- [Fix] parses comma delimited array while having percent-encoded comma treated as normal text (#336)
|
|
@@ -128,6 +187,32 @@
|
|
|
128
187
|
- [Tests] fix Buffer tests to work in node < 4.5 and node < 5.10
|
|
129
188
|
- [Tests] temporarily allow coverage to fail
|
|
130
189
|
|
|
190
|
+
## **6.6.1**
|
|
191
|
+
- [Fix] `parse`: ignore `__proto__` keys (#428)
|
|
192
|
+
- [Fix] fix for an impossible situation: when the formatter is called with a non-string value
|
|
193
|
+
- [Fix] `utils.merge`: avoid a crash with a null target and an array source
|
|
194
|
+
- [Fix] `utils.merge`: avoid a crash with a null target and a truthy non-array source
|
|
195
|
+
- [Fix] correctly parse nested arrays
|
|
196
|
+
- [Robustness] `stringify`: avoid relying on a global `undefined` (#427)
|
|
197
|
+
- [Robustness] `stringify`: cache `Object.prototype.hasOwnProperty`
|
|
198
|
+
- [Refactor] `formats`: tiny bit of cleanup.
|
|
199
|
+
- [Refactor] `utils`: `isBuffer`: small tweak; add tests
|
|
200
|
+
- [Refactor]: `stringify`/`utils`: cache `Array.isArray`
|
|
201
|
+
- [Refactor] `utils`: reduce observable [[Get]]s
|
|
202
|
+
- [Refactor] use cached `Array.isArray`
|
|
203
|
+
- [Refactor] `parse`/`stringify`: make a function to normalize the options
|
|
204
|
+
- [readme] remove travis badge; add github actions/codecov badges; update URLs
|
|
205
|
+
- [Docs] Clarify the need for "arrayLimit" option
|
|
206
|
+
- [meta] fix README.md (#399)
|
|
207
|
+
- [meta] do not publish workflow files
|
|
208
|
+
- [meta] Clean up license text so it’s properly detected as BSD-3-Clause
|
|
209
|
+
- [meta] add FUNDING.yml
|
|
210
|
+
- [meta] Fixes typo in CHANGELOG.md
|
|
211
|
+
- [actions] backport actions from main
|
|
212
|
+
- [Tests] fix Buffer tests to work in node < 4.5 and node < 5.10
|
|
213
|
+
- [Tests] always use `String(x)` over `x.toString()`
|
|
214
|
+
- [Dev Deps] backport from main
|
|
215
|
+
|
|
131
216
|
## **6.6.0**
|
|
132
217
|
- [New] Add support for iso-8859-1, utf8 "sentinel" and numeric entities (#268)
|
|
133
218
|
- [New] move two-value combine to a `utils` function (#189)
|
|
@@ -144,6 +229,30 @@
|
|
|
144
229
|
- [Dev Deps] update `browserify`, `eslint`, `@ljharb/eslint-config`, `iconv-lite`, `safe-publish-latest`, `tape`
|
|
145
230
|
- [Tests] up to `node` `v10.10`, `v9.11`, `v8.12`, `v6.14`, `v4.9`; pin included builds to LTS
|
|
146
231
|
|
|
232
|
+
## **6.5.3**
|
|
233
|
+
- [Fix] `parse`: ignore `__proto__` keys (#428)
|
|
234
|
+
- [Fix]` `utils.merge`: avoid a crash with a null target and a truthy non-array source
|
|
235
|
+
- [Fix] correctly parse nested arrays
|
|
236
|
+
- [Fix] `stringify`: fix a crash with `strictNullHandling` and a custom `filter`/`serializeDate` (#279)
|
|
237
|
+
- [Fix] `utils`: `merge`: fix crash when `source` is a truthy primitive & no options are provided
|
|
238
|
+
- [Fix] when `parseArrays` is false, properly handle keys ending in `[]`
|
|
239
|
+
- [Fix] fix for an impossible situation: when the formatter is called with a non-string value
|
|
240
|
+
- [Fix] `utils.merge`: avoid a crash with a null target and an array source
|
|
241
|
+
- [Refactor] `utils`: reduce observable [[Get]]s
|
|
242
|
+
- [Refactor] use cached `Array.isArray`
|
|
243
|
+
- [Refactor] `stringify`: Avoid arr = arr.concat(...), push to the existing instance (#269)
|
|
244
|
+
- [Refactor] `parse`: only need to reassign the var once
|
|
245
|
+
- [Robustness] `stringify`: avoid relying on a global `undefined` (#427)
|
|
246
|
+
- [readme] remove travis badge; add github actions/codecov badges; update URLs
|
|
247
|
+
- [Docs] Clean up license text so it’s properly detected as BSD-3-Clause
|
|
248
|
+
- [Docs] Clarify the need for "arrayLimit" option
|
|
249
|
+
- [meta] fix README.md (#399)
|
|
250
|
+
- [meta] add FUNDING.yml
|
|
251
|
+
- [actions] backport actions from main
|
|
252
|
+
- [Tests] always use `String(x)` over `x.toString()`
|
|
253
|
+
- [Tests] remove nonexistent tape option
|
|
254
|
+
- [Dev Deps] backport from main
|
|
255
|
+
|
|
147
256
|
## **6.5.2**
|
|
148
257
|
- [Fix] use `safer-buffer` instead of `Buffer` constructor
|
|
149
258
|
- [Refactor] utils: `module.exports` one thing, instead of mutating `exports` (#230)
|
|
@@ -170,6 +279,27 @@
|
|
|
170
279
|
- [Tests] up to `node` `v8.1`, `v7.10`, `v6.11`; npm v4.6 breaks on node < v1; npm v5+ breaks on node < v4
|
|
171
280
|
- [Tests] add `editorconfig-tools`
|
|
172
281
|
|
|
282
|
+
## **6.4.1**
|
|
283
|
+
- [Fix] `parse`: ignore `__proto__` keys (#428)
|
|
284
|
+
- [Fix] fix for an impossible situation: when the formatter is called with a non-string value
|
|
285
|
+
- [Fix] use `safer-buffer` instead of `Buffer` constructor
|
|
286
|
+
- [Fix] `utils.merge`: avoid a crash with a null target and an array source
|
|
287
|
+
- [Fix]` `utils.merge`: avoid a crash with a null target and a truthy non-array source
|
|
288
|
+
- [Fix] `stringify`: fix a crash with `strictNullHandling` and a custom `filter`/`serializeDate` (#279)
|
|
289
|
+
- [Fix] `utils`: `merge`: fix crash when `source` is a truthy primitive & no options are provided
|
|
290
|
+
- [Fix] when `parseArrays` is false, properly handle keys ending in `[]`
|
|
291
|
+
- [Robustness] `stringify`: avoid relying on a global `undefined` (#427)
|
|
292
|
+
- [Refactor] use cached `Array.isArray`
|
|
293
|
+
- [Refactor] `stringify`: Avoid arr = arr.concat(...), push to the existing instance (#269)
|
|
294
|
+
- [readme] remove travis badge; add github actions/codecov badges; update URLs
|
|
295
|
+
- [Docs] Clarify the need for "arrayLimit" option
|
|
296
|
+
- [meta] fix README.md (#399)
|
|
297
|
+
- [meta] Clean up license text so it’s properly detected as BSD-3-Clause
|
|
298
|
+
- [meta] add FUNDING.yml
|
|
299
|
+
- [actions] backport actions from main
|
|
300
|
+
- [Tests] remove nonexistent tape option
|
|
301
|
+
- [Dev Deps] backport from main
|
|
302
|
+
|
|
173
303
|
## **6.4.0**
|
|
174
304
|
- [New] `qs.stringify`: add `encodeValuesOnly` option
|
|
175
305
|
- [Fix] follow `allowPrototypes` option during merge (#201, #201)
|
|
@@ -179,6 +309,26 @@
|
|
|
179
309
|
- [Tests] up to `node` `v7.7`, `v6.10`,` v4.8`; disable osx builds since they block linux builds
|
|
180
310
|
- [eslint] reduce warnings
|
|
181
311
|
|
|
312
|
+
## **6.3.3**
|
|
313
|
+
- [Fix] `parse`: ignore `__proto__` keys (#428)
|
|
314
|
+
- [Fix] fix for an impossible situation: when the formatter is called with a non-string value
|
|
315
|
+
- [Fix] `utils.merge`: avoid a crash with a null target and an array source
|
|
316
|
+
- [Fix]` `utils.merge`: avoid a crash with a null target and a truthy non-array source
|
|
317
|
+
- [Fix] `stringify`: fix a crash with `strictNullHandling` and a custom `filter`/`serializeDate` (#279)
|
|
318
|
+
- [Fix] `utils`: `merge`: fix crash when `source` is a truthy primitive & no options are provided
|
|
319
|
+
- [Fix] when `parseArrays` is false, properly handle keys ending in `[]`
|
|
320
|
+
- [Robustness] `stringify`: avoid relying on a global `undefined` (#427)
|
|
321
|
+
- [Refactor] use cached `Array.isArray`
|
|
322
|
+
- [Refactor] `stringify`: Avoid arr = arr.concat(...), push to the existing instance (#269)
|
|
323
|
+
- [Docs] Clarify the need for "arrayLimit" option
|
|
324
|
+
- [meta] fix README.md (#399)
|
|
325
|
+
- [meta] Clean up license text so it’s properly detected as BSD-3-Clause
|
|
326
|
+
- [meta] add FUNDING.yml
|
|
327
|
+
- [actions] backport actions from main
|
|
328
|
+
- [Tests] use `safer-buffer` instead of `Buffer` constructor
|
|
329
|
+
- [Tests] remove nonexistent tape option
|
|
330
|
+
- [Dev Deps] backport from main
|
|
331
|
+
|
|
182
332
|
## **6.3.2**
|
|
183
333
|
- [Fix] follow `allowPrototypes` option during merge (#201, #200)
|
|
184
334
|
- [Dev Deps] update `eslint`
|
|
@@ -212,6 +362,23 @@
|
|
|
212
362
|
- [Tests] skip Object.create tests when null objects are not available
|
|
213
363
|
- [Tests] Turn on eslint for test files (#175)
|
|
214
364
|
|
|
365
|
+
## **6.2.4**
|
|
366
|
+
- [Fix] `parse`: ignore `__proto__` keys (#428)
|
|
367
|
+
- [Fix] `utils.merge`: avoid a crash with a null target and an array source
|
|
368
|
+
- [Fix] `utils.merge`: avoid a crash with a null target and a truthy non-array source
|
|
369
|
+
- [Fix] `utils`: `merge`: fix crash when `source` is a truthy primitive & no options are provided
|
|
370
|
+
- [Fix] when `parseArrays` is false, properly handle keys ending in `[]`
|
|
371
|
+
- [Robustness] `stringify`: avoid relying on a global `undefined` (#427)
|
|
372
|
+
- [Refactor] use cached `Array.isArray`
|
|
373
|
+
- [Docs] Clarify the need for "arrayLimit" option
|
|
374
|
+
- [meta] fix README.md (#399)
|
|
375
|
+
- [meta] Clean up license text so it’s properly detected as BSD-3-Clause
|
|
376
|
+
- [meta] add FUNDING.yml
|
|
377
|
+
- [actions] backport actions from main
|
|
378
|
+
- [Tests] use `safer-buffer` instead of `Buffer` constructor
|
|
379
|
+
- [Tests] remove nonexistent tape option
|
|
380
|
+
- [Dev Deps] backport from main
|
|
381
|
+
|
|
215
382
|
## **6.2.3**
|
|
216
383
|
- [Fix] follow `allowPrototypes` option during merge (#201, #200)
|
|
217
384
|
- [Fix] chmod a-x
|
package/README.md
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
# qs <sup>[![Version Badge][2]][1]</sup>
|
|
2
2
|
|
|
3
|
-
[![
|
|
4
|
-
[![
|
|
5
|
-
[![
|
|
3
|
+
[![github actions][actions-image]][actions-url]
|
|
4
|
+
[![coverage][codecov-image]][codecov-url]
|
|
5
|
+
[![dependency status][deps-svg]][deps-url]
|
|
6
|
+
[![dev dependency status][dev-deps-svg]][dev-deps-url]
|
|
6
7
|
[![License][license-image]][license-url]
|
|
7
8
|
[![Downloads][downloads-image]][downloads-url]
|
|
8
9
|
|
|
9
|
-
[![npm badge][
|
|
10
|
+
[![npm badge][npm-badge-png]][package-url]
|
|
10
11
|
|
|
11
12
|
A querystring parsing and stringifying library with some added security.
|
|
12
13
|
|
|
@@ -287,6 +288,17 @@ assert.deepEqual(arraysOfObjects, { a: ['b', 'c'] })
|
|
|
287
288
|
```
|
|
288
289
|
(_this cannot convert nested objects, such as `a={b:1},{c:d}`_)
|
|
289
290
|
|
|
291
|
+
### Parsing primitive/scalar values (numbers, booleans, null, etc)
|
|
292
|
+
|
|
293
|
+
By default, all values are parsed as strings. This behavior will not change and is explained in [issue #91](https://github.com/ljharb/qs/issues/91).
|
|
294
|
+
|
|
295
|
+
```javascript
|
|
296
|
+
var primitiveValues = qs.parse('a=15&b=true&c=null');
|
|
297
|
+
assert.deepEqual(primitiveValues, { a: '15', b: 'true', c: 'null' });
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
If you wish to auto-convert values which look like numbers, booleans, and other values into their primitive counterparts, you can use the [query-types Express JS middleware](https://github.com/xpepermint/query-types) which will auto-convert all request query parameters.
|
|
301
|
+
|
|
290
302
|
### Stringifying
|
|
291
303
|
|
|
292
304
|
[](#preventEval)
|
|
@@ -594,18 +606,18 @@ Available as part of the Tidelift Subscription
|
|
|
594
606
|
|
|
595
607
|
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)
|
|
596
608
|
|
|
597
|
-
[
|
|
598
|
-
[
|
|
599
|
-
[
|
|
600
|
-
[
|
|
601
|
-
[
|
|
602
|
-
[
|
|
603
|
-
[
|
|
604
|
-
[
|
|
605
|
-
[9]: https://ci.testling.com/ljharb/qs.png
|
|
606
|
-
[10]: https://ci.testling.com/ljharb/qs
|
|
607
|
-
[11]: https://nodei.co/npm/qs.png?downloads=true&stars=true
|
|
608
|
-
[license-image]: http://img.shields.io/npm/l/qs.svg
|
|
609
|
+
[package-url]: https://npmjs.org/package/qs
|
|
610
|
+
[npm-version-svg]: https://versionbadg.es/ljharb/qs.svg
|
|
611
|
+
[deps-svg]: https://david-dm.org/ljharb/qs.svg
|
|
612
|
+
[deps-url]: https://david-dm.org/ljharb/qs
|
|
613
|
+
[dev-deps-svg]: https://david-dm.org/ljharb/qs/dev-status.svg
|
|
614
|
+
[dev-deps-url]: https://david-dm.org/ljharb/qs#info=devDependencies
|
|
615
|
+
[npm-badge-png]: https://nodei.co/npm/qs.png?downloads=true&stars=true
|
|
616
|
+
[license-image]: https://img.shields.io/npm/l/qs.svg
|
|
609
617
|
[license-url]: LICENSE
|
|
610
|
-
[downloads-image]:
|
|
611
|
-
[downloads-url]:
|
|
618
|
+
[downloads-image]: https://img.shields.io/npm/dm/qs.svg
|
|
619
|
+
[downloads-url]: https://npm-stat.com/charts.html?package=qs
|
|
620
|
+
[codecov-image]: https://codecov.io/gh/ljharb/qs/branch/main/graphs/badge.svg
|
|
621
|
+
[codecov-url]: https://app.codecov.io/gh/ljharb/qs/
|
|
622
|
+
[actions-image]: https://img.shields.io/endpoint?url=https://github-actions-badge-u3jn4tfpocch.runkit.sh/ljharb/qs
|
|
623
|
+
[actions-url]: https://github.com/ljharb/qs/actions
|
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
|
}
|
|
@@ -323,6 +323,7 @@ var arrayPrefixGenerators = {
|
|
|
323
323
|
};
|
|
324
324
|
|
|
325
325
|
var isArray = Array.isArray;
|
|
326
|
+
var split = String.prototype.split;
|
|
326
327
|
var push = Array.prototype.push;
|
|
327
328
|
var pushToArray = function (arr, valueOrArray) {
|
|
328
329
|
push.apply(arr, isArray(valueOrArray) ? valueOrArray : [valueOrArray]);
|
|
@@ -359,6 +360,8 @@ var isNonNullishPrimitive = function isNonNullishPrimitive(v) {
|
|
|
359
360
|
|| typeof v === 'bigint';
|
|
360
361
|
};
|
|
361
362
|
|
|
363
|
+
var sentinel = {};
|
|
364
|
+
|
|
362
365
|
var stringify = function stringify(
|
|
363
366
|
object,
|
|
364
367
|
prefix,
|
|
@@ -378,8 +381,23 @@ var stringify = function stringify(
|
|
|
378
381
|
) {
|
|
379
382
|
var obj = object;
|
|
380
383
|
|
|
381
|
-
|
|
382
|
-
|
|
384
|
+
var tmpSc = sideChannel;
|
|
385
|
+
var step = 0;
|
|
386
|
+
var findFlag = false;
|
|
387
|
+
while ((tmpSc = tmpSc.get(sentinel)) !== void undefined && !findFlag) {
|
|
388
|
+
// Where object last appeared in the ref tree
|
|
389
|
+
var pos = tmpSc.get(object);
|
|
390
|
+
step += 1;
|
|
391
|
+
if (typeof pos !== 'undefined') {
|
|
392
|
+
if (pos === step) {
|
|
393
|
+
throw new RangeError('Cyclic object value');
|
|
394
|
+
} else {
|
|
395
|
+
findFlag = true; // Break while
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
if (typeof tmpSc.get(sentinel) === 'undefined') {
|
|
399
|
+
step = 0;
|
|
400
|
+
}
|
|
383
401
|
}
|
|
384
402
|
|
|
385
403
|
if (typeof filter === 'function') {
|
|
@@ -406,6 +424,14 @@ var stringify = function stringify(
|
|
|
406
424
|
if (isNonNullishPrimitive(obj) || utils.isBuffer(obj)) {
|
|
407
425
|
if (encoder) {
|
|
408
426
|
var keyValue = encodeValuesOnly ? prefix : encoder(prefix, defaults.encoder, charset, 'key', format);
|
|
427
|
+
if (generateArrayPrefix === 'comma' && encodeValuesOnly) {
|
|
428
|
+
var valuesArray = split.call(String(obj), ',');
|
|
429
|
+
var valuesJoined = '';
|
|
430
|
+
for (var i = 0; i < valuesArray.length; ++i) {
|
|
431
|
+
valuesJoined += (i === 0 ? '' : ',') + formatter(encoder(valuesArray[i], defaults.encoder, charset, 'value', format));
|
|
432
|
+
}
|
|
433
|
+
return [formatter(keyValue) + (i === 1 ? '[]' : '') + '=' + valuesJoined];
|
|
434
|
+
}
|
|
409
435
|
return [formatter(keyValue) + '=' + formatter(encoder(obj, defaults.encoder, charset, 'value', format))];
|
|
410
436
|
}
|
|
411
437
|
return [formatter(prefix) + '=' + formatter(String(obj))];
|
|
@@ -420,7 +446,7 @@ var stringify = function stringify(
|
|
|
420
446
|
var objKeys;
|
|
421
447
|
if (generateArrayPrefix === 'comma' && isArray(obj)) {
|
|
422
448
|
// we need to join elements in
|
|
423
|
-
objKeys = [{ value: obj.length > 0 ? obj.join(',') || null : undefined }];
|
|
449
|
+
objKeys = [{ value: obj.length > 0 ? obj.join(',') || null : void undefined }];
|
|
424
450
|
} else if (isArray(filter)) {
|
|
425
451
|
objKeys = filter;
|
|
426
452
|
} else {
|
|
@@ -428,9 +454,9 @@ var stringify = function stringify(
|
|
|
428
454
|
objKeys = sort ? keys.sort(sort) : keys;
|
|
429
455
|
}
|
|
430
456
|
|
|
431
|
-
for (var
|
|
432
|
-
var key = objKeys[
|
|
433
|
-
var value = typeof key === 'object' && key.value !== undefined ? key.value : obj[key];
|
|
457
|
+
for (var j = 0; j < objKeys.length; ++j) {
|
|
458
|
+
var key = objKeys[j];
|
|
459
|
+
var value = typeof key === 'object' && typeof key.value !== 'undefined' ? key.value : obj[key];
|
|
434
460
|
|
|
435
461
|
if (skipNulls && value === null) {
|
|
436
462
|
continue;
|
|
@@ -440,7 +466,9 @@ var stringify = function stringify(
|
|
|
440
466
|
? typeof generateArrayPrefix === 'function' ? generateArrayPrefix(prefix, key) : prefix
|
|
441
467
|
: prefix + (allowDots ? '.' + key : '[' + key + ']');
|
|
442
468
|
|
|
443
|
-
sideChannel.set(object,
|
|
469
|
+
sideChannel.set(object, step);
|
|
470
|
+
var valueSideChannel = getSideChannel();
|
|
471
|
+
valueSideChannel.set(sentinel, sideChannel);
|
|
444
472
|
pushToArray(values, stringify(
|
|
445
473
|
value,
|
|
446
474
|
keyPrefix,
|
|
@@ -456,7 +484,7 @@ var stringify = function stringify(
|
|
|
456
484
|
formatter,
|
|
457
485
|
encodeValuesOnly,
|
|
458
486
|
charset,
|
|
459
|
-
|
|
487
|
+
valueSideChannel
|
|
460
488
|
));
|
|
461
489
|
}
|
|
462
490
|
|
|
@@ -468,7 +496,7 @@ var normalizeStringifyOptions = function normalizeStringifyOptions(opts) {
|
|
|
468
496
|
return defaults;
|
|
469
497
|
}
|
|
470
498
|
|
|
471
|
-
if (opts.encoder !== null && opts.encoder !== undefined && typeof opts.encoder !== 'function') {
|
|
499
|
+
if (opts.encoder !== null && typeof opts.encoder !== 'undefined' && typeof opts.encoder !== 'function') {
|
|
472
500
|
throw new TypeError('Encoder has to be a function.');
|
|
473
501
|
}
|
|
474
502
|
|
|
@@ -772,6 +800,7 @@ var encode = function encode(str, defaultEncoder, charset, kind, format) {
|
|
|
772
800
|
|
|
773
801
|
i += 1;
|
|
774
802
|
c = 0x10000 + (((c & 0x3FF) << 10) | (string.charCodeAt(i) & 0x3FF));
|
|
803
|
+
/* eslint operator-linebreak: [2, "before"] */
|
|
775
804
|
out += hexTable[0xF0 | (c >> 18)]
|
|
776
805
|
+ hexTable[0x80 | ((c >> 12) & 0x3F)]
|
|
777
806
|
+ hexTable[0x80 | ((c >> 6) & 0x3F)]
|
|
@@ -1385,17 +1414,64 @@ var hasWeakMap = typeof WeakMap === 'function' && WeakMap.prototype;
|
|
|
1385
1414
|
var weakMapHas = hasWeakMap ? WeakMap.prototype.has : null;
|
|
1386
1415
|
var hasWeakSet = typeof WeakSet === 'function' && WeakSet.prototype;
|
|
1387
1416
|
var weakSetHas = hasWeakSet ? WeakSet.prototype.has : null;
|
|
1417
|
+
var hasWeakRef = typeof WeakRef === 'function' && WeakRef.prototype;
|
|
1418
|
+
var weakRefDeref = hasWeakRef ? WeakRef.prototype.deref : null;
|
|
1388
1419
|
var booleanValueOf = Boolean.prototype.valueOf;
|
|
1389
1420
|
var objectToString = Object.prototype.toString;
|
|
1390
1421
|
var functionToString = Function.prototype.toString;
|
|
1391
|
-
var match = String.prototype.match;
|
|
1422
|
+
var $match = String.prototype.match;
|
|
1423
|
+
var $slice = String.prototype.slice;
|
|
1424
|
+
var $replace = String.prototype.replace;
|
|
1425
|
+
var $toUpperCase = String.prototype.toUpperCase;
|
|
1426
|
+
var $toLowerCase = String.prototype.toLowerCase;
|
|
1427
|
+
var $test = RegExp.prototype.test;
|
|
1428
|
+
var $concat = Array.prototype.concat;
|
|
1429
|
+
var $join = Array.prototype.join;
|
|
1430
|
+
var $arrSlice = Array.prototype.slice;
|
|
1431
|
+
var $floor = Math.floor;
|
|
1392
1432
|
var bigIntValueOf = typeof BigInt === 'function' ? BigInt.prototype.valueOf : null;
|
|
1393
1433
|
var gOPS = Object.getOwnPropertySymbols;
|
|
1394
|
-
var symToString = typeof Symbol === 'function' ? Symbol.prototype.toString : null;
|
|
1434
|
+
var symToString = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ? Symbol.prototype.toString : null;
|
|
1435
|
+
var hasShammedSymbols = typeof Symbol === 'function' && typeof Symbol.iterator === 'object';
|
|
1436
|
+
// ie, `has-tostringtag/shams
|
|
1437
|
+
var toStringTag = typeof Symbol === 'function' && Symbol.toStringTag && (typeof Symbol.toStringTag === hasShammedSymbols ? 'object' : 'symbol')
|
|
1438
|
+
? Symbol.toStringTag
|
|
1439
|
+
: null;
|
|
1395
1440
|
var isEnumerable = Object.prototype.propertyIsEnumerable;
|
|
1396
1441
|
|
|
1397
|
-
var
|
|
1398
|
-
|
|
1442
|
+
var gPO = (typeof Reflect === 'function' ? Reflect.getPrototypeOf : Object.getPrototypeOf) || (
|
|
1443
|
+
[].__proto__ === Array.prototype // eslint-disable-line no-proto
|
|
1444
|
+
? function (O) {
|
|
1445
|
+
return O.__proto__; // eslint-disable-line no-proto
|
|
1446
|
+
}
|
|
1447
|
+
: null
|
|
1448
|
+
);
|
|
1449
|
+
|
|
1450
|
+
function addNumericSeparator(num, str) {
|
|
1451
|
+
if (
|
|
1452
|
+
num === Infinity
|
|
1453
|
+
|| num === -Infinity
|
|
1454
|
+
|| num !== num
|
|
1455
|
+
|| (num && num > -1000 && num < 1000)
|
|
1456
|
+
|| $test.call(/e/, str)
|
|
1457
|
+
) {
|
|
1458
|
+
return str;
|
|
1459
|
+
}
|
|
1460
|
+
var sepRegex = /[0-9](?=(?:[0-9]{3})+(?![0-9]))/g;
|
|
1461
|
+
if (typeof num === 'number') {
|
|
1462
|
+
var int = num < 0 ? -$floor(-num) : $floor(num); // trunc(num)
|
|
1463
|
+
if (int !== num) {
|
|
1464
|
+
var intStr = String(int);
|
|
1465
|
+
var dec = $slice.call(str, intStr.length + 1);
|
|
1466
|
+
return $replace.call(intStr, sepRegex, '$&_') + '.' + $replace.call($replace.call(dec, /([0-9]{3})/g, '$&_'), /_$/, '');
|
|
1467
|
+
}
|
|
1468
|
+
}
|
|
1469
|
+
return $replace.call(str, sepRegex, '$&_');
|
|
1470
|
+
}
|
|
1471
|
+
|
|
1472
|
+
var utilInspect = require('./util.inspect');
|
|
1473
|
+
var inspectCustom = utilInspect.custom;
|
|
1474
|
+
var inspectSymbol = isSymbol(inspectCustom) ? inspectCustom : null;
|
|
1399
1475
|
|
|
1400
1476
|
module.exports = function inspect_(obj, options, depth, seen) {
|
|
1401
1477
|
var opts = options || {};
|
|
@@ -1412,8 +1488,8 @@ module.exports = function inspect_(obj, options, depth, seen) {
|
|
|
1412
1488
|
throw new TypeError('option "maxStringLength", if provided, must be a positive integer, Infinity, or `null`');
|
|
1413
1489
|
}
|
|
1414
1490
|
var customInspect = has(opts, 'customInspect') ? opts.customInspect : true;
|
|
1415
|
-
if (typeof customInspect !== 'boolean') {
|
|
1416
|
-
throw new TypeError('option "customInspect", if provided, must be `true` or `
|
|
1491
|
+
if (typeof customInspect !== 'boolean' && customInspect !== 'symbol') {
|
|
1492
|
+
throw new TypeError('option "customInspect", if provided, must be `true`, `false`, or `\'symbol\'`');
|
|
1417
1493
|
}
|
|
1418
1494
|
|
|
1419
1495
|
if (
|
|
@@ -1422,8 +1498,12 @@ module.exports = function inspect_(obj, options, depth, seen) {
|
|
|
1422
1498
|
&& opts.indent !== '\t'
|
|
1423
1499
|
&& !(parseInt(opts.indent, 10) === opts.indent && opts.indent > 0)
|
|
1424
1500
|
) {
|
|
1425
|
-
throw new TypeError('
|
|
1501
|
+
throw new TypeError('option "indent" must be "\\t", an integer > 0, or `null`');
|
|
1426
1502
|
}
|
|
1503
|
+
if (has(opts, 'numericSeparator') && typeof opts.numericSeparator !== 'boolean') {
|
|
1504
|
+
throw new TypeError('option "numericSeparator", if provided, must be `true` or `false`');
|
|
1505
|
+
}
|
|
1506
|
+
var numericSeparator = opts.numericSeparator;
|
|
1427
1507
|
|
|
1428
1508
|
if (typeof obj === 'undefined') {
|
|
1429
1509
|
return 'undefined';
|
|
@@ -1442,10 +1522,12 @@ module.exports = function inspect_(obj, options, depth, seen) {
|
|
|
1442
1522
|
if (obj === 0) {
|
|
1443
1523
|
return Infinity / obj > 0 ? '0' : '-0';
|
|
1444
1524
|
}
|
|
1445
|
-
|
|
1525
|
+
var str = String(obj);
|
|
1526
|
+
return numericSeparator ? addNumericSeparator(obj, str) : str;
|
|
1446
1527
|
}
|
|
1447
1528
|
if (typeof obj === 'bigint') {
|
|
1448
|
-
|
|
1529
|
+
var bigIntStr = String(obj) + 'n';
|
|
1530
|
+
return numericSeparator ? addNumericSeparator(obj, bigIntStr) : bigIntStr;
|
|
1449
1531
|
}
|
|
1450
1532
|
|
|
1451
1533
|
var maxDepth = typeof opts.depth === 'undefined' ? 5 : opts.depth;
|
|
@@ -1464,7 +1546,7 @@ module.exports = function inspect_(obj, options, depth, seen) {
|
|
|
1464
1546
|
|
|
1465
1547
|
function inspect(value, from, noIndent) {
|
|
1466
1548
|
if (from) {
|
|
1467
|
-
seen =
|
|
1549
|
+
seen = $arrSlice.call(seen);
|
|
1468
1550
|
seen.push(from);
|
|
1469
1551
|
}
|
|
1470
1552
|
if (noIndent) {
|
|
@@ -1479,24 +1561,24 @@ module.exports = function inspect_(obj, options, depth, seen) {
|
|
|
1479
1561
|
return inspect_(value, opts, depth + 1, seen);
|
|
1480
1562
|
}
|
|
1481
1563
|
|
|
1482
|
-
if (typeof obj === 'function') {
|
|
1564
|
+
if (typeof obj === 'function' && !isRegExp(obj)) { // in older engines, regexes are callable
|
|
1483
1565
|
var name = nameOf(obj);
|
|
1484
1566
|
var keys = arrObjKeys(obj, inspect);
|
|
1485
|
-
return '[Function' + (name ? ': ' + name : ' (anonymous)') + ']' + (keys.length > 0 ? ' { ' +
|
|
1567
|
+
return '[Function' + (name ? ': ' + name : ' (anonymous)') + ']' + (keys.length > 0 ? ' { ' + $join.call(keys, ', ') + ' }' : '');
|
|
1486
1568
|
}
|
|
1487
1569
|
if (isSymbol(obj)) {
|
|
1488
|
-
var symString = symToString.call(obj);
|
|
1489
|
-
return typeof obj === 'object' ? markBoxed(symString) : symString;
|
|
1570
|
+
var symString = hasShammedSymbols ? $replace.call(String(obj), /^(Symbol\(.*\))_[^)]*$/, '$1') : symToString.call(obj);
|
|
1571
|
+
return typeof obj === 'object' && !hasShammedSymbols ? markBoxed(symString) : symString;
|
|
1490
1572
|
}
|
|
1491
1573
|
if (isElement(obj)) {
|
|
1492
|
-
var s = '<' + String(obj.nodeName)
|
|
1574
|
+
var s = '<' + $toLowerCase.call(String(obj.nodeName));
|
|
1493
1575
|
var attrs = obj.attributes || [];
|
|
1494
1576
|
for (var i = 0; i < attrs.length; i++) {
|
|
1495
1577
|
s += ' ' + attrs[i].name + '=' + wrapQuotes(quote(attrs[i].value), 'double', opts);
|
|
1496
1578
|
}
|
|
1497
1579
|
s += '>';
|
|
1498
1580
|
if (obj.childNodes && obj.childNodes.length) { s += '...'; }
|
|
1499
|
-
s += '</' + String(obj.nodeName)
|
|
1581
|
+
s += '</' + $toLowerCase.call(String(obj.nodeName)) + '>';
|
|
1500
1582
|
return s;
|
|
1501
1583
|
}
|
|
1502
1584
|
if (isArray(obj)) {
|
|
@@ -1505,17 +1587,20 @@ module.exports = function inspect_(obj, options, depth, seen) {
|
|
|
1505
1587
|
if (indent && !singleLineValues(xs)) {
|
|
1506
1588
|
return '[' + indentedJoin(xs, indent) + ']';
|
|
1507
1589
|
}
|
|
1508
|
-
return '[ ' +
|
|
1590
|
+
return '[ ' + $join.call(xs, ', ') + ' ]';
|
|
1509
1591
|
}
|
|
1510
1592
|
if (isError(obj)) {
|
|
1511
1593
|
var parts = arrObjKeys(obj, inspect);
|
|
1594
|
+
if (!('cause' in Error.prototype) && 'cause' in obj && !isEnumerable.call(obj, 'cause')) {
|
|
1595
|
+
return '{ [' + String(obj) + '] ' + $join.call($concat.call('[cause]: ' + inspect(obj.cause), parts), ', ') + ' }';
|
|
1596
|
+
}
|
|
1512
1597
|
if (parts.length === 0) { return '[' + String(obj) + ']'; }
|
|
1513
|
-
return '{ [' + String(obj) + '] ' +
|
|
1598
|
+
return '{ [' + String(obj) + '] ' + $join.call(parts, ', ') + ' }';
|
|
1514
1599
|
}
|
|
1515
1600
|
if (typeof obj === 'object' && customInspect) {
|
|
1516
|
-
if (inspectSymbol && typeof obj[inspectSymbol] === 'function') {
|
|
1517
|
-
return obj
|
|
1518
|
-
} else if (typeof obj.inspect === 'function') {
|
|
1601
|
+
if (inspectSymbol && typeof obj[inspectSymbol] === 'function' && utilInspect) {
|
|
1602
|
+
return utilInspect(obj, { depth: maxDepth - depth });
|
|
1603
|
+
} else if (customInspect !== 'symbol' && typeof obj.inspect === 'function') {
|
|
1519
1604
|
return obj.inspect();
|
|
1520
1605
|
}
|
|
1521
1606
|
}
|
|
@@ -1539,6 +1624,9 @@ module.exports = function inspect_(obj, options, depth, seen) {
|
|
|
1539
1624
|
if (isWeakSet(obj)) {
|
|
1540
1625
|
return weakCollectionOf('WeakSet');
|
|
1541
1626
|
}
|
|
1627
|
+
if (isWeakRef(obj)) {
|
|
1628
|
+
return weakCollectionOf('WeakRef');
|
|
1629
|
+
}
|
|
1542
1630
|
if (isNumber(obj)) {
|
|
1543
1631
|
return markBoxed(inspect(Number(obj)));
|
|
1544
1632
|
}
|
|
@@ -1553,11 +1641,16 @@ module.exports = function inspect_(obj, options, depth, seen) {
|
|
|
1553
1641
|
}
|
|
1554
1642
|
if (!isDate(obj) && !isRegExp(obj)) {
|
|
1555
1643
|
var ys = arrObjKeys(obj, inspect);
|
|
1556
|
-
|
|
1644
|
+
var isPlainObject = gPO ? gPO(obj) === Object.prototype : obj instanceof Object || obj.constructor === Object;
|
|
1645
|
+
var protoTag = obj instanceof Object ? '' : 'null prototype';
|
|
1646
|
+
var stringTag = !isPlainObject && toStringTag && Object(obj) === obj && toStringTag in obj ? $slice.call(toStr(obj), 8, -1) : protoTag ? 'Object' : '';
|
|
1647
|
+
var constructorTag = isPlainObject || typeof obj.constructor !== 'function' ? '' : obj.constructor.name ? obj.constructor.name + ' ' : '';
|
|
1648
|
+
var tag = constructorTag + (stringTag || protoTag ? '[' + $join.call($concat.call([], stringTag || [], protoTag || []), ': ') + '] ' : '');
|
|
1649
|
+
if (ys.length === 0) { return tag + '{}'; }
|
|
1557
1650
|
if (indent) {
|
|
1558
|
-
return '{' + indentedJoin(ys, indent) + '}';
|
|
1651
|
+
return tag + '{' + indentedJoin(ys, indent) + '}';
|
|
1559
1652
|
}
|
|
1560
|
-
return '{ ' +
|
|
1653
|
+
return tag + '{ ' + $join.call(ys, ', ') + ' }';
|
|
1561
1654
|
}
|
|
1562
1655
|
return String(obj);
|
|
1563
1656
|
};
|
|
@@ -1568,18 +1661,45 @@ function wrapQuotes(s, defaultStyle, opts) {
|
|
|
1568
1661
|
}
|
|
1569
1662
|
|
|
1570
1663
|
function quote(s) {
|
|
1571
|
-
return String(s)
|
|
1664
|
+
return $replace.call(String(s), /"/g, '"');
|
|
1665
|
+
}
|
|
1666
|
+
|
|
1667
|
+
function isArray(obj) { return toStr(obj) === '[object Array]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }
|
|
1668
|
+
function isDate(obj) { return toStr(obj) === '[object Date]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }
|
|
1669
|
+
function isRegExp(obj) { return toStr(obj) === '[object RegExp]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }
|
|
1670
|
+
function isError(obj) { return toStr(obj) === '[object Error]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }
|
|
1671
|
+
function isString(obj) { return toStr(obj) === '[object String]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }
|
|
1672
|
+
function isNumber(obj) { return toStr(obj) === '[object Number]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }
|
|
1673
|
+
function isBoolean(obj) { return toStr(obj) === '[object Boolean]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }
|
|
1674
|
+
|
|
1675
|
+
// Symbol and BigInt do have Symbol.toStringTag by spec, so that can't be used to eliminate false positives
|
|
1676
|
+
function isSymbol(obj) {
|
|
1677
|
+
if (hasShammedSymbols) {
|
|
1678
|
+
return obj && typeof obj === 'object' && obj instanceof Symbol;
|
|
1679
|
+
}
|
|
1680
|
+
if (typeof obj === 'symbol') {
|
|
1681
|
+
return true;
|
|
1682
|
+
}
|
|
1683
|
+
if (!obj || typeof obj !== 'object' || !symToString) {
|
|
1684
|
+
return false;
|
|
1685
|
+
}
|
|
1686
|
+
try {
|
|
1687
|
+
symToString.call(obj);
|
|
1688
|
+
return true;
|
|
1689
|
+
} catch (e) {}
|
|
1690
|
+
return false;
|
|
1572
1691
|
}
|
|
1573
1692
|
|
|
1574
|
-
function
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1693
|
+
function isBigInt(obj) {
|
|
1694
|
+
if (!obj || typeof obj !== 'object' || !bigIntValueOf) {
|
|
1695
|
+
return false;
|
|
1696
|
+
}
|
|
1697
|
+
try {
|
|
1698
|
+
bigIntValueOf.call(obj);
|
|
1699
|
+
return true;
|
|
1700
|
+
} catch (e) {}
|
|
1701
|
+
return false;
|
|
1702
|
+
}
|
|
1583
1703
|
|
|
1584
1704
|
var hasOwn = Object.prototype.hasOwnProperty || function (key) { return key in this; };
|
|
1585
1705
|
function has(obj, key) {
|
|
@@ -1592,7 +1712,7 @@ function toStr(obj) {
|
|
|
1592
1712
|
|
|
1593
1713
|
function nameOf(f) {
|
|
1594
1714
|
if (f.name) { return f.name; }
|
|
1595
|
-
var m = match.call(functionToString.call(f), /^function\s*([\w$]+)/);
|
|
1715
|
+
var m = $match.call(functionToString.call(f), /^function\s*([\w$]+)/);
|
|
1596
1716
|
if (m) { return m[1]; }
|
|
1597
1717
|
return null;
|
|
1598
1718
|
}
|
|
@@ -1637,6 +1757,17 @@ function isWeakMap(x) {
|
|
|
1637
1757
|
return false;
|
|
1638
1758
|
}
|
|
1639
1759
|
|
|
1760
|
+
function isWeakRef(x) {
|
|
1761
|
+
if (!weakRefDeref || !x || typeof x !== 'object') {
|
|
1762
|
+
return false;
|
|
1763
|
+
}
|
|
1764
|
+
try {
|
|
1765
|
+
weakRefDeref.call(x);
|
|
1766
|
+
return true;
|
|
1767
|
+
} catch (e) {}
|
|
1768
|
+
return false;
|
|
1769
|
+
}
|
|
1770
|
+
|
|
1640
1771
|
function isSet(x) {
|
|
1641
1772
|
if (!setSize || !x || typeof x !== 'object') {
|
|
1642
1773
|
return false;
|
|
@@ -1681,10 +1812,10 @@ function inspectString(str, opts) {
|
|
|
1681
1812
|
if (str.length > opts.maxStringLength) {
|
|
1682
1813
|
var remaining = str.length - opts.maxStringLength;
|
|
1683
1814
|
var trailer = '... ' + remaining + ' more character' + (remaining > 1 ? 's' : '');
|
|
1684
|
-
return inspectString(
|
|
1815
|
+
return inspectString($slice.call(str, 0, opts.maxStringLength), opts) + trailer;
|
|
1685
1816
|
}
|
|
1686
1817
|
// eslint-disable-next-line no-control-regex
|
|
1687
|
-
var s =
|
|
1818
|
+
var s = $replace.call($replace.call(str, /(['\\])/g, '\\$1'), /[\x00-\x1f]/g, lowbyte);
|
|
1688
1819
|
return wrapQuotes(s, 'single', opts);
|
|
1689
1820
|
}
|
|
1690
1821
|
|
|
@@ -1698,7 +1829,7 @@ function lowbyte(c) {
|
|
|
1698
1829
|
13: 'r'
|
|
1699
1830
|
}[n];
|
|
1700
1831
|
if (x) { return '\\' + x; }
|
|
1701
|
-
return '\\x' + (n < 0x10 ? '0' : '') + n.toString(16)
|
|
1832
|
+
return '\\x' + (n < 0x10 ? '0' : '') + $toUpperCase.call(n.toString(16));
|
|
1702
1833
|
}
|
|
1703
1834
|
|
|
1704
1835
|
function markBoxed(str) {
|
|
@@ -1710,7 +1841,7 @@ function weakCollectionOf(type) {
|
|
|
1710
1841
|
}
|
|
1711
1842
|
|
|
1712
1843
|
function collectionOf(type, size, entries, indent) {
|
|
1713
|
-
var joinedEntries = indent ? indentedJoin(entries, indent) :
|
|
1844
|
+
var joinedEntries = indent ? indentedJoin(entries, indent) : $join.call(entries, ', ');
|
|
1714
1845
|
return type + ' (' + size + ') {' + joinedEntries + '}';
|
|
1715
1846
|
}
|
|
1716
1847
|
|
|
@@ -1728,20 +1859,20 @@ function getIndent(opts, depth) {
|
|
|
1728
1859
|
if (opts.indent === '\t') {
|
|
1729
1860
|
baseIndent = '\t';
|
|
1730
1861
|
} else if (typeof opts.indent === 'number' && opts.indent > 0) {
|
|
1731
|
-
baseIndent = Array(opts.indent + 1)
|
|
1862
|
+
baseIndent = $join.call(Array(opts.indent + 1), ' ');
|
|
1732
1863
|
} else {
|
|
1733
1864
|
return null;
|
|
1734
1865
|
}
|
|
1735
1866
|
return {
|
|
1736
1867
|
base: baseIndent,
|
|
1737
|
-
prev: Array(depth + 1)
|
|
1868
|
+
prev: $join.call(Array(depth + 1), baseIndent)
|
|
1738
1869
|
};
|
|
1739
1870
|
}
|
|
1740
1871
|
|
|
1741
1872
|
function indentedJoin(xs, indent) {
|
|
1742
1873
|
if (xs.length === 0) { return ''; }
|
|
1743
1874
|
var lineJoiner = '\n' + indent.prev + indent.base;
|
|
1744
|
-
return lineJoiner +
|
|
1875
|
+
return lineJoiner + $join.call(xs, ',' + lineJoiner) + '\n' + indent.prev;
|
|
1745
1876
|
}
|
|
1746
1877
|
|
|
1747
1878
|
function arrObjKeys(obj, inspect) {
|
|
@@ -1753,17 +1884,28 @@ function arrObjKeys(obj, inspect) {
|
|
|
1753
1884
|
xs[i] = has(obj, i) ? inspect(obj[i], obj) : '';
|
|
1754
1885
|
}
|
|
1755
1886
|
}
|
|
1887
|
+
var syms = typeof gOPS === 'function' ? gOPS(obj) : [];
|
|
1888
|
+
var symMap;
|
|
1889
|
+
if (hasShammedSymbols) {
|
|
1890
|
+
symMap = {};
|
|
1891
|
+
for (var k = 0; k < syms.length; k++) {
|
|
1892
|
+
symMap['$' + syms[k]] = syms[k];
|
|
1893
|
+
}
|
|
1894
|
+
}
|
|
1895
|
+
|
|
1756
1896
|
for (var key in obj) { // eslint-disable-line no-restricted-syntax
|
|
1757
1897
|
if (!has(obj, key)) { continue; } // eslint-disable-line no-restricted-syntax, no-continue
|
|
1758
1898
|
if (isArr && String(Number(key)) === key && key < obj.length) { continue; } // eslint-disable-line no-restricted-syntax, no-continue
|
|
1759
|
-
if (
|
|
1899
|
+
if (hasShammedSymbols && symMap['$' + key] instanceof Symbol) {
|
|
1900
|
+
// this is to prevent shammed Symbols, which are stored as strings, from being included in the string key section
|
|
1901
|
+
continue; // eslint-disable-line no-restricted-syntax, no-continue
|
|
1902
|
+
} else if ($test.call(/[^\w$]/, key)) {
|
|
1760
1903
|
xs.push(inspect(key, obj) + ': ' + inspect(obj[key], obj));
|
|
1761
1904
|
} else {
|
|
1762
1905
|
xs.push(key + ': ' + inspect(obj[key], obj));
|
|
1763
1906
|
}
|
|
1764
1907
|
}
|
|
1765
1908
|
if (typeof gOPS === 'function') {
|
|
1766
|
-
var syms = gOPS(obj);
|
|
1767
1909
|
for (var j = 0; j < syms.length; j++) {
|
|
1768
1910
|
if (isEnumerable.call(obj, syms[j])) {
|
|
1769
1911
|
xs.push('[' + inspect(syms[j]) + ']: ' + inspect(obj[syms[j]], obj));
|
package/lib/parse.js
CHANGED
package/lib/stringify.js
CHANGED
|
@@ -19,6 +19,7 @@ var arrayPrefixGenerators = {
|
|
|
19
19
|
};
|
|
20
20
|
|
|
21
21
|
var isArray = Array.isArray;
|
|
22
|
+
var split = String.prototype.split;
|
|
22
23
|
var push = Array.prototype.push;
|
|
23
24
|
var pushToArray = function (arr, valueOrArray) {
|
|
24
25
|
push.apply(arr, isArray(valueOrArray) ? valueOrArray : [valueOrArray]);
|
|
@@ -55,6 +56,8 @@ var isNonNullishPrimitive = function isNonNullishPrimitive(v) {
|
|
|
55
56
|
|| typeof v === 'bigint';
|
|
56
57
|
};
|
|
57
58
|
|
|
59
|
+
var sentinel = {};
|
|
60
|
+
|
|
58
61
|
var stringify = function stringify(
|
|
59
62
|
object,
|
|
60
63
|
prefix,
|
|
@@ -74,8 +77,23 @@ var stringify = function stringify(
|
|
|
74
77
|
) {
|
|
75
78
|
var obj = object;
|
|
76
79
|
|
|
77
|
-
|
|
78
|
-
|
|
80
|
+
var tmpSc = sideChannel;
|
|
81
|
+
var step = 0;
|
|
82
|
+
var findFlag = false;
|
|
83
|
+
while ((tmpSc = tmpSc.get(sentinel)) !== void undefined && !findFlag) {
|
|
84
|
+
// Where object last appeared in the ref tree
|
|
85
|
+
var pos = tmpSc.get(object);
|
|
86
|
+
step += 1;
|
|
87
|
+
if (typeof pos !== 'undefined') {
|
|
88
|
+
if (pos === step) {
|
|
89
|
+
throw new RangeError('Cyclic object value');
|
|
90
|
+
} else {
|
|
91
|
+
findFlag = true; // Break while
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
if (typeof tmpSc.get(sentinel) === 'undefined') {
|
|
95
|
+
step = 0;
|
|
96
|
+
}
|
|
79
97
|
}
|
|
80
98
|
|
|
81
99
|
if (typeof filter === 'function') {
|
|
@@ -102,6 +120,14 @@ var stringify = function stringify(
|
|
|
102
120
|
if (isNonNullishPrimitive(obj) || utils.isBuffer(obj)) {
|
|
103
121
|
if (encoder) {
|
|
104
122
|
var keyValue = encodeValuesOnly ? prefix : encoder(prefix, defaults.encoder, charset, 'key', format);
|
|
123
|
+
if (generateArrayPrefix === 'comma' && encodeValuesOnly) {
|
|
124
|
+
var valuesArray = split.call(String(obj), ',');
|
|
125
|
+
var valuesJoined = '';
|
|
126
|
+
for (var i = 0; i < valuesArray.length; ++i) {
|
|
127
|
+
valuesJoined += (i === 0 ? '' : ',') + formatter(encoder(valuesArray[i], defaults.encoder, charset, 'value', format));
|
|
128
|
+
}
|
|
129
|
+
return [formatter(keyValue) + (i === 1 ? '[]' : '') + '=' + valuesJoined];
|
|
130
|
+
}
|
|
105
131
|
return [formatter(keyValue) + '=' + formatter(encoder(obj, defaults.encoder, charset, 'value', format))];
|
|
106
132
|
}
|
|
107
133
|
return [formatter(prefix) + '=' + formatter(String(obj))];
|
|
@@ -116,7 +142,7 @@ var stringify = function stringify(
|
|
|
116
142
|
var objKeys;
|
|
117
143
|
if (generateArrayPrefix === 'comma' && isArray(obj)) {
|
|
118
144
|
// we need to join elements in
|
|
119
|
-
objKeys = [{ value: obj.length > 0 ? obj.join(',') || null : undefined }];
|
|
145
|
+
objKeys = [{ value: obj.length > 0 ? obj.join(',') || null : void undefined }];
|
|
120
146
|
} else if (isArray(filter)) {
|
|
121
147
|
objKeys = filter;
|
|
122
148
|
} else {
|
|
@@ -124,9 +150,9 @@ var stringify = function stringify(
|
|
|
124
150
|
objKeys = sort ? keys.sort(sort) : keys;
|
|
125
151
|
}
|
|
126
152
|
|
|
127
|
-
for (var
|
|
128
|
-
var key = objKeys[
|
|
129
|
-
var value = typeof key === 'object' && key.value !== undefined ? key.value : obj[key];
|
|
153
|
+
for (var j = 0; j < objKeys.length; ++j) {
|
|
154
|
+
var key = objKeys[j];
|
|
155
|
+
var value = typeof key === 'object' && typeof key.value !== 'undefined' ? key.value : obj[key];
|
|
130
156
|
|
|
131
157
|
if (skipNulls && value === null) {
|
|
132
158
|
continue;
|
|
@@ -136,8 +162,9 @@ var stringify = function stringify(
|
|
|
136
162
|
? typeof generateArrayPrefix === 'function' ? generateArrayPrefix(prefix, key) : prefix
|
|
137
163
|
: prefix + (allowDots ? '.' + key : '[' + key + ']');
|
|
138
164
|
|
|
139
|
-
sideChannel.set(object,
|
|
165
|
+
sideChannel.set(object, step);
|
|
140
166
|
var valueSideChannel = getSideChannel();
|
|
167
|
+
valueSideChannel.set(sentinel, sideChannel);
|
|
141
168
|
pushToArray(values, stringify(
|
|
142
169
|
value,
|
|
143
170
|
keyPrefix,
|
|
@@ -165,7 +192,7 @@ var normalizeStringifyOptions = function normalizeStringifyOptions(opts) {
|
|
|
165
192
|
return defaults;
|
|
166
193
|
}
|
|
167
194
|
|
|
168
|
-
if (opts.encoder !== null && opts.encoder !== undefined && typeof opts.encoder !== 'function') {
|
|
195
|
+
if (opts.encoder !== null && typeof opts.encoder !== 'undefined' && typeof opts.encoder !== 'function') {
|
|
169
196
|
throw new TypeError('Encoder has to be a function.');
|
|
170
197
|
}
|
|
171
198
|
|
package/lib/utils.js
CHANGED
|
@@ -177,6 +177,7 @@ var encode = function encode(str, defaultEncoder, charset, kind, format) {
|
|
|
177
177
|
|
|
178
178
|
i += 1;
|
|
179
179
|
c = 0x10000 + (((c & 0x3FF) << 10) | (string.charCodeAt(i) & 0x3FF));
|
|
180
|
+
/* eslint operator-linebreak: [2, "before"] */
|
|
180
181
|
out += hexTable[0xF0 | (c >> 18)]
|
|
181
182
|
+ hexTable[0x80 | ((c >> 12) & 0x3F)]
|
|
182
183
|
+ hexTable[0x80 | ((c >> 6) & 0x3F)]
|
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.
|
|
5
|
+
"version": "6.10.4",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
8
8
|
"url": "https://github.com/ljharb/qs.git"
|
|
@@ -33,40 +33,45 @@
|
|
|
33
33
|
"side-channel": "^1.0.4"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
|
-
"@ljharb/eslint-config": "^
|
|
37
|
-
"aud": "^
|
|
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": "
|
|
40
|
+
"eslint": "=8.8.0",
|
|
41
41
|
"evalmd": "^0.0.19",
|
|
42
42
|
"for-each": "^0.3.3",
|
|
43
|
-
"has-symbols": "^1.0.
|
|
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.
|
|
49
|
+
"object-inspect": "^1.12.2",
|
|
49
50
|
"qs-iconv": "^1.0.4",
|
|
50
|
-
"safe-publish-latest": "^
|
|
51
|
+
"safe-publish-latest": "^2.0.0",
|
|
51
52
|
"safer-buffer": "^2.1.2",
|
|
52
|
-
"tape": "^5.
|
|
53
|
+
"tape": "^5.5.3"
|
|
53
54
|
},
|
|
54
55
|
"scripts": {
|
|
55
|
-
"
|
|
56
|
+
"prepack": "npmignore --auto --commentLines=autogenerated",
|
|
57
|
+
"prepublishOnly": "safe-publish-latest && npm run dist",
|
|
58
|
+
"prepublish": "not-in-publish || npm run prepublishOnly",
|
|
56
59
|
"pretest": "npm run --silent readme && npm run --silent lint",
|
|
57
60
|
"test": "npm run tests-only",
|
|
58
61
|
"tests-only": "nyc tape 'test/**/*.js'",
|
|
59
62
|
"posttest": "aud --production",
|
|
60
63
|
"readme": "evalmd README.md",
|
|
61
|
-
"postlint": "eclint check
|
|
62
|
-
"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 .",
|
|
63
66
|
"dist": "mkdirp dist && browserify --standalone Qs lib/index.js > dist/qs.js"
|
|
64
67
|
},
|
|
65
68
|
"license": "BSD-3-Clause",
|
|
66
|
-
"
|
|
69
|
+
"publishConfig": {
|
|
67
70
|
"ignore": [
|
|
68
|
-
"
|
|
69
|
-
"
|
|
71
|
+
"!dist/*",
|
|
72
|
+
"bower.json",
|
|
73
|
+
"component.json",
|
|
74
|
+
".github/workflows"
|
|
70
75
|
]
|
|
71
76
|
}
|
|
72
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,11 +131,25 @@ 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.equal(qs.stringify({ a: ['c'] }, { encodeValuesOnly: true, arrayFormat: 'indices' }), 'a[0]=c');
|
|
136
|
+
st.equal(qs.stringify({ a: ['c'] }, { encodeValuesOnly: true, arrayFormat: 'brackets' }), 'a[]=c');
|
|
137
|
+
st.equal(qs.stringify({ a: ['c'] }, { encodeValuesOnly: true, arrayFormat: 'comma' }), 'a[]=c'); // so it parses back as an array
|
|
138
|
+
st.equal(qs.stringify({ a: ['c'] }, { encodeValuesOnly: true }), 'a[0]=c');
|
|
139
|
+
|
|
140
|
+
st.equal(qs.stringify({ a: ['c', 'd'] }, { encodeValuesOnly: true, arrayFormat: 'indices' }), 'a[0]=c&a[1]=d');
|
|
141
|
+
st.equal(qs.stringify({ a: ['c', 'd'] }, { encodeValuesOnly: true, arrayFormat: 'brackets' }), 'a[]=c&a[]=d');
|
|
142
|
+
st.equal(qs.stringify({ a: ['c', 'd'] }, { encodeValuesOnly: true, arrayFormat: 'comma' }), 'a=c,d');
|
|
143
|
+
st.equal(qs.stringify({ a: ['c', 'd'] }, { encodeValuesOnly: true }), 'a[0]=c&a[1]=d');
|
|
144
|
+
|
|
145
|
+
st.end();
|
|
146
|
+
});
|
|
147
|
+
|
|
134
148
|
t.test('stringifies a nested array value', function (st) {
|
|
135
|
-
st.equal(qs.stringify({ a: { b: ['c', 'd'] } }, { arrayFormat: 'indices' }), 'a
|
|
136
|
-
st.equal(qs.stringify({ a: { b: ['c', 'd'] } }, { arrayFormat: 'brackets' }), 'a
|
|
137
|
-
st.equal(qs.stringify({ a: { b: ['c', 'd'] } }, { arrayFormat: 'comma' }), 'a
|
|
138
|
-
st.equal(qs.stringify({ a: { b: ['c', 'd'] } }), 'a
|
|
149
|
+
st.equal(qs.stringify({ a: { b: ['c', 'd'] } }, { encodeValuesOnly: true, arrayFormat: 'indices' }), 'a[b][0]=c&a[b][1]=d');
|
|
150
|
+
st.equal(qs.stringify({ a: { b: ['c', 'd'] } }, { encodeValuesOnly: true, arrayFormat: 'brackets' }), 'a[b][]=c&a[b][]=d');
|
|
151
|
+
st.equal(qs.stringify({ a: { b: ['c', 'd'] } }, { encodeValuesOnly: true, arrayFormat: 'comma' }), 'a[b]=c,d');
|
|
152
|
+
st.equal(qs.stringify({ a: { b: ['c', 'd'] } }, { encodeValuesOnly: true }), 'a[b][0]=c&a[b][1]=d');
|
|
139
153
|
st.end();
|
|
140
154
|
});
|
|
141
155
|
|
|
@@ -143,7 +157,7 @@ test('stringify()', function (t) {
|
|
|
143
157
|
st.equal(
|
|
144
158
|
qs.stringify(
|
|
145
159
|
{ a: { b: ['c', 'd'] } },
|
|
146
|
-
{ allowDots: true,
|
|
160
|
+
{ allowDots: true, encodeValuesOnly: true, arrayFormat: 'indices' }
|
|
147
161
|
),
|
|
148
162
|
'a.b[0]=c&a.b[1]=d',
|
|
149
163
|
'indices: stringifies with dots + indices'
|
|
@@ -151,7 +165,7 @@ test('stringify()', function (t) {
|
|
|
151
165
|
st.equal(
|
|
152
166
|
qs.stringify(
|
|
153
167
|
{ a: { b: ['c', 'd'] } },
|
|
154
|
-
{ allowDots: true,
|
|
168
|
+
{ allowDots: true, encodeValuesOnly: true, arrayFormat: 'brackets' }
|
|
155
169
|
),
|
|
156
170
|
'a.b[]=c&a.b[]=d',
|
|
157
171
|
'brackets: stringifies with dots + brackets'
|
|
@@ -159,7 +173,7 @@ test('stringify()', function (t) {
|
|
|
159
173
|
st.equal(
|
|
160
174
|
qs.stringify(
|
|
161
175
|
{ a: { b: ['c', 'd'] } },
|
|
162
|
-
{ allowDots: true,
|
|
176
|
+
{ allowDots: true, encodeValuesOnly: true, arrayFormat: 'comma' }
|
|
163
177
|
),
|
|
164
178
|
'a.b=c,d',
|
|
165
179
|
'comma: stringifies with dots + comma'
|
|
@@ -167,7 +181,7 @@ test('stringify()', function (t) {
|
|
|
167
181
|
st.equal(
|
|
168
182
|
qs.stringify(
|
|
169
183
|
{ a: { b: ['c', 'd'] } },
|
|
170
|
-
{ allowDots: true,
|
|
184
|
+
{ allowDots: true, encodeValuesOnly: true }
|
|
171
185
|
),
|
|
172
186
|
'a.b[0]=c&a.b[1]=d',
|
|
173
187
|
'default: stringifies with dots + indices'
|
|
@@ -215,17 +229,23 @@ test('stringify()', function (t) {
|
|
|
215
229
|
|
|
216
230
|
t.test('stringifies an array with mixed objects and primitives', function (st) {
|
|
217
231
|
st.equal(
|
|
218
|
-
qs.stringify({ a: [{ b: 1 }, 2, 3] }, {
|
|
232
|
+
qs.stringify({ a: [{ b: 1 }, 2, 3] }, { encodeValuesOnly: true, arrayFormat: 'indices' }),
|
|
219
233
|
'a[0][b]=1&a[1]=2&a[2]=3',
|
|
220
234
|
'indices => indices'
|
|
221
235
|
);
|
|
222
236
|
st.equal(
|
|
223
|
-
qs.stringify({ a: [{ b: 1 }, 2, 3] }, {
|
|
237
|
+
qs.stringify({ a: [{ b: 1 }, 2, 3] }, { encodeValuesOnly: true, arrayFormat: 'brackets' }),
|
|
224
238
|
'a[][b]=1&a[]=2&a[]=3',
|
|
225
239
|
'brackets => brackets'
|
|
226
240
|
);
|
|
227
241
|
st.equal(
|
|
228
|
-
qs.stringify({ a: [{ b: 1 }, 2, 3] }, {
|
|
242
|
+
qs.stringify({ a: [{ b: 1 }, 2, 3] }, { encodeValuesOnly: true, arrayFormat: 'comma' }),
|
|
243
|
+
'???',
|
|
244
|
+
'brackets => brackets',
|
|
245
|
+
{ skip: 'TODO: figure out what this should do' }
|
|
246
|
+
);
|
|
247
|
+
st.equal(
|
|
248
|
+
qs.stringify({ a: [{ b: 1 }, 2, 3] }, { encodeValuesOnly: true }),
|
|
229
249
|
'a[0][b]=1&a[1]=2&a[2]=3',
|
|
230
250
|
'default => indices'
|
|
231
251
|
);
|
|
@@ -448,7 +468,7 @@ test('stringify()', function (t) {
|
|
|
448
468
|
|
|
449
469
|
st['throws'](
|
|
450
470
|
function () { qs.stringify({ 'foo[bar]': 'baz', 'foo[baz]': a }); },
|
|
451
|
-
RangeError
|
|
471
|
+
/RangeError: Cyclic object value/,
|
|
452
472
|
'cyclic values throw'
|
|
453
473
|
);
|
|
454
474
|
|
|
@@ -458,10 +478,16 @@ test('stringify()', function (t) {
|
|
|
458
478
|
circular.a = circular;
|
|
459
479
|
st['throws'](
|
|
460
480
|
function () { qs.stringify(circular); },
|
|
461
|
-
RangeError
|
|
481
|
+
/RangeError: Cyclic object value/,
|
|
462
482
|
'cyclic values throw'
|
|
463
483
|
);
|
|
464
484
|
|
|
485
|
+
var arr = ['a'];
|
|
486
|
+
st.doesNotThrow(
|
|
487
|
+
function () { qs.stringify({ x: arr, y: arr }); },
|
|
488
|
+
'non-cyclic values do not throw'
|
|
489
|
+
);
|
|
490
|
+
|
|
465
491
|
st.end();
|
|
466
492
|
});
|
|
467
493
|
|
|
@@ -702,16 +728,14 @@ test('stringify()', function (t) {
|
|
|
702
728
|
});
|
|
703
729
|
|
|
704
730
|
t.test('Edge cases and unknown formats', function (st) {
|
|
705
|
-
['UFO1234', false, 1234, null, {}, []].forEach(
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
}
|
|
714
|
-
);
|
|
731
|
+
['UFO1234', false, 1234, null, {}, []].forEach(function (format) {
|
|
732
|
+
st['throws'](
|
|
733
|
+
function () {
|
|
734
|
+
qs.stringify({ a: 'b c' }, { format: format });
|
|
735
|
+
},
|
|
736
|
+
new TypeError('Unknown format option provided.')
|
|
737
|
+
);
|
|
738
|
+
});
|
|
715
739
|
st.end();
|
|
716
740
|
});
|
|
717
741
|
|
|
@@ -829,7 +853,12 @@ test('stringify()', function (t) {
|
|
|
829
853
|
st.equal(qs.stringify(withArray, { encode: false }), 'a[b][0][c]=d&a[b][0][e]=f', 'array, no arrayFormat');
|
|
830
854
|
st.equal(qs.stringify(withArray, { encode: false, arrayFormat: 'bracket' }), 'a[b][0][c]=d&a[b][0][e]=f', 'array, bracket');
|
|
831
855
|
st.equal(qs.stringify(withArray, { encode: false, arrayFormat: 'indices' }), 'a[b][0][c]=d&a[b][0][e]=f', 'array, indices');
|
|
832
|
-
st.equal(
|
|
856
|
+
st.equal(
|
|
857
|
+
qs.stringify(withArray, { encode: false, arrayFormat: 'comma' }),
|
|
858
|
+
'???',
|
|
859
|
+
'array, comma',
|
|
860
|
+
{ skip: 'TODO: figure out what this should do' }
|
|
861
|
+
);
|
|
833
862
|
|
|
834
863
|
st.end();
|
|
835
864
|
});
|
package/.eslintignore
DELETED