step-node-agent 3.25.3 → 3.25.5

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.
Files changed (82) hide show
  1. package/node_modules/aws4/README.md +3 -5
  2. package/node_modules/aws4/aws4.js +22 -20
  3. package/node_modules/aws4/package.json +2 -2
  4. package/node_modules/body-parser/HISTORY.md +7 -0
  5. package/node_modules/body-parser/README.md +11 -0
  6. package/node_modules/body-parser/lib/types/urlencoded.js +30 -7
  7. package/node_modules/body-parser/package.json +2 -2
  8. package/node_modules/encodeurl/README.md +19 -38
  9. package/node_modules/encodeurl/index.js +1 -1
  10. package/node_modules/encodeurl/package.json +7 -7
  11. package/node_modules/express/History.md +27 -0
  12. package/node_modules/express/Readme.md +100 -6
  13. package/node_modules/express/lib/response.js +11 -10
  14. package/node_modules/express/package.json +11 -11
  15. package/node_modules/finalhandler/HISTORY.md +15 -0
  16. package/node_modules/finalhandler/README.md +2 -2
  17. package/node_modules/finalhandler/index.js +7 -2
  18. package/node_modules/finalhandler/package.json +8 -7
  19. package/node_modules/is-core-module/CHANGELOG.md +10 -0
  20. package/node_modules/is-core-module/core.json +2 -2
  21. package/node_modules/is-core-module/package.json +4 -4
  22. package/node_modules/is-core-module/test/index.js +17 -1
  23. package/node_modules/merge-descriptors/README.md +4 -3
  24. package/node_modules/merge-descriptors/index.js +3 -3
  25. package/node_modules/merge-descriptors/package.json +14 -7
  26. package/node_modules/path-to-regexp/index.js +57 -40
  27. package/node_modules/path-to-regexp/package.json +2 -2
  28. package/node_modules/qs/.editorconfig +3 -0
  29. package/node_modules/qs/.eslintrc +2 -2
  30. package/node_modules/qs/CHANGELOG.md +59 -5
  31. package/node_modules/qs/README.md +133 -49
  32. package/node_modules/qs/dist/qs.js +56 -2020
  33. package/node_modules/qs/lib/parse.js +46 -13
  34. package/node_modules/qs/lib/stringify.js +53 -28
  35. package/node_modules/qs/lib/utils.js +47 -34
  36. package/node_modules/qs/package.json +26 -12
  37. package/node_modules/qs/test/empty-keys-cases.js +267 -0
  38. package/node_modules/qs/test/parse.js +347 -32
  39. package/node_modules/qs/test/stringify.js +436 -47
  40. package/node_modules/send/HISTORY.md +5 -0
  41. package/node_modules/send/index.js +1 -2
  42. package/node_modules/send/node_modules/encodeurl/LICENSE +22 -0
  43. package/node_modules/send/node_modules/encodeurl/README.md +128 -0
  44. package/node_modules/send/node_modules/encodeurl/index.js +60 -0
  45. package/node_modules/send/node_modules/encodeurl/package.json +40 -0
  46. package/node_modules/send/package.json +1 -1
  47. package/node_modules/serve-static/HISTORY.md +16 -0
  48. package/node_modules/serve-static/index.js +1 -2
  49. package/node_modules/serve-static/package.json +3 -3
  50. package/node_modules/underscore/amd/_setup.js +1 -1
  51. package/node_modules/underscore/amd/_stringTagBug.js +6 -3
  52. package/node_modules/underscore/amd/isDataView.js +4 -2
  53. package/node_modules/underscore/amd/isEqual.js +1 -1
  54. package/node_modules/underscore/cjs/_setup.js +1 -1
  55. package/node_modules/underscore/cjs/_stringTagBug.js +6 -3
  56. package/node_modules/underscore/cjs/isDataView.js +4 -2
  57. package/node_modules/underscore/cjs/isEqual.js +1 -1
  58. package/node_modules/underscore/modules/_setup.js +1 -1
  59. package/node_modules/underscore/modules/_stringTagBug.js +5 -2
  60. package/node_modules/underscore/modules/index.js +2 -2
  61. package/node_modules/underscore/modules/isDataView.js +5 -3
  62. package/node_modules/underscore/modules/isEqual.js +2 -2
  63. package/node_modules/underscore/modules/package.json +1 -1
  64. package/node_modules/underscore/package.json +2 -2
  65. package/node_modules/underscore/underscore-esm-min.js +3 -3
  66. package/node_modules/underscore/underscore-esm-min.js.map +1 -1
  67. package/node_modules/underscore/underscore-esm.js +13 -8
  68. package/node_modules/underscore/underscore-esm.js.map +1 -1
  69. package/node_modules/underscore/underscore-min.js +3 -3
  70. package/node_modules/underscore/underscore-min.js.map +1 -1
  71. package/node_modules/underscore/underscore-node-f.cjs +13 -8
  72. package/node_modules/underscore/underscore-node-f.cjs.map +1 -1
  73. package/node_modules/underscore/underscore-node.cjs +2 -2
  74. package/node_modules/underscore/underscore-node.mjs +2 -2
  75. package/node_modules/underscore/underscore-umd-min.js +3 -3
  76. package/node_modules/underscore/underscore-umd-min.js.map +1 -1
  77. package/node_modules/underscore/underscore-umd.js +13 -8
  78. package/node_modules/underscore/underscore-umd.js.map +1 -1
  79. package/node_modules/underscore/underscore.js +13 -8
  80. package/package.json +1 -1
  81. package/node_modules/path-to-regexp/History.md +0 -36
  82. /package/node_modules/{encodeurl → send/node_modules/encodeurl}/HISTORY.md +0 -0
@@ -6,6 +6,8 @@ var utils = require('../lib/utils');
6
6
  var iconv = require('iconv-lite');
7
7
  var SaferBuffer = require('safer-buffer').Buffer;
