qs 6.0.4 → 6.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc +3 -3
- package/.travis.yml +30 -134
- package/CHANGELOG.md +3 -8
- package/component.json +1 -1
- package/dist/qs.js +17 -23
- package/lib/index.js +0 -0
- package/lib/parse.js +10 -13
- package/lib/stringify.js +5 -4
- package/lib/utils.js +2 -6
- package/package.json +2 -3
- package/test/parse.js +7 -70
- 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,173 +1,69 @@
|
|
|
1
1
|
language: node_js
|
|
2
|
-
os:
|
|
3
|
-
- linux
|
|
4
2
|
node_js:
|
|
5
|
-
- "
|
|
6
|
-
- "
|
|
7
|
-
- "5.
|
|
8
|
-
- "
|
|
3
|
+
- "5.3"
|
|
4
|
+
- "5.2"
|
|
5
|
+
- "5.1"
|
|
6
|
+
- "5.0"
|
|
7
|
+
- "4.2"
|
|
8
|
+
- "4.1"
|
|
9
|
+
- "4.0"
|
|
9
10
|
- "iojs-v3.3"
|
|
11
|
+
- "iojs-v3.2"
|
|
12
|
+
- "iojs-v3.1"
|
|
13
|
+
- "iojs-v3.0"
|
|
10
14
|
- "iojs-v2.5"
|
|
15
|
+
- "iojs-v2.4"
|
|
16
|
+
- "iojs-v2.3"
|
|
17
|
+
- "iojs-v2.2"
|
|
18
|
+
- "iojs-v2.1"
|
|
19
|
+
- "iojs-v2.0"
|
|
11
20
|
- "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"
|
|
12
29
|
- "0.12"
|
|
30
|
+
- "0.11"
|
|
13
31
|
- "0.10"
|
|
32
|
+
- "0.9"
|
|
14
33
|
- "0.8"
|
|
34
|
+
- "0.6"
|
|
35
|
+
- "0.4"
|
|
15
36
|
before_install:
|
|
16
|
-
- 'if [ "${TRAVIS_NODE_VERSION}"
|
|
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'
|
|
17
38
|
- 'if [ "${TRAVIS_NODE_VERSION}" != "0.6" ] && [ "${TRAVIS_NODE_VERSION}" != "0.9" ]; then npm install -g npm; fi'
|
|
18
39
|
script:
|
|
19
|
-
- 'if [
|
|
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'
|
|
40
|
+
- 'if [ "${TRAVIS_NODE_VERSION}" != "4.2" ]; then npm run tests-only ; else npm test ; fi'
|
|
23
41
|
sudo: false
|
|
24
|
-
env:
|
|
25
|
-
- TEST=true
|
|
26
42
|
matrix:
|
|
27
43
|
fast_finish: true
|
|
28
|
-
|
|
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
|
|
44
|
+
allow_failures:
|
|
85
45
|
- node_js: "5.2"
|
|
86
|
-
env: TEST=true ALLOW_FAILURE=true
|
|
87
46
|
- node_js: "5.1"
|
|
88
|
-
env: TEST=true ALLOW_FAILURE=true
|
|
89
47
|
- 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
|
|
103
48
|
- node_js: "4.1"
|
|
104
|
-
env: TEST=true ALLOW_FAILURE=true
|
|
105
49
|
- node_js: "4.0"
|
|
106
|
-
env: TEST=true ALLOW_FAILURE=true
|
|
107
50
|
- node_js: "iojs-v3.2"
|
|
108
|
-
env: TEST=true ALLOW_FAILURE=true
|
|
109
51
|
- node_js: "iojs-v3.1"
|
|
110
|
-
env: TEST=true ALLOW_FAILURE=true
|
|
111
52
|
- node_js: "iojs-v3.0"
|
|
112
|
-
env: TEST=true ALLOW_FAILURE=true
|
|
113
53
|
- node_js: "iojs-v2.4"
|
|
114
|
-
env: TEST=true ALLOW_FAILURE=true
|
|
115
54
|
- node_js: "iojs-v2.3"
|
|
116
|
-
env: TEST=true ALLOW_FAILURE=true
|
|
117
55
|
- node_js: "iojs-v2.2"
|
|
118
|
-
env: TEST=true ALLOW_FAILURE=true
|
|
119
56
|
- node_js: "iojs-v2.1"
|
|
120
|
-
env: TEST=true ALLOW_FAILURE=true
|
|
121
57
|
- node_js: "iojs-v2.0"
|
|
122
|
-
env: TEST=true ALLOW_FAILURE=true
|
|
123
58
|
- node_js: "iojs-v1.7"
|
|
124
|
-
env: TEST=true ALLOW_FAILURE=true
|
|
125
59
|
- node_js: "iojs-v1.6"
|
|
126
|
-
env: TEST=true ALLOW_FAILURE=true
|
|
127
60
|
- node_js: "iojs-v1.5"
|
|
128
|
-
env: TEST=true ALLOW_FAILURE=true
|
|
129
61
|
- node_js: "iojs-v1.4"
|
|
130
|
-
env: TEST=true ALLOW_FAILURE=true
|
|
131
62
|
- node_js: "iojs-v1.3"
|
|
132
|
-
env: TEST=true ALLOW_FAILURE=true
|
|
133
63
|
- node_js: "iojs-v1.2"
|
|
134
|
-
env: TEST=true ALLOW_FAILURE=true
|
|
135
64
|
- node_js: "iojs-v1.1"
|
|
136
|
-
env: TEST=true ALLOW_FAILURE=true
|
|
137
65
|
- node_js: "iojs-v1.0"
|
|
138
|
-
env: TEST=true ALLOW_FAILURE=true
|
|
139
66
|
- node_js: "0.11"
|
|
140
|
-
env: TEST=true ALLOW_FAILURE=true
|
|
141
67
|
- node_js: "0.9"
|
|
142
|
-
env: TEST=true ALLOW_FAILURE=true
|
|
143
68
|
- node_js: "0.6"
|
|
144
|
-
env: TEST=true ALLOW_FAILURE=true
|
|
145
69
|
- 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,11 +1,6 @@
|
|
|
1
|
-
## **6.0.
|
|
2
|
-
- [
|
|
3
|
-
- [Fix]
|
|
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.0.3**
|
|
8
|
-
- [Fix] ensure that `allowPrototypes: false` does not ever shadow Object.prototype properties
|
|
1
|
+
## [**6.1.0**](https://github.com/ljharb/qs/issues?milestone=34&state=closed)
|
|
2
|
+
- [New] allowDots option for `stringify` (#151)
|
|
3
|
+
- [Fix] "sort" option should work at a depth of 3 or more (#151)
|
|
9
4
|
- [Fix] Restore `dist` directory; will be removed in v7 (#148)
|
|
10
5
|
|
|
11
6
|
## [**6.0.2**](https://github.com/ljharb/qs/issues?milestone=33&state=closed)
|
package/component.json
CHANGED
package/dist/qs.js
CHANGED
|
@@ -25,8 +25,6 @@ var internals = {
|
|
|
25
25
|
allowDots: false
|
|
26
26
|
};
|
|
27
27
|
|
|
28
|
-
var has = Object.prototype.hasOwnProperty;
|
|
29
|
-
|
|
30
28
|
internals.parseValues = function (str, options) {
|
|
31
29
|
var obj = {};
|
|
32
30
|
var parts = str.split(options.delimiter, options.parameterLimit === Infinity ? undefined : options.parameterLimit);
|
|
@@ -45,7 +43,7 @@ internals.parseValues = function (str, options) {
|
|
|
45
43
|
var key = Utils.decode(part.slice(0, pos));
|
|
46
44
|
var val = Utils.decode(part.slice(pos + 1));
|
|
47
45
|
|
|
48
|
-
if (
|
|
46
|
+
if (Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
49
47
|
obj[key] = [].concat(obj[key]).concat(val);
|
|
50
48
|
} else {
|
|
51
49
|
obj[key] = val;
|
|
@@ -69,7 +67,7 @@ internals.parseObject = function (chain, val, options) {
|
|
|
69
67
|
obj = obj.concat(internals.parseObject(chain, val, options));
|
|
70
68
|
} else {
|
|
71
69
|
obj = options.plainObjects ? Object.create(null) : {};
|
|
72
|
-
var cleanRoot = root
|
|
70
|
+
var cleanRoot = root[0] === '[' && root[root.length - 1] === ']' ? root.slice(1, root.length - 1) : root;
|
|
73
71
|
var index = parseInt(cleanRoot, 10);
|
|
74
72
|
if (
|
|
75
73
|
!isNaN(index) &&
|
|
@@ -98,27 +96,26 @@ internals.parseKeys = function (givenKey, val, options) {
|
|
|
98
96
|
|
|
99
97
|
// The regex chunks
|
|
100
98
|
|
|
101
|
-
var
|
|
102
|
-
var child = /(\[[
|
|
99
|
+
var parent = /^([^\[\]]*)/;
|
|
100
|
+
var child = /(\[[^\[\]]*\])/g;
|
|
103
101
|
|
|
104
102
|
// Get the parent
|
|
105
103
|
|
|
106
|
-
var segment =
|
|
107
|
-
var parent = segment ? key.slice(0, segment.index) : key;
|
|
104
|
+
var segment = parent.exec(key);
|
|
108
105
|
|
|
109
106
|
// Stash the parent if it exists
|
|
110
107
|
|
|
111
108
|
var keys = [];
|
|
112
|
-
if (
|
|
109
|
+
if (segment[1]) {
|
|
113
110
|
// If we aren't using plain objects, optionally prefix keys
|
|
114
111
|
// that would overwrite object prototype properties
|
|
115
|
-
if (!options.plainObjects &&
|
|
112
|
+
if (!options.plainObjects && Object.prototype.hasOwnProperty(segment[1])) {
|
|
116
113
|
if (!options.allowPrototypes) {
|
|
117
114
|
return;
|
|
118
115
|
}
|
|
119
116
|
}
|
|
120
117
|
|
|
121
|
-
keys.push(
|
|
118
|
+
keys.push(segment[1]);
|
|
122
119
|
}
|
|
123
120
|
|
|
124
121
|
// Loop through children appending to the array until we hit depth
|
|
@@ -126,9 +123,9 @@ internals.parseKeys = function (givenKey, val, options) {
|
|
|
126
123
|
var i = 0;
|
|
127
124
|
while ((segment = child.exec(key)) !== null && i < options.depth) {
|
|
128
125
|
i += 1;
|
|
129
|
-
if (!options.plainObjects &&
|
|
126
|
+
if (!options.plainObjects && Object.prototype.hasOwnProperty(segment[1].replace(/\[|\]/g, ''))) {
|
|
130
127
|
if (!options.allowPrototypes) {
|
|
131
|
-
|
|
128
|
+
continue;
|
|
132
129
|
}
|
|
133
130
|
}
|
|
134
131
|
keys.push(segment[1]);
|
|
@@ -201,7 +198,7 @@ var internals = {
|
|
|
201
198
|
encode: true
|
|
202
199
|
};
|
|
203
200
|
|
|
204
|
-
internals.stringify = function (object, prefix, generateArrayPrefix, strictNullHandling, skipNulls, encode, filter, sort) {
|
|
201
|
+
internals.stringify = function (object, prefix, generateArrayPrefix, strictNullHandling, skipNulls, encode, filter, sort, allowDots) {
|
|
205
202
|
var obj = object;
|
|
206
203
|
if (typeof filter === 'function') {
|
|
207
204
|
obj = filter(prefix, obj);
|
|
@@ -246,9 +243,9 @@ internals.stringify = function (object, prefix, generateArrayPrefix, strictNullH
|
|
|
246
243
|
}
|
|
247
244
|
|
|
248
245
|
if (Array.isArray(obj)) {
|
|
249
|
-
values = values.concat(internals.stringify(obj[key], generateArrayPrefix(prefix, key), generateArrayPrefix, strictNullHandling, skipNulls, encode, filter));
|
|
246
|
+
values = values.concat(internals.stringify(obj[key], generateArrayPrefix(prefix, key), generateArrayPrefix, strictNullHandling, skipNulls, encode, filter, sort, allowDots));
|
|
250
247
|
} else {
|
|
251
|
-
values = values.concat(internals.stringify(obj[key], prefix + '[' + key + ']', generateArrayPrefix, strictNullHandling, skipNulls, encode, filter));
|
|
248
|
+
values = values.concat(internals.stringify(obj[key], prefix + (allowDots ? '.' + key : '[' + key + ']'), generateArrayPrefix, strictNullHandling, skipNulls, encode, filter, sort, allowDots));
|
|
252
249
|
}
|
|
253
250
|
}
|
|
254
251
|
|
|
@@ -263,6 +260,7 @@ module.exports = function (object, opts) {
|
|
|
263
260
|
var skipNulls = typeof options.skipNulls === 'boolean' ? options.skipNulls : internals.skipNulls;
|
|
264
261
|
var encode = typeof options.encode === 'boolean' ? options.encode : internals.encode;
|
|
265
262
|
var sort = typeof options.sort === 'function' ? options.sort : null;
|
|
263
|
+
var allowDots = typeof options.allowDots === 'undefined' ? false : options.allowDots;
|
|
266
264
|
var objKeys;
|
|
267
265
|
var filter;
|
|
268
266
|
if (typeof options.filter === 'function') {
|
|
@@ -304,7 +302,7 @@ module.exports = function (object, opts) {
|
|
|
304
302
|
continue;
|
|
305
303
|
}
|
|
306
304
|
|
|
307
|
-
keys = keys.concat(internals.stringify(obj[key], key, generateArrayPrefix, strictNullHandling, skipNulls, encode, filter, sort));
|
|
305
|
+
keys = keys.concat(internals.stringify(obj[key], key, generateArrayPrefix, strictNullHandling, skipNulls, encode, filter, sort, allowDots));
|
|
308
306
|
}
|
|
309
307
|
|
|
310
308
|
return keys.join(delimiter);
|
|
@@ -322,8 +320,6 @@ var hexTable = (function () {
|
|
|
322
320
|
return array;
|
|
323
321
|
}());
|
|
324
322
|
|
|
325
|
-
var has = Object.prototype.hasOwnProperty;
|
|
326
|
-
|
|
327
323
|
exports.arrayToObject = function (source, options) {
|
|
328
324
|
var obj = options.plainObjects ? Object.create(null) : {};
|
|
329
325
|
for (var i = 0; i < source.length; ++i) {
|
|
@@ -344,9 +340,7 @@ exports.merge = function (target, source, options) {
|
|
|
344
340
|
if (Array.isArray(target)) {
|
|
345
341
|
target.push(source);
|
|
346
342
|
} else if (typeof target === 'object') {
|
|
347
|
-
|
|
348
|
-
target[source] = true;
|
|
349
|
-
}
|
|
343
|
+
target[source] = true;
|
|
350
344
|
} else {
|
|
351
345
|
return [target, source];
|
|
352
346
|
}
|
|
@@ -366,7 +360,7 @@ exports.merge = function (target, source, options) {
|
|
|
366
360
|
return Object.keys(source).reduce(function (acc, key) {
|
|
367
361
|
var value = source[key];
|
|
368
362
|
|
|
369
|
-
if (
|
|
363
|
+
if (Object.prototype.hasOwnProperty.call(acc, key)) {
|
|
370
364
|
acc[key] = exports.merge(acc[key], value, options);
|
|
371
365
|
} else {
|
|
372
366
|
acc[key] = value;
|
package/lib/index.js
CHANGED
|
File without changes
|
package/lib/parse.js
CHANGED
|
@@ -13,8 +13,6 @@ var internals = {
|
|
|
13
13
|
allowDots: false
|
|
14
14
|
};
|
|
15
15
|
|
|
16
|
-
var has = Object.prototype.hasOwnProperty;
|
|
17
|
-
|
|
18
16
|
internals.parseValues = function (str, options) {
|
|
19
17
|
var obj = {};
|
|
20
18
|
var parts = str.split(options.delimiter, options.parameterLimit === Infinity ? undefined : options.parameterLimit);
|
|
@@ -33,7 +31,7 @@ internals.parseValues = function (str, options) {
|
|
|
33
31
|
var key = Utils.decode(part.slice(0, pos));
|
|
34
32
|
var val = Utils.decode(part.slice(pos + 1));
|
|
35
33
|
|
|
36
|
-
if (
|
|
34
|
+
if (Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
37
35
|
obj[key] = [].concat(obj[key]).concat(val);
|
|
38
36
|
} else {
|
|
39
37
|
obj[key] = val;
|
|
@@ -57,7 +55,7 @@ internals.parseObject = function (chain, val, options) {
|
|
|
57
55
|
obj = obj.concat(internals.parseObject(chain, val, options));
|
|
58
56
|
} else {
|
|
59
57
|
obj = options.plainObjects ? Object.create(null) : {};
|
|
60
|
-
var cleanRoot = root
|
|
58
|
+
var cleanRoot = root[0] === '[' && root[root.length - 1] === ']' ? root.slice(1, root.length - 1) : root;
|
|
61
59
|
var index = parseInt(cleanRoot, 10);
|
|
62
60
|
if (
|
|
63
61
|
!isNaN(index) &&
|
|
@@ -86,27 +84,26 @@ internals.parseKeys = function (givenKey, val, options) {
|
|
|
86
84
|
|
|
87
85
|
// The regex chunks
|
|
88
86
|
|
|
89
|
-
var
|
|
90
|
-
var child = /(\[[
|
|
87
|
+
var parent = /^([^\[\]]*)/;
|
|
88
|
+
var child = /(\[[^\[\]]*\])/g;
|
|
91
89
|
|
|
92
90
|
// Get the parent
|
|
93
91
|
|
|
94
|
-
var segment =
|
|
95
|
-
var parent = segment ? key.slice(0, segment.index) : key;
|
|
92
|
+
var segment = parent.exec(key);
|
|
96
93
|
|
|
97
94
|
// Stash the parent if it exists
|
|
98
95
|
|
|
99
96
|
var keys = [];
|
|
100
|
-
if (
|
|
97
|
+
if (segment[1]) {
|
|
101
98
|
// If we aren't using plain objects, optionally prefix keys
|
|
102
99
|
// that would overwrite object prototype properties
|
|
103
|
-
if (!options.plainObjects &&
|
|
100
|
+
if (!options.plainObjects && Object.prototype.hasOwnProperty(segment[1])) {
|
|
104
101
|
if (!options.allowPrototypes) {
|
|
105
102
|
return;
|
|
106
103
|
}
|
|
107
104
|
}
|
|
108
105
|
|
|
109
|
-
keys.push(
|
|
106
|
+
keys.push(segment[1]);
|
|
110
107
|
}
|
|
111
108
|
|
|
112
109
|
// Loop through children appending to the array until we hit depth
|
|
@@ -114,9 +111,9 @@ internals.parseKeys = function (givenKey, val, options) {
|
|
|
114
111
|
var i = 0;
|
|
115
112
|
while ((segment = child.exec(key)) !== null && i < options.depth) {
|
|
116
113
|
i += 1;
|
|
117
|
-
if (!options.plainObjects &&
|
|
114
|
+
if (!options.plainObjects && Object.prototype.hasOwnProperty(segment[1].replace(/\[|\]/g, ''))) {
|
|
118
115
|
if (!options.allowPrototypes) {
|
|
119
|
-
|
|
116
|
+
continue;
|
|
120
117
|
}
|
|
121
118
|
}
|
|
122
119
|
keys.push(segment[1]);
|
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,8 +9,6 @@ var hexTable = (function () {
|
|
|
9
9
|
return array;
|
|
10
10
|
}());
|
|
11
11
|
|
|
12
|
-
var has = Object.prototype.hasOwnProperty;
|
|
13
|
-
|
|
14
12
|
exports.arrayToObject = function (source, options) {
|
|
15
13
|
var obj = options.plainObjects ? Object.create(null) : {};
|
|
16
14
|
for (var i = 0; i < source.length; ++i) {
|
|
@@ -31,9 +29,7 @@ exports.merge = function (target, source, options) {
|
|
|
31
29
|
if (Array.isArray(target)) {
|
|
32
30
|
target.push(source);
|
|
33
31
|
} else if (typeof target === 'object') {
|
|
34
|
-
|
|
35
|
-
target[source] = true;
|
|
36
|
-
}
|
|
32
|
+
target[source] = true;
|
|
37
33
|
} else {
|
|
38
34
|
return [target, source];
|
|
39
35
|
}
|
|
@@ -53,7 +49,7 @@ exports.merge = function (target, source, options) {
|
|
|
53
49
|
return Object.keys(source).reduce(function (acc, key) {
|
|
54
50
|
var value = source[key];
|
|
55
51
|
|
|
56
|
-
if (
|
|
52
|
+
if (Object.prototype.hasOwnProperty.call(acc, key)) {
|
|
57
53
|
acc[key] = exports.merge(acc[key], value, options);
|
|
58
54
|
} else {
|
|
59
55
|
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.0
|
|
5
|
+
"version": "6.1.0",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
8
8
|
"url": "https://github.com/ljharb/qs.git"
|
|
@@ -34,8 +34,7 @@
|
|
|
34
34
|
"evalmd": "^0.0.16"
|
|
35
35
|
},
|
|
36
36
|
"scripts": {
|
|
37
|
-
"
|
|
38
|
-
"test": "npm run coverage",
|
|
37
|
+
"test": "parallelshell 'npm run readme' 'npm run lint' 'npm run coverage'",
|
|
39
38
|
"tests-only": "node test",
|
|
40
39
|
"readme": "evalmd README.md",
|
|
41
40
|
"lint": "eslint lib/*.js text/*.js",
|
package/test/parse.js
CHANGED
|
@@ -120,11 +120,8 @@ test('parse()', function (t) {
|
|
|
120
120
|
st.deepEqual(qs.parse('foo[]=bar&foo[bad]=baz'), { foo: { '0': 'bar', bad: 'baz' } });
|
|
121
121
|
st.deepEqual(qs.parse('foo[bad]=baz&foo[]=bar&foo[]=foo'), { foo: { bad: 'baz', '0': 'bar', '1': 'foo' } });
|
|
122
122
|
st.deepEqual(qs.parse('foo[0][a]=a&foo[0][b]=b&foo[1][a]=aa&foo[1][b]=bb'), { foo: [{ a: 'a', b: 'b' }, { a: 'aa', b: 'bb' }] });
|
|
123
|
-
|
|
124
|
-
st.deepEqual(qs.parse('a[]=b&a[
|
|
125
|
-
st.deepEqual(qs.parse('a[]=b&a[t]=u&a[hasOwnProperty]=c', { allowPrototypes: true }), { a: { 0: 'b', t: 'u', hasOwnProperty: 'c' } });
|
|
126
|
-
st.deepEqual(qs.parse('a[]=b&a[hasOwnProperty]=c&a[x]=y', { allowPrototypes: false }), { a: { 0: 'b', x: 'y' } });
|
|
127
|
-
st.deepEqual(qs.parse('a[]=b&a[hasOwnProperty]=c&a[x]=y', { allowPrototypes: true }), { a: { 0: 'b', hasOwnProperty: 'c', x: 'y' } });
|
|
123
|
+
st.deepEqual(qs.parse('a[]=b&a[t]=u&a[hasOwnProperty]=c'), { a: { '0': 'b', t: 'u', c: true } });
|
|
124
|
+
st.deepEqual(qs.parse('a[]=b&a[hasOwnProperty]=c&a[x]=y'), { a: { '0': 'b', '1': 'c', x: 'y' } });
|
|
128
125
|
st.end();
|
|
129
126
|
});
|
|
130
127
|
|
|
@@ -142,6 +139,8 @@ test('parse()', function (t) {
|
|
|
142
139
|
st.end();
|
|
143
140
|
});
|
|
144
141
|
|
|
142
|
+
t.deepEqual(qs.parse('a[b]=c&a=d'), { a: { b: 'c', d: true } }, 'can add keys to objects');
|
|
143
|
+
|
|
145
144
|
t.test('correctly prunes undefined values when converting an array to an object', function (st) {
|
|
146
145
|
st.deepEqual(qs.parse('a[2]=b&a[99999999]=c'), { a: { '2': 'b', '99999999': 'c' } });
|
|
147
146
|
st.end();
|
|
@@ -371,75 +370,13 @@ test('parse()', function (t) {
|
|
|
371
370
|
st.end();
|
|
372
371
|
});
|
|
373
372
|
|
|
374
|
-
t.test('does not allow overwriting prototype properties', function (st) {
|
|
375
|
-
st.deepEqual(qs.parse('a[hasOwnProperty]=b', { allowPrototypes: false }), {});
|
|
376
|
-
st.deepEqual(qs.parse('hasOwnProperty=b', { allowPrototypes: false }), {});
|
|
377
|
-
|
|
378
|
-
st.deepEqual(
|
|
379
|
-
qs.parse('toString', { allowPrototypes: false }),
|
|
380
|
-
{},
|
|
381
|
-
'bare "toString" results in {}'
|
|
382
|
-
);
|
|
383
|
-
|
|
384
|
-
st.end();
|
|
385
|
-
});
|
|
386
|
-
|
|
387
373
|
t.test('can allow overwriting prototype properties', function (st) {
|
|
388
|
-
st.deepEqual(qs.parse('a[hasOwnProperty]=b', { allowPrototypes: true }), { a: { hasOwnProperty: 'b' } });
|
|
389
|
-
st.deepEqual(qs.parse('hasOwnProperty=b', { allowPrototypes: true }), { hasOwnProperty: 'b' });
|
|
390
|
-
|
|
391
|
-
st.deepEqual(
|
|
392
|
-
qs.parse('toString', { allowPrototypes: true }),
|
|
393
|
-
{ toString: '' },
|
|
394
|
-
'bare "toString" results in { toString: "" }'
|
|
395
|
-
);
|
|
396
|
-
|
|
397
|
-
st.end();
|
|
398
|
-
});
|
|
399
|
-
|
|
400
|
-
t.test('params starting with a closing bracket', function (st) {
|
|
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
|
-
|
|
374
|
+
st.deepEqual(qs.parse('a[hasOwnProperty]=b', { allowPrototypes: true }), { a: { hasOwnProperty: 'b' } }, { prototype: false });
|
|
375
|
+
st.deepEqual(qs.parse('hasOwnProperty=b', { allowPrototypes: true }), { hasOwnProperty: 'b' }, { prototype: false });
|
|
439
376
|
st.end();
|
|
440
377
|
});
|
|
441
378
|
|
|
442
|
-
t.test('can return
|
|
379
|
+
t.test('can return plain objects', function (st) {
|
|
443
380
|
var expected = Object.create(null);
|
|
444
381
|
expected.a = Object.create(null);
|
|
445
382
|
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
|