qs 6.2.4 → 6.3.3
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 -2
- package/.eslintrc +0 -2
- package/CHANGELOG.md +32 -5
- package/README.md +59 -4
- package/component.json +1 -1
- package/dist/qs.js +109 -75
- package/lib/formats.js +18 -0
- package/lib/index.js +6 -4
- package/lib/parse.js +12 -12
- package/lib/stringify.js +51 -23
- package/lib/utils.js +16 -32
- package/package.json +1 -1
- package/test/parse.js +26 -16
- package/test/stringify.js +286 -21
- package/CONTRIBUTING.md +0 -1
package/test/stringify.js
CHANGED
|
@@ -31,7 +31,21 @@ test('stringify()', function (t) {
|
|
|
31
31
|
});
|
|
32
32
|
|
|
33
33
|
t.test('stringifies an array value', function (st) {
|
|
34
|
-
st.equal(
|
|
34
|
+
st.equal(
|
|
35
|
+
qs.stringify({ a: ['b', 'c', 'd'] }, { arrayFormat: 'indices' }),
|
|
36
|
+
'a%5B0%5D=b&a%5B1%5D=c&a%5B2%5D=d',
|
|
37
|
+
'indices => indices'
|
|
38
|
+
);
|
|
39
|
+
st.equal(
|
|
40
|
+
qs.stringify({ a: ['b', 'c', 'd'] }, { arrayFormat: 'brackets' }),
|
|
41
|
+
'a%5B%5D=b&a%5B%5D=c&a%5B%5D=d',
|
|
42
|
+
'brackets => brackets'
|
|
43
|
+
);
|
|
44
|
+
st.equal(
|
|
45
|
+
qs.stringify({ a: ['b', 'c', 'd'] }),
|
|
46
|
+
'a%5B0%5D=b&a%5B1%5D=c&a%5B2%5D=d',
|
|
47
|
+
'default => indices'
|
|
48
|
+
);
|
|
35
49
|
st.end();
|
|
36
50
|
});
|
|
37
51
|
|
|
@@ -51,29 +65,149 @@ test('stringify()', function (t) {
|
|
|
51
65
|
});
|
|
52
66
|
|
|
53
67
|
t.test('stringifies a nested array value', function (st) {
|
|
68
|
+
st.equal(qs.stringify({ a: { b: ['c', 'd'] } }, { arrayFormat: 'indices' }), 'a%5Bb%5D%5B0%5D=c&a%5Bb%5D%5B1%5D=d');
|
|
69
|
+
st.equal(qs.stringify({ a: { b: ['c', 'd'] } }, { arrayFormat: 'brackets' }), 'a%5Bb%5D%5B%5D=c&a%5Bb%5D%5B%5D=d');
|
|
54
70
|
st.equal(qs.stringify({ a: { b: ['c', 'd'] } }), 'a%5Bb%5D%5B0%5D=c&a%5Bb%5D%5B1%5D=d');
|
|
55
71
|
st.end();
|
|
56
72
|
});
|
|
57
73
|
|
|
58
74
|
t.test('stringifies a nested array value with dots notation', function (st) {
|
|
59
|
-
st.equal(
|
|
75
|
+
st.equal(
|
|
76
|
+
qs.stringify(
|
|
77
|
+
{ a: { b: ['c', 'd'] } },
|
|
78
|
+
{ allowDots: true, encode: false, arrayFormat: 'indices' }
|
|
79
|
+
),
|
|
80
|
+
'a.b[0]=c&a.b[1]=d',
|
|
81
|
+
'indices: stringifies with dots + indices'
|
|
82
|
+
);
|
|
83
|
+
st.equal(
|
|
84
|
+
qs.stringify(
|
|
85
|
+
{ a: { b: ['c', 'd'] } },
|
|
86
|
+
{ allowDots: true, encode: false, arrayFormat: 'brackets' }
|
|
87
|
+
),
|
|
88
|
+
'a.b[]=c&a.b[]=d',
|
|
89
|
+
'brackets: stringifies with dots + brackets'
|
|
90
|
+
);
|
|
91
|
+
st.equal(
|
|
92
|
+
qs.stringify(
|
|
93
|
+
{ a: { b: ['c', 'd'] } },
|
|
94
|
+
{ allowDots: true, encode: false }
|
|
95
|
+
),
|
|
96
|
+
'a.b[0]=c&a.b[1]=d',
|
|
97
|
+
'default: stringifies with dots + indices'
|
|
98
|
+
);
|
|
60
99
|
st.end();
|
|
61
100
|
});
|
|
62
101
|
|
|
63
102
|
t.test('stringifies an object inside an array', function (st) {
|
|
64
|
-
st.equal(
|
|
65
|
-
|
|
103
|
+
st.equal(
|
|
104
|
+
qs.stringify({ a: [{ b: 'c' }] }, { arrayFormat: 'indices' }),
|
|
105
|
+
'a%5B0%5D%5Bb%5D=c',
|
|
106
|
+
'indices => brackets'
|
|
107
|
+
);
|
|
108
|
+
st.equal(
|
|
109
|
+
qs.stringify({ a: [{ b: 'c' }] }, { arrayFormat: 'brackets' }),
|
|
110
|
+
'a%5B%5D%5Bb%5D=c',
|
|
111
|
+
'brackets => brackets'
|
|
112
|
+
);
|
|
113
|
+
st.equal(
|
|
114
|
+
qs.stringify({ a: [{ b: 'c' }] }),
|
|
115
|
+
'a%5B0%5D%5Bb%5D=c',
|
|
116
|
+
'default => indices'
|
|
117
|
+
);
|
|
118
|
+
|
|
119
|
+
st.equal(
|
|
120
|
+
qs.stringify({ a: [{ b: { c: [1] } }] }, { arrayFormat: 'indices' }),
|
|
121
|
+
'a%5B0%5D%5Bb%5D%5Bc%5D%5B0%5D=1',
|
|
122
|
+
'indices => indices'
|
|
123
|
+
);
|
|
124
|
+
|
|
125
|
+
st.equal(
|
|
126
|
+
qs.stringify({ a: [{ b: { c: [1] } }] }, { arrayFormat: 'brackets' }),
|
|
127
|
+
'a%5B%5D%5Bb%5D%5Bc%5D%5B%5D=1',
|
|
128
|
+
'brackets => brackets'
|
|
129
|
+
);
|
|
130
|
+
|
|
131
|
+
st.equal(
|
|
132
|
+
qs.stringify({ a: [{ b: { c: [1] } }] }),
|
|
133
|
+
'a%5B0%5D%5Bb%5D%5Bc%5D%5B0%5D=1',
|
|
134
|
+
'default => indices'
|
|
135
|
+
);
|
|
136
|
+
|
|
66
137
|
st.end();
|
|
67
138
|
});
|
|
68
139
|
|
|
69
140
|
t.test('stringifies an array with mixed objects and primitives', function (st) {
|
|
70
|
-
st.equal(
|
|
141
|
+
st.equal(
|
|
142
|
+
qs.stringify({ a: [{ b: 1 }, 2, 3] }, { encode: false, arrayFormat: 'indices' }),
|
|
143
|
+
'a[0][b]=1&a[1]=2&a[2]=3',
|
|
144
|
+
'indices => indices'
|
|
145
|
+
);
|
|
146
|
+
st.equal(
|
|
147
|
+
qs.stringify({ a: [{ b: 1 }, 2, 3] }, { encode: false, arrayFormat: 'brackets' }),
|
|
148
|
+
'a[][b]=1&a[]=2&a[]=3',
|
|
149
|
+
'brackets => brackets'
|
|
150
|
+
);
|
|
151
|
+
st.equal(
|
|
152
|
+
qs.stringify({ a: [{ b: 1 }, 2, 3] }, { encode: false }),
|
|
153
|
+
'a[0][b]=1&a[1]=2&a[2]=3',
|
|
154
|
+
'default => indices'
|
|
155
|
+
);
|
|
156
|
+
|
|
71
157
|
st.end();
|
|
72
158
|
});
|
|
73
159
|
|
|
74
160
|
t.test('stringifies an object inside an array with dots notation', function (st) {
|
|
75
|
-
st.equal(
|
|
76
|
-
|
|
161
|
+
st.equal(
|
|
162
|
+
qs.stringify(
|
|
163
|
+
{ a: [{ b: 'c' }] },
|
|
164
|
+
{ allowDots: true, encode: false, arrayFormat: 'indices' }
|
|
165
|
+
),
|
|
166
|
+
'a[0].b=c',
|
|
167
|
+
'indices => indices'
|
|
168
|
+
);
|
|
169
|
+
st.equal(
|
|
170
|
+
qs.stringify(
|
|
171
|
+
{ a: [{ b: 'c' }] },
|
|
172
|
+
{ allowDots: true, encode: false, arrayFormat: 'brackets' }
|
|
173
|
+
),
|
|
174
|
+
'a[].b=c',
|
|
175
|
+
'brackets => brackets'
|
|
176
|
+
);
|
|
177
|
+
st.equal(
|
|
178
|
+
qs.stringify(
|
|
179
|
+
{ a: [{ b: 'c' }] },
|
|
180
|
+
{ allowDots: true, encode: false }
|
|
181
|
+
),
|
|
182
|
+
'a[0].b=c',
|
|
183
|
+
'default => indices'
|
|
184
|
+
);
|
|
185
|
+
|
|
186
|
+
st.equal(
|
|
187
|
+
qs.stringify(
|
|
188
|
+
{ a: [{ b: { c: [1] } }] },
|
|
189
|
+
{ allowDots: true, encode: false, arrayFormat: 'indices' }
|
|
190
|
+
),
|
|
191
|
+
'a[0].b.c[0]=1',
|
|
192
|
+
'indices => indices'
|
|
193
|
+
);
|
|
194
|
+
st.equal(
|
|
195
|
+
qs.stringify(
|
|
196
|
+
{ a: [{ b: { c: [1] } }] },
|
|
197
|
+
{ allowDots: true, encode: false, arrayFormat: 'brackets' }
|
|
198
|
+
),
|
|
199
|
+
'a[].b.c[]=1',
|
|
200
|
+
'brackets => brackets'
|
|
201
|
+
);
|
|
202
|
+
st.equal(
|
|
203
|
+
qs.stringify(
|
|
204
|
+
{ a: [{ b: { c: [1] } }] },
|
|
205
|
+
{ allowDots: true, encode: false }
|
|
206
|
+
),
|
|
207
|
+
'a[0].b.c[0]=1',
|
|
208
|
+
'default => indices'
|
|
209
|
+
);
|
|
210
|
+
|
|
77
211
|
st.end();
|
|
78
212
|
});
|
|
79
213
|
|
|
@@ -126,7 +260,7 @@ test('stringify()', function (t) {
|
|
|
126
260
|
st.end();
|
|
127
261
|
});
|
|
128
262
|
|
|
129
|
-
t.test('stringifies
|
|
263
|
+
t.test('stringifies a null object', { skip: !Object.create }, function (st) {
|
|
130
264
|
var obj = Object.create(null);
|
|
131
265
|
obj.a = 'b';
|
|
132
266
|
st.equal(qs.stringify(obj), 'a=b');
|
|
@@ -141,10 +275,8 @@ test('stringify()', function (t) {
|
|
|
141
275
|
st.end();
|
|
142
276
|
});
|
|
143
277
|
|
|
144
|
-
t.test('stringifies an object with
|
|
145
|
-
var obj = {
|
|
146
|
-
a: Object.create(null)
|
|
147
|
-
};
|
|
278
|
+
t.test('stringifies an object with a null object as a child', { skip: !Object.create }, function (st) {
|
|
279
|
+
var obj = { a: Object.create(null) };
|
|
148
280
|
|
|
149
281
|
obj.a.b = 'c';
|
|
150
282
|
st.equal(qs.stringify(obj), 'a%5Bb%5D=c');
|
|
@@ -216,7 +348,32 @@ test('stringify()', function (t) {
|
|
|
216
348
|
t.test('selects properties when filter=array', function (st) {
|
|
217
349
|
st.equal(qs.stringify({ a: 'b' }, { filter: ['a'] }), 'a=b');
|
|
218
350
|
st.equal(qs.stringify({ a: 1 }, { filter: [] }), '');
|
|
219
|
-
|
|
351
|
+
|
|
352
|
+
st.equal(
|
|
353
|
+
qs.stringify(
|
|
354
|
+
{ a: { b: [1, 2, 3, 4], c: 'd' }, c: 'f' },
|
|
355
|
+
{ filter: ['a', 'b', 0, 2], arrayFormat: 'indices' }
|
|
356
|
+
),
|
|
357
|
+
'a%5Bb%5D%5B0%5D=1&a%5Bb%5D%5B2%5D=3',
|
|
358
|
+
'indices => indices'
|
|
359
|
+
);
|
|
360
|
+
st.equal(
|
|
361
|
+
qs.stringify(
|
|
362
|
+
{ a: { b: [1, 2, 3, 4], c: 'd' }, c: 'f' },
|
|
363
|
+
{ filter: ['a', 'b', 0, 2], arrayFormat: 'brackets' }
|
|
364
|
+
),
|
|
365
|
+
'a%5Bb%5D%5B%5D=1&a%5Bb%5D%5B%5D=3',
|
|
366
|
+
'brackets => brackets'
|
|
367
|
+
);
|
|
368
|
+
st.equal(
|
|
369
|
+
qs.stringify(
|
|
370
|
+
{ a: { b: [1, 2, 3, 4], c: 'd' }, c: 'f' },
|
|
371
|
+
{ filter: ['a', 'b', 0, 2] }
|
|
372
|
+
),
|
|
373
|
+
'a%5Bb%5D%5B0%5D=1&a%5Bb%5D%5B2%5D=3',
|
|
374
|
+
'default => indices'
|
|
375
|
+
);
|
|
376
|
+
|
|
220
377
|
st.end();
|
|
221
378
|
});
|
|
222
379
|
|
|
@@ -229,7 +386,7 @@ test('stringify()', function (t) {
|
|
|
229
386
|
st.equal(prefix, '', 'prefix is empty');
|
|
230
387
|
st.equal(value, obj);
|
|
231
388
|
} else if (prefix === 'c') {
|
|
232
|
-
return;
|
|
389
|
+
return void 0;
|
|
233
390
|
} else if (value instanceof Date) {
|
|
234
391
|
st.equal(prefix, 'e[f]');
|
|
235
392
|
return value.getTime();
|
|
@@ -250,16 +407,32 @@ test('stringify()', function (t) {
|
|
|
250
407
|
});
|
|
251
408
|
|
|
252
409
|
t.test('can sort the keys', function (st) {
|
|
253
|
-
var sort = function (a, b) {
|
|
410
|
+
var sort = function (a, b) {
|
|
411
|
+
return a.localeCompare(b);
|
|
412
|
+
};
|
|
254
413
|
st.equal(qs.stringify({ a: 'c', z: 'y', b: 'f' }, { sort: sort }), 'a=c&b=f&z=y');
|
|
255
414
|
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');
|
|
256
415
|
st.end();
|
|
257
416
|
});
|
|
258
417
|
|
|
259
418
|
t.test('can sort the keys at depth 3 or more too', function (st) {
|
|
260
|
-
var sort = function (a, b) {
|
|
261
|
-
|
|
262
|
-
|
|
419
|
+
var sort = function (a, b) {
|
|
420
|
+
return a.localeCompare(b);
|
|
421
|
+
};
|
|
422
|
+
st.equal(
|
|
423
|
+
qs.stringify(
|
|
424
|
+
{ a: 'a', z: { zj: { zjb: 'zjb', zja: 'zja' }, zi: { zib: 'zib', zia: 'zia' } }, b: 'b' },
|
|
425
|
+
{ sort: sort, encode: false }
|
|
426
|
+
),
|
|
427
|
+
'a=a&b=b&z[zi][zia]=zia&z[zi][zib]=zib&z[zj][zja]=zja&z[zj][zjb]=zjb'
|
|
428
|
+
);
|
|
429
|
+
st.equal(
|
|
430
|
+
qs.stringify(
|
|
431
|
+
{ a: 'a', z: { zj: { zjb: 'zjb', zja: 'zja' }, zi: { zib: 'zib', zia: 'zia' } }, b: 'b' },
|
|
432
|
+
{ sort: null, encode: false }
|
|
433
|
+
),
|
|
434
|
+
'a=a&z[zj][zjb]=zjb&z[zj][zja]=zja&z[zi][zib]=zib&z[zi][zia]=zia&b=b'
|
|
435
|
+
);
|
|
263
436
|
st.end();
|
|
264
437
|
});
|
|
265
438
|
|
|
@@ -282,9 +455,7 @@ test('stringify()', function (t) {
|
|
|
282
455
|
|
|
283
456
|
t.test('throws error with wrong encoder', function (st) {
|
|
284
457
|
st['throws'](function () {
|
|
285
|
-
qs.stringify({}, {
|
|
286
|
-
encoder: 'string'
|
|
287
|
-
});
|
|
458
|
+
qs.stringify({}, { encoder: 'string' });
|
|
288
459
|
}, new TypeError('Encoder has to be a function.'));
|
|
289
460
|
st.end();
|
|
290
461
|
});
|
|
@@ -298,6 +469,100 @@ test('stringify()', function (t) {
|
|
|
298
469
|
return String.fromCharCode(buffer.readUInt8(0) + 97);
|
|
299
470
|
}
|
|
300
471
|
}), '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
|
+
st.end();
|
|
479
|
+
});
|
|
480
|
+
|
|
481
|
+
t.test('serializeDate option', function (st) {
|
|
482
|
+
var date = new Date();
|
|
483
|
+
st.equal(
|
|
484
|
+
qs.stringify({ a: date }),
|
|
485
|
+
'a=' + date.toISOString().replace(/:/g, '%3A'),
|
|
486
|
+
'default is toISOString'
|
|
487
|
+
);
|
|
488
|
+
|
|
489
|
+
var mutatedDate = new Date();
|
|
490
|
+
mutatedDate.toISOString = function () {
|
|
491
|
+
throw new SyntaxError();
|
|
492
|
+
};
|
|
493
|
+
st['throws'](function () {
|
|
494
|
+
mutatedDate.toISOString();
|
|
495
|
+
}, SyntaxError);
|
|
496
|
+
st.equal(
|
|
497
|
+
qs.stringify({ a: mutatedDate }),
|
|
498
|
+
'a=' + Date.prototype.toISOString.call(mutatedDate).replace(/:/g, '%3A'),
|
|
499
|
+
'toISOString works even when method is not locally present'
|
|
500
|
+
);
|
|
501
|
+
|
|
502
|
+
var specificDate = new Date(6);
|
|
503
|
+
st.equal(
|
|
504
|
+
qs.stringify(
|
|
505
|
+
{ a: specificDate },
|
|
506
|
+
{ serializeDate: function (d) { return d.getTime() * 7; } }
|
|
507
|
+
),
|
|
508
|
+
'a=42',
|
|
509
|
+
'custom serializeDate function called'
|
|
510
|
+
);
|
|
511
|
+
|
|
512
|
+
st.end();
|
|
513
|
+
});
|
|
514
|
+
|
|
515
|
+
t.test('RFC 1738 spaces serialization', function (st) {
|
|
516
|
+
st.equal(qs.stringify({ a: 'b c' }, { format: qs.formats.RFC1738 }), 'a=b+c');
|
|
517
|
+
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');
|
|
301
519
|
st.end();
|
|
302
520
|
});
|
|
521
|
+
|
|
522
|
+
t.test('RFC 3986 spaces serialization', function (st) {
|
|
523
|
+
st.equal(qs.stringify({ a: 'b c' }, { format: qs.formats.RFC3986 }), 'a=b%20c');
|
|
524
|
+
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
|
+
st.end();
|
|
527
|
+
});
|
|
528
|
+
|
|
529
|
+
t.test('Backward compatibility to RFC 3986', function (st) {
|
|
530
|
+
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
|
+
st.end();
|
|
533
|
+
});
|
|
534
|
+
|
|
535
|
+
t.test('Edge cases and unknown formats', function (st) {
|
|
536
|
+
['UFO1234', false, 1234, null, {}, []].forEach(function (format) {
|
|
537
|
+
st['throws'](
|
|
538
|
+
function () {
|
|
539
|
+
qs.stringify({ a: 'b c' }, { format: format });
|
|
540
|
+
},
|
|
541
|
+
new TypeError('Unknown format option provided.')
|
|
542
|
+
);
|
|
543
|
+
});
|
|
544
|
+
st.end();
|
|
545
|
+
});
|
|
546
|
+
|
|
547
|
+
t.test('strictNullHandling works with custom filter', function (st) {
|
|
548
|
+
var filter = function (prefix, value) {
|
|
549
|
+
return value;
|
|
550
|
+
};
|
|
551
|
+
|
|
552
|
+
var options = { strictNullHandling: true, filter: filter };
|
|
553
|
+
st.equal(qs.stringify({ key: null }, options), 'key');
|
|
554
|
+
st.end();
|
|
555
|
+
});
|
|
556
|
+
|
|
557
|
+
t.test('strictNullHandling works with null serializeDate', function (st) {
|
|
558
|
+
var serializeDate = function () {
|
|
559
|
+
return null;
|
|
560
|
+
};
|
|
561
|
+
var options = { strictNullHandling: true, serializeDate: serializeDate };
|
|
562
|
+
var date = new Date();
|
|
563
|
+
st.equal(qs.stringify({ key: date }, options), 'key');
|
|
564
|
+
st.end();
|
|
565
|
+
});
|
|
566
|
+
|
|
567
|
+
t.end();
|
|
303
568
|
});
|
package/CONTRIBUTING.md
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
Please view our [hapijs contributing guide](https://github.com/hapijs/hapi/blob/master/CONTRIBUTING.md).
|