qs 6.3.3 → 6.4.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/.eslintignore +1 -0
- package/.eslintrc +4 -23
- package/.jscs.json +176 -0
- package/CHANGELOG.md +16 -24
- package/LICENSE +28 -0
- package/README.md +10 -25
- package/dist/qs.js +54 -59
- package/lib/formats.js +1 -1
- package/lib/parse.js +10 -11
- package/lib/stringify.js +30 -30
- package/lib/utils.js +11 -15
- package/package.json +48 -52
- package/test/.eslintrc +11 -0
- package/test/parse.js +6 -74
- package/test/stringify.js +37 -38
- package/test/utils.js +0 -7
- package/.editorconfig +0 -44
- package/.github/FUNDING.yml +0 -12
- package/.nycrc +0 -13
- package/LICENSE.md +0 -29
- package/bower.json +0 -21
- package/component.json +0 -15
package/lib/parse.js
CHANGED
|
@@ -50,25 +50,23 @@ var parseObject = function parseObjectRecursive(chain, val, options) {
|
|
|
50
50
|
var root = chain.shift();
|
|
51
51
|
|
|
52
52
|
var obj;
|
|
53
|
-
if (root === '[]'
|
|
53
|
+
if (root === '[]') {
|
|
54
54
|
obj = [];
|
|
55
55
|
obj = obj.concat(parseObject(chain, val, options));
|
|
56
56
|
} else {
|
|
57
57
|
obj = options.plainObjects ? Object.create(null) : {};
|
|
58
58
|
var cleanRoot = root.charAt(0) === '[' && root.charAt(root.length - 1) === ']' ? root.slice(1, -1) : root;
|
|
59
59
|
var index = parseInt(cleanRoot, 10);
|
|
60
|
-
if (
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
&&
|
|
66
|
-
&& index >= 0
|
|
67
|
-
&& (options.parseArrays && index <= options.arrayLimit)
|
|
60
|
+
if (
|
|
61
|
+
!isNaN(index) &&
|
|
62
|
+
root !== cleanRoot &&
|
|
63
|
+
String(index) === cleanRoot &&
|
|
64
|
+
index >= 0 &&
|
|
65
|
+
(options.parseArrays && index <= options.arrayLimit)
|
|
68
66
|
) {
|
|
69
67
|
obj = [];
|
|
70
68
|
obj[index] = parseObject(chain, val, options);
|
|
71
|
-
} else
|
|
69
|
+
} else {
|
|
72
70
|
obj[cleanRoot] = parseObject(chain, val, options);
|
|
73
71
|
}
|
|
74
72
|
}
|
|
@@ -98,7 +96,8 @@ var parseKeys = function parseQueryStringKeys(givenKey, val, options) {
|
|
|
98
96
|
|
|
99
97
|
var keys = [];
|
|
100
98
|
if (parent) {
|
|
101
|
-
// If we aren't using plain objects, optionally prefix keys
|
|
99
|
+
// If we aren't using plain objects, optionally prefix keys
|
|
100
|
+
// that would overwrite object prototype properties
|
|
102
101
|
if (!options.plainObjects && has.call(Object.prototype, parent)) {
|
|
103
102
|
if (!options.allowPrototypes) {
|
|
104
103
|
return;
|
package/lib/stringify.js
CHANGED
|
@@ -4,37 +4,32 @@ var utils = require('./utils');
|
|
|
4
4
|
var formats = require('./formats');
|
|
5
5
|
|
|
6
6
|
var arrayPrefixGenerators = {
|
|
7
|
-
brackets: function brackets(prefix) {
|
|
7
|
+
brackets: function brackets(prefix) { // eslint-disable-line func-name-matching
|
|
8
8
|
return prefix + '[]';
|
|
9
9
|
},
|
|
10
|
-
indices: function indices(prefix, key) {
|
|
10
|
+
indices: function indices(prefix, key) { // eslint-disable-line func-name-matching
|
|
11
11
|
return prefix + '[' + key + ']';
|
|
12
12
|
},
|
|
13
|
-
repeat: function repeat(prefix) {
|
|
13
|
+
repeat: function repeat(prefix) { // eslint-disable-line func-name-matching
|
|
14
14
|
return prefix;
|
|
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
|
-
|
|
24
18
|
var toISO = Date.prototype.toISOString;
|
|
25
19
|
|
|
26
20
|
var defaults = {
|
|
27
21
|
delimiter: '&',
|
|
28
22
|
encode: true,
|
|
29
23
|
encoder: utils.encode,
|
|
30
|
-
|
|
24
|
+
encodeValuesOnly: false,
|
|
25
|
+
serializeDate: function serializeDate(date) { // eslint-disable-line func-name-matching
|
|
31
26
|
return toISO.call(date);
|
|
32
27
|
},
|
|
33
28
|
skipNulls: false,
|
|
34
29
|
strictNullHandling: false
|
|
35
30
|
};
|
|
36
31
|
|
|
37
|
-
var stringify = function stringify(
|
|
32
|
+
var stringify = function stringify( // eslint-disable-line func-name-matching
|
|
38
33
|
object,
|
|
39
34
|
prefix,
|
|
40
35
|
generateArrayPrefix,
|
|
@@ -45,18 +40,17 @@ var stringify = function stringify(
|
|
|
45
40
|
sort,
|
|
46
41
|
allowDots,
|
|
47
42
|
serializeDate,
|
|
48
|
-
formatter
|
|
43
|
+
formatter,
|
|
44
|
+
encodeValuesOnly
|
|
49
45
|
) {
|
|
50
46
|
var obj = object;
|
|
51
47
|
if (typeof filter === 'function') {
|
|
52
48
|
obj = filter(prefix, obj);
|
|
53
49
|
} else if (obj instanceof Date) {
|
|
54
50
|
obj = serializeDate(obj);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
if (obj === null) {
|
|
51
|
+
} else if (obj === null) {
|
|
58
52
|
if (strictNullHandling) {
|
|
59
|
-
return encoder ? encoder(prefix) : prefix;
|
|
53
|
+
return encoder && !encodeValuesOnly ? encoder(prefix) : prefix;
|
|
60
54
|
}
|
|
61
55
|
|
|
62
56
|
obj = '';
|
|
@@ -64,7 +58,8 @@ var stringify = function stringify(
|
|
|
64
58
|
|
|
65
59
|
if (typeof obj === 'string' || typeof obj === 'number' || typeof obj === 'boolean' || utils.isBuffer(obj)) {
|
|
66
60
|
if (encoder) {
|
|
67
|
-
|
|
61
|
+
var keyValue = encodeValuesOnly ? prefix : encoder(prefix);
|
|
62
|
+
return [formatter(keyValue) + '=' + formatter(encoder(obj))];
|
|
68
63
|
}
|
|
69
64
|
return [formatter(prefix) + '=' + formatter(String(obj))];
|
|
70
65
|
}
|
|
@@ -76,7 +71,7 @@ var stringify = function stringify(
|
|
|
76
71
|
}
|
|
77
72
|
|
|
78
73
|
var objKeys;
|
|
79
|
-
if (isArray(filter)) {
|
|
74
|
+
if (Array.isArray(filter)) {
|
|
80
75
|
objKeys = filter;
|
|
81
76
|
} else {
|
|
82
77
|
var keys = Object.keys(obj);
|
|
@@ -90,8 +85,8 @@ var stringify = function stringify(
|
|
|
90
85
|
continue;
|
|
91
86
|
}
|
|
92
87
|
|
|
93
|
-
if (isArray(obj)) {
|
|
94
|
-
|
|
88
|
+
if (Array.isArray(obj)) {
|
|
89
|
+
values = values.concat(stringify(
|
|
95
90
|
obj[key],
|
|
96
91
|
generateArrayPrefix(prefix, key),
|
|
97
92
|
generateArrayPrefix,
|
|
@@ -102,10 +97,11 @@ var stringify = function stringify(
|
|
|
102
97
|
sort,
|
|
103
98
|
allowDots,
|
|
104
99
|
serializeDate,
|
|
105
|
-
formatter
|
|
100
|
+
formatter,
|
|
101
|
+
encodeValuesOnly
|
|
106
102
|
));
|
|
107
103
|
} else {
|
|
108
|
-
|
|
104
|
+
values = values.concat(stringify(
|
|
109
105
|
obj[key],
|
|
110
106
|
prefix + (allowDots ? '.' + key : '[' + key + ']'),
|
|
111
107
|
generateArrayPrefix,
|
|
@@ -116,7 +112,8 @@ var stringify = function stringify(
|
|
|
116
112
|
sort,
|
|
117
113
|
allowDots,
|
|
118
114
|
serializeDate,
|
|
119
|
-
formatter
|
|
115
|
+
formatter,
|
|
116
|
+
encodeValuesOnly
|
|
120
117
|
));
|
|
121
118
|
}
|
|
122
119
|
}
|
|
@@ -128,7 +125,7 @@ module.exports = function (object, opts) {
|
|
|
128
125
|
var obj = object;
|
|
129
126
|
var options = opts || {};
|
|
130
127
|
|
|
131
|
-
if (options.encoder !== null &&
|
|
128
|
+
if (options.encoder !== null && options.encoder !== undefined && typeof options.encoder !== 'function') {
|
|
132
129
|
throw new TypeError('Encoder has to be a function.');
|
|
133
130
|
}
|
|
134
131
|
|
|
@@ -136,12 +133,13 @@ module.exports = function (object, opts) {
|
|
|
136
133
|
var strictNullHandling = typeof options.strictNullHandling === 'boolean' ? options.strictNullHandling : defaults.strictNullHandling;
|
|
137
134
|
var skipNulls = typeof options.skipNulls === 'boolean' ? options.skipNulls : defaults.skipNulls;
|
|
138
135
|
var encode = typeof options.encode === 'boolean' ? options.encode : defaults.encode;
|
|
139
|
-
var encoder =
|
|
136
|
+
var encoder = typeof options.encoder === 'function' ? options.encoder : defaults.encoder;
|
|
140
137
|
var sort = typeof options.sort === 'function' ? options.sort : null;
|
|
141
138
|
var allowDots = typeof options.allowDots === 'undefined' ? false : options.allowDots;
|
|
142
139
|
var serializeDate = typeof options.serializeDate === 'function' ? options.serializeDate : defaults.serializeDate;
|
|
140
|
+
var encodeValuesOnly = typeof options.encodeValuesOnly === 'boolean' ? options.encodeValuesOnly : defaults.encodeValuesOnly;
|
|
143
141
|
if (typeof options.format === 'undefined') {
|
|
144
|
-
options.format = formats
|
|
142
|
+
options.format = formats.default;
|
|
145
143
|
} else if (!Object.prototype.hasOwnProperty.call(formats.formatters, options.format)) {
|
|
146
144
|
throw new TypeError('Unknown format option provided.');
|
|
147
145
|
}
|
|
@@ -152,7 +150,7 @@ module.exports = function (object, opts) {
|
|
|
152
150
|
if (typeof options.filter === 'function') {
|
|
153
151
|
filter = options.filter;
|
|
154
152
|
obj = filter('', obj);
|
|
155
|
-
} else if (isArray(options.filter)) {
|
|
153
|
+
} else if (Array.isArray(options.filter)) {
|
|
156
154
|
filter = options.filter;
|
|
157
155
|
objKeys = filter;
|
|
158
156
|
}
|
|
@@ -188,18 +186,20 @@ module.exports = function (object, opts) {
|
|
|
188
186
|
if (skipNulls && obj[key] === null) {
|
|
189
187
|
continue;
|
|
190
188
|
}
|
|
191
|
-
|
|
189
|
+
|
|
190
|
+
keys = keys.concat(stringify(
|
|
192
191
|
obj[key],
|
|
193
192
|
key,
|
|
194
193
|
generateArrayPrefix,
|
|
195
194
|
strictNullHandling,
|
|
196
195
|
skipNulls,
|
|
197
|
-
encoder,
|
|
196
|
+
encode ? encoder : null,
|
|
198
197
|
filter,
|
|
199
198
|
sort,
|
|
200
199
|
allowDots,
|
|
201
200
|
serializeDate,
|
|
202
|
-
formatter
|
|
201
|
+
formatter,
|
|
202
|
+
encodeValuesOnly
|
|
203
203
|
));
|
|
204
204
|
}
|
|
205
205
|
|
package/lib/utils.js
CHANGED
|
@@ -30,8 +30,8 @@ exports.merge = function (target, source, options) {
|
|
|
30
30
|
if (typeof source !== 'object') {
|
|
31
31
|
if (Array.isArray(target)) {
|
|
32
32
|
target.push(source);
|
|
33
|
-
} else if (
|
|
34
|
-
if (
|
|
33
|
+
} else if (typeof target === 'object') {
|
|
34
|
+
if (options.plainObjects || options.allowPrototypes || !has.call(Object.prototype, source)) {
|
|
35
35
|
target[source] = true;
|
|
36
36
|
}
|
|
37
37
|
} else {
|
|
@@ -41,7 +41,7 @@ exports.merge = function (target, source, options) {
|
|
|
41
41
|
return target;
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
if (
|
|
44
|
+
if (typeof target !== 'object') {
|
|
45
45
|
return [target].concat(source);
|
|
46
46
|
}
|
|
47
47
|
|
|
@@ -99,13 +99,13 @@ exports.encode = function (str) {
|
|
|
99
99
|
var c = string.charCodeAt(i);
|
|
100
100
|
|
|
101
101
|
if (
|
|
102
|
-
c === 0x2D // -
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
102
|
+
c === 0x2D || // -
|
|
103
|
+
c === 0x2E || // .
|
|
104
|
+
c === 0x5F || // _
|
|
105
|
+
c === 0x7E || // ~
|
|
106
|
+
(c >= 0x30 && c <= 0x39) || // 0-9
|
|
107
|
+
(c >= 0x41 && c <= 0x5A) || // a-z
|
|
108
|
+
(c >= 0x61 && c <= 0x7A) // A-Z
|
|
109
109
|
) {
|
|
110
110
|
out += string.charAt(i);
|
|
111
111
|
continue;
|
|
@@ -128,11 +128,7 @@ exports.encode = function (str) {
|
|
|
128
128
|
|
|
129
129
|
i += 1;
|
|
130
130
|
c = 0x10000 + (((c & 0x3FF) << 10) | (string.charCodeAt(i) & 0x3FF));
|
|
131
|
-
|
|
132
|
-
out += hexTable[0xF0 | (c >> 18)]
|
|
133
|
-
+ hexTable[0x80 | ((c >> 12) & 0x3F)]
|
|
134
|
-
+ hexTable[0x80 | ((c >> 6) & 0x3F)]
|
|
135
|
-
+ hexTable[0x80 | (c & 0x3F)];
|
|
131
|
+
out += hexTable[0xF0 | (c >> 18)] + hexTable[0x80 | ((c >> 12) & 0x3F)] + hexTable[0x80 | ((c >> 6) & 0x3F)] + hexTable[0x80 | (c & 0x3F)]; // eslint-disable-line max-len
|
|
136
132
|
}
|
|
137
133
|
|
|
138
134
|
return out;
|
package/package.json
CHANGED
|
@@ -1,54 +1,50 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
"
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
"lint": "eslint --ext=js,mjs .",
|
|
51
|
-
"dist": "mkdirp dist && browserify --standalone Qs lib/index.js > dist/qs.js"
|
|
52
|
-
},
|
|
53
|
-
"license": "BSD-3-Clause"
|
|
2
|
+
"name": "qs",
|
|
3
|
+
"description": "A querystring parser that supports nesting and arrays, with a depth limit",
|
|
4
|
+
"homepage": "https://github.com/ljharb/qs",
|
|
5
|
+
"version": "6.4.0",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "https://github.com/ljharb/qs.git"
|
|
9
|
+
},
|
|
10
|
+
"main": "lib/index.js",
|
|
11
|
+
"contributors": [
|
|
12
|
+
{
|
|
13
|
+
"name": "Jordan Harband",
|
|
14
|
+
"email": "ljharb@gmail.com",
|
|
15
|
+
"url": "http://ljharb.codes"
|
|
16
|
+
}
|
|
17
|
+
],
|
|
18
|
+
"keywords": [
|
|
19
|
+
"querystring",
|
|
20
|
+
"qs"
|
|
21
|
+
],
|
|
22
|
+
"engines": {
|
|
23
|
+
"node": ">=0.6"
|
|
24
|
+
},
|
|
25
|
+
"dependencies": {},
|
|
26
|
+
"devDependencies": {
|
|
27
|
+
"@ljharb/eslint-config": "^11.0.0",
|
|
28
|
+
"browserify": "^14.1.0",
|
|
29
|
+
"covert": "^1.1.0",
|
|
30
|
+
"eslint": "^3.17.0",
|
|
31
|
+
"evalmd": "^0.0.17",
|
|
32
|
+
"iconv-lite": "^0.4.15",
|
|
33
|
+
"mkdirp": "^0.5.1",
|
|
34
|
+
"parallelshell": "^2.0.0",
|
|
35
|
+
"qs-iconv": "^1.0.4",
|
|
36
|
+
"safe-publish-latest": "^1.1.1",
|
|
37
|
+
"tape": "^4.6.3"
|
|
38
|
+
},
|
|
39
|
+
"scripts": {
|
|
40
|
+
"prepublish": "safe-publish-latest && npm run dist",
|
|
41
|
+
"pretest": "npm run --silent readme && npm run --silent lint",
|
|
42
|
+
"test": "npm run --silent coverage",
|
|
43
|
+
"tests-only": "node test",
|
|
44
|
+
"readme": "evalmd README.md",
|
|
45
|
+
"lint": "eslint lib/*.js test/*.js",
|
|
46
|
+
"coverage": "covert test",
|
|
47
|
+
"dist": "mkdirp dist && browserify --standalone Qs lib/index.js > dist/qs.js"
|
|
48
|
+
},
|
|
49
|
+
"license": "BSD-3-Clause"
|
|
54
50
|
}
|
package/test/.eslintrc
ADDED
package/test/parse.js
CHANGED
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
var test = require('tape');
|
|
4
4
|
var qs = require('../');
|
|
5
5
|
var iconv = require('iconv-lite');
|
|
6
|
-
var SaferBuffer = require('safer-buffer').Buffer;
|
|
7
6
|
|
|
8
7
|
test('parse()', function (t) {
|
|
9
8
|
t.test('parses a simple string', function (st) {
|
|
@@ -231,7 +230,7 @@ test('parse()', function (t) {
|
|
|
231
230
|
});
|
|
232
231
|
|
|
233
232
|
t.test('parses buffers correctly', function (st) {
|
|
234
|
-
var b =
|
|
233
|
+
var b = new Buffer('test');
|
|
235
234
|
st.deepEqual(qs.parse({ a: b }), { a: b });
|
|
236
235
|
st.end();
|
|
237
236
|
});
|
|
@@ -256,7 +255,7 @@ test('parse()', function (t) {
|
|
|
256
255
|
st.end();
|
|
257
256
|
});
|
|
258
257
|
|
|
259
|
-
t.test('should not throw when a native prototype has an enumerable property', function (st) {
|
|
258
|
+
t.test('should not throw when a native prototype has an enumerable property', { parallel: false }, function (st) {
|
|
260
259
|
Object.prototype.crash = '';
|
|
261
260
|
Array.prototype.crash = '';
|
|
262
261
|
st.doesNotThrow(qs.parse.bind(null, 'a=b'));
|
|
@@ -301,14 +300,7 @@ test('parse()', function (t) {
|
|
|
301
300
|
});
|
|
302
301
|
|
|
303
302
|
t.test('allows disabling array parsing', function (st) {
|
|
304
|
-
|
|
305
|
-
st.deepEqual(indices, { a: { 0: 'b', 1: 'c' } });
|
|
306
|
-
st.equal(Array.isArray(indices.a), false, 'parseArrays:false, indices case is not an array');
|
|
307
|
-
|
|
308
|
-
var emptyBrackets = qs.parse('a[]=b', { parseArrays: false });
|
|
309
|
-
st.deepEqual(emptyBrackets, { a: { 0: 'b' } });
|
|
310
|
-
st.equal(Array.isArray(emptyBrackets.a), false, 'parseArrays:false, empty brackets case is not an array');
|
|
311
|
-
|
|
303
|
+
st.deepEqual(qs.parse('a[0]=b&a[1]=c', { parseArrays: false }), { a: { 0: 'b', 1: 'c' } });
|
|
312
304
|
st.end();
|
|
313
305
|
});
|
|
314
306
|
|
|
@@ -480,73 +472,13 @@ test('parse()', function (t) {
|
|
|
480
472
|
|
|
481
473
|
st.deepEqual(
|
|
482
474
|
qs.parse('a[b]=c&a=toString', { plainObjects: true }),
|
|
483
|
-
{
|
|
475
|
+
{ a: { b: 'c', toString: true } },
|
|
484
476
|
'can overwrite prototype with plainObjects true'
|
|
485
477
|
);
|
|
486
478
|
|
|
487
479
|
st.end();
|
|
488
480
|
});
|
|
489
481
|
|
|
490
|
-
t.test('dunder proto is ignored', function (st) {
|
|
491
|
-
var payload = 'categories[__proto__]=login&categories[__proto__]&categories[length]=42';
|
|
492
|
-
var result = qs.parse(payload, { allowPrototypes: true });
|
|
493
|
-
|
|
494
|
-
st.deepEqual(
|
|
495
|
-
result,
|
|
496
|
-
{
|
|
497
|
-
categories: {
|
|
498
|
-
length: '42'
|
|
499
|
-
}
|
|
500
|
-
},
|
|
501
|
-
'silent [[Prototype]] payload'
|
|
502
|
-
);
|
|
503
|
-
|
|
504
|
-
var plainResult = qs.parse(payload, { allowPrototypes: true, plainObjects: true });
|
|
505
|
-
|
|
506
|
-
st.deepEqual(
|
|
507
|
-
plainResult,
|
|
508
|
-
{
|
|
509
|
-
__proto__: null,
|
|
510
|
-
categories: {
|
|
511
|
-
__proto__: null,
|
|
512
|
-
length: '42'
|
|
513
|
-
}
|
|
514
|
-
},
|
|
515
|
-
'silent [[Prototype]] payload: plain objects'
|
|
516
|
-
);
|
|
517
|
-
|
|
518
|
-
var query = qs.parse('categories[__proto__]=cats&categories[__proto__]=dogs&categories[some][json]=toInject', { allowPrototypes: true });
|
|
519
|
-
|
|
520
|
-
st.notOk(Array.isArray(query.categories), 'is not an array');
|
|
521
|
-
st.notOk(query.categories instanceof Array, 'is not instanceof an array');
|
|
522
|
-
st.deepEqual(query.categories, { some: { json: 'toInject' } });
|
|
523
|
-
st.equal(JSON.stringify(query.categories), '{"some":{"json":"toInject"}}', 'stringifies as a non-array');
|
|
524
|
-
|
|
525
|
-
st.deepEqual(
|
|
526
|
-
qs.parse('foo[__proto__][hidden]=value&foo[bar]=stuffs', { allowPrototypes: true }),
|
|
527
|
-
{
|
|
528
|
-
foo: {
|
|
529
|
-
bar: 'stuffs'
|
|
530
|
-
}
|
|
531
|
-
},
|
|
532
|
-
'hidden values'
|
|
533
|
-
);
|
|
534
|
-
|
|
535
|
-
st.deepEqual(
|
|
536
|
-
qs.parse('foo[__proto__][hidden]=value&foo[bar]=stuffs', { allowPrototypes: true, plainObjects: true }),
|
|
537
|
-
{
|
|
538
|
-
__proto__: null,
|
|
539
|
-
foo: {
|
|
540
|
-
__proto__: null,
|
|
541
|
-
bar: 'stuffs'
|
|
542
|
-
}
|
|
543
|
-
},
|
|
544
|
-
'hidden values: plain objects'
|
|
545
|
-
);
|
|
546
|
-
|
|
547
|
-
st.end();
|
|
548
|
-
});
|
|
549
|
-
|
|
550
482
|
t.test('can return null objects', { skip: !Object.create }, function (st) {
|
|
551
483
|
var expected = Object.create(null);
|
|
552
484
|
expected.a = Object.create(null);
|
|
@@ -572,14 +504,14 @@ test('parse()', function (t) {
|
|
|
572
504
|
result.push(parseInt(parts[1], 16));
|
|
573
505
|
parts = reg.exec(str);
|
|
574
506
|
}
|
|
575
|
-
return iconv.decode(
|
|
507
|
+
return iconv.decode(new Buffer(result), 'shift_jis').toString();
|
|
576
508
|
}
|
|
577
509
|
}), { 県: '大阪府' });
|
|
578
510
|
st.end();
|
|
579
511
|
});
|
|
580
512
|
|
|
581
513
|
t.test('throws error with wrong decoder', function (st) {
|
|
582
|
-
st
|
|
514
|
+
st.throws(function () {
|
|
583
515
|
qs.parse({}, { decoder: 'string' });
|
|
584
516
|
}, new TypeError('Decoder has to be a function.'));
|
|
585
517
|
st.end();
|
package/test/stringify.js
CHANGED
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
var test = require('tape');
|
|
4
4
|
var qs = require('../');
|
|
5
5
|
var iconv = require('iconv-lite');
|
|
6
|
-
var SaferBuffer = require('safer-buffer').Buffer;
|
|
7
6
|
|
|
8
7
|
test('stringify()', function (t) {
|
|
9
8
|
t.test('stringifies a querystring object', function (st) {
|
|
@@ -326,8 +325,8 @@ test('stringify()', function (t) {
|
|
|
326
325
|
});
|
|
327
326
|
|
|
328
327
|
t.test('stringifies buffer values', function (st) {
|
|
329
|
-
st.equal(qs.stringify({ a:
|
|
330
|
-
st.equal(qs.stringify({ a: { b:
|
|
328
|
+
st.equal(qs.stringify({ a: new Buffer('test') }), 'a=test');
|
|
329
|
+
st.equal(qs.stringify({ a: { b: new Buffer('test') } }), 'a%5Bb%5D=test');
|
|
331
330
|
st.end();
|
|
332
331
|
});
|
|
333
332
|
|
|
@@ -454,14 +453,14 @@ test('stringify()', function (t) {
|
|
|
454
453
|
});
|
|
455
454
|
|
|
456
455
|
t.test('throws error with wrong encoder', function (st) {
|
|
457
|
-
st
|
|
456
|
+
st.throws(function () {
|
|
458
457
|
qs.stringify({}, { encoder: 'string' });
|
|
459
458
|
}, new TypeError('Encoder has to be a function.'));
|
|
460
459
|
st.end();
|
|
461
460
|
});
|
|
462
461
|
|
|
463
462
|
t.test('can use custom encoder for a buffer object', { skip: typeof Buffer === 'undefined' }, function (st) {
|
|
464
|
-
st.equal(qs.stringify({ a:
|
|
463
|
+
st.equal(qs.stringify({ a: new Buffer([1]) }, {
|
|
465
464
|
encoder: function (buffer) {
|
|
466
465
|
if (typeof buffer === 'string') {
|
|
467
466
|
return buffer;
|
|
@@ -469,12 +468,6 @@ test('stringify()', function (t) {
|
|
|
469
468
|
return String.fromCharCode(buffer.readUInt8(0) + 97);
|
|
470
469
|
}
|
|
471
470
|
}), 'a=b');
|
|
472
|
-
|
|
473
|
-
st.equal(qs.stringify({ a: SaferBuffer.from('a b') }, {
|
|
474
|
-
encoder: function (buffer) {
|
|
475
|
-
return buffer;
|
|
476
|
-
}
|
|
477
|
-
}), 'a=a b');
|
|
478
471
|
st.end();
|
|
479
472
|
});
|
|
480
473
|
|
|
@@ -490,7 +483,7 @@ test('stringify()', function (t) {
|
|
|
490
483
|
mutatedDate.toISOString = function () {
|
|
491
484
|
throw new SyntaxError();
|
|
492
485
|
};
|
|
493
|
-
st
|
|
486
|
+
st.throws(function () {
|
|
494
487
|
mutatedDate.toISOString();
|
|
495
488
|
}, SyntaxError);
|
|
496
489
|
st.equal(
|
|
@@ -515,54 +508,60 @@ test('stringify()', function (t) {
|
|
|
515
508
|
t.test('RFC 1738 spaces serialization', function (st) {
|
|
516
509
|
st.equal(qs.stringify({ a: 'b c' }, { format: qs.formats.RFC1738 }), 'a=b+c');
|
|
517
510
|
st.equal(qs.stringify({ 'a b': 'c d' }, { format: qs.formats.RFC1738 }), 'a+b=c+d');
|
|
518
|
-
st.equal(qs.stringify({ 'a b': SaferBuffer.from('a b') }, { format: qs.formats.RFC1738 }), 'a+b=a+b');
|
|
519
511
|
st.end();
|
|
520
512
|
});
|
|
521
513
|
|
|
522
514
|
t.test('RFC 3986 spaces serialization', function (st) {
|
|
523
515
|
st.equal(qs.stringify({ a: 'b c' }, { format: qs.formats.RFC3986 }), 'a=b%20c');
|
|
524
516
|
st.equal(qs.stringify({ 'a b': 'c d' }, { format: qs.formats.RFC3986 }), 'a%20b=c%20d');
|
|
525
|
-
st.equal(qs.stringify({ 'a b': SaferBuffer.from('a b') }, { format: qs.formats.RFC3986 }), 'a%20b=a%20b');
|
|
526
517
|
st.end();
|
|
527
518
|
});
|
|
528
519
|
|
|
529
520
|
t.test('Backward compatibility to RFC 3986', function (st) {
|
|
530
521
|
st.equal(qs.stringify({ a: 'b c' }), 'a=b%20c');
|
|
531
|
-
st.equal(qs.stringify({ 'a b': SaferBuffer.from('a b') }), 'a%20b=a%20b');
|
|
532
522
|
st.end();
|
|
533
523
|
});
|
|
534
524
|
|
|
535
525
|
t.test('Edge cases and unknown formats', function (st) {
|
|
536
|
-
['UFO1234', false, 1234, null, {}, []].forEach(
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
526
|
+
['UFO1234', false, 1234, null, {}, []].forEach(
|
|
527
|
+
function (format) {
|
|
528
|
+
st.throws(
|
|
529
|
+
function () {
|
|
530
|
+
qs.stringify({ a: 'b c' }, { format: format });
|
|
531
|
+
},
|
|
532
|
+
new TypeError('Unknown format option provided.')
|
|
533
|
+
);
|
|
534
|
+
}
|
|
535
|
+
);
|
|
544
536
|
st.end();
|
|
545
537
|
});
|
|
546
538
|
|
|
547
|
-
t.test('
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
539
|
+
t.test('encodeValuesOnly', function (st) {
|
|
540
|
+
st.equal(
|
|
541
|
+
qs.stringify(
|
|
542
|
+
{ a: 'b', c: ['d', 'e=f'], f: [['g'], ['h']] },
|
|
543
|
+
{ encodeValuesOnly: true }
|
|
544
|
+
),
|
|
545
|
+
'a=b&c[0]=d&c[1]=e%3Df&f[0][0]=g&f[1][0]=h'
|
|
546
|
+
);
|
|
547
|
+
st.equal(
|
|
548
|
+
qs.stringify(
|
|
549
|
+
{ a: 'b', c: ['d', 'e'], f: [['g'], ['h']] }
|
|
550
|
+
),
|
|
551
|
+
'a=b&c%5B0%5D=d&c%5B1%5D=e&f%5B0%5D%5B0%5D=g&f%5B1%5D%5B0%5D=h'
|
|
552
|
+
);
|
|
554
553
|
st.end();
|
|
555
554
|
});
|
|
556
555
|
|
|
557
|
-
t.test('
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
556
|
+
t.test('encodeValuesOnly - strictNullHandling', function (st) {
|
|
557
|
+
st.equal(
|
|
558
|
+
qs.stringify(
|
|
559
|
+
{ a: { b: null } },
|
|
560
|
+
{ encodeValuesOnly: true, strictNullHandling: true }
|
|
561
|
+
),
|
|
562
|
+
'a[b]'
|
|
563
|
+
);
|
|
564
564
|
st.end();
|
|
565
565
|
});
|
|
566
566
|
|
|
567
|
-
t.end();
|
|
568
567
|
});
|