qs 6.9.5 → 6.10.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.editorconfig +1 -0
- package/.eslintrc +1 -2
- package/CHANGELOG.md +26 -0
- package/README.md +38 -19
- package/dist/qs.js +2001 -0
- package/lib/parse.js +6 -0
- package/lib/stringify.js +44 -5
- package/lib/utils.js +1 -0
- package/package.json +16 -12
- package/test/parse.js +9 -0
- package/test/stringify.js +85 -13
package/lib/parse.js
CHANGED
|
@@ -8,6 +8,7 @@ var isArray = Array.isArray;
|
|
|
8
8
|
var defaults = {
|
|
9
9
|
allowDots: false,
|
|
10
10
|
allowPrototypes: false,
|
|
11
|
+
allowSparse: false,
|
|
11
12
|
arrayLimit: 20,
|
|
12
13
|
charset: 'utf-8',
|
|
13
14
|
charsetSentinel: false,
|
|
@@ -217,6 +218,7 @@ var normalizeParseOptions = function normalizeParseOptions(opts) {
|
|
|
217
218
|
return {
|
|
218
219
|
allowDots: typeof opts.allowDots === 'undefined' ? defaults.allowDots : !!opts.allowDots,
|
|
219
220
|
allowPrototypes: typeof opts.allowPrototypes === 'boolean' ? opts.allowPrototypes : defaults.allowPrototypes,
|
|
221
|
+
allowSparse: typeof opts.allowSparse === 'boolean' ? opts.allowSparse : defaults.allowSparse,
|
|
220
222
|
arrayLimit: typeof opts.arrayLimit === 'number' ? opts.arrayLimit : defaults.arrayLimit,
|
|
221
223
|
charset: charset,
|
|
222
224
|
charsetSentinel: typeof opts.charsetSentinel === 'boolean' ? opts.charsetSentinel : defaults.charsetSentinel,
|
|
@@ -253,5 +255,9 @@ module.exports = function (str, opts) {
|
|
|
253
255
|
obj = utils.merge(obj, newObj, options);
|
|
254
256
|
}
|
|
255
257
|
|
|
258
|
+
if (options.allowSparse === true) {
|
|
259
|
+
return obj;
|
|
260
|
+
}
|
|
261
|
+
|
|
256
262
|
return utils.compact(obj);
|
|
257
263
|
};
|
package/lib/stringify.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var getSideChannel = require('side-channel');
|
|
3
4
|
var utils = require('./utils');
|
|
4
5
|
var formats = require('./formats');
|
|
5
6
|
var has = Object.prototype.hasOwnProperty;
|
|
@@ -18,6 +19,7 @@ var arrayPrefixGenerators = {
|
|
|
18
19
|
};
|
|
19
20
|
|
|
20
21
|
var isArray = Array.isArray;
|
|
22
|
+
var split = String.prototype.split;
|
|
21
23
|
var push = Array.prototype.push;
|
|
22
24
|
var pushToArray = function (arr, valueOrArray) {
|
|
23
25
|
push.apply(arr, isArray(valueOrArray) ? valueOrArray : [valueOrArray]);
|
|
@@ -54,6 +56,8 @@ var isNonNullishPrimitive = function isNonNullishPrimitive(v) {
|
|
|
54
56
|
|| typeof v === 'bigint';
|
|
55
57
|
};
|
|
56
58
|
|
|
59
|
+
var sentinel = {};
|
|
60
|
+
|
|
57
61
|
var stringify = function stringify(
|
|
58
62
|
object,
|
|
59
63
|
prefix,
|
|
@@ -68,9 +72,30 @@ var stringify = function stringify(
|
|
|
68
72
|
format,
|
|
69
73
|
formatter,
|
|
70
74
|
encodeValuesOnly,
|
|
71
|
-
charset
|
|
75
|
+
charset,
|
|
76
|
+
sideChannel
|
|
72
77
|
) {
|
|
73
78
|
var obj = object;
|
|
79
|
+
|
|
80
|
+
var tmpSc = sideChannel;
|
|
81
|
+
var step = 0;
|
|
82
|
+
var findFlag = false;
|
|
83
|
+
while ((tmpSc = tmpSc.get(sentinel)) !== undefined && !findFlag) {
|
|
84
|
+
// Where object last appeared in the ref tree
|
|
85
|
+
var pos = tmpSc.get(object);
|
|
86
|
+
step += 1;
|
|
87
|
+
if (typeof pos !== 'undefined') {
|
|
88
|
+
if (pos === step) {
|
|
89
|
+
throw new RangeError('Cyclic object value');
|
|
90
|
+
} else {
|
|
91
|
+
findFlag = true; // Break while
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
if (typeof tmpSc.get(sentinel) === 'undefined') {
|
|
95
|
+
step = 0;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
74
99
|
if (typeof filter === 'function') {
|
|
75
100
|
obj = filter(prefix, obj);
|
|
76
101
|
} else if (obj instanceof Date) {
|
|
@@ -95,6 +120,14 @@ var stringify = function stringify(
|
|
|
95
120
|
if (isNonNullishPrimitive(obj) || utils.isBuffer(obj)) {
|
|
96
121
|
if (encoder) {
|
|
97
122
|
var keyValue = encodeValuesOnly ? prefix : encoder(prefix, defaults.encoder, charset, 'key', format);
|
|
123
|
+
if (generateArrayPrefix === 'comma' && encodeValuesOnly) {
|
|
124
|
+
var valuesArray = split.call(String(obj), ',');
|
|
125
|
+
var valuesJoined = '';
|
|
126
|
+
for (var i = 0; i < valuesArray.length; ++i) {
|
|
127
|
+
valuesJoined += (i === 0 ? '' : ',') + formatter(encoder(valuesArray[i], defaults.encoder, charset, 'value', format));
|
|
128
|
+
}
|
|
129
|
+
return [formatter(keyValue) + '=' + valuesJoined];
|
|
130
|
+
}
|
|
98
131
|
return [formatter(keyValue) + '=' + formatter(encoder(obj, defaults.encoder, charset, 'value', format))];
|
|
99
132
|
}
|
|
100
133
|
return [formatter(prefix) + '=' + formatter(String(obj))];
|
|
@@ -117,8 +150,8 @@ var stringify = function stringify(
|
|
|
117
150
|
objKeys = sort ? keys.sort(sort) : keys;
|
|
118
151
|
}
|
|
119
152
|
|
|
120
|
-
for (var
|
|
121
|
-
var key = objKeys[
|
|
153
|
+
for (var j = 0; j < objKeys.length; ++j) {
|
|
154
|
+
var key = objKeys[j];
|
|
122
155
|
var value = typeof key === 'object' && key.value !== undefined ? key.value : obj[key];
|
|
123
156
|
|
|
124
157
|
if (skipNulls && value === null) {
|
|
@@ -129,6 +162,9 @@ var stringify = function stringify(
|
|
|
129
162
|
? typeof generateArrayPrefix === 'function' ? generateArrayPrefix(prefix, key) : prefix
|
|
130
163
|
: prefix + (allowDots ? '.' + key : '[' + key + ']');
|
|
131
164
|
|
|
165
|
+
sideChannel.set(object, step);
|
|
166
|
+
var valueSideChannel = getSideChannel();
|
|
167
|
+
valueSideChannel.set(sentinel, sideChannel);
|
|
132
168
|
pushToArray(values, stringify(
|
|
133
169
|
value,
|
|
134
170
|
keyPrefix,
|
|
@@ -143,7 +179,8 @@ var stringify = function stringify(
|
|
|
143
179
|
format,
|
|
144
180
|
formatter,
|
|
145
181
|
encodeValuesOnly,
|
|
146
|
-
charset
|
|
182
|
+
charset,
|
|
183
|
+
valueSideChannel
|
|
147
184
|
));
|
|
148
185
|
}
|
|
149
186
|
|
|
@@ -237,6 +274,7 @@ module.exports = function (object, opts) {
|
|
|
237
274
|
objKeys.sort(options.sort);
|
|
238
275
|
}
|
|
239
276
|
|
|
277
|
+
var sideChannel = getSideChannel();
|
|
240
278
|
for (var i = 0; i < objKeys.length; ++i) {
|
|
241
279
|
var key = objKeys[i];
|
|
242
280
|
|
|
@@ -257,7 +295,8 @@ module.exports = function (object, opts) {
|
|
|
257
295
|
options.format,
|
|
258
296
|
options.formatter,
|
|
259
297
|
options.encodeValuesOnly,
|
|
260
|
-
options.charset
|
|
298
|
+
options.charset,
|
|
299
|
+
sideChannel
|
|
261
300
|
));
|
|
262
301
|
}
|
|
263
302
|
|
package/lib/utils.js
CHANGED
|
@@ -177,6 +177,7 @@ var encode = function encode(str, defaultEncoder, charset, kind, format) {
|
|
|
177
177
|
|
|
178
178
|
i += 1;
|
|
179
179
|
c = 0x10000 + (((c & 0x3FF) << 10) | (string.charCodeAt(i) & 0x3FF));
|
|
180
|
+
/* eslint operator-linebreak: [2, "before"] */
|
|
180
181
|
out += hexTable[0xF0 | (c >> 18)]
|
|
181
182
|
+ hexTable[0x80 | ((c >> 12) & 0x3F)]
|
|
182
183
|
+ hexTable[0x80 | ((c >> 6) & 0x3F)]
|
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.10.2",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
8
8
|
"url": "https://github.com/ljharb/qs.git"
|
|
@@ -29,34 +29,38 @@
|
|
|
29
29
|
"engines": {
|
|
30
30
|
"node": ">=0.6"
|
|
31
31
|
},
|
|
32
|
-
"dependencies": {
|
|
32
|
+
"dependencies": {
|
|
33
|
+
"side-channel": "^1.0.4"
|
|
34
|
+
},
|
|
33
35
|
"devDependencies": {
|
|
34
|
-
"@ljharb/eslint-config": "^
|
|
35
|
-
"aud": "^1.1.
|
|
36
|
+
"@ljharb/eslint-config": "^20.0.0",
|
|
37
|
+
"aud": "^1.1.5",
|
|
36
38
|
"browserify": "^16.5.2",
|
|
37
39
|
"eclint": "^2.8.1",
|
|
38
|
-
"eslint": "^
|
|
40
|
+
"eslint": "^8.4.0",
|
|
39
41
|
"evalmd": "^0.0.19",
|
|
40
42
|
"for-each": "^0.3.3",
|
|
41
|
-
"has-symbols": "^1.0.
|
|
43
|
+
"has-symbols": "^1.0.2",
|
|
42
44
|
"iconv-lite": "^0.5.1",
|
|
45
|
+
"in-publish": "^2.0.1",
|
|
43
46
|
"mkdirp": "^0.5.5",
|
|
44
47
|
"nyc": "^10.3.2",
|
|
45
|
-
"object-inspect": "^1.
|
|
48
|
+
"object-inspect": "^1.11.0",
|
|
46
49
|
"qs-iconv": "^1.0.4",
|
|
47
|
-
"safe-publish-latest": "^
|
|
50
|
+
"safe-publish-latest": "^2.0.0",
|
|
48
51
|
"safer-buffer": "^2.1.2",
|
|
49
|
-
"tape": "^5.
|
|
52
|
+
"tape": "^5.3.2"
|
|
50
53
|
},
|
|
51
54
|
"scripts": {
|
|
52
|
-
"
|
|
55
|
+
"prepublishOnly": "safe-publish-latest && npm run dist",
|
|
56
|
+
"prepublish": "not-in-publish || npm run prepublishOnly",
|
|
53
57
|
"pretest": "npm run --silent readme && npm run --silent lint",
|
|
54
58
|
"test": "npm run tests-only",
|
|
55
59
|
"tests-only": "nyc tape 'test/**/*.js'",
|
|
56
60
|
"posttest": "aud --production",
|
|
57
61
|
"readme": "evalmd README.md",
|
|
58
|
-
"postlint": "eclint check * lib/* test/*",
|
|
59
|
-
"lint": "eslint
|
|
62
|
+
"postlint": "eclint check * lib/* test/* !dist/*",
|
|
63
|
+
"lint": "eslint .",
|
|
60
64
|
"dist": "mkdirp dist && browserify --standalone Qs lib/index.js > dist/qs.js"
|
|
61
65
|
},
|
|
62
66
|
"license": "BSD-3-Clause",
|
package/test/parse.js
CHANGED
|
@@ -269,6 +269,15 @@ test('parse()', function (t) {
|
|
|
269
269
|
st.end();
|
|
270
270
|
});
|
|
271
271
|
|
|
272
|
+
t.test('parses sparse arrays', function (st) {
|
|
273
|
+
/* eslint no-sparse-arrays: 0 */
|
|
274
|
+
st.deepEqual(qs.parse('a[4]=1&a[1]=2', { allowSparse: true }), { a: [, '2', , , '1'] });
|
|
275
|
+
st.deepEqual(qs.parse('a[1][b][2][c]=1', { allowSparse: true }), { a: [, { b: [, , { c: '1' }] }] });
|
|
276
|
+
st.deepEqual(qs.parse('a[1][2][3][c]=1', { allowSparse: true }), { a: [, [, , [, , , { c: '1' }]]] });
|
|
277
|
+
st.deepEqual(qs.parse('a[1][2][3][c][1]=1', { allowSparse: true }), { a: [, [, , [, , , { c: [, '1'] }]]] });
|
|
278
|
+
st.end();
|
|
279
|
+
});
|
|
280
|
+
|
|
272
281
|
t.test('parses semi-parsed strings', function (st) {
|
|
273
282
|
st.deepEqual(qs.parse({ 'a[b]': 'c' }), { a: { b: 'c' } });
|
|
274
283
|
st.deepEqual(qs.parse({ 'a[b]': 'c', 'a[d]': 'e' }), { a: { b: 'c', d: 'e' } });
|
package/test/stringify.js
CHANGED
|
@@ -132,10 +132,10 @@ test('stringify()', function (t) {
|
|
|
132
132
|
});
|
|
133
133
|
|
|
134
134
|
t.test('stringifies a nested array value', function (st) {
|
|
135
|
-
st.equal(qs.stringify({ a: { b: ['c', 'd'] } }, { arrayFormat: 'indices' }), 'a
|
|
136
|
-
st.equal(qs.stringify({ a: { b: ['c', 'd'] } }, { arrayFormat: 'brackets' }), 'a
|
|
137
|
-
st.equal(qs.stringify({ a: { b: ['c', 'd'] } }, { arrayFormat: 'comma' }), 'a
|
|
138
|
-
st.equal(qs.stringify({ a: { b: ['c', 'd'] } }), 'a
|
|
135
|
+
st.equal(qs.stringify({ a: { b: ['c', 'd'] } }, { encodeValuesOnly: true, arrayFormat: 'indices' }), 'a[b][0]=c&a[b][1]=d');
|
|
136
|
+
st.equal(qs.stringify({ a: { b: ['c', 'd'] } }, { encodeValuesOnly: true, arrayFormat: 'brackets' }), 'a[b][]=c&a[b][]=d');
|
|
137
|
+
st.equal(qs.stringify({ a: { b: ['c', 'd'] } }, { encodeValuesOnly: true, arrayFormat: 'comma' }), 'a[b]=c,d');
|
|
138
|
+
st.equal(qs.stringify({ a: { b: ['c', 'd'] } }, { encodeValuesOnly: true }), 'a[b][0]=c&a[b][1]=d');
|
|
139
139
|
st.end();
|
|
140
140
|
});
|
|
141
141
|
|
|
@@ -143,7 +143,7 @@ test('stringify()', function (t) {
|
|
|
143
143
|
st.equal(
|
|
144
144
|
qs.stringify(
|
|
145
145
|
{ a: { b: ['c', 'd'] } },
|
|
146
|
-
{ allowDots: true,
|
|
146
|
+
{ allowDots: true, encodeValuesOnly: true, arrayFormat: 'indices' }
|
|
147
147
|
),
|
|
148
148
|
'a.b[0]=c&a.b[1]=d',
|
|
149
149
|
'indices: stringifies with dots + indices'
|
|
@@ -151,7 +151,7 @@ test('stringify()', function (t) {
|
|
|
151
151
|
st.equal(
|
|
152
152
|
qs.stringify(
|
|
153
153
|
{ a: { b: ['c', 'd'] } },
|
|
154
|
-
{ allowDots: true,
|
|
154
|
+
{ allowDots: true, encodeValuesOnly: true, arrayFormat: 'brackets' }
|
|
155
155
|
),
|
|
156
156
|
'a.b[]=c&a.b[]=d',
|
|
157
157
|
'brackets: stringifies with dots + brackets'
|
|
@@ -159,7 +159,7 @@ test('stringify()', function (t) {
|
|
|
159
159
|
st.equal(
|
|
160
160
|
qs.stringify(
|
|
161
161
|
{ a: { b: ['c', 'd'] } },
|
|
162
|
-
{ allowDots: true,
|
|
162
|
+
{ allowDots: true, encodeValuesOnly: true, arrayFormat: 'comma' }
|
|
163
163
|
),
|
|
164
164
|
'a.b=c,d',
|
|
165
165
|
'comma: stringifies with dots + comma'
|
|
@@ -167,7 +167,7 @@ test('stringify()', function (t) {
|
|
|
167
167
|
st.equal(
|
|
168
168
|
qs.stringify(
|
|
169
169
|
{ a: { b: ['c', 'd'] } },
|
|
170
|
-
{ allowDots: true,
|
|
170
|
+
{ allowDots: true, encodeValuesOnly: true }
|
|
171
171
|
),
|
|
172
172
|
'a.b[0]=c&a.b[1]=d',
|
|
173
173
|
'default: stringifies with dots + indices'
|
|
@@ -215,17 +215,23 @@ test('stringify()', function (t) {
|
|
|
215
215
|
|
|
216
216
|
t.test('stringifies an array with mixed objects and primitives', function (st) {
|
|
217
217
|
st.equal(
|
|
218
|
-
qs.stringify({ a: [{ b: 1 }, 2, 3] }, {
|
|
218
|
+
qs.stringify({ a: [{ b: 1 }, 2, 3] }, { encodeValuesOnly: true, arrayFormat: 'indices' }),
|
|
219
219
|
'a[0][b]=1&a[1]=2&a[2]=3',
|
|
220
220
|
'indices => indices'
|
|
221
221
|
);
|
|
222
222
|
st.equal(
|
|
223
|
-
qs.stringify({ a: [{ b: 1 }, 2, 3] }, {
|
|
223
|
+
qs.stringify({ a: [{ b: 1 }, 2, 3] }, { encodeValuesOnly: true, arrayFormat: 'brackets' }),
|
|
224
224
|
'a[][b]=1&a[]=2&a[]=3',
|
|
225
225
|
'brackets => brackets'
|
|
226
226
|
);
|
|
227
227
|
st.equal(
|
|
228
|
-
qs.stringify({ a: [{ b: 1 }, 2, 3] }, {
|
|
228
|
+
qs.stringify({ a: [{ b: 1 }, 2, 3] }, { encodeValuesOnly: true, arrayFormat: 'comma' }),
|
|
229
|
+
'???',
|
|
230
|
+
'brackets => brackets',
|
|
231
|
+
{ skip: 'TODO: figure out what this should do' }
|
|
232
|
+
);
|
|
233
|
+
st.equal(
|
|
234
|
+
qs.stringify({ a: [{ b: 1 }, 2, 3] }, { encodeValuesOnly: true }),
|
|
229
235
|
'a[0][b]=1&a[1]=2&a[2]=3',
|
|
230
236
|
'default => indices'
|
|
231
237
|
);
|
|
@@ -433,7 +439,7 @@ test('stringify()', function (t) {
|
|
|
433
439
|
st.end();
|
|
434
440
|
});
|
|
435
441
|
|
|
436
|
-
t.test('
|
|
442
|
+
t.test('does not blow up when Buffer global is missing', function (st) {
|
|
437
443
|
var tempBuffer = global.Buffer;
|
|
438
444
|
delete global.Buffer;
|
|
439
445
|
var result = qs.stringify({ a: 'b', c: 'd' });
|
|
@@ -442,6 +448,57 @@ test('stringify()', function (t) {
|
|
|
442
448
|
st.end();
|
|
443
449
|
});
|
|
444
450
|
|
|
451
|
+
t.test('does not crash when parsing circular references', function (st) {
|
|
452
|
+
var a = {};
|
|
453
|
+
a.b = a;
|
|
454
|
+
|
|
455
|
+
st['throws'](
|
|
456
|
+
function () { qs.stringify({ 'foo[bar]': 'baz', 'foo[baz]': a }); },
|
|
457
|
+
/RangeError: Cyclic object value/,
|
|
458
|
+
'cyclic values throw'
|
|
459
|
+
);
|
|
460
|
+
|
|
461
|
+
var circular = {
|
|
462
|
+
a: 'value'
|
|
463
|
+
};
|
|
464
|
+
circular.a = circular;
|
|
465
|
+
st['throws'](
|
|
466
|
+
function () { qs.stringify(circular); },
|
|
467
|
+
/RangeError: Cyclic object value/,
|
|
468
|
+
'cyclic values throw'
|
|
469
|
+
);
|
|
470
|
+
|
|
471
|
+
var arr = ['a'];
|
|
472
|
+
st.doesNotThrow(
|
|
473
|
+
function () { qs.stringify({ x: arr, y: arr }); },
|
|
474
|
+
'non-cyclic values do not throw'
|
|
475
|
+
);
|
|
476
|
+
|
|
477
|
+
st.end();
|
|
478
|
+
});
|
|
479
|
+
|
|
480
|
+
t.test('non-circular duplicated references can still work', function (st) {
|
|
481
|
+
var hourOfDay = {
|
|
482
|
+
'function': 'hour_of_day'
|
|
483
|
+
};
|
|
484
|
+
|
|
485
|
+
var p1 = {
|
|
486
|
+
'function': 'gte',
|
|
487
|
+
arguments: [hourOfDay, 0]
|
|
488
|
+
};
|
|
489
|
+
var p2 = {
|
|
490
|
+
'function': 'lte',
|
|
491
|
+
arguments: [hourOfDay, 23]
|
|
492
|
+
};
|
|
493
|
+
|
|
494
|
+
st.equal(
|
|
495
|
+
qs.stringify({ filters: { $and: [p1, p2] } }, { encodeValuesOnly: true }),
|
|
496
|
+
'filters[$and][0][function]=gte&filters[$and][0][arguments][0][function]=hour_of_day&filters[$and][0][arguments][1]=0&filters[$and][1][function]=lte&filters[$and][1][arguments][0][function]=hour_of_day&filters[$and][1][arguments][1]=23'
|
|
497
|
+
);
|
|
498
|
+
|
|
499
|
+
st.end();
|
|
500
|
+
});
|
|
501
|
+
|
|
445
502
|
t.test('selects properties when filter=array', function (st) {
|
|
446
503
|
st.equal(qs.stringify({ a: 'b' }, { filter: ['a'] }), 'a=b');
|
|
447
504
|
st.equal(qs.stringify({ a: 1 }, { filter: [] }), '');
|
|
@@ -784,7 +841,22 @@ test('stringify()', function (t) {
|
|
|
784
841
|
st.equal(qs.stringify(withArray, { encode: false }), 'a[b][0][c]=d&a[b][0][e]=f', 'array, no arrayFormat');
|
|
785
842
|
st.equal(qs.stringify(withArray, { encode: false, arrayFormat: 'bracket' }), 'a[b][0][c]=d&a[b][0][e]=f', 'array, bracket');
|
|
786
843
|
st.equal(qs.stringify(withArray, { encode: false, arrayFormat: 'indices' }), 'a[b][0][c]=d&a[b][0][e]=f', 'array, indices');
|
|
787
|
-
st.equal(
|
|
844
|
+
st.equal(
|
|
845
|
+
qs.stringify(withArray, { encode: false, arrayFormat: 'comma' }),
|
|
846
|
+
'???',
|
|
847
|
+
'array, comma',
|
|
848
|
+
{ skip: 'TODO: figure out what this should do' }
|
|
849
|
+
);
|
|
850
|
+
|
|
851
|
+
st.end();
|
|
852
|
+
});
|
|
853
|
+
|
|
854
|
+
t.test('stringifies sparse arrays', function (st) {
|
|
855
|
+
/* eslint no-sparse-arrays: 0 */
|
|
856
|
+
st.equal(qs.stringify({ a: [, '2', , , '1'] }, { encodeValuesOnly: true }), 'a[1]=2&a[4]=1');
|
|
857
|
+
st.equal(qs.stringify({ a: [, { b: [, , { c: '1' }] }] }, { encodeValuesOnly: true }), 'a[1][b][2][c]=1');
|
|
858
|
+
st.equal(qs.stringify({ a: [, [, , [, , , { c: '1' }]]] }, { encodeValuesOnly: true }), 'a[1][2][3][c]=1');
|
|
859
|
+
st.equal(qs.stringify({ a: [, [, , [, , , { c: [, '1'] }]]] }, { encodeValuesOnly: true }), 'a[1][2][3][c][1]=1');
|
|
788
860
|
|
|
789
861
|
st.end();
|
|
790
862
|
});
|