8
8
  var hasSymbols = require('has-symbols');
9
+ var mockProperty = require('mock-property');
10
+ var emptyTestCases = require('./empty-keys-cases').emptyTestCases;
9
11
  var hasBigInt = typeof BigInt === 'function';
10
12
 
11
13
  test('stringify()', function (t) {
@@ -63,6 +65,138 @@ test('stringify()', function (t) {
63
65
  st.end();
64
66
  });
65
67
 
68
+ t.test('encodes dot in key of object when encodeDotInKeys and allowDots is provided', function (st) {
69
+ st.equal(
70
+ qs.stringify(
71
+ { 'name.obj': { first: 'John', last: 'Doe' } },
72
+ { allowDots: false, encodeDotInKeys: false }
73
+ ),
74
+ 'name.obj%5Bfirst%5D=John&name.obj%5Blast%5D=Doe',
75
+ 'with allowDots false and encodeDotInKeys false'
76
+ );
77
+ st.equal(
78
+ qs.stringify(
79
+ { 'name.obj': { first: 'John', last: 'Doe' } },
80
+ { allowDots: true, encodeDotInKeys: false }
81
+ ),
82
+ 'name.obj.first=John&name.obj.last=Doe',
83
+ 'with allowDots true and encodeDotInKeys false'
84
+ );
85
+ st.equal(
86
+ qs.stringify(
87
+ { 'name.obj': { first: 'John', last: 'Doe' } },
88
+ { allowDots: false, encodeDotInKeys: true }
89
+ ),
90
+ 'name%252Eobj%5Bfirst%5D=John&name%252Eobj%5Blast%5D=Doe',
91
+ 'with allowDots false and encodeDotInKeys true'
92
+ );
93
+ st.equal(
94
+ qs.stringify(
95
+ { 'name.obj': { first: 'John', last: 'Doe' } },
96
+ { allowDots: true, encodeDotInKeys: true }
97
+ ),
98
+ 'name%252Eobj.first=John&name%252Eobj.last=Doe',
99
+ 'with allowDots true and encodeDotInKeys true'
100
+ );
101
+
102
+ st.equal(
103
+ qs.stringify(
104
+ { 'name.obj.subobject': { 'first.godly.name': 'John', last: 'Doe' } },
105
+ { allowDots: false, encodeDotInKeys: false }
106
+ ),
107
+ 'name.obj.subobject%5Bfirst.godly.name%5D=John&name.obj.subobject%5Blast%5D=Doe',
108
+ 'with allowDots false and encodeDotInKeys false'
109
+ );
110
+ st.equal(
111
+ qs.stringify(
112
+ { 'name.obj.subobject': { 'first.godly.name': 'John', last: 'Doe' } },
113
+ { allowDots: true, encodeDotInKeys: false }
114
+ ),
115
+ 'name.obj.subobject.first.godly.name=John&name.obj.subobject.last=Doe',
116
+ 'with allowDots false and encodeDotInKeys false'
117
+ );
118
+ st.equal(
119
+ qs.stringify(
120
+ { 'name.obj.subobject': { 'first.godly.name': 'John', last: 'Doe' } },
121
+ { allowDots: false, encodeDotInKeys: true }
122
+ ),
123
+ 'name%252Eobj%252Esubobject%5Bfirst.godly.name%5D=John&name%252Eobj%252Esubobject%5Blast%5D=Doe',
124
+ 'with allowDots false and encodeDotInKeys true'
125
+ );
126
+ st.equal(
127
+ qs.stringify(
128
+ { 'name.obj.subobject': { 'first.godly.name': 'John', last: 'Doe' } },
129
+ { allowDots: true, encodeDotInKeys: true }
130
+ ),
131
+ 'name%252Eobj%252Esubobject.first%252Egodly%252Ename=John&name%252Eobj%252Esubobject.last=Doe',
132
+ 'with allowDots true and encodeDotInKeys true'
133
+ );
134
+
135
+ st.end();
136
+ });
137
+
138
+ t.test('should encode dot in key of object, and automatically set allowDots to `true` when encodeDotInKeys is true and allowDots in undefined', function (st) {
139
+ st.equal(
140
+ qs.stringify(
141
+ { 'name.obj.subobject': { 'first.godly.name': 'John', last: 'Doe' } },
142
+ { encodeDotInKeys: true }
143
+ ),
144
+ 'name%252Eobj%252Esubobject.first%252Egodly%252Ename=John&name%252Eobj%252Esubobject.last=Doe',
145
+ 'with allowDots undefined and encodeDotInKeys true'
146
+ );
147
+ st.end();
148
+ });
149
+
150
+ t.test('should encode dot in key of object when encodeDotInKeys and allowDots is provided, and nothing else when encodeValuesOnly is provided', function (st) {
151
+ st.equal(
152
+ qs.stringify({ 'name.obj': { first: 'John', last: 'Doe' } }, {
153
+ encodeDotInKeys: true, allowDots: true, encodeValuesOnly: true
154
+ }),
155
+ 'name%2Eobj.first=John&name%2Eobj.last=Doe'
156
+ );
157
+
158
+ st.equal(
159
+ qs.stringify({ 'name.obj.subobject': { 'first.godly.name': 'John', last: 'Doe' } }, { allowDots: true, encodeDotInKeys: true, encodeValuesOnly: true }),
160
+ 'name%2Eobj%2Esubobject.first%2Egodly%2Ename=John&name%2Eobj%2Esubobject.last=Doe'
161
+ );
162
+
163
+ st.end();
164
+ });
165
+
166
+ t.test('throws when `commaRoundTrip` is not a boolean', function (st) {
167
+ st['throws'](
168
+ function () { qs.stringify({}, { commaRoundTrip: 'not a boolean' }); },
169
+ TypeError,
170
+ 'throws when `commaRoundTrip` is not a boolean'
171
+ );
172
+
173
+ st.end();
174
+ });
175
+
176
+ t.test('throws when `encodeDotInKeys` is not a boolean', function (st) {
177
+ st['throws'](
178
+ function () { qs.stringify({ a: [], b: 'zz' }, { encodeDotInKeys: 'foobar' }); },
179
+ TypeError
180
+ );
181
+
182
+ st['throws'](
183
+ function () { qs.stringify({ a: [], b: 'zz' }, { encodeDotInKeys: 0 }); },
184
+ TypeError
185
+ );
186
+
187
+ st['throws'](
188
+ function () { qs.stringify({ a: [], b: 'zz' }, { encodeDotInKeys: NaN }); },
189
+ TypeError
190
+ );
191
+
192
+ st['throws'](
193
+ function () { qs.stringify({ a: [], b: 'zz' }, { encodeDotInKeys: null }); },
194
+ TypeError
195
+ );
196
+
197
+ st.end();
198
+ });
199
+
66
200
  t.test('adds query prefix', function (st) {
67
201
  st.equal(qs.stringify({ a: 'b' }, { addQueryPrefix: true }), '?a=b');
68
202
  st.end();
@@ -86,7 +220,7 @@ test('stringify()', function (t) {
86
220
  st.end();
87
221
  });
88
222
 
89
- t.test('stringifies a nested object with dots notation', function (st) {
223
+ t.test('`allowDots` option: stringifies a nested object with dots notation', function (st) {
90
224
  st.equal(qs.stringify({ a: { b: 'c' } }, { allowDots: true }), 'a.b=c');
91
225
  st.equal(qs.stringify({ a: { b: { c: { d: 'e' } } } }, { allowDots: true }), 'a.b.c.d=e');
92
226
  st.end();
@@ -108,6 +242,11 @@ test('stringify()', function (t) {
108
242
  'a=b%2Cc%2Cd',
109
243
  'comma => comma'
110
244
  );
245
+ st.equal(
246
+ qs.stringify({ a: ['b', 'c', 'd'] }, { arrayFormat: 'comma', commaRoundTrip: true }),
247
+ 'a=b%2Cc%2Cd',
248
+ 'comma round trip => comma'
249
+ );
111
250
  st.equal(
112
251
  qs.stringify({ a: ['b', 'c', 'd'] }),
113
252
  'a%5B0%5D=b&a%5B1%5D=c&a%5B2%5D=d',
@@ -116,18 +255,75 @@ test('stringify()', function (t) {
116
255
  st.end();
117
256
  });
118
257
 
119
- t.test('omits nulls when asked', function (st) {
120
- st.equal(qs.stringify({ a: 'b', c: null }, { skipNulls: true }), 'a=b');
121
- st.end();
122
- });
258
+ t.test('`skipNulls` option', function (st) {
259
+ st.equal(
260
+ qs.stringify({ a: 'b', c: null }, { skipNulls: true }),
261
+ 'a=b',
262
+ 'omits nulls when asked'
263
+ );
264
+
265
+ st.equal(
266
+ qs.stringify({ a: { b: 'c', d: null } }, { skipNulls: true }),
267
+ 'a%5Bb%5D=c',
268
+ 'omits nested nulls when asked'
269
+ );
123
270
 
124
- t.test('omits nested nulls when asked', function (st) {
125
- st.equal(qs.stringify({ a: { b: 'c', d: null } }, { skipNulls: true }), 'a%5Bb%5D=c');
126
271
  st.end();
127
272
  });
128
273
 
129
274
  t.test('omits array indices when asked', function (st) {
130
275
  st.equal(qs.stringify({ a: ['b', 'c', 'd'] }, { indices: false }), 'a=b&a=c&a=d');
276
+
277
+ st.end();
278
+ });
279
+
280
+ t.test('omits object key/value pair when value is empty array', function (st) {
281
+ st.equal(qs.stringify({ a: [], b: 'zz' }), 'b=zz');
282
+
283
+ st.end();
284
+ });
285
+
286
+ t.test('should not omit object key/value pair when value is empty array and when asked', function (st) {
287
+ st.equal(qs.stringify({ a: [], b: 'zz' }), 'b=zz');
288
+ st.equal(qs.stringify({ a: [], b: 'zz' }, { allowEmptyArrays: false }), 'b=zz');
289
+ st.equal(qs.stringify({ a: [], b: 'zz' }, { allowEmptyArrays: true }), 'a[]&b=zz');
290
+
291
+ st.end();
292
+ });
293
+
294
+ t.test('should throw when allowEmptyArrays is not of type boolean', function (st) {
295
+ st['throws'](
296
+ function () { qs.stringify({ a: [], b: 'zz' }, { allowEmptyArrays: 'foobar' }); },
297
+ TypeError
298
+ );
299
+
300
+ st['throws'](
301
+ function () { qs.stringify({ a: [], b: 'zz' }, { allowEmptyArrays: 0 }); },
302
+ TypeError
303
+ );
304
+
305
+ st['throws'](
306
+ function () { qs.stringify({ a: [], b: 'zz' }, { allowEmptyArrays: NaN }); },
307
+ TypeError
308
+ );
309
+
310
+ st['throws'](
311
+ function () { qs.stringify({ a: [], b: 'zz' }, { allowEmptyArrays: null }); },
312
+ TypeError
313
+ );
314
+
315
+ st.end();
316
+ });
317
+
318
+ t.test('allowEmptyArrays + strictNullHandling', function (st) {
319
+ st.equal(
320
+ qs.stringify(
321
+ { testEmptyArray: [] },
322
+ { strictNullHandling: true, allowEmptyArrays: true }
323
+ ),
324
+ 'testEmptyArray[]'
325
+ );
326
+
131
327
  st.end();
132
328
  });
133
329
 
@@ -155,11 +351,22 @@ test('stringify()', function (t) {
155
351
  s2t.equal(qs.stringify({ a: ['c', 'd'] }, { encodeValuesOnly: true, arrayFormat: 'indices' }), 'a[0]=c&a[1]=d');
156
352
  s2t.equal(qs.stringify({ a: ['c', 'd'] }, { encodeValuesOnly: true, arrayFormat: 'brackets' }), 'a[]=c&a[]=d');
157
353
  s2t.equal(qs.stringify({ a: ['c', 'd'] }, { encodeValuesOnly: true, arrayFormat: 'comma' }), 'a=c,d');
354
+ s2t.equal(qs.stringify({ a: ['c', 'd'] }, { encodeValuesOnly: true, arrayFormat: 'comma', commaRoundTrip: true }), 'a=c,d');
158
355
  s2t.equal(qs.stringify({ a: ['c', 'd'] }, { encodeValuesOnly: true }), 'a[0]=c&a[1]=d');
159
356
 
160
357
  s2t.end();
161
358
  });
162
359
 
360
+ st.test('array with multiple items with a comma inside', function (s2t) {
361
+ s2t.equal(qs.stringify({ a: ['c,d', 'e'] }, { encodeValuesOnly: true, arrayFormat: 'comma' }), 'a=c%2Cd,e');
362
+ s2t.equal(qs.stringify({ a: ['c,d', 'e'] }, { arrayFormat: 'comma' }), 'a=c%2Cd%2Ce');
363
+
364
+ s2t.equal(qs.stringify({ a: ['c,d', 'e'] }, { encodeValuesOnly: true, arrayFormat: 'comma', commaRoundTrip: true }), 'a=c%2Cd,e');
365
+ s2t.equal(qs.stringify({ a: ['c,d', 'e'] }, { arrayFormat: 'comma', commaRoundTrip: true }), 'a=c%2Cd%2Ce');
366
+
367
+ s2t.end();
368
+ });
369
+
163
370
  st.end();
164
371
  });
165
372
 
@@ -171,6 +378,44 @@ test('stringify()', function (t) {
171
378
  st.end();
172
379
  });
173
380
 
381
+ t.test('stringifies comma and empty array values', function (st) {
382
+ st.equal(qs.stringify({ a: [',', '', 'c,d%'] }, { encode: false, arrayFormat: 'indices' }), 'a[0]=,&a[1]=&a[2]=c,d%');
383
+ st.equal(qs.stringify({ a: [',', '', 'c,d%'] }, { encode: false, arrayFormat: 'brackets' }), 'a[]=,&a[]=&a[]=c,d%');
384
+ st.equal(qs.stringify({ a: [',', '', 'c,d%'] }, { encode: false, arrayFormat: 'comma' }), 'a=,,,c,d%');
385
+ st.equal(qs.stringify({ a: [',', '', 'c,d%'] }, { encode: false, arrayFormat: 'repeat' }), 'a=,&a=&a=c,d%');
386
+
387
+ st.equal(qs.stringify({ a: [',', '', 'c,d%'] }, { encode: true, encodeValuesOnly: true, arrayFormat: 'indices' }), 'a[0]=%2C&a[1]=&a[2]=c%2Cd%25');
388
+ st.equal(qs.stringify({ a: [',', '', 'c,d%'] }, { encode: true, encodeValuesOnly: true, arrayFormat: 'brackets' }), 'a[]=%2C&a[]=&a[]=c%2Cd%25');
389
+ st.equal(qs.stringify({ a: [',', '', 'c,d%'] }, { encode: true, encodeValuesOnly: true, arrayFormat: 'comma' }), 'a=%2C,,c%2Cd%25');
390
+ st.equal(qs.stringify({ a: [',', '', 'c,d%'] }, { encode: true, encodeValuesOnly: true, arrayFormat: 'repeat' }), 'a=%2C&a=&a=c%2Cd%25');
391
+
392
+ st.equal(qs.stringify({ a: [',', '', 'c,d%'] }, { encode: true, encodeValuesOnly: false, arrayFormat: 'indices' }), 'a%5B0%5D=%2C&a%5B1%5D=&a%5B2%5D=c%2Cd%25');
393
+ st.equal(qs.stringify({ a: [',', '', 'c,d%'] }, { encode: true, encodeValuesOnly: false, arrayFormat: 'brackets' }), 'a%5B%5D=%2C&a%5B%5D=&a%5B%5D=c%2Cd%25');
394
+ st.equal(qs.stringify({ a: [',', '', 'c,d%'] }, { encode: true, encodeValuesOnly: false, arrayFormat: 'comma' }), 'a=%2C%2C%2Cc%2Cd%25');
395
+ st.equal(qs.stringify({ a: [',', '', 'c,d%'] }, { encode: true, encodeValuesOnly: false, arrayFormat: 'repeat' }), 'a=%2C&a=&a=c%2Cd%25');
396
+
397
+ st.end();
398
+ });
399
+
400
+ t.test('stringifies comma and empty non-array values', function (st) {
401
+ st.equal(qs.stringify({ a: ',', b: '', c: 'c,d%' }, { encode: false, arrayFormat: 'indices' }), 'a=,&b=&c=c,d%');
402
+ st.equal(qs.stringify({ a: ',', b: '', c: 'c,d%' }, { encode: false, arrayFormat: 'brackets' }), 'a=,&b=&c=c,d%');
403
+ st.equal(qs.stringify({ a: ',', b: '', c: 'c,d%' }, { encode: false, arrayFormat: 'comma' }), 'a=,&b=&c=c,d%');
404
+ st.equal(qs.stringify({ a: ',', b: '', c: 'c,d%' }, { encode: false, arrayFormat: 'repeat' }), 'a=,&b=&c=c,d%');
405
+
406
+ st.equal(qs.stringify({ a: ',', b: '', c: 'c,d%' }, { encode: true, encodeValuesOnly: true, arrayFormat: 'indices' }), 'a=%2C&b=&c=c%2Cd%25');
407
+ st.equal(qs.stringify({ a: ',', b: '', c: 'c,d%' }, { encode: true, encodeValuesOnly: true, arrayFormat: 'brackets' }), 'a=%2C&b=&c=c%2Cd%25');
408
+ st.equal(qs.stringify({ a: ',', b: '', c: 'c,d%' }, { encode: true, encodeValuesOnly: true, arrayFormat: 'comma' }), 'a=%2C&b=&c=c%2Cd%25');
409
+ st.equal(qs.stringify({ a: ',', b: '', c: 'c,d%' }, { encode: true, encodeValuesOnly: true, arrayFormat: 'repeat' }), 'a=%2C&b=&c=c%2Cd%25');
410
+
411
+ st.equal(qs.stringify({ a: ',', b: '', c: 'c,d%' }, { encode: true, encodeValuesOnly: false, arrayFormat: 'indices' }), 'a=%2C&b=&c=c%2Cd%25');
412
+ st.equal(qs.stringify({ a: ',', b: '', c: 'c,d%' }, { encode: true, encodeValuesOnly: false, arrayFormat: 'brackets' }), 'a=%2C&b=&c=c%2Cd%25');
413
+ st.equal(qs.stringify({ a: ',', b: '', c: 'c,d%' }, { encode: true, encodeValuesOnly: false, arrayFormat: 'comma' }), 'a=%2C&b=&c=c%2Cd%25');
414
+ st.equal(qs.stringify({ a: ',', b: '', c: 'c,d%' }, { encode: true, encodeValuesOnly: false, arrayFormat: 'repeat' }), 'a=%2C&b=&c=c%2Cd%25');
415
+
416
+ st.end();
417
+ });
418
+
174
419
  t.test('stringifies a nested array value with dots notation', function (st) {
175
420
  st.equal(
176
421
  qs.stringify(
@@ -209,36 +454,44 @@ test('stringify()', function (t) {
209
454
 
210
455
  t.test('stringifies an object inside an array', function (st) {
211
456
  st.equal(
212
- qs.stringify({ a: [{ b: 'c' }] }, { arrayFormat: 'indices' }),
213
- 'a%5B0%5D%5Bb%5D=c', // a[0][b]=c
214
- 'indices => brackets'
457
+ qs.stringify({ a: [{ b: 'c' }] }, { arrayFormat: 'indices', encodeValuesOnly: true }),
458
+ 'a[0][b]=c',
459
+ 'indices => indices'
460
+ );
461
+ st.equal(
462
+ qs.stringify({ a: [{ b: 'c' }] }, { arrayFormat: 'repeat', encodeValuesOnly: true }),
463
+ 'a[b]=c',
464
+ 'repeat => repeat'
215
465
  );
216
466
  st.equal(
217
- qs.stringify({ a: [{ b: 'c' }] }, { arrayFormat: 'brackets' }),
218
- 'a%5B%5D%5Bb%5D=c', // a[][b]=c
467
+ qs.stringify({ a: [{ b: 'c' }] }, { arrayFormat: 'brackets', encodeValuesOnly: true }),
468
+ 'a[][b]=c',
219
469
  'brackets => brackets'
220
470
  );
221
471
  st.equal(
222
- qs.stringify({ a: [{ b: 'c' }] }),
223
- 'a%5B0%5D%5Bb%5D=c',
472
+ qs.stringify({ a: [{ b: 'c' }] }, { encodeValuesOnly: true }),
473
+ 'a[0][b]=c',
224
474
  'default => indices'
225
475
  );
226
476
 
227
477
  st.equal(
228
- qs.stringify({ a: [{ b: { c: [1] } }] }, { arrayFormat: 'indices' }),
229
- 'a%5B0%5D%5Bb%5D%5Bc%5D%5B0%5D=1',
478
+ qs.stringify({ a: [{ b: { c: [1] } }] }, { arrayFormat: 'indices', encodeValuesOnly: true }),
479
+ 'a[0][b][c][0]=1',
230
480
  'indices => indices'
231
481
  );
232
-
233
482
  st.equal(
234
- qs.stringify({ a: [{ b: { c: [1] } }] }, { arrayFormat: 'brackets' }),
235
- 'a%5B%5D%5Bb%5D%5Bc%5D%5B%5D=1',
483
+ qs.stringify({ a: [{ b: { c: [1] } }] }, { arrayFormat: 'repeat', encodeValuesOnly: true }),
484
+ 'a[b][c]=1',
485
+ 'repeat => repeat'
486
+ );
487
+ st.equal(
488
+ qs.stringify({ a: [{ b: { c: [1] } }] }, { arrayFormat: 'brackets', encodeValuesOnly: true }),
489
+ 'a[][b][c][]=1',
236
490
  'brackets => brackets'
237
491
  );
238
-
239
492
  st.equal(
240
- qs.stringify({ a: [{ b: { c: [1] } }] }),
241
- 'a%5B0%5D%5Bb%5D%5Bc%5D%5B0%5D=1',
493
+ qs.stringify({ a: [{ b: { c: [1] } }] }, { encodeValuesOnly: true }),
494
+ 'a[0][b][c][0]=1',
242
495
  'default => indices'
243
496
  );
244
497
 
@@ -340,17 +593,17 @@ test('stringify()', function (t) {
340
593
  st.end();
341
594
  });
342
595
 
343
- t.test('uses indices notation for arrays when no arrayFormat=indices', function (st) {
596
+ t.test('uses indices notation for arrays when arrayFormat=indices', function (st) {
344
597
  st.equal(qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'indices' }), 'a%5B0%5D=b&a%5B1%5D=c');
345
598
  st.end();
346
599
  });
347
600
 
348
- t.test('uses repeat notation for arrays when no arrayFormat=repeat', function (st) {
601
+ t.test('uses repeat notation for arrays when arrayFormat=repeat', function (st) {
349
602
  st.equal(qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'repeat' }), 'a=b&a=c');
350
603
  st.end();
351
604
  });
352
605
 
353
- t.test('uses brackets notation for arrays when no arrayFormat=brackets', function (st) {
606
+ t.test('uses brackets notation for arrays when arrayFormat=brackets', function (st) {
354
607
  st.equal(qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'brackets' }), 'a%5B%5D=b&a%5B%5D=c');
355
608
  st.end();
356
609
  });
@@ -447,10 +700,11 @@ test('stringify()', function (t) {
447
700
  });
448
701
 
449
702
  t.test('skips properties that are part of the object prototype', function (st) {
450
- Object.prototype.crash = 'test';
703
+ st.intercept(Object.prototype, 'crash', { value: 'test' });
704
+
451
705
  st.equal(qs.stringify({ a: 'b' }), 'a=b');
452
706
  st.equal(qs.stringify({ a: { b: 'c' } }), 'a%5Bb%5D=c');
453
- delete Object.prototype.crash;
707
+
454
708
  st.end();
455
709
  });
456
710
 
@@ -474,10 +728,12 @@ test('stringify()', function (t) {
474
728
  });
475
729
 
476
730
  t.test('does not blow up when Buffer global is missing', function (st) {
477
- var tempBuffer = global.Buffer;
478
- delete global.Buffer;
731
+ var restore = mockProperty(global, 'Buffer', { 'delete': true });
732
+
479
733
  var result = qs.stringify({ a: 'b', c: 'd' });
480
- global.Buffer = tempBuffer;
734
+
735
+ restore();
736
+
481
737
  st.equal(result, 'a=b&c=d');
482
738
  st.end();
483
739
  });
@@ -526,9 +782,17 @@ test('stringify()', function (t) {
526
782
  };
527
783
 
528
784
  st.equal(
529
- qs.stringify({ filters: { $and: [p1, p2] } }, { encodeValuesOnly: true }),
785
+ qs.stringify({ filters: { $and: [p1, p2] } }, { encodeValuesOnly: true, arrayFormat: 'indices' }),
530
786
  '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'
531
787
  );
788
+ st.equal(
789
+ qs.stringify({ filters: { $and: [p1, p2] } }, { encodeValuesOnly: true, arrayFormat: 'brackets' }),
790
+ 'filters[$and][][function]=gte&filters[$and][][arguments][][function]=hour_of_day&filters[$and][][arguments][]=0&filters[$and][][function]=lte&filters[$and][][arguments][][function]=hour_of_day&filters[$and][][arguments][]=23'
791
+ );
792
+ st.equal(
793
+ qs.stringify({ filters: { $and: [p1, p2] } }, { encodeValuesOnly: true, arrayFormat: 'repeat' }),
794
+ 'filters[$and][function]=gte&filters[$and][arguments][function]=hour_of_day&filters[$and][arguments]=0&filters[$and][function]=lte&filters[$and][arguments][function]=hour_of_day&filters[$and][arguments]=23'
795
+ );
532
796
 
533
797
  st.end();
534
798
  });
@@ -641,13 +905,28 @@ test('stringify()', function (t) {
641
905
  st.end();
642
906
  });
643
907
 
908
+ t.test('receives the default encoder as a second argument', function (st) {
909
+ st.plan(8);
910
+
911
+ qs.stringify({ a: 1, b: new Date(), c: true, d: [1] }, {
912
+ encoder: function (str) {
913
+ st.match(typeof str, /^(?:string|number|boolean)$/);
914
+ return '';
915
+ }
916
+ });
917
+
918
+ st.end();
919
+ });
920
+
644
921
  t.test('receives the default encoder as a second argument', function (st) {
645
922
  st.plan(2);
923
+
646
924
  qs.stringify({ a: 1 }, {
647
925
  encoder: function (str, defaultEncoder) {
648
926
  st.equal(defaultEncoder, utils.encode);
649
927
  }
650
928
  });
929
+
651
930
  st.end();
652
931
  });
653
932
 
@@ -775,16 +1054,53 @@ test('stringify()', function (t) {
775
1054
  st.equal(
776
1055
  qs.stringify(
777
1056
  { a: 'b', c: ['d', 'e=f'], f: [['g'], ['h']] },
778
- { encodeValuesOnly: true }
1057
+ { encodeValuesOnly: true, arrayFormat: 'indices' }
1058
+ ),
1059
+ 'a=b&c[0]=d&c[1]=e%3Df&f[0][0]=g&f[1][0]=h',
1060
+ 'encodeValuesOnly + indices'
1061
+ );
1062
+ st.equal(
1063
+ qs.stringify(
1064
+ { a: 'b', c: ['d', 'e=f'], f: [['g'], ['h']] },
1065
+ { encodeValuesOnly: true, arrayFormat: 'brackets' }
1066
+ ),
1067
+ 'a=b&c[]=d&c[]=e%3Df&f[][]=g&f[][]=h',
1068
+ 'encodeValuesOnly + brackets'
1069
+ );
1070
+ st.equal(
1071
+ qs.stringify(
1072
+ { a: 'b', c: ['d', 'e=f'], f: [['g'], ['h']] },
1073
+ { encodeValuesOnly: true, arrayFormat: 'repeat' }
779
1074
  ),
780
- 'a=b&c[0]=d&c[1]=e%3Df&f[0][0]=g&f[1][0]=h'
1075
+ 'a=b&c=d&c=e%3Df&f=g&f=h',
1076
+ 'encodeValuesOnly + repeat'
781
1077
  );
1078
+
782
1079
  st.equal(
783
1080
  qs.stringify(
784
- { a: 'b', c: ['d', 'e'], f: [['g'], ['h']] }
1081
+ { a: 'b', c: ['d', 'e'], f: [['g'], ['h']] },
1082
+ { arrayFormat: 'indices' }
785
1083
  ),
786
- 'a=b&c%5B0%5D=d&c%5B1%5D=e&f%5B0%5D%5B0%5D=g&f%5B1%5D%5B0%5D=h'
1084
+ 'a=b&c%5B0%5D=d&c%5B1%5D=e&f%5B0%5D%5B0%5D=g&f%5B1%5D%5B0%5D=h',
1085
+ 'no encodeValuesOnly + indices'
787
1086
  );
1087
+ st.equal(
1088
+ qs.stringify(
1089
+ { a: 'b', c: ['d', 'e'], f: [['g'], ['h']] },
1090
+ { arrayFormat: 'brackets' }
1091
+ ),
1092
+ 'a=b&c%5B%5D=d&c%5B%5D=e&f%5B%5D%5B%5D=g&f%5B%5D%5B%5D=h',
1093
+ 'no encodeValuesOnly + brackets'
1094
+ );
1095
+ st.equal(
1096
+ qs.stringify(
1097
+ { a: 'b', c: ['d', 'e'], f: [['g'], ['h']] },
1098
+ { arrayFormat: 'repeat' }
1099
+ ),
1100
+ 'a=b&c=d&c=e&f=g&f=h',
1101
+ 'no encodeValuesOnly + repeat'
1102
+ );
1103
+
788
1104
  st.end();
789
1105
  });
790
1106
 
@@ -821,13 +1137,19 @@ test('stringify()', function (t) {
821
1137
  st.end();
822
1138
  });
823
1139
 
824
- t.test('adds the right sentinel when instructed to and the charset is utf-8', function (st) {
825
- st.equal(qs.stringify({ a: 'æ' }, { charsetSentinel: true, charset: 'utf-8' }), 'utf8=%E2%9C%93&a=%C3%A6');
826
- st.end();
827
- });
1140
+ t.test('`charsetSentinel` option', function (st) {
1141
+ st.equal(
1142
+ qs.stringify({ a: 'æ' }, { charsetSentinel: true, charset: 'utf-8' }),
1143
+ 'utf8=%E2%9C%93&a=%C3%A6',
1144
+ 'adds the right sentinel when instructed to and the charset is utf-8'
1145
+ );
1146
+
1147
+ st.equal(
1148
+ qs.stringify({ a: 'æ' }, { charsetSentinel: true, charset: 'iso-8859-1' }),
1149
+ 'utf8=%26%2310003%3B&a=%E6',
1150
+ 'adds the right sentinel when instructed to and the charset is iso-8859-1'
1151
+ );
828
1152
 
829
- t.test('adds the right sentinel when instructed to and the charset is iso-8859-1', function (st) {
830
- st.equal(qs.stringify({ a: 'æ' }, { charsetSentinel: true, charset: 'iso-8859-1' }), 'utf8=%26%2310003%3B&a=%E6');
831
1153
  st.end();
832
1154
  });
833
1155
 
@@ -878,13 +1200,15 @@ test('stringify()', function (t) {
878
1200
  var withArray = { a: { b: [{ c: 'd', e: 'f' }] } };
879
1201
 
880
1202
  st.equal(qs.stringify(obj, { encode: false }), 'a[b][c]=d&a[b][e]=f', 'no array, no arrayFormat');
881
- st.equal(qs.stringify(obj, { encode: false, arrayFormat: 'bracket' }), 'a[b][c]=d&a[b][e]=f', 'no array, bracket');
1203
+ st.equal(qs.stringify(obj, { encode: false, arrayFormat: 'brackets' }), 'a[b][c]=d&a[b][e]=f', 'no array, bracket');
882
1204
  st.equal(qs.stringify(obj, { encode: false, arrayFormat: 'indices' }), 'a[b][c]=d&a[b][e]=f', 'no array, indices');
1205
+ st.equal(qs.stringify(obj, { encode: false, arrayFormat: 'repeat' }), 'a[b][c]=d&a[b][e]=f', 'no array, repeat');
883
1206
  st.equal(qs.stringify(obj, { encode: false, arrayFormat: 'comma' }), 'a[b][c]=d&a[b][e]=f', 'no array, comma');
884
1207
 
885
1208
  st.equal(qs.stringify(withArray, { encode: false }), 'a[b][0][c]=d&a[b][0][e]=f', 'array, no arrayFormat');
886
- st.equal(qs.stringify(withArray, { encode: false, arrayFormat: 'bracket' }), 'a[b][0][c]=d&a[b][0][e]=f', 'array, bracket');
1209
+ st.equal(qs.stringify(withArray, { encode: false, arrayFormat: 'brackets' }), 'a[b][][c]=d&a[b][][e]=f', 'array, bracket');
887
1210
  st.equal(qs.stringify(withArray, { encode: false, arrayFormat: 'indices' }), 'a[b][0][c]=d&a[b][0][e]=f', 'array, indices');
1211
+ st.equal(qs.stringify(withArray, { encode: false, arrayFormat: 'repeat' }), 'a[b][c]=d&a[b][e]=f', 'array, repeat');
888
1212
  st.equal(
889
1213
  qs.stringify(withArray, { encode: false, arrayFormat: 'comma' }),
890
1214
  '???',
@@ -897,13 +1221,78 @@ test('stringify()', function (t) {
897
1221
 
898
1222
  t.test('stringifies sparse arrays', function (st) {
899
1223
  /* eslint no-sparse-arrays: 0 */
900
- st.equal(qs.stringify({ a: [, '2', , , '1'] }, { encodeValuesOnly: true }), 'a[1]=2&a[4]=1');
901
- st.equal(qs.stringify({ a: [, { b: [, , { c: '1' }] }] }, { encodeValuesOnly: true }), 'a[1][b][2][c]=1');
902
- st.equal(qs.stringify({ a: [, [, , [, , , { c: '1' }]]] }, { encodeValuesOnly: true }), 'a[1][2][3][c]=1');
903
- st.equal(qs.stringify({ a: [, [, , [, , , { c: [, '1'] }]]] }, { encodeValuesOnly: true }), 'a[1][2][3][c][1]=1');
1224
+ st.equal(qs.stringify({ a: [, '2', , , '1'] }, { encodeValuesOnly: true, arrayFormat: 'indices' }), 'a[1]=2&a[4]=1');
1225
+ st.equal(qs.stringify({ a: [, '2', , , '1'] }, { encodeValuesOnly: true, arrayFormat: 'brackets' }), 'a[]=2&a[]=1');
1226
+ st.equal(qs.stringify({ a: [, '2', , , '1'] }, { encodeValuesOnly: true, arrayFormat: 'repeat' }), 'a=2&a=1');
1227
+
1228
+ st.equal(qs.stringify({ a: [, { b: [, , { c: '1' }] }] }, { encodeValuesOnly: true, arrayFormat: 'indices' }), 'a[1][b][2][c]=1');
1229
+ st.equal(qs.stringify({ a: [, { b: [, , { c: '1' }] }] }, { encodeValuesOnly: true, arrayFormat: 'brackets' }), 'a[][b][][c]=1');
1230
+ st.equal(qs.stringify({ a: [, { b: [, , { c: '1' }] }] }, { encodeValuesOnly: true, arrayFormat: 'repeat' }), 'a[b][c]=1');
1231
+
1232
+ st.equal(qs.stringify({ a: [, [, , [, , , { c: '1' }]]] }, { encodeValuesOnly: true, arrayFormat: 'indices' }), 'a[1][2][3][c]=1');
1233
+ st.equal(qs.stringify({ a: [, [, , [, , , { c: '1' }]]] }, { encodeValuesOnly: true, arrayFormat: 'brackets' }), 'a[][][][c]=1');
1234
+ st.equal(qs.stringify({ a: [, [, , [, , , { c: '1' }]]] }, { encodeValuesOnly: true, arrayFormat: 'repeat' }), 'a[c]=1');
1235
+
1236
+ st.equal(qs.stringify({ a: [, [, , [, , , { c: [, '1'] }]]] }, { encodeValuesOnly: true, arrayFormat: 'indices' }), 'a[1][2][3][c][1]=1');
1237
+ st.equal(qs.stringify({ a: [, [, , [, , , { c: [, '1'] }]]] }, { encodeValuesOnly: true, arrayFormat: 'brackets' }), 'a[][][][c][]=1');
1238
+ st.equal(qs.stringify({ a: [, [, , [, , , { c: [, '1'] }]]] }, { encodeValuesOnly: true, arrayFormat: 'repeat' }), 'a[c]=1');
1239
+
1240
+ st.end();
1241
+ });
1242
+
1243
+ t.test('encodes a very long string', function (st) {
1244
+ var chars = [];
1245
+ var expected = [];
1246
+ for (var i = 0; i < 5e3; i++) {
1247
+ chars.push(' ' + i);
1248
+
1249
+ expected.push('%20' + i);
1250
+ }
1251
+
1252
+ var obj = {
1253
+ foo: chars.join('')
1254
+ };
1255
+
1256
+ st.equal(
1257
+ qs.stringify(obj, { arrayFormat: 'bracket', charset: 'utf-8' }),
1258
+ 'foo=' + expected.join('')
1259
+ );
904
1260
 
905
1261
  st.end();
906
1262
  });
907
1263
 
908
1264
  t.end();
909
1265
  });
1266
+
1267
+ test('stringifies empty keys', function (t) {
1268
+ emptyTestCases.forEach(function (testCase) {
1269
+ t.test('stringifies an object with empty string key with ' + testCase.input, function (st) {
1270
+ st.deepEqual(
1271
+ qs.stringify(testCase.withEmptyKeys, { encode: false, arrayFormat: 'indices' }),
1272
+ testCase.stringifyOutput.indices,
1273
+ 'test case: ' + testCase.input + ', indices'
1274
+ );
1275
+ st.deepEqual(
1276
+ qs.stringify(testCase.withEmptyKeys, { encode: false, arrayFormat: 'brackets' }),
1277
+ testCase.stringifyOutput.brackets,
1278
+ 'test case: ' + testCase.input + ', brackets'
1279
+ );
1280
+ st.deepEqual(
1281
+ qs.stringify(testCase.withEmptyKeys, { encode: false, arrayFormat: 'repeat' }),
1282
+ testCase.stringifyOutput.repeat,
1283
+ 'test case: ' + testCase.input + ', repeat'
1284
+ );
1285
+
1286
+ st.end();
1287
+ });
1288
+ });
1289
+
1290
+ t.test('edge case with object/arrays', function (st) {
1291
+ st.deepEqual(qs.stringify({ '': { '': [2, 3] } }, { encode: false }), '[][0]=2&[][1]=3');
1292
+ st.deepEqual(qs.stringify({ '': { '': [2, 3], a: 2 } }, { encode: false }), '[][0]=2&[][1]=3&[a]=2');
1293
+ st.deepEqual(qs.stringify({ '': { '': [2, 3] } }, { encode: false, arrayFormat: 'indices' }), '[][0]=2&[][1]=3');
1294
+ st.deepEqual(qs.stringify({ '': { '': [2, 3], a: 2 } }, { encode: false, arrayFormat: 'indices' }), '[][0]=2&[][1]=3&[a]=2');
1295
+
1296
+ st.end();
1297
+ });
1298
+ });
@@ -1,3 +1,8 @@
1
+ 0.19.0 / 2024-09-10
2
+ ===================
3
+
4
+ * Remove link renderization in html while redirecting
5
+
1
6
  0.18.0 / 2022-03-23
2
7
  ===================
3
8