qs 6.5.0 → 6.6.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 +6 -3
- package/CHANGELOG.md +30 -0
- package/README.md +88 -2
- package/dist/qs.js +210 -88
- package/lib/parse.js +87 -33
- package/lib/stringify.js +46 -14
- package/lib/utils.js +78 -42
- package/package.json +9 -8
- package/test/.eslintrc +6 -0
- package/test/parse.js +118 -5
- package/test/stringify.js +59 -6
- package/test/utils.js +55 -0
package/lib/parse.js
CHANGED
|
@@ -8,21 +8,62 @@ var defaults = {
|
|
|
8
8
|
allowDots: false,
|
|
9
9
|
allowPrototypes: false,
|
|
10
10
|
arrayLimit: 20,
|
|
11
|
+
charset: 'utf-8',
|
|
12
|
+
charsetSentinel: false,
|
|
11
13
|
decoder: utils.decode,
|
|
12
14
|
delimiter: '&',
|
|
13
15
|
depth: 5,
|
|
16
|
+
ignoreQueryPrefix: false,
|
|
17
|
+
interpretNumericEntities: false,
|
|
14
18
|
parameterLimit: 1000,
|
|
19
|
+
parseArrays: true,
|
|
15
20
|
plainObjects: false,
|
|
16
21
|
strictNullHandling: false
|
|
17
22
|
};
|
|
18
23
|
|
|
24
|
+
var interpretNumericEntities = function (str) {
|
|
25
|
+
return str.replace(/&#(\d+);/g, function ($0, numberStr) {
|
|
26
|
+
return String.fromCharCode(parseInt(numberStr, 10));
|
|
27
|
+
});
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
// This is what browsers will submit when the ✓ character occurs in an
|
|
31
|
+
// application/x-www-form-urlencoded body and the encoding of the page containing
|
|
32
|
+
// the form is iso-8859-1, or when the submitted form has an accept-charset
|
|
33
|
+
// attribute of iso-8859-1. Presumably also with other charsets that do not contain
|
|
34
|
+
// the ✓ character, such as us-ascii.
|
|
35
|
+
var isoSentinel = 'utf8=%26%2310003%3B'; // encodeURIComponent('✓')
|
|
36
|
+
|
|
37
|
+
// These are the percent-encoded utf-8 octets representing a checkmark, indicating that the request actually is utf-8 encoded.
|
|
38
|
+
var charsetSentinel = 'utf8=%E2%9C%93'; // encodeURIComponent('✓')
|
|
39
|
+
|
|
19
40
|
var parseValues = function parseQueryStringValues(str, options) {
|
|
20
41
|
var obj = {};
|
|
21
42
|
var cleanStr = options.ignoreQueryPrefix ? str.replace(/^\?/, '') : str;
|
|
22
43
|
var limit = options.parameterLimit === Infinity ? undefined : options.parameterLimit;
|
|
23
44
|
var parts = cleanStr.split(options.delimiter, limit);
|
|
45
|
+
var skipIndex = -1; // Keep track of where the utf8 sentinel was found
|
|
46
|
+
var i;
|
|
47
|
+
|
|
48
|
+
var charset = options.charset;
|
|
49
|
+
if (options.charsetSentinel) {
|
|
50
|
+
for (i = 0; i < parts.length; ++i) {
|
|
51
|
+
if (parts[i].indexOf('utf8=') === 0) {
|
|
52
|
+
if (parts[i] === charsetSentinel) {
|
|
53
|
+
charset = 'utf-8';
|
|
54
|
+
} else if (parts[i] === isoSentinel) {
|
|
55
|
+
charset = 'iso-8859-1';
|
|
56
|
+
}
|
|
57
|
+
skipIndex = i;
|
|
58
|
+
i = parts.length; // The eslint settings do not allow break;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
24
62
|
|
|
25
|
-
for (
|
|
63
|
+
for (i = 0; i < parts.length; ++i) {
|
|
64
|
+
if (i === skipIndex) {
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
26
67
|
var part = parts[i];
|
|
27
68
|
|
|
28
69
|
var bracketEqualsPos = part.indexOf(']=');
|
|
@@ -30,14 +71,18 @@ var parseValues = function parseQueryStringValues(str, options) {
|
|
|
30
71
|
|
|
31
72
|
var key, val;
|
|
32
73
|
if (pos === -1) {
|
|
33
|
-
key = options.decoder(part, defaults.decoder);
|
|
74
|
+
key = options.decoder(part, defaults.decoder, charset);
|
|
34
75
|
val = options.strictNullHandling ? null : '';
|
|
35
76
|
} else {
|
|
36
|
-
key = options.decoder(part.slice(0, pos), defaults.decoder);
|
|
37
|
-
val = options.decoder(part.slice(pos + 1), defaults.decoder);
|
|
77
|
+
key = options.decoder(part.slice(0, pos), defaults.decoder, charset);
|
|
78
|
+
val = options.decoder(part.slice(pos + 1), defaults.decoder, charset);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (val && options.interpretNumericEntities && charset === 'iso-8859-1') {
|
|
82
|
+
val = interpretNumericEntities(val);
|
|
38
83
|
}
|
|
39
84
|
if (has.call(obj, key)) {
|
|
40
|
-
obj[key] =
|
|
85
|
+
obj[key] = utils.combine(obj[key], val);
|
|
41
86
|
} else {
|
|
42
87
|
obj[key] = val;
|
|
43
88
|
}
|
|
@@ -46,36 +91,39 @@ var parseValues = function parseQueryStringValues(str, options) {
|
|
|
46
91
|
return obj;
|
|
47
92
|
};
|
|
48
93
|
|
|
49
|
-
var parseObject = function
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
94
|
+
var parseObject = function (chain, val, options) {
|
|
95
|
+
var leaf = val;
|
|
96
|
+
|
|
97
|
+
for (var i = chain.length - 1; i >= 0; --i) {
|
|
98
|
+
var obj;
|
|
99
|
+
var root = chain[i];
|
|
53
100
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
var obj;
|
|
57
|
-
if (root === '[]') {
|
|
58
|
-
obj = [];
|
|
59
|
-
obj = obj.concat(parseObject(chain, val, options));
|
|
60
|
-
} else {
|
|
61
|
-
obj = options.plainObjects ? Object.create(null) : {};
|
|
62
|
-
var cleanRoot = root.charAt(0) === '[' && root.charAt(root.length - 1) === ']' ? root.slice(1, -1) : root;
|
|
63
|
-
var index = parseInt(cleanRoot, 10);
|
|
64
|
-
if (
|
|
65
|
-
!isNaN(index)
|
|
66
|
-
&& root !== cleanRoot
|
|
67
|
-
&& String(index) === cleanRoot
|
|
68
|
-
&& index >= 0
|
|
69
|
-
&& (options.parseArrays && index <= options.arrayLimit)
|
|
70
|
-
) {
|
|
71
|
-
obj = [];
|
|
72
|
-
obj[index] = parseObject(chain, val, options);
|
|
101
|
+
if (root === '[]' && options.parseArrays) {
|
|
102
|
+
obj = [].concat(leaf);
|
|
73
103
|
} else {
|
|
74
|
-
obj
|
|
104
|
+
obj = options.plainObjects ? Object.create(null) : {};
|
|
105
|
+
var cleanRoot = root.charAt(0) === '[' && root.charAt(root.length - 1) === ']' ? root.slice(1, -1) : root;
|
|
106
|
+
var index = parseInt(cleanRoot, 10);
|
|
107
|
+
if (!options.parseArrays && cleanRoot === '') {
|
|
108
|
+
obj = { 0: leaf };
|
|
109
|
+
} else if (
|
|
110
|
+
!isNaN(index)
|
|
111
|
+
&& root !== cleanRoot
|
|
112
|
+
&& String(index) === cleanRoot
|
|
113
|
+
&& index >= 0
|
|
114
|
+
&& (options.parseArrays && index <= options.arrayLimit)
|
|
115
|
+
) {
|
|
116
|
+
obj = [];
|
|
117
|
+
obj[index] = leaf;
|
|
118
|
+
} else {
|
|
119
|
+
obj[cleanRoot] = leaf;
|
|
120
|
+
}
|
|
75
121
|
}
|
|
122
|
+
|
|
123
|
+
leaf = obj;
|
|
76
124
|
}
|
|
77
125
|
|
|
78
|
-
return
|
|
126
|
+
return leaf;
|
|
79
127
|
};
|
|
80
128
|
|
|
81
129
|
var parseKeys = function parseQueryStringKeys(givenKey, val, options) {
|
|
@@ -100,8 +148,7 @@ var parseKeys = function parseQueryStringKeys(givenKey, val, options) {
|
|
|
100
148
|
|
|
101
149
|
var keys = [];
|
|
102
150
|
if (parent) {
|
|
103
|
-
// If we aren't using plain objects, optionally prefix keys
|
|
104
|
-
// that would overwrite object prototype properties
|
|
151
|
+
// If we aren't using plain objects, optionally prefix keys that would overwrite object prototype properties
|
|
105
152
|
if (!options.plainObjects && has.call(Object.prototype, parent)) {
|
|
106
153
|
if (!options.allowPrototypes) {
|
|
107
154
|
return;
|
|
@@ -146,12 +193,19 @@ module.exports = function (str, opts) {
|
|
|
146
193
|
options.arrayLimit = typeof options.arrayLimit === 'number' ? options.arrayLimit : defaults.arrayLimit;
|
|
147
194
|
options.parseArrays = options.parseArrays !== false;
|
|
148
195
|
options.decoder = typeof options.decoder === 'function' ? options.decoder : defaults.decoder;
|
|
149
|
-
options.allowDots = typeof options.allowDots === '
|
|
196
|
+
options.allowDots = typeof options.allowDots === 'undefined' ? defaults.allowDots : !!options.allowDots;
|
|
150
197
|
options.plainObjects = typeof options.plainObjects === 'boolean' ? options.plainObjects : defaults.plainObjects;
|
|
151
198
|
options.allowPrototypes = typeof options.allowPrototypes === 'boolean' ? options.allowPrototypes : defaults.allowPrototypes;
|
|
152
199
|
options.parameterLimit = typeof options.parameterLimit === 'number' ? options.parameterLimit : defaults.parameterLimit;
|
|
153
200
|
options.strictNullHandling = typeof options.strictNullHandling === 'boolean' ? options.strictNullHandling : defaults.strictNullHandling;
|
|
154
201
|
|
|
202
|
+
if (typeof options.charset !== 'undefined' && options.charset !== 'utf-8' && options.charset !== 'iso-8859-1') {
|
|
203
|
+
throw new Error('The charset option must be either utf-8, iso-8859-1, or undefined');
|
|
204
|
+
}
|
|
205
|
+
if (typeof options.charset === 'undefined') {
|
|
206
|
+
options.charset = defaults.charset;
|
|
207
|
+
}
|
|
208
|
+
|
|
155
209
|
if (str === '' || str === null || typeof str === 'undefined') {
|
|
156
210
|
return options.plainObjects ? Object.create(null) : {};
|
|
157
211
|
}
|
package/lib/stringify.js
CHANGED
|
@@ -15,13 +15,25 @@ var arrayPrefixGenerators = {
|
|
|
15
15
|
}
|
|
16
16
|
};
|
|
17
17
|
|
|
18
|
+
var isArray = Array.isArray;
|
|
19
|
+
var push = Array.prototype.push;
|
|
20
|
+
var pushToArray = function (arr, valueOrArray) {
|
|
21
|
+
push.apply(arr, isArray(valueOrArray) ? valueOrArray : [valueOrArray]);
|
|
22
|
+
};
|
|
23
|
+
|
|
18
24
|
var toISO = Date.prototype.toISOString;
|
|
19
25
|
|
|
20
26
|
var defaults = {
|
|
27
|
+
addQueryPrefix: false,
|
|
28
|
+
allowDots: false,
|
|
29
|
+
charset: 'utf-8',
|
|
30
|
+
charsetSentinel: false,
|
|
21
31
|
delimiter: '&',
|
|
22
32
|
encode: true,
|
|
23
33
|
encoder: utils.encode,
|
|
24
34
|
encodeValuesOnly: false,
|
|
35
|
+
// deprecated
|
|
36
|
+
indices: false,
|
|
25
37
|
serializeDate: function serializeDate(date) { // eslint-disable-line func-name-matching
|
|
26
38
|
return toISO.call(date);
|
|
27
39
|
},
|
|
@@ -41,16 +53,19 @@ var stringify = function stringify( // eslint-disable-line func-name-matching
|
|
|
41
53
|
allowDots,
|
|
42
54
|
serializeDate,
|
|
43
55
|
formatter,
|
|
44
|
-
encodeValuesOnly
|
|
56
|
+
encodeValuesOnly,
|
|
57
|
+
charset
|
|
45
58
|
) {
|
|
46
59
|
var obj = object;
|
|
47
60
|
if (typeof filter === 'function') {
|
|
48
61
|
obj = filter(prefix, obj);
|
|
49
62
|
} else if (obj instanceof Date) {
|
|
50
63
|
obj = serializeDate(obj);
|
|
51
|
-
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (obj === null) {
|
|
52
67
|
if (strictNullHandling) {
|
|
53
|
-
return encoder && !encodeValuesOnly ? encoder(prefix, defaults.encoder) : prefix;
|
|
68
|
+
return encoder && !encodeValuesOnly ? encoder(prefix, defaults.encoder, charset) : prefix;
|
|
54
69
|
}
|
|
55
70
|
|
|
56
71
|
obj = '';
|
|
@@ -58,8 +73,8 @@ var stringify = function stringify( // eslint-disable-line func-name-matching
|
|
|
58
73
|
|
|
59
74
|
if (typeof obj === 'string' || typeof obj === 'number' || typeof obj === 'boolean' || utils.isBuffer(obj)) {
|
|
60
75
|
if (encoder) {
|
|
61
|
-
var keyValue = encodeValuesOnly ? prefix : encoder(prefix, defaults.encoder);
|
|
62
|
-
return [formatter(keyValue) + '=' + formatter(encoder(obj, defaults.encoder))];
|
|
76
|
+
var keyValue = encodeValuesOnly ? prefix : encoder(prefix, defaults.encoder, charset);
|
|
77
|
+
return [formatter(keyValue) + '=' + formatter(encoder(obj, defaults.encoder, charset))];
|
|
63
78
|
}
|
|
64
79
|
return [formatter(prefix) + '=' + formatter(String(obj))];
|
|
65
80
|
}
|
|
@@ -86,7 +101,7 @@ var stringify = function stringify( // eslint-disable-line func-name-matching
|
|
|
86
101
|
}
|
|
87
102
|
|
|
88
103
|
if (Array.isArray(obj)) {
|
|
89
|
-
values
|
|
104
|
+
pushToArray(values, stringify(
|
|
90
105
|
obj[key],
|
|
91
106
|
generateArrayPrefix(prefix, key),
|
|
92
107
|
generateArrayPrefix,
|
|
@@ -98,10 +113,11 @@ var stringify = function stringify( // eslint-disable-line func-name-matching
|
|
|
98
113
|
allowDots,
|
|
99
114
|
serializeDate,
|
|
100
115
|
formatter,
|
|
101
|
-
encodeValuesOnly
|
|
116
|
+
encodeValuesOnly,
|
|
117
|
+
charset
|
|
102
118
|
));
|
|
103
119
|
} else {
|
|
104
|
-
values
|
|
120
|
+
pushToArray(values, stringify(
|
|
105
121
|
obj[key],
|
|
106
122
|
prefix + (allowDots ? '.' + key : '[' + key + ']'),
|
|
107
123
|
generateArrayPrefix,
|
|
@@ -113,7 +129,8 @@ var stringify = function stringify( // eslint-disable-line func-name-matching
|
|
|
113
129
|
allowDots,
|
|
114
130
|
serializeDate,
|
|
115
131
|
formatter,
|
|
116
|
-
encodeValuesOnly
|
|
132
|
+
encodeValuesOnly,
|
|
133
|
+
charset
|
|
117
134
|
));
|
|
118
135
|
}
|
|
119
136
|
}
|
|
@@ -135,11 +152,16 @@ module.exports = function (object, opts) {
|
|
|
135
152
|
var encode = typeof options.encode === 'boolean' ? options.encode : defaults.encode;
|
|
136
153
|
var encoder = typeof options.encoder === 'function' ? options.encoder : defaults.encoder;
|
|
137
154
|
var sort = typeof options.sort === 'function' ? options.sort : null;
|
|
138
|
-
var allowDots = typeof options.allowDots === 'undefined' ?
|
|
155
|
+
var allowDots = typeof options.allowDots === 'undefined' ? defaults.allowDots : !!options.allowDots;
|
|
139
156
|
var serializeDate = typeof options.serializeDate === 'function' ? options.serializeDate : defaults.serializeDate;
|
|
140
157
|
var encodeValuesOnly = typeof options.encodeValuesOnly === 'boolean' ? options.encodeValuesOnly : defaults.encodeValuesOnly;
|
|
158
|
+
var charset = options.charset || defaults.charset;
|
|
159
|
+
if (typeof options.charset !== 'undefined' && options.charset !== 'utf-8' && options.charset !== 'iso-8859-1') {
|
|
160
|
+
throw new Error('The charset option must be either utf-8, iso-8859-1, or undefined');
|
|
161
|
+
}
|
|
162
|
+
|
|
141
163
|
if (typeof options.format === 'undefined') {
|
|
142
|
-
options.format = formats
|
|
164
|
+
options.format = formats['default'];
|
|
143
165
|
} else if (!Object.prototype.hasOwnProperty.call(formats.formatters, options.format)) {
|
|
144
166
|
throw new TypeError('Unknown format option provided.');
|
|
145
167
|
}
|
|
@@ -186,8 +208,7 @@ module.exports = function (object, opts) {
|
|
|
186
208
|
if (skipNulls && obj[key] === null) {
|
|
187
209
|
continue;
|
|
188
210
|
}
|
|
189
|
-
|
|
190
|
-
keys = keys.concat(stringify(
|
|
211
|
+
pushToArray(keys, stringify(
|
|
191
212
|
obj[key],
|
|
192
213
|
key,
|
|
193
214
|
generateArrayPrefix,
|
|
@@ -199,12 +220,23 @@ module.exports = function (object, opts) {
|
|
|
199
220
|
allowDots,
|
|
200
221
|
serializeDate,
|
|
201
222
|
formatter,
|
|
202
|
-
encodeValuesOnly
|
|
223
|
+
encodeValuesOnly,
|
|
224
|
+
charset
|
|
203
225
|
));
|
|
204
226
|
}
|
|
205
227
|
|
|
206
228
|
var joined = keys.join(delimiter);
|
|
207
229
|
var prefix = options.addQueryPrefix === true ? '?' : '';
|
|
208
230
|
|
|
231
|
+
if (options.charsetSentinel) {
|
|
232
|
+
if (charset === 'iso-8859-1') {
|
|
233
|
+
// encodeURIComponent('✓'), the "numeric entity" representation of a checkmark
|
|
234
|
+
prefix += 'utf8=%26%2310003%3B&';
|
|
235
|
+
} else {
|
|
236
|
+
// encodeURIComponent('✓')
|
|
237
|
+
prefix += 'utf8=%E2%9C%93&';
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
209
241
|
return joined.length > 0 ? prefix + joined : '';
|
|
210
242
|
};
|
package/lib/utils.js
CHANGED
|
@@ -11,7 +11,26 @@ var hexTable = (function () {
|
|
|
11
11
|
return array;
|
|
12
12
|
}());
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
var compactQueue = function compactQueue(queue) {
|
|
15
|
+
while (queue.length > 1) {
|
|
16
|
+
var item = queue.pop();
|
|
17
|
+
var obj = item.obj[item.prop];
|
|
18
|
+
|
|
19
|
+
if (Array.isArray(obj)) {
|
|
20
|
+
var compacted = [];
|
|
21
|
+
|
|
22
|
+
for (var j = 0; j < obj.length; ++j) {
|
|
23
|
+
if (typeof obj[j] !== 'undefined') {
|
|
24
|
+
compacted.push(obj[j]);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
item.obj[item.prop] = compacted;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
var arrayToObject = function arrayToObject(source, options) {
|
|
15
34
|
var obj = options && options.plainObjects ? Object.create(null) : {};
|
|
16
35
|
for (var i = 0; i < source.length; ++i) {
|
|
17
36
|
if (typeof source[i] !== 'undefined') {
|
|
@@ -22,7 +41,7 @@ exports.arrayToObject = function (source, options) {
|
|
|
22
41
|
return obj;
|
|
23
42
|
};
|
|
24
43
|
|
|
25
|
-
|
|
44
|
+
var merge = function merge(target, source, options) {
|
|
26
45
|
if (!source) {
|
|
27
46
|
return target;
|
|
28
47
|
}
|
|
@@ -31,7 +50,7 @@ exports.merge = function (target, source, options) {
|
|
|
31
50
|
if (Array.isArray(target)) {
|
|
32
51
|
target.push(source);
|
|
33
52
|
} else if (typeof target === 'object') {
|
|
34
|
-
if (options.plainObjects || options.allowPrototypes || !has.call(Object.prototype, source)) {
|
|
53
|
+
if ((options && (options.plainObjects || options.allowPrototypes)) || !has.call(Object.prototype, source)) {
|
|
35
54
|
target[source] = true;
|
|
36
55
|
}
|
|
37
56
|
} else {
|
|
@@ -47,14 +66,14 @@ exports.merge = function (target, source, options) {
|
|
|
47
66
|
|
|
48
67
|
var mergeTarget = target;
|
|
49
68
|
if (Array.isArray(target) && !Array.isArray(source)) {
|
|
50
|
-
mergeTarget =
|
|
69
|
+
mergeTarget = arrayToObject(target, options);
|
|
51
70
|
}
|
|
52
71
|
|
|
53
72
|
if (Array.isArray(target) && Array.isArray(source)) {
|
|
54
73
|
source.forEach(function (item, i) {
|
|
55
74
|
if (has.call(target, i)) {
|
|
56
75
|
if (target[i] && typeof target[i] === 'object') {
|
|
57
|
-
target[i] =
|
|
76
|
+
target[i] = merge(target[i], item, options);
|
|
58
77
|
} else {
|
|
59
78
|
target.push(item);
|
|
60
79
|
}
|
|
@@ -69,7 +88,7 @@ exports.merge = function (target, source, options) {
|
|
|
69
88
|
var value = source[key];
|
|
70
89
|
|
|
71
90
|
if (has.call(acc, key)) {
|
|
72
|
-
acc[key] =
|
|
91
|
+
acc[key] = merge(acc[key], value, options);
|
|
73
92
|
} else {
|
|
74
93
|
acc[key] = value;
|
|
75
94
|
}
|
|
@@ -77,22 +96,28 @@ exports.merge = function (target, source, options) {
|
|
|
77
96
|
}, mergeTarget);
|
|
78
97
|
};
|
|
79
98
|
|
|
80
|
-
|
|
99
|
+
var assign = function assignSingleSource(target, source) {
|
|
81
100
|
return Object.keys(source).reduce(function (acc, key) {
|
|
82
101
|
acc[key] = source[key];
|
|
83
102
|
return acc;
|
|
84
103
|
}, target);
|
|
85
104
|
};
|
|
86
105
|
|
|
87
|
-
|
|
106
|
+
var decode = function (str, decoder, charset) {
|
|
107
|
+
var strWithoutPlus = str.replace(/\+/g, ' ');
|
|
108
|
+
if (charset === 'iso-8859-1') {
|
|
109
|
+
// unescape never throws, no try...catch needed:
|
|
110
|
+
return strWithoutPlus.replace(/%[0-9a-f]{2}/gi, unescape);
|
|
111
|
+
}
|
|
112
|
+
// utf-8
|
|
88
113
|
try {
|
|
89
|
-
return decodeURIComponent(
|
|
114
|
+
return decodeURIComponent(strWithoutPlus);
|
|
90
115
|
} catch (e) {
|
|
91
|
-
return
|
|
116
|
+
return strWithoutPlus;
|
|
92
117
|
}
|
|
93
118
|
};
|
|
94
119
|
|
|
95
|
-
|
|
120
|
+
var encode = function encode(str, defaultEncoder, charset) {
|
|
96
121
|
// This code was originally written by Brian White (mscdex) for the io.js core querystring library.
|
|
97
122
|
// It has been adapted here for stricter adherence to RFC 3986
|
|
98
123
|
if (str.length === 0) {
|
|
@@ -101,12 +126,18 @@ exports.encode = function (str) {
|
|
|
101
126
|
|
|
102
127
|
var string = typeof str === 'string' ? str : String(str);
|
|
103
128
|
|
|
129
|
+
if (charset === 'iso-8859-1') {
|
|
130
|
+
return escape(string).replace(/%u[0-9a-f]{4}/gi, function ($0) {
|
|
131
|
+
return '%26%23' + parseInt($0.slice(2), 16) + '%3B';
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
|
|
104
135
|
var out = '';
|
|
105
136
|
for (var i = 0; i < string.length; ++i) {
|
|
106
137
|
var c = string.charCodeAt(i);
|
|
107
138
|
|
|
108
139
|
if (
|
|
109
|
-
c === 0x2D
|
|
140
|
+
c === 0x2D // -
|
|
110
141
|
|| c === 0x2E // .
|
|
111
142
|
|| c === 0x5F // _
|
|
112
143
|
|| c === 0x7E // ~
|
|
@@ -144,49 +175,54 @@ exports.encode = function (str) {
|
|
|
144
175
|
return out;
|
|
145
176
|
};
|
|
146
177
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
for (var i = 0; i < obj.length; ++i) {
|
|
164
|
-
if (obj[i] && typeof obj[i] === 'object') {
|
|
165
|
-
compacted.push(exports.compact(obj[i], refs));
|
|
166
|
-
} else if (typeof obj[i] !== 'undefined') {
|
|
167
|
-
compacted.push(obj[i]);
|
|
178
|
+
var compact = function compact(value) {
|
|
179
|
+
var queue = [{ obj: { o: value }, prop: 'o' }];
|
|
180
|
+
var refs = [];
|
|
181
|
+
|
|
182
|
+
for (var i = 0; i < queue.length; ++i) {
|
|
183
|
+
var item = queue[i];
|
|
184
|
+
var obj = item.obj[item.prop];
|
|
185
|
+
|
|
186
|
+
var keys = Object.keys(obj);
|
|
187
|
+
for (var j = 0; j < keys.length; ++j) {
|
|
188
|
+
var key = keys[j];
|
|
189
|
+
var val = obj[key];
|
|
190
|
+
if (typeof val === 'object' && val !== null && refs.indexOf(val) === -1) {
|
|
191
|
+
queue.push({ obj: obj, prop: key });
|
|
192
|
+
refs.push(val);
|
|
168
193
|
}
|
|
169
194
|
}
|
|
170
|
-
|
|
171
|
-
return compacted;
|
|
172
195
|
}
|
|
173
196
|
|
|
174
|
-
|
|
175
|
-
keys.forEach(function (key) {
|
|
176
|
-
obj[key] = exports.compact(obj[key], refs);
|
|
177
|
-
});
|
|
197
|
+
compactQueue(queue);
|
|
178
198
|
|
|
179
|
-
return
|
|
199
|
+
return value;
|
|
180
200
|
};
|
|
181
201
|
|
|
182
|
-
|
|
202
|
+
var isRegExp = function isRegExp(obj) {
|
|
183
203
|
return Object.prototype.toString.call(obj) === '[object RegExp]';
|
|
184
204
|
};
|
|
185
205
|
|
|
186
|
-
|
|
206
|
+
var isBuffer = function isBuffer(obj) {
|
|
187
207
|
if (obj === null || typeof obj === 'undefined') {
|
|
188
208
|
return false;
|
|
189
209
|
}
|
|
190
210
|
|
|
191
211
|
return !!(obj.constructor && obj.constructor.isBuffer && obj.constructor.isBuffer(obj));
|
|
192
212
|
};
|
|
213
|
+
|
|
214
|
+
var combine = function combine(a, b) {
|
|
215
|
+
return [].concat(a, b);
|
|
216
|
+
};
|
|
217
|
+
|
|
218
|
+
module.exports = {
|
|
219
|
+
arrayToObject: arrayToObject,
|
|
220
|
+
assign: assign,
|
|
221
|
+
combine: combine,
|
|
222
|
+
compact: compact,
|
|
223
|
+
decode: decode,
|
|
224
|
+
encode: encode,
|
|
225
|
+
isBuffer: isBuffer,
|
|
226
|
+
isRegExp: isRegExp,
|
|
227
|
+
merge: merge
|
|
228
|
+
};
|
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.6.0",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
8
8
|
"url": "https://github.com/ljharb/qs.git"
|
|
@@ -24,17 +24,18 @@
|
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {},
|
|
26
26
|
"devDependencies": {
|
|
27
|
-
"@ljharb/eslint-config": "^
|
|
28
|
-
"browserify": "^
|
|
27
|
+
"@ljharb/eslint-config": "^13.0.0",
|
|
28
|
+
"browserify": "^16.2.3",
|
|
29
29
|
"covert": "^1.1.0",
|
|
30
30
|
"editorconfig-tools": "^0.1.1",
|
|
31
|
-
"eslint": "^
|
|
31
|
+
"eslint": "^5.9.0",
|
|
32
32
|
"evalmd": "^0.0.17",
|
|
33
|
-
"iconv-lite": "^0.4.
|
|
33
|
+
"iconv-lite": "^0.4.24",
|
|
34
34
|
"mkdirp": "^0.5.1",
|
|
35
35
|
"qs-iconv": "^1.0.4",
|
|
36
|
-
"safe-publish-latest": "^1.1.
|
|
37
|
-
"
|
|
36
|
+
"safe-publish-latest": "^1.1.2",
|
|
37
|
+
"safer-buffer": "^2.1.2",
|
|
38
|
+
"tape": "^4.9.1"
|
|
38
39
|
},
|
|
39
40
|
"scripts": {
|
|
40
41
|
"prepublish": "safe-publish-latest && npm run dist",
|
|
@@ -42,7 +43,7 @@
|
|
|
42
43
|
"test": "npm run --silent coverage",
|
|
43
44
|
"tests-only": "node test",
|
|
44
45
|
"readme": "evalmd README.md",
|
|
45
|
-
"
|
|
46
|
+
"postlint": "editorconfig-tools check * lib/* test/*",
|
|
46
47
|
"lint": "eslint lib/*.js test/*.js",
|
|
47
48
|
"coverage": "covert test",
|
|
48
49
|
"dist": "mkdirp dist && browserify --standalone Qs lib/index.js > dist/qs.js"
|
package/test/.eslintrc
CHANGED
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"rules": {
|
|
3
|
+
"array-bracket-newline": 0,
|
|
4
|
+
"array-element-newline": 0,
|
|
3
5
|
"consistent-return": 2,
|
|
6
|
+
"function-paren-newline": 0,
|
|
4
7
|
"max-lines": 0,
|
|
8
|
+
"max-lines-per-function": 0,
|
|
5
9
|
"max-nested-callbacks": [2, 3],
|
|
6
10
|
"max-statements": 0,
|
|
11
|
+
"no-buffer-constructor": 0,
|
|
7
12
|
"no-extend-native": 0,
|
|
8
13
|
"no-magic-numbers": 0,
|
|
14
|
+
"object-curly-newline": 0,
|
|
9
15
|
"sort-keys": 0
|
|
10
16
|
}
|
|
11
17
|
}
|