qs 6.5.3 → 6.5.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/README.md +9 -3
- package/dist/qs.js +10 -10
- package/lib/parse.js +4 -4
- package/lib/utils.js +6 -6
- package/package.json +13 -4
- package/test/parse.js +9 -0
- package/test/stringify.js +6 -0
- package/bower.json +0 -21
- package/component.json +0 -15
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
## **6.5.5**
|
|
2
|
+
- [Fix] fix regressions from robustness refactor
|
|
3
|
+
- [meta] add `npmignore` to autogenerate an npmignore file
|
|
4
|
+
- [actions] update reusable workflows
|
|
5
|
+
|
|
6
|
+
## **6.5.4**
|
|
7
|
+
- [Robustness] avoid `.push`, use `void`
|
|
8
|
+
- [readme] clarify `parseArrays` and `arrayLimit` documentation (#543)
|
|
9
|
+
- [readme] document that `addQueryPrefix` does not add `?` to empty output (#418)
|
|
10
|
+
- [readme] replace runkit CI badge with shields.io check-runs badge
|
|
11
|
+
- [actions] fix rebase workflow permissions
|
|
12
|
+
|
|
1
13
|
## **6.5.3**
|
|
2
14
|
- [Fix] `parse`: ignore `__proto__` keys (#428)
|
|
3
15
|
- [Fix]` `utils.merge`: avoid a crash with a null target and a truthy non-array source
|
package/README.md
CHANGED
|
@@ -182,7 +182,7 @@ var withIndexedEmptyString = qs.parse('a[0]=b&a[1]=&a[2]=c');
|
|
|
182
182
|
assert.deepEqual(withIndexedEmptyString, { a: ['b', '', 'c'] });
|
|
183
183
|
```
|
|
184
184
|
|
|
185
|
-
**qs** will also limit
|
|
185
|
+
**qs** will also limit arrays to a maximum of `20` elements. Any array members with an index of `20` or greater will
|
|
186
186
|
instead be converted to an object with the index as the key. This is needed to handle cases when someone sent, for example, `a[999999999]` and it will take significant time to iterate over this huge array.
|
|
187
187
|
|
|
188
188
|
```javascript
|
|
@@ -197,7 +197,7 @@ var withArrayLimit = qs.parse('a[1]=b', { arrayLimit: 0 });
|
|
|
197
197
|
assert.deepEqual(withArrayLimit, { a: { '1': 'b' } });
|
|
198
198
|
```
|
|
199
199
|
|
|
200
|
-
To
|
|
200
|
+
To prevent array syntax (`a[]`, `a[0]`) from being parsed as arrays, set `parseArrays` to `false`.
|
|
201
201
|
|
|
202
202
|
```javascript
|
|
203
203
|
var noParsingArrays = qs.parse('a[]=b', { parseArrays: false });
|
|
@@ -361,6 +361,12 @@ The query string may optionally be prepended with a question mark:
|
|
|
361
361
|
assert.equal(qs.stringify({ a: 'b', c: 'd' }, { addQueryPrefix: true }), '?a=b&c=d');
|
|
362
362
|
```
|
|
363
363
|
|
|
364
|
+
Note that when the output is an empty string, the prefix will not be added:
|
|
365
|
+
|
|
366
|
+
```javascript
|
|
367
|
+
assert.equal(qs.stringify({}, { addQueryPrefix: true }), '');
|
|
368
|
+
```
|
|
369
|
+
|
|
364
370
|
The delimiter may be overridden with stringify as well:
|
|
365
371
|
|
|
366
372
|
```javascript
|
|
@@ -506,5 +512,5 @@ The maintainers of qs and thousands of other packages are working with Tidelift
|
|
|
506
512
|
[downloads-url]: https://npm-stat.com/charts.html?package=qs
|
|
507
513
|
[codecov-image]: https://codecov.io/gh/ljharb/qs/branch/main/graphs/badge.svg
|
|
508
514
|
[codecov-url]: https://app.codecov.io/gh/ljharb/qs/
|
|
509
|
-
[actions-image]: https://img.shields.io/
|
|
515
|
+
[actions-image]: https://img.shields.io/github/check-runs/ljharb/qs/main
|
|
510
516
|
[actions-url]: https://github.com/ljharb/qs/actions
|
package/dist/qs.js
CHANGED
|
@@ -53,7 +53,7 @@ var defaults = {
|
|
|
53
53
|
var parseValues = function parseQueryStringValues(str, options) {
|
|
54
54
|
var obj = {};
|
|
55
55
|
var cleanStr = options.ignoreQueryPrefix ? str.replace(/^\?/, '') : str;
|
|
56
|
-
var limit = options.parameterLimit === Infinity ? undefined : options.parameterLimit;
|
|
56
|
+
var limit = options.parameterLimit === Infinity ? void undefined : options.parameterLimit;
|
|
57
57
|
var parts = cleanStr.split(options.delimiter, limit);
|
|
58
58
|
|
|
59
59
|
for (var i = 0; i < parts.length; ++i) {
|
|
@@ -145,7 +145,7 @@ var parseKeys = function parseQueryStringKeys(givenKey, val, options) {
|
|
|
145
145
|
}
|
|
146
146
|
}
|
|
147
147
|
|
|
148
|
-
keys.
|
|
148
|
+
keys[keys.length] = parent;
|
|
149
149
|
}
|
|
150
150
|
|
|
151
151
|
// Loop through children appending to the array until we hit depth
|
|
@@ -158,13 +158,13 @@ var parseKeys = function parseQueryStringKeys(givenKey, val, options) {
|
|
|
158
158
|
return;
|
|
159
159
|
}
|
|
160
160
|
}
|
|
161
|
-
keys.
|
|
161
|
+
keys[keys.length] = segment[1];
|
|
162
162
|
}
|
|
163
163
|
|
|
164
164
|
// If there's a remainder, just add whatever is left
|
|
165
165
|
|
|
166
166
|
if (segment) {
|
|
167
|
-
keys.
|
|
167
|
+
keys[keys.length] = '[' + key.slice(segment.index) + ']';
|
|
168
168
|
}
|
|
169
169
|
|
|
170
170
|
return parseObject(keys, val, options);
|
|
@@ -435,7 +435,7 @@ var has = Object.prototype.hasOwnProperty;
|
|
|
435
435
|
var hexTable = (function () {
|
|
436
436
|
var array = [];
|
|
437
437
|
for (var i = 0; i < 256; ++i) {
|
|
438
|
-
array.
|
|
438
|
+
array[array.length] = '%' + ((i < 16 ? '0' : '') + i.toString(16)).toUpperCase();
|
|
439
439
|
}
|
|
440
440
|
|
|
441
441
|
return array;
|
|
@@ -453,7 +453,7 @@ var compactQueue = function compactQueue(queue) {
|
|
|
453
453
|
|
|
454
454
|
for (var j = 0; j < obj.length; ++j) {
|
|
455
455
|
if (typeof obj[j] !== 'undefined') {
|
|
456
|
-
compacted.
|
|
456
|
+
compacted[compacted.length] = obj[j];
|
|
457
457
|
}
|
|
458
458
|
}
|
|
459
459
|
|
|
@@ -482,7 +482,7 @@ var merge = function merge(target, source, options) {
|
|
|
482
482
|
|
|
483
483
|
if (typeof source !== 'object') {
|
|
484
484
|
if (Array.isArray(target)) {
|
|
485
|
-
target.
|
|
485
|
+
target[target.length] = source;
|
|
486
486
|
} else if (target && typeof target === 'object') {
|
|
487
487
|
if ((options && (options.plainObjects || options.allowPrototypes)) || !has.call(Object.prototype, source)) {
|
|
488
488
|
target[source] = true;
|
|
@@ -510,7 +510,7 @@ var merge = function merge(target, source, options) {
|
|
|
510
510
|
if (targetItem && typeof targetItem === 'object' && item && typeof item === 'object') {
|
|
511
511
|
target[i] = merge(targetItem, item, options);
|
|
512
512
|
} else {
|
|
513
|
-
target.
|
|
513
|
+
target[target.length] = item;
|
|
514
514
|
}
|
|
515
515
|
} else {
|
|
516
516
|
target[i] = item;
|
|
@@ -612,8 +612,8 @@ var compact = function compact(value) {
|
|
|
612
612
|
var key = keys[j];
|
|
613
613
|
var val = obj[key];
|
|
614
614
|
if (typeof val === 'object' && val !== null && refs.indexOf(val) === -1) {
|
|
615
|
-
queue.
|
|
616
|
-
refs.
|
|
615
|
+
queue[queue.length] = { obj: obj, prop: key };
|
|
616
|
+
refs[refs.length] = val;
|
|
617
617
|
}
|
|
618
618
|
}
|
|
619
619
|
}
|
package/lib/parse.js
CHANGED
|
@@ -19,7 +19,7 @@ var defaults = {
|
|
|
19
19
|
var parseValues = function parseQueryStringValues(str, options) {
|
|
20
20
|
var obj = {};
|
|
21
21
|
var cleanStr = options.ignoreQueryPrefix ? str.replace(/^\?/, '') : str;
|
|
22
|
-
var limit = options.parameterLimit === Infinity ? undefined : options.parameterLimit;
|
|
22
|
+
var limit = options.parameterLimit === Infinity ? void undefined : options.parameterLimit;
|
|
23
23
|
var parts = cleanStr.split(options.delimiter, limit);
|
|
24
24
|
|
|
25
25
|
for (var i = 0; i < parts.length; ++i) {
|
|
@@ -111,7 +111,7 @@ var parseKeys = function parseQueryStringKeys(givenKey, val, options) {
|
|
|
111
111
|
}
|
|
112
112
|
}
|
|
113
113
|
|
|
114
|
-
keys.
|
|
114
|
+
keys[keys.length] = parent;
|
|
115
115
|
}
|
|
116
116
|
|
|
117
117
|
// Loop through children appending to the array until we hit depth
|
|
@@ -124,13 +124,13 @@ var parseKeys = function parseQueryStringKeys(givenKey, val, options) {
|
|
|
124
124
|
return;
|
|
125
125
|
}
|
|
126
126
|
}
|
|
127
|
-
keys.
|
|
127
|
+
keys[keys.length] = segment[1];
|
|
128
128
|
}
|
|
129
129
|
|
|
130
130
|
// If there's a remainder, just add whatever is left
|
|
131
131
|
|
|
132
132
|
if (segment) {
|
|
133
|
-
keys.
|
|
133
|
+
keys[keys.length] = '[' + key.slice(segment.index) + ']';
|
|
134
134
|
}
|
|
135
135
|
|
|
136
136
|
return parseObject(keys, val, options);
|
package/lib/utils.js
CHANGED
|
@@ -5,7 +5,7 @@ var has = Object.prototype.hasOwnProperty;
|
|
|
5
5
|
var hexTable = (function () {
|
|
6
6
|
var array = [];
|
|
7
7
|
for (var i = 0; i < 256; ++i) {
|
|
8
|
-
array.
|
|
8
|
+
array[array.length] = '%' + ((i < 16 ? '0' : '') + i.toString(16)).toUpperCase();
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
return array;
|
|
@@ -23,7 +23,7 @@ var compactQueue = function compactQueue(queue) {
|
|
|
23
23
|
|
|
24
24
|
for (var j = 0; j < obj.length; ++j) {
|
|
25
25
|
if (typeof obj[j] !== 'undefined') {
|
|
26
|
-
compacted.
|
|
26
|
+
compacted[compacted.length] = obj[j];
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
29
|
|
|
@@ -52,7 +52,7 @@ var merge = function merge(target, source, options) {
|
|
|
52
52
|
|
|
53
53
|
if (typeof source !== 'object') {
|
|
54
54
|
if (Array.isArray(target)) {
|
|
55
|
-
target.
|
|
55
|
+
target[target.length] = source;
|
|
56
56
|
} else if (target && typeof target === 'object') {
|
|
57
57
|
if ((options && (options.plainObjects || options.allowPrototypes)) || !has.call(Object.prototype, source)) {
|
|
58
58
|
target[source] = true;
|
|
@@ -80,7 +80,7 @@ var merge = function merge(target, source, options) {
|
|
|
80
80
|
if (targetItem && typeof targetItem === 'object' && item && typeof item === 'object') {
|
|
81
81
|
target[i] = merge(targetItem, item, options);
|
|
82
82
|
} else {
|
|
83
|
-
target.
|
|
83
|
+
target[target.length] = item;
|
|
84
84
|
}
|
|
85
85
|
} else {
|
|
86
86
|
target[i] = item;
|
|
@@ -182,8 +182,8 @@ var compact = function compact(value) {
|
|
|
182
182
|
var key = keys[j];
|
|
183
183
|
var val = obj[key];
|
|
184
184
|
if (typeof val === 'object' && val !== null && refs.indexOf(val) === -1) {
|
|
185
|
-
queue.
|
|
186
|
-
refs.
|
|
185
|
+
queue[queue.length] = { obj: obj, prop: key };
|
|
186
|
+
refs[refs.length] = val;
|
|
187
187
|
}
|
|
188
188
|
}
|
|
189
189
|
}
|
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.
|
|
5
|
+
"version": "6.5.5",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
8
8
|
"url": "https://github.com/ljharb/qs.git"
|
|
@@ -36,10 +36,11 @@
|
|
|
36
36
|
"qs-iconv": "^1.0.4",
|
|
37
37
|
"safe-publish-latest": "^2.0.0",
|
|
38
38
|
"safer-buffer": "^2.1.2",
|
|
39
|
-
"tape": "^5.4.0"
|
|
39
|
+
"tape": "^5.4.0",
|
|
40
|
+
"npmignore": "^0.3.1"
|
|
40
41
|
},
|
|
41
42
|
"scripts": {
|
|
42
|
-
"prepublishOnly": "safe-publish-latest && npm run dist",
|
|
43
|
+
"prepublishOnly": "safe-publish-latest && npmignore --auto --commentLines=autogenerated && npm run dist",
|
|
43
44
|
"prepublish": "not-in-publish || npm run prepublishOnly",
|
|
44
45
|
"pretest": "npm run --silent readme && npm run --silent lint",
|
|
45
46
|
"test": "npm run --silent tests-only",
|
|
@@ -50,5 +51,13 @@
|
|
|
50
51
|
"lint": "eslint --ext=js,mjs .",
|
|
51
52
|
"dist": "mkdirp dist && browserify --standalone Qs lib/index.js > dist/qs.js"
|
|
52
53
|
},
|
|
53
|
-
"license": "BSD-3-Clause"
|
|
54
|
+
"license": "BSD-3-Clause",
|
|
55
|
+
"publishConfig": {
|
|
56
|
+
"ignore": [
|
|
57
|
+
"!dist/*",
|
|
58
|
+
"bower.json",
|
|
59
|
+
"component.json",
|
|
60
|
+
".github/workflows"
|
|
61
|
+
]
|
|
62
|
+
}
|
|
54
63
|
}
|
package/test/parse.js
CHANGED
|
@@ -52,6 +52,15 @@ test('parse()', function (t) {
|
|
|
52
52
|
st.end();
|
|
53
53
|
});
|
|
54
54
|
|
|
55
|
+
t.test('correctly computes the remainder when depth is exceeded', function (st) {
|
|
56
|
+
st.deepEqual(
|
|
57
|
+
qs.parse('a[b][c][d][e]=f', { depth: 2 }),
|
|
58
|
+
{ a: { b: { c: { '[d][e]': 'f' } } } },
|
|
59
|
+
'the remainder is "[d][e]", not the full original key'
|
|
60
|
+
);
|
|
61
|
+
st.end();
|
|
62
|
+
});
|
|
63
|
+
|
|
55
64
|
t.deepEqual(qs.parse('a=b&a=c'), { a: ['b', 'c'] }, 'parses a simple array');
|
|
56
65
|
|
|
57
66
|
t.test('parses an explicit array', function (st) {
|
package/test/stringify.js
CHANGED
|
@@ -19,6 +19,12 @@ test('stringify()', function (t) {
|
|
|
19
19
|
st.end();
|
|
20
20
|
});
|
|
21
21
|
|
|
22
|
+
t.test('correctly encodes low-byte characters', function (st) {
|
|
23
|
+
st.equal(qs.stringify({ a: String.fromCharCode(1) }), 'a=%01', 'encodes 0x01');
|
|
24
|
+
st.equal(qs.stringify({ a: String.fromCharCode(15) }), 'a=%0F', 'encodes 0x0F');
|
|
25
|
+
st.end();
|
|
26
|
+
});
|
|
27
|
+
|
|
22
28
|
t.test('stringifies falsy values', function (st) {
|
|
23
29
|
st.equal(qs.stringify(undefined), '');
|
|
24
30
|
st.equal(qs.stringify(null), '');
|
package/bower.json
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "qs",
|
|
3
|
-
"main": "dist/qs.js",
|
|
4
|
-
"homepage": "https://github.com/hapijs/qs",
|
|
5
|
-
"authors": [
|
|
6
|
-
"Nathan LaFreniere <quitlahok@gmail.com>"
|
|
7
|
-
],
|
|
8
|
-
"description": "A querystring parser that supports nesting and arrays, with a depth limit",
|
|
9
|
-
"keywords": [
|
|
10
|
-
"querystring",
|
|
11
|
-
"qs"
|
|
12
|
-
],
|
|
13
|
-
"license": "BSD-3-Clause",
|
|
14
|
-
"ignore": [
|
|
15
|
-
"**/.*",
|
|
16
|
-
"node_modules",
|
|
17
|
-
"bower_components",
|
|
18
|
-
"test",
|
|
19
|
-
"tests"
|
|
20
|
-
]
|
|
21
|
-
}
|
package/component.json
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "qs",
|
|
3
|
-
"repository": "ljharb/qs",
|
|
4
|
-
"description": "query-string parser / stringifier with nesting support",
|
|
5
|
-
"version": "6.5.3",
|
|
6
|
-
"keywords": ["querystring", "query", "parser"],
|
|
7
|
-
"main": "lib/index.js",
|
|
8
|
-
"scripts": [
|
|
9
|
-
"lib/index.js",
|
|
10
|
-
"lib/parse.js",
|
|
11
|
-
"lib/stringify.js",
|
|
12
|
-
"lib/utils.js"
|
|
13
|
-
],
|
|
14
|
-
"license": "BSD-3-Clause"
|
|
15
|
-
}
|