qs 3.1.0 → 5.2.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/.npmignore +0 -1
- package/.travis.yml +4 -2
- package/CHANGELOG.md +13 -2
- package/README.md +32 -4
- package/bower.json +1 -1
- package/component.json +15 -0
- package/dist/qs.js +544 -0
- package/lib/parse.js +33 -12
- package/lib/stringify.js +41 -8
- package/lib/utils.js +8 -8
- package/package.json +15 -12
- package/test/parse.js +137 -114
- package/test/stringify.js +44 -10
- package/.jshintignore +0 -1
- package/.jshintrc +0 -10
- package/Makefile +0 -8
- package/index.js +0 -1
package/lib/parse.js
CHANGED
|
@@ -10,7 +10,10 @@ var internals = {
|
|
|
10
10
|
depth: 5,
|
|
11
11
|
arrayLimit: 20,
|
|
12
12
|
parameterLimit: 1000,
|
|
13
|
-
strictNullHandling: false
|
|
13
|
+
strictNullHandling: false,
|
|
14
|
+
plainObjects: false,
|
|
15
|
+
allowPrototypes: false,
|
|
16
|
+
allowDots: false
|
|
14
17
|
};
|
|
15
18
|
|
|
16
19
|
|
|
@@ -61,7 +64,7 @@ internals.parseObject = function (chain, val, options) {
|
|
|
61
64
|
obj = obj.concat(internals.parseObject(chain, val, options));
|
|
62
65
|
}
|
|
63
66
|
else {
|
|
64
|
-
obj = Object.create(null);
|
|
67
|
+
obj = options.plainObjects ? Object.create(null) : {};
|
|
65
68
|
var cleanRoot = root[0] === '[' && root[root.length - 1] === ']' ? root.slice(1, root.length - 1) : root;
|
|
66
69
|
var index = parseInt(cleanRoot, 10);
|
|
67
70
|
var indexString = '' + index;
|
|
@@ -109,6 +112,16 @@ internals.parseKeys = function (key, val, options) {
|
|
|
109
112
|
|
|
110
113
|
var keys = [];
|
|
111
114
|
if (segment[1]) {
|
|
115
|
+
// If we aren't using plain objects, optionally prefix keys
|
|
116
|
+
// that would overwrite object prototype properties
|
|
117
|
+
if (!options.plainObjects &&
|
|
118
|
+
Object.prototype.hasOwnProperty(segment[1])) {
|
|
119
|
+
|
|
120
|
+
if (!options.allowPrototypes) {
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
112
125
|
keys.push(segment[1]);
|
|
113
126
|
}
|
|
114
127
|
|
|
@@ -118,6 +131,13 @@ internals.parseKeys = function (key, val, options) {
|
|
|
118
131
|
while ((segment = child.exec(key)) !== null && i < options.depth) {
|
|
119
132
|
|
|
120
133
|
++i;
|
|
134
|
+
if (!options.plainObjects &&
|
|
135
|
+
Object.prototype.hasOwnProperty(segment[1].replace(/\[|\]/g, ''))) {
|
|
136
|
+
|
|
137
|
+
if (!options.allowPrototypes) {
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
121
141
|
keys.push(segment[1]);
|
|
122
142
|
}
|
|
123
143
|
|
|
@@ -133,25 +153,26 @@ internals.parseKeys = function (key, val, options) {
|
|
|
133
153
|
|
|
134
154
|
module.exports = function (str, options) {
|
|
135
155
|
|
|
136
|
-
if (str === '' ||
|
|
137
|
-
str === null ||
|
|
138
|
-
typeof str === 'undefined') {
|
|
139
|
-
|
|
140
|
-
return Object.create(null);
|
|
141
|
-
}
|
|
142
|
-
|
|
143
156
|
options = options || {};
|
|
144
157
|
options.delimiter = typeof options.delimiter === 'string' || Utils.isRegExp(options.delimiter) ? options.delimiter : internals.delimiter;
|
|
145
158
|
options.depth = typeof options.depth === 'number' ? options.depth : internals.depth;
|
|
146
159
|
options.arrayLimit = typeof options.arrayLimit === 'number' ? options.arrayLimit : internals.arrayLimit;
|
|
147
160
|
options.parseArrays = options.parseArrays !== false;
|
|
148
|
-
options.allowDots = options.allowDots
|
|
161
|
+
options.allowDots = typeof options.allowDots === 'boolean' ? options.allowDots : internals.allowDots;
|
|
162
|
+
options.plainObjects = typeof options.plainObjects === 'boolean' ? options.plainObjects : internals.plainObjects;
|
|
163
|
+
options.allowPrototypes = typeof options.allowPrototypes === 'boolean' ? options.allowPrototypes : internals.allowPrototypes;
|
|
149
164
|
options.parameterLimit = typeof options.parameterLimit === 'number' ? options.parameterLimit : internals.parameterLimit;
|
|
150
165
|
options.strictNullHandling = typeof options.strictNullHandling === 'boolean' ? options.strictNullHandling : internals.strictNullHandling;
|
|
151
166
|
|
|
167
|
+
if (str === '' ||
|
|
168
|
+
str === null ||
|
|
169
|
+
typeof str === 'undefined') {
|
|
170
|
+
|
|
171
|
+
return options.plainObjects ? Object.create(null) : {};
|
|
172
|
+
}
|
|
152
173
|
|
|
153
174
|
var tempObj = typeof str === 'string' ? internals.parseValues(str, options) : str;
|
|
154
|
-
var obj = Object.create(null);
|
|
175
|
+
var obj = options.plainObjects ? Object.create(null) : {};
|
|
155
176
|
|
|
156
177
|
// Iterate over the keys and setup the new object
|
|
157
178
|
|
|
@@ -159,7 +180,7 @@ module.exports = function (str, options) {
|
|
|
159
180
|
for (var i = 0, il = keys.length; i < il; ++i) {
|
|
160
181
|
var key = keys[i];
|
|
161
182
|
var newObj = internals.parseKeys(key, tempObj[key], options);
|
|
162
|
-
obj = Utils.merge(obj, newObj);
|
|
183
|
+
obj = Utils.merge(obj, newObj, options);
|
|
163
184
|
}
|
|
164
185
|
|
|
165
186
|
return Utils.compact(obj);
|
package/lib/stringify.js
CHANGED
|
@@ -21,11 +21,13 @@ var internals = {
|
|
|
21
21
|
return prefix;
|
|
22
22
|
}
|
|
23
23
|
},
|
|
24
|
-
strictNullHandling: false
|
|
24
|
+
strictNullHandling: false,
|
|
25
|
+
skipNulls: false,
|
|
26
|
+
encode: true
|
|
25
27
|
};
|
|
26
28
|
|
|
27
29
|
|
|
28
|
-
internals.stringify = function (obj, prefix, generateArrayPrefix, strictNullHandling, filter) {
|
|
30
|
+
internals.stringify = function (obj, prefix, generateArrayPrefix, strictNullHandling, skipNulls, encode, filter, sort) {
|
|
29
31
|
|
|
30
32
|
if (typeof filter === 'function') {
|
|
31
33
|
obj = filter(prefix, obj);
|
|
@@ -38,7 +40,7 @@ internals.stringify = function (obj, prefix, generateArrayPrefix, strictNullHand
|
|
|
38
40
|
}
|
|
39
41
|
else if (obj === null) {
|
|
40
42
|
if (strictNullHandling) {
|
|
41
|
-
return Utils.encode(prefix);
|
|
43
|
+
return encode ? Utils.encode(prefix) : prefix;
|
|
42
44
|
}
|
|
43
45
|
|
|
44
46
|
obj = '';
|
|
@@ -48,7 +50,10 @@ internals.stringify = function (obj, prefix, generateArrayPrefix, strictNullHand
|
|
|
48
50
|
typeof obj === 'number' ||
|
|
49
51
|
typeof obj === 'boolean') {
|
|
50
52
|
|
|
51
|
-
|
|
53
|
+
if (encode) {
|
|
54
|
+
return [Utils.encode(prefix) + '=' + Utils.encode(obj)];
|
|
55
|
+
}
|
|
56
|
+
return [prefix + '=' + obj];
|
|
52
57
|
}
|
|
53
58
|
|
|
54
59
|
var values = [];
|
|
@@ -57,15 +62,28 @@ internals.stringify = function (obj, prefix, generateArrayPrefix, strictNullHand
|
|
|
57
62
|
return values;
|
|
58
63
|
}
|
|
59
64
|
|
|
60
|
-
var objKeys
|
|
65
|
+
var objKeys;
|
|
66
|
+
if (Array.isArray(filter)) {
|
|
67
|
+
objKeys = filter;
|
|
68
|
+
} else {
|
|
69
|
+
var keys = Object.keys(obj);
|
|
70
|
+
objKeys = sort ? keys.sort(sort) : keys;
|
|
71
|
+
}
|
|
72
|
+
|
|
61
73
|
for (var i = 0, il = objKeys.length; i < il; ++i) {
|
|
62
74
|
var key = objKeys[i];
|
|
63
75
|
|
|
76
|
+
if (skipNulls &&
|
|
77
|
+
obj[key] === null) {
|
|
78
|
+
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
|
|
64
82
|
if (Array.isArray(obj)) {
|
|
65
|
-
values = values.concat(internals.stringify(obj[key], generateArrayPrefix(prefix, key), generateArrayPrefix, strictNullHandling, filter));
|
|
83
|
+
values = values.concat(internals.stringify(obj[key], generateArrayPrefix(prefix, key), generateArrayPrefix, strictNullHandling, skipNulls, encode, filter));
|
|
66
84
|
}
|
|
67
85
|
else {
|
|
68
|
-
values = values.concat(internals.stringify(obj[key], prefix + '[' + key + ']', generateArrayPrefix, strictNullHandling, filter));
|
|
86
|
+
values = values.concat(internals.stringify(obj[key], prefix + '[' + key + ']', generateArrayPrefix, strictNullHandling, skipNulls, encode, filter));
|
|
69
87
|
}
|
|
70
88
|
}
|
|
71
89
|
|
|
@@ -78,6 +96,9 @@ module.exports = function (obj, options) {
|
|
|
78
96
|
options = options || {};
|
|
79
97
|
var delimiter = typeof options.delimiter === 'undefined' ? internals.delimiter : options.delimiter;
|
|
80
98
|
var strictNullHandling = typeof options.strictNullHandling === 'boolean' ? options.strictNullHandling : internals.strictNullHandling;
|
|
99
|
+
var skipNulls = typeof options.skipNulls === 'boolean' ? options.skipNulls : internals.skipNulls;
|
|
100
|
+
var encode = typeof options.encode === 'boolean' ? options.encode : internals.encode;
|
|
101
|
+
var sort = typeof options.sort === 'function' ? options.sort : null;
|
|
81
102
|
var objKeys;
|
|
82
103
|
var filter;
|
|
83
104
|
if (typeof options.filter === 'function') {
|
|
@@ -112,9 +133,21 @@ module.exports = function (obj, options) {
|
|
|
112
133
|
if (!objKeys) {
|
|
113
134
|
objKeys = Object.keys(obj);
|
|
114
135
|
}
|
|
136
|
+
|
|
137
|
+
if (sort) {
|
|
138
|
+
objKeys.sort(sort);
|
|
139
|
+
}
|
|
140
|
+
|
|
115
141
|
for (var i = 0, il = objKeys.length; i < il; ++i) {
|
|
116
142
|
var key = objKeys[i];
|
|
117
|
-
|
|
143
|
+
|
|
144
|
+
if (skipNulls &&
|
|
145
|
+
obj[key] === null) {
|
|
146
|
+
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
keys = keys.concat(internals.stringify(obj[key], key, generateArrayPrefix, strictNullHandling, skipNulls, encode, filter, sort));
|
|
118
151
|
}
|
|
119
152
|
|
|
120
153
|
return keys.join(delimiter);
|
package/lib/utils.js
CHANGED
|
@@ -5,14 +5,14 @@
|
|
|
5
5
|
|
|
6
6
|
var internals = {};
|
|
7
7
|
internals.hexTable = new Array(256);
|
|
8
|
-
for (var
|
|
9
|
-
internals.hexTable[
|
|
8
|
+
for (var h = 0; h < 256; ++h) {
|
|
9
|
+
internals.hexTable[h] = '%' + ((h < 16 ? '0' : '') + h.toString(16)).toUpperCase();
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
|
|
13
|
-
exports.arrayToObject = function (source) {
|
|
13
|
+
exports.arrayToObject = function (source, options) {
|
|
14
14
|
|
|
15
|
-
var obj = Object.create(null);
|
|
15
|
+
var obj = options.plainObjects ? Object.create(null) : {};
|
|
16
16
|
for (var i = 0, il = source.length; i < il; ++i) {
|
|
17
17
|
if (typeof source[i] !== 'undefined') {
|
|
18
18
|
|
|
@@ -24,7 +24,7 @@ exports.arrayToObject = function (source) {
|
|
|
24
24
|
};
|
|
25
25
|
|
|
26
26
|
|
|
27
|
-
exports.merge = function (target, source) {
|
|
27
|
+
exports.merge = function (target, source, options) {
|
|
28
28
|
|
|
29
29
|
if (!source) {
|
|
30
30
|
return target;
|
|
@@ -52,7 +52,7 @@ exports.merge = function (target, source) {
|
|
|
52
52
|
if (Array.isArray(target) &&
|
|
53
53
|
!Array.isArray(source)) {
|
|
54
54
|
|
|
55
|
-
target = exports.arrayToObject(target);
|
|
55
|
+
target = exports.arrayToObject(target, options);
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
var keys = Object.keys(source);
|
|
@@ -60,11 +60,11 @@ exports.merge = function (target, source) {
|
|
|
60
60
|
var key = keys[k];
|
|
61
61
|
var value = source[key];
|
|
62
62
|
|
|
63
|
-
if (!target
|
|
63
|
+
if (!Object.prototype.hasOwnProperty.call(target, key)) {
|
|
64
64
|
target[key] = value;
|
|
65
65
|
}
|
|
66
66
|
else {
|
|
67
|
-
target[key] = exports.merge(target[key], value);
|
|
67
|
+
target[key] = exports.merge(target[key], value, options);
|
|
68
68
|
}
|
|
69
69
|
}
|
|
70
70
|
|
package/package.json
CHANGED
|
@@ -1,26 +1,29 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "qs",
|
|
3
|
-
"version": "3.1.0",
|
|
4
3
|
"description": "A querystring parser that supports nesting and arrays, with a depth limit",
|
|
5
4
|
"homepage": "https://github.com/hapijs/qs",
|
|
6
|
-
"
|
|
7
|
-
"dependencies": {},
|
|
8
|
-
"devDependencies": {
|
|
9
|
-
"browserify": "^10.2.1",
|
|
10
|
-
"code": "1.x.x",
|
|
11
|
-
"lab": "5.x.x"
|
|
12
|
-
},
|
|
13
|
-
"scripts": {
|
|
14
|
-
"test": "make test-cov",
|
|
15
|
-
"dist": "browserify --standalone Qs index.js > dist/qs.js"
|
|
16
|
-
},
|
|
5
|
+
"version": "5.2.0",
|
|
17
6
|
"repository": {
|
|
18
7
|
"type": "git",
|
|
19
8
|
"url": "https://github.com/hapijs/qs.git"
|
|
20
9
|
},
|
|
10
|
+
"main": "lib/index.js",
|
|
21
11
|
"keywords": [
|
|
22
12
|
"querystring",
|
|
23
13
|
"qs"
|
|
24
14
|
],
|
|
15
|
+
"engines": ">=0.10.40",
|
|
16
|
+
"dependencies": {},
|
|
17
|
+
"devDependencies": {
|
|
18
|
+
"browserify": "^10.2.1",
|
|
19
|
+
"code": "1.x.x",
|
|
20
|
+
"lab": "5.x.x"
|
|
21
|
+
},
|
|
22
|
+
"scripts": {
|
|
23
|
+
"test": "lab -a code -t 100 -L",
|
|
24
|
+
"test-tap": "lab -a code -r tap -o tests.tap",
|
|
25
|
+
"test-cov-html": "lab -a code -r html -o coverage.html",
|
|
26
|
+
"dist": "browserify --standalone Qs lib/index.js > dist/qs.js"
|
|
27
|
+
},
|
|
25
28
|
"license": "BSD-3-Clause"
|
|
26
29
|
}
|