qs 6.0.3 → 6.1.2
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/.eslintrc +3 -3
- package/.travis.yml +134 -30
- package/CHANGELOG.md +11 -1
- package/bower.json +0 -1
- package/component.json +1 -1
- package/dist/qs.js +21 -13
- package/lib/index.js +0 -0
- package/lib/parse.js +10 -7
- package/lib/stringify.js +5 -4
- package/lib/utils.js +6 -2
- package/package.json +3 -2
- package/test/parse.js +38 -3
- package/test/stringify.js +24 -0
- package/test/utils.js +0 -0
package/.eslintrc
CHANGED
|
@@ -4,10 +4,10 @@
|
|
|
4
4
|
"extends": "@ljharb",
|
|
5
5
|
|
|
6
6
|
"rules": {
|
|
7
|
-
"complexity": [2,
|
|
7
|
+
"complexity": [2, 19],
|
|
8
8
|
"consistent-return": [1],
|
|
9
|
-
"max-params": [2,
|
|
10
|
-
"max-statements": [2,
|
|
9
|
+
"max-params": [2, 9],
|
|
10
|
+
"max-statements": [2, 33],
|
|
11
11
|
"no-extra-parens": [1],
|
|
12
12
|
"no-continue": [1],
|
|
13
13
|
"no-magic-numbers": 0,
|
package/.travis.yml
CHANGED
|
@@ -1,69 +1,173 @@
|
|
|
1
1
|
language: node_js
|
|
2
|
+
os:
|
|
3
|
+
- linux
|
|
2
4
|
node_js:
|
|
3
|
-
- "
|
|
4
|
-
- "
|
|
5
|
-
- "5.
|
|
6
|
-
- "
|
|
7
|
-
- "4.2"
|
|
8
|
-
- "4.1"
|
|
9
|
-
- "4.0"
|
|
5
|
+
- "7.7"
|
|
6
|
+
- "6.10"
|
|
7
|
+
- "5.12"
|
|
8
|
+
- "4.8"
|
|
10
9
|
- "iojs-v3.3"
|
|
11
|
-
- "iojs-v3.2"
|
|
12
|
-
- "iojs-v3.1"
|
|
13
|
-
- "iojs-v3.0"
|
|
14
10
|
- "iojs-v2.5"
|
|
15
|
-
- "iojs-v2.4"
|
|
16
|
-
- "iojs-v2.3"
|
|
17
|
-
- "iojs-v2.2"
|
|
18
|
-
- "iojs-v2.1"
|
|
19
|
-
- "iojs-v2.0"
|
|
20
11
|
- "iojs-v1.8"
|
|
21
|
-
- "iojs-v1.7"
|
|
22
|
-
- "iojs-v1.6"
|
|
23
|
-
- "iojs-v1.5"
|
|
24
|
-
- "iojs-v1.4"
|
|
25
|
-
- "iojs-v1.3"
|
|
26
|
-
- "iojs-v1.2"
|
|
27
|
-
- "iojs-v1.1"
|
|
28
|
-
- "iojs-v1.0"
|
|
29
12
|
- "0.12"
|
|
30
|
-
- "0.11"
|
|
31
13
|
- "0.10"
|
|
32
|
-
- "0.9"
|
|
33
14
|
- "0.8"
|
|
34
|
-
- "0.6"
|
|
35
|
-
- "0.4"
|
|
36
15
|
before_install:
|
|
37
|
-
- 'if [ "${TRAVIS_NODE_VERSION}" != "0.9" ]; then case "$(npm --version)" in 1.*) npm install -g npm@1.4.28 ;; 2.*) npm install -g npm@2 ;; esac ; fi'
|
|
16
|
+
- 'if [ "${TRAVIS_NODE_VERSION}" = "0.6" ]; then npm install -g npm@1.3 ; elif [ "${TRAVIS_NODE_VERSION}" != "0.9" ]; then case "$(npm --version)" in 1.*) npm install -g npm@1.4.28 ;; 2.*) npm install -g npm@2 ;; esac ; fi'
|
|
38
17
|
- 'if [ "${TRAVIS_NODE_VERSION}" != "0.6" ] && [ "${TRAVIS_NODE_VERSION}" != "0.9" ]; then npm install -g npm; fi'
|
|
39
18
|
script:
|
|
40
|
-
- 'if [ "${
|
|
19
|
+
- 'if [ -n "${PRETEST-}" ]; then npm run pretest ; fi'
|
|
20
|
+
- 'if [ -n "${POSTTEST-}" ]; then npm run posttest ; fi'
|
|
21
|
+
- 'if [ -n "${COVERAGE-}" ]; then npm run coverage ; fi'
|
|
22
|
+
- 'if [ -n "${TEST-}" ]; then npm run tests-only ; fi'
|
|
41
23
|
sudo: false
|
|
24
|
+
env:
|
|
25
|
+
- TEST=true
|
|
42
26
|
matrix:
|
|
43
27
|
fast_finish: true
|
|
44
|
-
|
|
28
|
+
include:
|
|
29
|
+
- node_js: "node"
|
|
30
|
+
env: PRETEST=true
|
|
31
|
+
- node_js: "4"
|
|
32
|
+
env: COVERAGE=true
|
|
33
|
+
- node_js: "7.6"
|
|
34
|
+
env: TEST=true ALLOW_FAILURE=true
|
|
35
|
+
- node_js: "7.5"
|
|
36
|
+
env: TEST=true ALLOW_FAILURE=true
|
|
37
|
+
- node_js: "7.4"
|
|
38
|
+
env: TEST=true ALLOW_FAILURE=true
|
|
39
|
+
- node_js: "7.3"
|
|
40
|
+
env: TEST=true ALLOW_FAILURE=true
|
|
41
|
+
- node_js: "7.2"
|
|
42
|
+
env: TEST=true ALLOW_FAILURE=true
|
|
43
|
+
- node_js: "7.1"
|
|
44
|
+
env: TEST=true ALLOW_FAILURE=true
|
|
45
|
+
- node_js: "7.0"
|
|
46
|
+
env: TEST=true ALLOW_FAILURE=true
|
|
47
|
+
- node_js: "6.9"
|
|
48
|
+
env: TEST=true ALLOW_FAILURE=true
|
|
49
|
+
- node_js: "6.8"
|
|
50
|
+
env: TEST=true ALLOW_FAILURE=true
|
|
51
|
+
- node_js: "6.7"
|
|
52
|
+
env: TEST=true ALLOW_FAILURE=true
|
|
53
|
+
- node_js: "6.6"
|
|
54
|
+
env: TEST=true ALLOW_FAILURE=true
|
|
55
|
+
- node_js: "6.5"
|
|
56
|
+
env: TEST=true ALLOW_FAILURE=true
|
|
57
|
+
- node_js: "6.4"
|
|
58
|
+
env: TEST=true ALLOW_FAILURE=true
|
|
59
|
+
- node_js: "6.3"
|
|
60
|
+
env: TEST=true ALLOW_FAILURE=true
|
|
61
|
+
- node_js: "6.2"
|
|
62
|
+
env: TEST=true ALLOW_FAILURE=true
|
|
63
|
+
- node_js: "6.1"
|
|
64
|
+
env: TEST=true ALLOW_FAILURE=true
|
|
65
|
+
- node_js: "6.0"
|
|
66
|
+
env: TEST=true ALLOW_FAILURE=true
|
|
67
|
+
- node_js: "5.11"
|
|
68
|
+
env: TEST=true ALLOW_FAILURE=true
|
|
69
|
+
- node_js: "5.10"
|
|
70
|
+
env: TEST=true ALLOW_FAILURE=true
|
|
71
|
+
- node_js: "5.9"
|
|
72
|
+
env: TEST=true ALLOW_FAILURE=true
|
|
73
|
+
- node_js: "5.8"
|
|
74
|
+
env: TEST=true ALLOW_FAILURE=true
|
|
75
|
+
- node_js: "5.7"
|
|
76
|
+
env: TEST=true ALLOW_FAILURE=true
|
|
77
|
+
- node_js: "5.6"
|
|
78
|
+
env: TEST=true ALLOW_FAILURE=true
|
|
79
|
+
- node_js: "5.5"
|
|
80
|
+
env: TEST=true ALLOW_FAILURE=true
|
|
81
|
+
- node_js: "5.4"
|
|
82
|
+
env: TEST=true ALLOW_FAILURE=true
|
|
83
|
+
- node_js: "5.3"
|
|
84
|
+
env: TEST=true ALLOW_FAILURE=true
|
|
45
85
|
- node_js: "5.2"
|
|
86
|
+
env: TEST=true ALLOW_FAILURE=true
|
|
46
87
|
- node_js: "5.1"
|
|
88
|
+
env: TEST=true ALLOW_FAILURE=true
|
|
47
89
|
- node_js: "5.0"
|
|
90
|
+
env: TEST=true ALLOW_FAILURE=true
|
|
91
|
+
- node_js: "4.7"
|
|
92
|
+
env: TEST=true ALLOW_FAILURE=true
|
|
93
|
+
- node_js: "4.6"
|
|
94
|
+
env: TEST=true ALLOW_FAILURE=true
|
|
95
|
+
- node_js: "4.5"
|
|
96
|
+
env: TEST=true ALLOW_FAILURE=true
|
|
97
|
+
- node_js: "4.4"
|
|
98
|
+
env: TEST=true ALLOW_FAILURE=true
|
|
99
|
+
- node_js: "4.3"
|
|
100
|
+
env: TEST=true ALLOW_FAILURE=true
|
|
101
|
+
- node_js: "4.2"
|
|
102
|
+
env: TEST=true ALLOW_FAILURE=true
|
|
48
103
|
- node_js: "4.1"
|
|
104
|
+
env: TEST=true ALLOW_FAILURE=true
|
|
49
105
|
- node_js: "4.0"
|
|
106
|
+
env: TEST=true ALLOW_FAILURE=true
|
|
50
107
|
- node_js: "iojs-v3.2"
|
|
108
|
+
env: TEST=true ALLOW_FAILURE=true
|
|
51
109
|
- node_js: "iojs-v3.1"
|
|
110
|
+
env: TEST=true ALLOW_FAILURE=true
|
|
52
111
|
- node_js: "iojs-v3.0"
|
|
112
|
+
env: TEST=true ALLOW_FAILURE=true
|
|
53
113
|
- node_js: "iojs-v2.4"
|
|
114
|
+
env: TEST=true ALLOW_FAILURE=true
|
|
54
115
|
- node_js: "iojs-v2.3"
|
|
116
|
+
env: TEST=true ALLOW_FAILURE=true
|
|
55
117
|
- node_js: "iojs-v2.2"
|
|
118
|
+
env: TEST=true ALLOW_FAILURE=true
|
|
56
119
|
- node_js: "iojs-v2.1"
|
|
120
|
+
env: TEST=true ALLOW_FAILURE=true
|
|
57
121
|
- node_js: "iojs-v2.0"
|
|
122
|
+
env: TEST=true ALLOW_FAILURE=true
|
|
58
123
|
- node_js: "iojs-v1.7"
|
|
124
|
+
env: TEST=true ALLOW_FAILURE=true
|
|
59
125
|
- node_js: "iojs-v1.6"
|
|
126
|
+
env: TEST=true ALLOW_FAILURE=true
|
|
60
127
|
- node_js: "iojs-v1.5"
|
|
128
|
+
env: TEST=true ALLOW_FAILURE=true
|
|
61
129
|
- node_js: "iojs-v1.4"
|
|
130
|
+
env: TEST=true ALLOW_FAILURE=true
|
|
62
131
|
- node_js: "iojs-v1.3"
|
|
132
|
+
env: TEST=true ALLOW_FAILURE=true
|
|
63
133
|
- node_js: "iojs-v1.2"
|
|
134
|
+
env: TEST=true ALLOW_FAILURE=true
|
|
64
135
|
- node_js: "iojs-v1.1"
|
|
136
|
+
env: TEST=true ALLOW_FAILURE=true
|
|
65
137
|
- node_js: "iojs-v1.0"
|
|
138
|
+
env: TEST=true ALLOW_FAILURE=true
|
|
66
139
|
- node_js: "0.11"
|
|
140
|
+
env: TEST=true ALLOW_FAILURE=true
|
|
67
141
|
- node_js: "0.9"
|
|
142
|
+
env: TEST=true ALLOW_FAILURE=true
|
|
68
143
|
- node_js: "0.6"
|
|
144
|
+
env: TEST=true ALLOW_FAILURE=true
|
|
69
145
|
- node_js: "0.4"
|
|
146
|
+
env: TEST=true ALLOW_FAILURE=true
|
|
147
|
+
##- node_js: "7"
|
|
148
|
+
#env: TEST=true
|
|
149
|
+
#os: osx
|
|
150
|
+
#- node_js: "6"
|
|
151
|
+
#env: TEST=true
|
|
152
|
+
#os: osx
|
|
153
|
+
#- node_js: "5"
|
|
154
|
+
#env: TEST=true
|
|
155
|
+
#os: osx
|
|
156
|
+
#- node_js: "4"
|
|
157
|
+
#env: TEST=true
|
|
158
|
+
#os: osx
|
|
159
|
+
#- node_js: "iojs"
|
|
160
|
+
#env: TEST=true
|
|
161
|
+
#os: osx
|
|
162
|
+
#- node_js: "0.12"
|
|
163
|
+
#env: TEST=true
|
|
164
|
+
#os: osx
|
|
165
|
+
#- node_js: "0.10"
|
|
166
|
+
#env: TEST=true
|
|
167
|
+
#os: osx
|
|
168
|
+
#- node_js: "0.8"
|
|
169
|
+
#env: TEST=true
|
|
170
|
+
#os: osx
|
|
171
|
+
allow_failures:
|
|
172
|
+
- os: osx
|
|
173
|
+
- env: TEST=true ALLOW_FAILURE=true
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
|
-
## **6.
|
|
1
|
+
## **6.1.2**
|
|
2
|
+
- [Fix] follow `allowPrototypes` option during merge (#201, #200)
|
|
3
|
+
- [Fix] chmod a-x
|
|
4
|
+
- [Fix] support keys starting with brackets (#202, #200)
|
|
5
|
+
- [Tests] up to `node` `v7.7`, `v6.10`,` v4.8`; disable osx builds since they block linux builds
|
|
6
|
+
|
|
7
|
+
## **6.1.1**
|
|
2
8
|
- [Fix] ensure that `allowPrototypes: false` does not ever shadow Object.prototype properties
|
|
9
|
+
|
|
10
|
+
## [**6.1.0**](https://github.com/ljharb/qs/issues?milestone=34&state=closed)
|
|
11
|
+
- [New] allowDots option for `stringify` (#151)
|
|
12
|
+
- [Fix] "sort" option should work at a depth of 3 or more (#151)
|
|
3
13
|
- [Fix] Restore `dist` directory; will be removed in v7 (#148)
|
|
4
14
|
|
|
5
15
|
## [**6.0.2**](https://github.com/ljharb/qs/issues?milestone=33&state=closed)
|
package/bower.json
CHANGED
package/component.json
CHANGED
package/dist/qs.js
CHANGED
|
@@ -25,6 +25,8 @@ var internals = {
|
|
|
25
25
|
allowDots: false
|
|
26
26
|
};
|
|
27
27
|
|
|
28
|
+
var has = Object.prototype.hasOwnProperty;
|
|
29
|
+
|
|
28
30
|
internals.parseValues = function (str, options) {
|
|
29
31
|
var obj = {};
|
|
30
32
|
var parts = str.split(options.delimiter, options.parameterLimit === Infinity ? undefined : options.parameterLimit);
|
|
@@ -43,7 +45,7 @@ internals.parseValues = function (str, options) {
|
|
|
43
45
|
var key = Utils.decode(part.slice(0, pos));
|
|
44
46
|
var val = Utils.decode(part.slice(pos + 1));
|
|
45
47
|
|
|
46
|
-
if (
|
|
48
|
+
if (has.call(obj, key)) {
|
|
47
49
|
obj[key] = [].concat(obj[key]).concat(val);
|
|
48
50
|
} else {
|
|
49
51
|
obj[key] = val;
|
|
@@ -96,26 +98,27 @@ internals.parseKeys = function (givenKey, val, options) {
|
|
|
96
98
|
|
|
97
99
|
// The regex chunks
|
|
98
100
|
|
|
99
|
-
var
|
|
101
|
+
var brackets = /(\[[^[\]]*])/;
|
|
100
102
|
var child = /(\[[^[\]]*])/g;
|
|
101
103
|
|
|
102
104
|
// Get the parent
|
|
103
105
|
|
|
104
|
-
var segment =
|
|
106
|
+
var segment = brackets.exec(key);
|
|
107
|
+
var parent = segment ? key.slice(0, segment.index) : key;
|
|
105
108
|
|
|
106
109
|
// Stash the parent if it exists
|
|
107
110
|
|
|
108
111
|
var keys = [];
|
|
109
|
-
if (
|
|
112
|
+
if (parent) {
|
|
110
113
|
// If we aren't using plain objects, optionally prefix keys
|
|
111
114
|
// that would overwrite object prototype properties
|
|
112
|
-
if (!options.plainObjects && Object.prototype
|
|
115
|
+
if (!options.plainObjects && has.call(Object.prototype, parent)) {
|
|
113
116
|
if (!options.allowPrototypes) {
|
|
114
117
|
return;
|
|
115
118
|
}
|
|
116
119
|
}
|
|
117
120
|
|
|
118
|
-
keys.push(
|
|
121
|
+
keys.push(parent);
|
|
119
122
|
}
|
|
120
123
|
|
|
121
124
|
// Loop through children appending to the array until we hit depth
|
|
@@ -123,7 +126,7 @@ internals.parseKeys = function (givenKey, val, options) {
|
|
|
123
126
|
var i = 0;
|
|
124
127
|
while ((segment = child.exec(key)) !== null && i < options.depth) {
|
|
125
128
|
i += 1;
|
|
126
|
-
if (!options.plainObjects &&
|
|
129
|
+
if (!options.plainObjects && has.call(Object.prototype, segment[1].slice(1, -1))) {
|
|
127
130
|
if (!options.allowPrototypes) {
|
|
128
131
|
return;
|
|
129
132
|
}
|
|
@@ -198,7 +201,7 @@ var internals = {
|
|
|
198
201
|
encode: true
|
|
199
202
|
};
|
|
200
203
|
|
|
201
|
-
internals.stringify = function (object, prefix, generateArrayPrefix, strictNullHandling, skipNulls, encode, filter, sort) {
|
|
204
|
+
internals.stringify = function (object, prefix, generateArrayPrefix, strictNullHandling, skipNulls, encode, filter, sort, allowDots) {
|
|
202
205
|
var obj = object;
|
|
203
206
|
if (typeof filter === 'function') {
|
|
204
207
|
obj = filter(prefix, obj);
|
|
@@ -243,9 +246,9 @@ internals.stringify = function (object, prefix, generateArrayPrefix, strictNullH
|
|
|
243
246
|
}
|
|
244
247
|
|
|
245
248
|
if (Array.isArray(obj)) {
|
|
246
|
-
values = values.concat(internals.stringify(obj[key], generateArrayPrefix(prefix, key), generateArrayPrefix, strictNullHandling, skipNulls, encode, filter));
|
|
249
|
+
values = values.concat(internals.stringify(obj[key], generateArrayPrefix(prefix, key), generateArrayPrefix, strictNullHandling, skipNulls, encode, filter, sort, allowDots));
|
|
247
250
|
} else {
|
|
248
|
-
values = values.concat(internals.stringify(obj[key], prefix + '[' + key + ']', generateArrayPrefix, strictNullHandling, skipNulls, encode, filter));
|
|
251
|
+
values = values.concat(internals.stringify(obj[key], prefix + (allowDots ? '.' + key : '[' + key + ']'), generateArrayPrefix, strictNullHandling, skipNulls, encode, filter, sort, allowDots));
|
|
249
252
|
}
|
|
250
253
|
}
|
|
251
254
|
|
|
@@ -260,6 +263,7 @@ module.exports = function (object, opts) {
|
|
|
260
263
|
var skipNulls = typeof options.skipNulls === 'boolean' ? options.skipNulls : internals.skipNulls;
|
|
261
264
|
var encode = typeof options.encode === 'boolean' ? options.encode : internals.encode;
|
|
262
265
|
var sort = typeof options.sort === 'function' ? options.sort : null;
|
|
266
|
+
var allowDots = typeof options.allowDots === 'undefined' ? false : options.allowDots;
|
|
263
267
|
var objKeys;
|
|
264
268
|
var filter;
|
|
265
269
|
if (typeof options.filter === 'function') {
|
|
@@ -301,7 +305,7 @@ module.exports = function (object, opts) {
|
|
|
301
305
|
continue;
|
|
302
306
|
}
|
|
303
307
|
|
|
304
|
-
keys = keys.concat(internals.stringify(obj[key], key, generateArrayPrefix, strictNullHandling, skipNulls, encode, filter, sort));
|
|
308
|
+
keys = keys.concat(internals.stringify(obj[key], key, generateArrayPrefix, strictNullHandling, skipNulls, encode, filter, sort, allowDots));
|
|
305
309
|
}
|
|
306
310
|
|
|
307
311
|
return keys.join(delimiter);
|
|
@@ -319,6 +323,8 @@ var hexTable = (function () {
|
|
|
319
323
|
return array;
|
|
320
324
|
}());
|
|
321
325
|
|
|
326
|
+
var has = Object.prototype.hasOwnProperty;
|
|
327
|
+
|
|
322
328
|
exports.arrayToObject = function (source, options) {
|
|
323
329
|
var obj = options.plainObjects ? Object.create(null) : {};
|
|
324
330
|
for (var i = 0; i < source.length; ++i) {
|
|
@@ -339,7 +345,9 @@ exports.merge = function (target, source, options) {
|
|
|
339
345
|
if (Array.isArray(target)) {
|
|
340
346
|
target.push(source);
|
|
341
347
|
} else if (typeof target === 'object') {
|
|
342
|
-
|
|
348
|
+
if (options.plainObjects || options.allowPrototypes || !has.call(Object.prototype, source)) {
|
|
349
|
+
target[source] = true;
|
|
350
|
+
}
|
|
343
351
|
} else {
|
|
344
352
|
return [target, source];
|
|
345
353
|
}
|
|
@@ -359,7 +367,7 @@ exports.merge = function (target, source, options) {
|
|
|
359
367
|
return Object.keys(source).reduce(function (acc, key) {
|
|
360
368
|
var value = source[key];
|
|
361
369
|
|
|
362
|
-
if (
|
|
370
|
+
if (has.call(acc, key)) {
|
|
363
371
|
acc[key] = exports.merge(acc[key], value, options);
|
|
364
372
|
} else {
|
|
365
373
|
acc[key] = value;
|
package/lib/index.js
CHANGED
|
File without changes
|
package/lib/parse.js
CHANGED
|
@@ -13,6 +13,8 @@ var internals = {
|
|
|
13
13
|
allowDots: false
|
|
14
14
|
};
|
|
15
15
|
|
|
16
|
+
var has = Object.prototype.hasOwnProperty;
|
|
17
|
+
|
|
16
18
|
internals.parseValues = function (str, options) {
|
|
17
19
|
var obj = {};
|
|
18
20
|
var parts = str.split(options.delimiter, options.parameterLimit === Infinity ? undefined : options.parameterLimit);
|
|
@@ -31,7 +33,7 @@ internals.parseValues = function (str, options) {
|
|
|
31
33
|
var key = Utils.decode(part.slice(0, pos));
|
|
32
34
|
var val = Utils.decode(part.slice(pos + 1));
|
|
33
35
|
|
|
34
|
-
if (
|
|
36
|
+
if (has.call(obj, key)) {
|
|
35
37
|
obj[key] = [].concat(obj[key]).concat(val);
|
|
36
38
|
} else {
|
|
37
39
|
obj[key] = val;
|
|
@@ -84,26 +86,27 @@ internals.parseKeys = function (givenKey, val, options) {
|
|
|
84
86
|
|
|
85
87
|
// The regex chunks
|
|
86
88
|
|
|
87
|
-
var
|
|
89
|
+
var brackets = /(\[[^[\]]*])/;
|
|
88
90
|
var child = /(\[[^[\]]*])/g;
|
|
89
91
|
|
|
90
92
|
// Get the parent
|
|
91
93
|
|
|
92
|
-
var segment =
|
|
94
|
+
var segment = brackets.exec(key);
|
|
95
|
+
var parent = segment ? key.slice(0, segment.index) : key;
|
|
93
96
|
|
|
94
97
|
// Stash the parent if it exists
|
|
95
98
|
|
|
96
99
|
var keys = [];
|
|
97
|
-
if (
|
|
100
|
+
if (parent) {
|
|
98
101
|
// If we aren't using plain objects, optionally prefix keys
|
|
99
102
|
// that would overwrite object prototype properties
|
|
100
|
-
if (!options.plainObjects && Object.prototype
|
|
103
|
+
if (!options.plainObjects && has.call(Object.prototype, parent)) {
|
|
101
104
|
if (!options.allowPrototypes) {
|
|
102
105
|
return;
|
|
103
106
|
}
|
|
104
107
|
}
|
|
105
108
|
|
|
106
|
-
keys.push(
|
|
109
|
+
keys.push(parent);
|
|
107
110
|
}
|
|
108
111
|
|
|
109
112
|
// Loop through children appending to the array until we hit depth
|
|
@@ -111,7 +114,7 @@ internals.parseKeys = function (givenKey, val, options) {
|
|
|
111
114
|
var i = 0;
|
|
112
115
|
while ((segment = child.exec(key)) !== null && i < options.depth) {
|
|
113
116
|
i += 1;
|
|
114
|
-
if (!options.plainObjects &&
|
|
117
|
+
if (!options.plainObjects && has.call(Object.prototype, segment[1].slice(1, -1))) {
|
|
115
118
|
if (!options.allowPrototypes) {
|
|
116
119
|
return;
|
|
117
120
|
}
|
package/lib/stringify.js
CHANGED
|
@@ -20,7 +20,7 @@ var internals = {
|
|
|
20
20
|
encode: true
|
|
21
21
|
};
|
|
22
22
|
|
|
23
|
-
internals.stringify = function (object, prefix, generateArrayPrefix, strictNullHandling, skipNulls, encode, filter, sort) {
|
|
23
|
+
internals.stringify = function (object, prefix, generateArrayPrefix, strictNullHandling, skipNulls, encode, filter, sort, allowDots) {
|
|
24
24
|
var obj = object;
|
|
25
25
|
if (typeof filter === 'function') {
|
|
26
26
|
obj = filter(prefix, obj);
|
|
@@ -65,9 +65,9 @@ internals.stringify = function (object, prefix, generateArrayPrefix, strictNullH
|
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
if (Array.isArray(obj)) {
|
|
68
|
-
values = values.concat(internals.stringify(obj[key], generateArrayPrefix(prefix, key), generateArrayPrefix, strictNullHandling, skipNulls, encode, filter));
|
|
68
|
+
values = values.concat(internals.stringify(obj[key], generateArrayPrefix(prefix, key), generateArrayPrefix, strictNullHandling, skipNulls, encode, filter, sort, allowDots));
|
|
69
69
|
} else {
|
|
70
|
-
values = values.concat(internals.stringify(obj[key], prefix + '[' + key + ']', generateArrayPrefix, strictNullHandling, skipNulls, encode, filter));
|
|
70
|
+
values = values.concat(internals.stringify(obj[key], prefix + (allowDots ? '.' + key : '[' + key + ']'), generateArrayPrefix, strictNullHandling, skipNulls, encode, filter, sort, allowDots));
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
73
|
|
|
@@ -82,6 +82,7 @@ module.exports = function (object, opts) {
|
|
|
82
82
|
var skipNulls = typeof options.skipNulls === 'boolean' ? options.skipNulls : internals.skipNulls;
|
|
83
83
|
var encode = typeof options.encode === 'boolean' ? options.encode : internals.encode;
|
|
84
84
|
var sort = typeof options.sort === 'function' ? options.sort : null;
|
|
85
|
+
var allowDots = typeof options.allowDots === 'undefined' ? false : options.allowDots;
|
|
85
86
|
var objKeys;
|
|
86
87
|
var filter;
|
|
87
88
|
if (typeof options.filter === 'function') {
|
|
@@ -123,7 +124,7 @@ module.exports = function (object, opts) {
|
|
|
123
124
|
continue;
|
|
124
125
|
}
|
|
125
126
|
|
|
126
|
-
keys = keys.concat(internals.stringify(obj[key], key, generateArrayPrefix, strictNullHandling, skipNulls, encode, filter, sort));
|
|
127
|
+
keys = keys.concat(internals.stringify(obj[key], key, generateArrayPrefix, strictNullHandling, skipNulls, encode, filter, sort, allowDots));
|
|
127
128
|
}
|
|
128
129
|
|
|
129
130
|
return keys.join(delimiter);
|
package/lib/utils.js
CHANGED
|
@@ -9,6 +9,8 @@ var hexTable = (function () {
|
|
|
9
9
|
return array;
|
|
10
10
|
}());
|
|
11
11
|
|
|
12
|
+
var has = Object.prototype.hasOwnProperty;
|
|
13
|
+
|
|
12
14
|
exports.arrayToObject = function (source, options) {
|
|
13
15
|
var obj = options.plainObjects ? Object.create(null) : {};
|
|
14
16
|
for (var i = 0; i < source.length; ++i) {
|
|
@@ -29,7 +31,9 @@ exports.merge = function (target, source, options) {
|
|
|
29
31
|
if (Array.isArray(target)) {
|
|
30
32
|
target.push(source);
|
|
31
33
|
} else if (typeof target === 'object') {
|
|
32
|
-
|
|
34
|
+
if (options.plainObjects || options.allowPrototypes || !has.call(Object.prototype, source)) {
|
|
35
|
+
target[source] = true;
|
|
36
|
+
}
|
|
33
37
|
} else {
|
|
34
38
|
return [target, source];
|
|
35
39
|
}
|
|
@@ -49,7 +53,7 @@ exports.merge = function (target, source, options) {
|
|
|
49
53
|
return Object.keys(source).reduce(function (acc, key) {
|
|
50
54
|
var value = source[key];
|
|
51
55
|
|
|
52
|
-
if (
|
|
56
|
+
if (has.call(acc, key)) {
|
|
53
57
|
acc[key] = exports.merge(acc[key], value, options);
|
|
54
58
|
} else {
|
|
55
59
|
acc[key] = value;
|
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.1.2",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
8
8
|
"url": "https://github.com/ljharb/qs.git"
|
|
@@ -34,7 +34,8 @@
|
|
|
34
34
|
"evalmd": "^0.0.16"
|
|
35
35
|
},
|
|
36
36
|
"scripts": {
|
|
37
|
-
"
|
|
37
|
+
"pretest": "npm run lint && npm run readme",
|
|
38
|
+
"test": "npm run coverage",
|
|
38
39
|
"tests-only": "node test",
|
|
39
40
|
"readme": "evalmd README.md",
|
|
40
41
|
"lint": "eslint lib/*.js text/*.js",
|
package/test/parse.js
CHANGED
|
@@ -142,8 +142,6 @@ test('parse()', function (t) {
|
|
|
142
142
|
st.end();
|
|
143
143
|
});
|
|
144
144
|
|
|
145
|
-
t.deepEqual(qs.parse('a[b]=c&a=d'), { a: { b: 'c', d: true } }, 'can add keys to objects');
|
|
146
|
-
|
|
147
145
|
t.test('correctly prunes undefined values when converting an array to an object', function (st) {
|
|
148
146
|
st.deepEqual(qs.parse('a[2]=b&a[99999999]=c'), { a: { '2': 'b', '99999999': 'c' } });
|
|
149
147
|
st.end();
|
|
@@ -401,10 +399,47 @@ test('parse()', function (t) {
|
|
|
401
399
|
|
|
402
400
|
t.test('params starting with a closing bracket', function (st) {
|
|
403
401
|
st.deepEqual(qs.parse(']=toString'), { ']': 'toString' });
|
|
402
|
+
st.deepEqual(qs.parse(']]=toString'), { ']]': 'toString' });
|
|
403
|
+
st.deepEqual(qs.parse(']hello]=toString'), { ']hello]': 'toString' });
|
|
404
|
+
st.end();
|
|
405
|
+
});
|
|
406
|
+
|
|
407
|
+
t.test('params starting with a starting bracket', function (st) {
|
|
408
|
+
st.deepEqual(qs.parse('[=toString'), { '[': 'toString' });
|
|
409
|
+
st.deepEqual(qs.parse('[[=toString'), { '[[': 'toString' });
|
|
410
|
+
st.deepEqual(qs.parse('[hello[=toString'), { '[hello[': 'toString' });
|
|
411
|
+
st.end();
|
|
412
|
+
});
|
|
413
|
+
|
|
414
|
+
t.test('add keys to objects', function (st) {
|
|
415
|
+
st.deepEqual(
|
|
416
|
+
qs.parse('a[b]=c&a=d'),
|
|
417
|
+
{ a: { b: 'c', d: true } },
|
|
418
|
+
'can add keys to objects'
|
|
419
|
+
);
|
|
420
|
+
|
|
421
|
+
st.deepEqual(
|
|
422
|
+
qs.parse('a[b]=c&a=toString'),
|
|
423
|
+
{ a: { b: 'c' } },
|
|
424
|
+
'can not overwrite prototype'
|
|
425
|
+
);
|
|
426
|
+
|
|
427
|
+
st.deepEqual(
|
|
428
|
+
qs.parse('a[b]=c&a=toString', { allowPrototypes: true }),
|
|
429
|
+
{ a: { b: 'c', toString: true } },
|
|
430
|
+
'can overwrite prototype with allowPrototypes true'
|
|
431
|
+
);
|
|
432
|
+
|
|
433
|
+
st.deepEqual(
|
|
434
|
+
qs.parse('a[b]=c&a=toString', { plainObjects: true }),
|
|
435
|
+
{ a: { b: 'c', toString: true } },
|
|
436
|
+
'can overwrite prototype with plainObjects true'
|
|
437
|
+
);
|
|
438
|
+
|
|
404
439
|
st.end();
|
|
405
440
|
});
|
|
406
441
|
|
|
407
|
-
t.test('can return
|
|
442
|
+
t.test('can return null objects', { skip: !Object.create }, function (st) {
|
|
408
443
|
var expected = Object.create(null);
|
|
409
444
|
expected.a = Object.create(null);
|
|
410
445
|
expected.a.b = 'c';
|
package/test/stringify.js
CHANGED
|
@@ -21,6 +21,12 @@ test('stringify()', function (t) {
|
|
|
21
21
|
st.equal(qs.stringify({ a: { b: { c: { d: 'e' } } } }), 'a%5Bb%5D%5Bc%5D%5Bd%5D=e');
|
|
22
22
|
st.end();
|
|
23
23
|
});
|
|
24
|
+
|
|
25
|
+
t.test('stringifies a nested object with dots notation', function (st) {
|
|
26
|
+
st.equal(qs.stringify({ a: { b: 'c' } }, { allowDots: true }), 'a.b=c');
|
|
27
|
+
st.equal(qs.stringify({ a: { b: { c: { d: 'e' } } } }, { allowDots: true }), 'a.b.c.d=e');
|
|
28
|
+
st.end();
|
|
29
|
+
});
|
|
24
30
|
|
|
25
31
|
t.test('stringifies an array value', function (st) {
|
|
26
32
|
st.equal(qs.stringify({ a: ['b', 'c', 'd'] }), 'a%5B0%5D=b&a%5B1%5D=c&a%5B2%5D=d');
|
|
@@ -47,12 +53,23 @@ test('stringify()', function (t) {
|
|
|
47
53
|
st.equal(qs.stringify({ a: { b: ['c', 'd'] } }), 'a%5Bb%5D%5B0%5D=c&a%5Bb%5D%5B1%5D=d');
|
|
48
54
|
st.end();
|
|
49
55
|
});
|
|
56
|
+
|
|
57
|
+
t.test('stringifies a nested array value with dots notation', function (st) {
|
|
58
|
+
st.equal(qs.stringify({ a: { b: ['c', 'd'] } }, { allowDots: true, encode: false }), 'a.b[0]=c&a.b[1]=d');
|
|
59
|
+
st.end();
|
|
60
|
+
});
|
|
50
61
|
|
|
51
62
|
t.test('stringifies an object inside an array', function (st) {
|
|
52
63
|
st.equal(qs.stringify({ a: [{ b: 'c' }] }), 'a%5B0%5D%5Bb%5D=c');
|
|
53
64
|
st.equal(qs.stringify({ a: [{ b: { c: [1] } }] }), 'a%5B0%5D%5Bb%5D%5Bc%5D%5B0%5D=1');
|
|
54
65
|
st.end();
|
|
55
66
|
});
|
|
67
|
+
|
|
68
|
+
t.test('stringifies an object inside an array with dots notation', function (st) {
|
|
69
|
+
st.equal(qs.stringify({ a: [{ b: 'c' }] }, { allowDots: true, encode: false }), 'a[0].b=c');
|
|
70
|
+
st.equal(qs.stringify({ a: [{ b: { c: [1] } }] }, { allowDots: true, encode: false }), 'a[0].b.c[0]=1');
|
|
71
|
+
st.end();
|
|
72
|
+
});
|
|
56
73
|
|
|
57
74
|
t.test('does not omit object keys when indices = false', function (st) {
|
|
58
75
|
st.equal(qs.stringify({ a: [{ b: 'c' }] }, { indices: false }), 'a%5Bb%5D=c');
|
|
@@ -232,4 +249,11 @@ test('stringify()', function (t) {
|
|
|
232
249
|
st.equal(qs.stringify({ a: 'c', z: { j: 'a', i: 'b' }, b: 'f' }, { sort: sort }), 'a=c&b=f&z%5Bi%5D=b&z%5Bj%5D=a');
|
|
233
250
|
st.end();
|
|
234
251
|
});
|
|
252
|
+
|
|
253
|
+
t.test('can sort the keys at depth 3 or more too', function (st) {
|
|
254
|
+
var sort = function (a, b) { return a.localeCompare(b); };
|
|
255
|
+
st.equal(qs.stringify({ a: 'a', z: { zj: {zjb: 'zjb', zja: 'zja'}, zi: {zib: 'zib', zia: 'zia'} }, b: 'b' }, { sort: sort, encode: false }), 'a=a&b=b&z[zi][zia]=zia&z[zi][zib]=zib&z[zj][zja]=zja&z[zj][zjb]=zjb');
|
|
256
|
+
st.equal(qs.stringify({ a: 'a', z: { zj: {zjb: 'zjb', zja: 'zja'}, zi: {zib: 'zib', zia: 'zia'} }, b: 'b' }, { sort: null, encode: false }), 'a=a&z[zj][zjb]=zjb&z[zj][zja]=zja&z[zi][zib]=zib&z[zi][zia]=zia&b=b');
|
|
257
|
+
st.end();
|
|
258
|
+
});
|
|
235
259
|
});
|
package/test/utils.js
CHANGED
|
File without changes
|