step-node-agent 3.28.4 → 3.29.1

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 (104) hide show
  1. package/AgentConf.yaml +3 -1
  2. package/api/filemanager/filemanager.js +24 -1
  3. package/middleware/jwtAuth.js +37 -0
  4. package/node_modules/body-parser/HISTORY.md +8 -0
  5. package/node_modules/body-parser/lib/types/urlencoded.js +2 -9
  6. package/node_modules/body-parser/package.json +9 -10
  7. package/node_modules/cookie/index.js +2 -1
  8. package/node_modules/cookie/package.json +1 -1
  9. package/node_modules/cookie-signature/History.md +5 -1
  10. package/node_modules/cookie-signature/index.js +6 -6
  11. package/node_modules/cookie-signature/package.json +2 -2
  12. package/node_modules/express/History.md +11 -0
  13. package/node_modules/express/package.json +17 -17
  14. package/node_modules/finalhandler/HISTORY.md +6 -0
  15. package/node_modules/finalhandler/package.json +3 -3
  16. package/node_modules/http-errors/HISTORY.md +6 -0
  17. package/node_modules/http-errors/index.js +4 -3
  18. package/node_modules/http-errors/package.json +12 -8
  19. package/node_modules/qs/.eslintrc +1 -0
  20. package/node_modules/qs/CHANGELOG.md +22 -0
  21. package/node_modules/qs/README.md +25 -1
  22. package/node_modules/qs/dist/qs.js +95 -44
  23. package/node_modules/qs/lib/parse.js +44 -12
  24. package/node_modules/qs/lib/stringify.js +11 -6
  25. package/node_modules/qs/lib/utils.js +7 -4
  26. package/node_modules/qs/package.json +9 -7
  27. package/node_modules/qs/test/parse.js +133 -27
  28. package/node_modules/qs/test/stringify.js +19 -11
  29. package/node_modules/qs/test/utils.js +126 -0
  30. package/node_modules/raw-body/package.json +5 -7
  31. package/node_modules/resolve/.eslintrc +1 -1
  32. package/node_modules/resolve/.github/INCIDENT_RESPONSE_PROCESS.md +119 -0
  33. package/node_modules/resolve/.github/THREAT_MODEL.md +74 -0
  34. package/node_modules/resolve/SECURITY.md +9 -1
  35. package/node_modules/resolve/lib/async.js +8 -4
  36. package/node_modules/resolve/lib/core.json +1 -1
  37. package/node_modules/resolve/lib/node-modules-paths.js +5 -2
  38. package/node_modules/resolve/lib/sync.js +7 -3
  39. package/node_modules/resolve/package.json +5 -5
  40. package/node_modules/send/HISTORY.md +12 -7
  41. package/node_modules/send/node_modules/http-errors/HISTORY.md +180 -0
  42. package/node_modules/send/node_modules/http-errors/LICENSE +23 -0
  43. package/node_modules/send/node_modules/http-errors/README.md +169 -0
  44. package/node_modules/send/node_modules/http-errors/index.js +289 -0
  45. package/node_modules/send/node_modules/http-errors/package.json +50 -0
  46. package/node_modules/send/node_modules/statuses/HISTORY.md +82 -0
  47. package/node_modules/send/node_modules/statuses/LICENSE +23 -0
  48. package/node_modules/send/node_modules/statuses/README.md +136 -0
  49. package/node_modules/send/node_modules/statuses/codes.json +65 -0
  50. package/node_modules/send/node_modules/statuses/index.js +146 -0
  51. package/node_modules/send/node_modules/statuses/package.json +49 -0
  52. package/node_modules/send/package.json +2 -2
  53. package/node_modules/serve-static/node_modules/http-errors/HISTORY.md +180 -0
  54. package/node_modules/serve-static/node_modules/http-errors/LICENSE +23 -0
  55. package/node_modules/serve-static/node_modules/http-errors/README.md +169 -0
  56. package/node_modules/serve-static/node_modules/http-errors/index.js +289 -0
  57. package/node_modules/serve-static/node_modules/http-errors/package.json +50 -0
  58. package/node_modules/serve-static/node_modules/ms/index.js +162 -0
  59. package/node_modules/serve-static/node_modules/ms/license.md +21 -0
  60. package/node_modules/serve-static/node_modules/ms/package.json +38 -0
  61. package/node_modules/serve-static/node_modules/ms/readme.md +59 -0
  62. package/node_modules/serve-static/node_modules/send/HISTORY.md +526 -0
  63. package/node_modules/serve-static/node_modules/send/LICENSE +23 -0
  64. package/node_modules/serve-static/node_modules/send/README.md +327 -0
  65. package/node_modules/{raw-body → serve-static/node_modules/send}/SECURITY.md +4 -4
  66. package/node_modules/serve-static/node_modules/send/index.js +1142 -0
  67. package/node_modules/serve-static/node_modules/send/package.json +62 -0
  68. package/node_modules/serve-static/node_modules/statuses/HISTORY.md +82 -0
  69. package/node_modules/serve-static/node_modules/statuses/LICENSE +23 -0
  70. package/node_modules/serve-static/node_modules/statuses/README.md +136 -0
  71. package/node_modules/serve-static/node_modules/statuses/codes.json +65 -0
  72. package/node_modules/serve-static/node_modules/statuses/index.js +146 -0
  73. package/node_modules/serve-static/node_modules/statuses/package.json +49 -0
  74. package/node_modules/statuses/HISTORY.md +5 -0
  75. package/node_modules/statuses/README.md +3 -0
  76. package/node_modules/statuses/package.json +7 -7
  77. package/node_modules/yaml/browser/dist/compose/compose-collection.js +1 -1
  78. package/node_modules/yaml/browser/dist/compose/resolve-block-seq.js +1 -1
  79. package/node_modules/yaml/browser/dist/compose/resolve-flow-collection.js +2 -2
  80. package/node_modules/yaml/browser/dist/errors.js +1 -1
  81. package/node_modules/yaml/browser/dist/nodes/Alias.js +1 -1
  82. package/node_modules/yaml/browser/dist/parse/parser.js +2 -2
  83. package/node_modules/yaml/browser/dist/stringify/stringifyNumber.js +1 -1
  84. package/node_modules/yaml/browser/dist/stringify/stringifyPair.js +1 -1
  85. package/node_modules/yaml/dist/compose/compose-collection.js +1 -1
  86. package/node_modules/yaml/dist/compose/resolve-block-seq.js +1 -1
  87. package/node_modules/yaml/dist/compose/resolve-flow-collection.js +2 -2
  88. package/node_modules/yaml/dist/errors.js +1 -1
  89. package/node_modules/yaml/dist/nodes/Alias.js +1 -1
  90. package/node_modules/yaml/dist/parse/parser.js +2 -2
  91. package/node_modules/yaml/dist/stringify/stringifyNumber.js +1 -1
  92. package/node_modules/yaml/dist/stringify/stringifyPair.js +1 -1
  93. package/node_modules/yaml/package.json +4 -4
  94. package/package.json +2 -1
  95. package/server.js +27 -8
  96. package/utils/jwtUtils.js +21 -0
  97. package/node_modules/body-parser/SECURITY.md +0 -25
  98. package/node_modules/cookie-signature/.npmignore +0 -4
  99. package/node_modules/raw-body/HISTORY.md +0 -308
  100. /package/node_modules/{send → serve-static/node_modules/send}/node_modules/encodeurl/HISTORY.md +0 -0
  101. /package/node_modules/{send → serve-static/node_modules/send}/node_modules/encodeurl/LICENSE +0 -0
  102. /package/node_modules/{send → serve-static/node_modules/send}/node_modules/encodeurl/README.md +0 -0
  103. /package/node_modules/{send → serve-static/node_modules/send}/node_modules/encodeurl/index.js +0 -0
  104. /package/node_modules/{send → serve-static/node_modules/send}/node_modules/encodeurl/package.json +0 -0
@@ -34,11 +34,13 @@ var defaults = {
34
34
  arrayFormat: 'indices',
35
35
  charset: 'utf-8',
36
36
  charsetSentinel: false,
37
+ commaRoundTrip: false,
37
38
  delimiter: '&',
38
39
  encode: true,
39
40
  encodeDotInKeys: false,
40
41
  encoder: utils.encode,
41
42
  encodeValuesOnly: false,
43
+ filter: void undefined,
42
44
  format: defaultFormat,
43
45
  formatter: formats.formatters[defaultFormat],
44
46
  // deprecated
@@ -150,7 +152,7 @@ var stringify = function stringify(
150
152
  objKeys = sort ? keys.sort(sort) : keys;
151
153
  }
152
154
 
153
- var encodedPrefix = encodeDotInKeys ? prefix.replace(/\./g, '%2E') : prefix;
155
+ var encodedPrefix = encodeDotInKeys ? String(prefix).replace(/\./g, '%2E') : String(prefix);
154
156
 
155
157
  var adjustedPrefix = commaRoundTrip && isArray(obj) && obj.length === 1 ? encodedPrefix + '[]' : encodedPrefix;
156
158
 
@@ -160,13 +162,15 @@ var stringify = function stringify(
160
162
 
161
163
  for (var j = 0; j < objKeys.length; ++j) {
162
164
  var key = objKeys[j];
163
- var value = typeof key === 'object' && typeof key.value !== 'undefined' ? key.value : obj[key];
165
+ var value = typeof key === 'object' && key && typeof key.value !== 'undefined'
166
+ ? key.value
167
+ : obj[key];
164
168
 
165
169
  if (skipNulls && value === null) {
166
170
  continue;
167
171
  }
168
172
 
169
- var encodedKey = allowDots && encodeDotInKeys ? key.replace(/\./g, '%2E') : key;
173
+ var encodedKey = allowDots && encodeDotInKeys ? String(key).replace(/\./g, '%2E') : String(key);
170
174
  var keyPrefix = isArray(obj)
171
175
  ? typeof generateArrayPrefix === 'function' ? generateArrayPrefix(adjustedPrefix, encodedKey) : adjustedPrefix
172
176
  : adjustedPrefix + (allowDots ? '.' + encodedKey : '[' + encodedKey + ']');
@@ -257,7 +261,7 @@ var normalizeStringifyOptions = function normalizeStringifyOptions(opts) {
257
261
  arrayFormat: arrayFormat,
258
262
  charset: charset,
259
263
  charsetSentinel: typeof opts.charsetSentinel === 'boolean' ? opts.charsetSentinel : defaults.charsetSentinel,
260
- commaRoundTrip: opts.commaRoundTrip,
264
+ commaRoundTrip: !!opts.commaRoundTrip,
261
265
  delimiter: typeof opts.delimiter === 'undefined' ? defaults.delimiter : opts.delimiter,
262
266
  encode: typeof opts.encode === 'boolean' ? opts.encode : defaults.encode,
263
267
  encodeDotInKeys: typeof opts.encodeDotInKeys === 'boolean' ? opts.encodeDotInKeys : defaults.encodeDotInKeys,
@@ -308,12 +312,13 @@ module.exports = function (object, opts) {
308
312
  var sideChannel = getSideChannel();
309
313
  for (var i = 0; i < objKeys.length; ++i) {
310
314
  var key = objKeys[i];
315
+ var value = obj[key];
311
316
 
312
- if (options.skipNulls && obj[key] === null) {
317
+ if (options.skipNulls && value === null) {
313
318
  continue;
314
319
  }
315
320
  pushToArray(keys, stringify(
316
- obj[key],
321
+ value,
317
322
  key,
318
323
  generateArrayPrefix,
319
324
  commaRoundTrip,
@@ -34,7 +34,7 @@ var compactQueue = function compactQueue(queue) {
34
34
  };
35
35
 
36
36
  var arrayToObject = function arrayToObject(source, options) {
37
- var obj = options && options.plainObjects ? Object.create(null) : {};
37
+ var obj = options && options.plainObjects ? { __proto__: null } : {};
38
38
  for (var i = 0; i < source.length; ++i) {
39
39
  if (typeof source[i] !== 'undefined') {
40
40
  obj[i] = source[i];
@@ -50,11 +50,14 @@ var merge = function merge(target, source, options) {
50
50
  return target;
51
51
  }
52
52
 
53
- if (typeof source !== 'object') {
53
+ if (typeof source !== 'object' && typeof source !== 'function') {
54
54
  if (isArray(target)) {
55
55
  target.push(source);
56
56
  } else if (target && typeof target === 'object') {
57
- if ((options && (options.plainObjects || options.allowPrototypes)) || !has.call(Object.prototype, source)) {
57
+ if (
58
+ (options && (options.plainObjects || options.allowPrototypes))
59
+ || !has.call(Object.prototype, source)
60
+ ) {
58
61
  target[source] = true;
59
62
  }
60
63
  } else {
@@ -108,7 +111,7 @@ var assign = function assignSingleSource(target, source) {
108
111
  }, target);
109
112
  };
110
113
 
111
- var decode = function (str, decoder, charset) {
114
+ var decode = function (str, defaultDecoder, charset) {
112
115
  var strWithoutPlus = str.replace(/\+/g, ' ');
113
116
  if (charset === 'iso-8859-1') {
114
117
  // unescape never throws, no try...catch needed:
@@ -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.13.0",
5
+ "version": "6.14.0",
6
6
  "repository": {
7
7
  "type": "git",
8
8
  "url": "https://github.com/ljharb/qs.git"
@@ -31,7 +31,7 @@
31
31
  "node": ">=0.6"
32
32
  },
33
33
  "dependencies": {
34
- "side-channel": "^1.0.6"
34
+ "side-channel": "^1.1.0"
35
35
  },
36
36
  "devDependencies": {
37
37
  "@browserify/envify": "^6.0.0",
@@ -41,27 +41,29 @@
41
41
  "bundle-collapser": "^1.4.0",
42
42
  "common-shakeify": "~1.0.0",
43
43
  "eclint": "^2.8.1",
44
- "es-value-fixtures": "^1.4.2",
44
+ "es-value-fixtures": "^1.7.0",
45
45
  "eslint": "=8.8.0",
46
46
  "evalmd": "^0.0.19",
47
47
  "for-each": "^0.3.3",
48
48
  "glob": "=10.3.7",
49
+ "has-bigints": "^1.1.0",
49
50
  "has-override-mistake": "^1.0.1",
50
51
  "has-property-descriptors": "^1.0.2",
51
- "has-symbols": "^1.0.3",
52
+ "has-proto": "^1.2.0",
53
+ "has-symbols": "^1.1.0",
52
54
  "iconv-lite": "^0.5.1",
53
55
  "in-publish": "^2.0.1",
54
56
  "jackspeak": "=2.1.1",
55
57
  "mkdirp": "^0.5.5",
56
- "mock-property": "^1.0.3",
58
+ "mock-property": "^1.1.0",
57
59
  "module-deps": "^6.2.3",
58
60
  "npmignore": "^0.3.1",
59
61
  "nyc": "^10.3.2",
60
- "object-inspect": "^1.13.2",
62
+ "object-inspect": "^1.13.3",
61
63
  "qs-iconv": "^1.0.4",
62
64
  "safe-publish-latest": "^2.0.0",
63
65
  "safer-buffer": "^2.1.2",
64
- "tape": "^5.8.1",
66
+ "tape": "^5.9.0",
65
67
  "unassertify": "^3.0.1"
66
68
  },
67
69
  "scripts": {
@@ -9,6 +9,7 @@ var SaferBuffer = require('safer-buffer').Buffer;
9
9
  var v = require('es-value-fixtures');
10
10
  var inspect = require('object-inspect');
11
11
  var emptyTestCases = require('./empty-keys-cases').emptyTestCases;
12
+ var hasProto = require('has-proto')();
12
13
 
13
14
  var qs = require('../');
14
15
  var utils = require('../lib/utils');
@@ -117,7 +118,7 @@ test('parse()', function (t) {
117
118
  st.end();
118
119
  });
119
120
 
120
- t.test('should decode dot in key of object, and allow enabling dot notation when decodeDotInKeys is set to true and allowDots is undefined', function (st) {
121
+ t.test('decodes dot in key of object, and allow enabling dot notation when decodeDotInKeys is set to true and allowDots is undefined', function (st) {
121
122
  st.deepEqual(
122
123
  qs.parse(
123
124
  'name%252Eobj%252Esubobject.first%252Egodly%252Ename=John&name%252Eobj%252Esubobject.last=Doe',
@@ -130,7 +131,7 @@ test('parse()', function (t) {
130
131
  st.end();
131
132
  });
132
133
 
133
- t.test('should throw when decodeDotInKeys is not of type boolean', function (st) {
134
+ t.test('throws when decodeDotInKeys is not of type boolean', function (st) {
134
135
  st['throws'](
135
136
  function () { qs.parse('foo[]&bar=baz', { decodeDotInKeys: 'foobar' }); },
136
137
  TypeError
@@ -160,7 +161,7 @@ test('parse()', function (t) {
160
161
  st.end();
161
162
  });
162
163
 
163
- t.test('should throw when allowEmptyArrays is not of type boolean', function (st) {
164
+ t.test('throws when allowEmptyArrays is not of type boolean', function (st) {
164
165
  st['throws'](
165
166
  function () { qs.parse('foo[]&bar=baz', { allowEmptyArrays: 'foobar' }); },
166
167
  TypeError
@@ -443,7 +444,7 @@ test('parse()', function (t) {
443
444
  st.end();
444
445
  });
445
446
 
446
- t.test('should not throw when a native prototype has an enumerable property', function (st) {
447
+ t.test('does not throw when a native prototype has an enumerable property', function (st) {
447
448
  st.intercept(Object.prototype, 'crash', { value: '' });
448
449
  st.intercept(Array.prototype, 'crash', { value: '' });
449
450
 
@@ -691,9 +692,8 @@ test('parse()', function (t) {
691
692
  st.end();
692
693
  });
693
694
 
694
- t.test('parses null objects correctly', { skip: !Object.create }, function (st) {
695
- var a = Object.create(null);
696
- a.b = 'c';
695
+ t.test('parses null objects correctly', { skip: !hasProto }, function (st) {
696
+ var a = { __proto__: null, b: 'c' };
697
697
 
698
698
  st.deepEqual(qs.parse(a), { b: 'c' });
699
699
  var result = qs.parse({ a: a });
@@ -870,17 +870,25 @@ test('parse()', function (t) {
870
870
  st.end();
871
871
  });
872
872
 
873
- t.test('can return null objects', { skip: !Object.create }, function (st) {
874
- var expected = Object.create(null);
875
- expected.a = Object.create(null);
876
- expected.a.b = 'c';
877
- expected.a.hasOwnProperty = 'd';
873
+ t.test('can return null objects', { skip: !hasProto }, function (st) {
874
+ var expected = {
875
+ __proto__: null,
876
+ a: {
877
+ __proto__: null,
878
+ b: 'c',
879
+ hasOwnProperty: 'd'
880
+ }
881
+ };
878
882
  st.deepEqual(qs.parse('a[b]=c&a[hasOwnProperty]=d', { plainObjects: true }), expected);
879
- st.deepEqual(qs.parse(null, { plainObjects: true }), Object.create(null));
880
- var expectedArray = Object.create(null);
881
- expectedArray.a = Object.create(null);
882
- expectedArray.a[0] = 'b';
883
- expectedArray.a.c = 'd';
883
+ st.deepEqual(qs.parse(null, { plainObjects: true }), { __proto__: null });
884
+ var expectedArray = {
885
+ __proto__: null,
886
+ a: {
887
+ __proto__: null,
888
+ 0: 'b',
889
+ c: 'd'
890
+ }
891
+ };
884
892
  st.deepEqual(qs.parse('a[]=b&a[c]=d', { plainObjects: true }), expectedArray);
885
893
  st.end();
886
894
  });
@@ -957,7 +965,7 @@ test('parse()', function (t) {
957
965
  st.end();
958
966
  });
959
967
 
960
- t.test('should ignore an utf8 sentinel with an unknown value', function (st) {
968
+ t.test('ignores an utf8 sentinel with an unknown value', function (st) {
961
969
  st.deepEqual(qs.parse('utf8=foo&' + urlEncodedOSlashInUtf8 + '=' + urlEncodedOSlashInUtf8, { charsetSentinel: true, charset: 'utf-8' }), { ø: 'ø' });
962
970
  st.end();
963
971
  });
@@ -998,6 +1006,15 @@ test('parse()', function (t) {
998
1006
  st.end();
999
1007
  });
1000
1008
 
1009
+ t.test('interpretNumericEntities with comma:true and iso charset does not crash', function (st) {
1010
+ st.deepEqual(
1011
+ qs.parse('b&a[]=1,' + urlEncodedNumSmiley, { comma: true, charset: 'iso-8859-1', interpretNumericEntities: true }),
1012
+ { b: '', a: ['1,☺'] }
1013
+ );
1014
+
1015
+ st.end();
1016
+ });
1017
+
1001
1018
  t.test('does not interpret %uXXXX syntax in iso-8859-1 mode', function (st) {
1002
1019
  st.deepEqual(qs.parse('%u263A=%u263A', { charset: 'iso-8859-1' }), { '%u263A': '%u263A' });
1003
1020
  st.end();
@@ -1018,6 +1035,95 @@ test('parse()', function (t) {
1018
1035
  st.end();
1019
1036
  });
1020
1037
 
1038
+ t.test('parameter limit tests', function (st) {
1039
+ st.test('does not throw error when within parameter limit', function (sst) {
1040
+ var result = qs.parse('a=1&b=2&c=3', { parameterLimit: 5, throwOnLimitExceeded: true });
1041
+ sst.deepEqual(result, { a: '1', b: '2', c: '3' }, 'parses without errors');
1042
+ sst.end();
1043
+ });
1044
+
1045
+ st.test('throws error when throwOnLimitExceeded is present but not boolean', function (sst) {
1046
+ sst['throws'](
1047
+ function () {
1048
+ qs.parse('a=1&b=2&c=3&d=4&e=5&f=6', { parameterLimit: 3, throwOnLimitExceeded: 'true' });
1049
+ },
1050
+ new TypeError('`throwOnLimitExceeded` option must be a boolean'),
1051
+ 'throws error when throwOnLimitExceeded is present and not boolean'
1052
+ );
1053
+ sst.end();
1054
+ });
1055
+
1056
+ st.test('throws error when parameter limit exceeded', function (sst) {
1057
+ sst['throws'](
1058
+ function () {
1059
+ qs.parse('a=1&b=2&c=3&d=4&e=5&f=6', { parameterLimit: 3, throwOnLimitExceeded: true });
1060
+ },
1061
+ new RangeError('Parameter limit exceeded. Only 3 parameters allowed.'),
1062
+ 'throws error when parameter limit is exceeded'
1063
+ );
1064
+ sst.end();
1065
+ });
1066
+
1067
+ st.test('silently truncates when throwOnLimitExceeded is not given', function (sst) {
1068
+ var result = qs.parse('a=1&b=2&c=3&d=4&e=5', { parameterLimit: 3 });
1069
+ sst.deepEqual(result, { a: '1', b: '2', c: '3' }, 'parses and truncates silently');
1070
+ sst.end();
1071
+ });
1072
+
1073
+ st.test('silently truncates when parameter limit exceeded without error', function (sst) {
1074
+ var result = qs.parse('a=1&b=2&c=3&d=4&e=5', { parameterLimit: 3, throwOnLimitExceeded: false });
1075
+ sst.deepEqual(result, { a: '1', b: '2', c: '3' }, 'parses and truncates silently');
1076
+ sst.end();
1077
+ });
1078
+
1079
+ st.test('allows unlimited parameters when parameterLimit set to Infinity', function (sst) {
1080
+ var result = qs.parse('a=1&b=2&c=3&d=4&e=5&f=6', { parameterLimit: Infinity });
1081
+ sst.deepEqual(result, { a: '1', b: '2', c: '3', d: '4', e: '5', f: '6' }, 'parses all parameters without truncation');
1082
+ sst.end();
1083
+ });
1084
+
1085
+ st.end();
1086
+ });
1087
+
1088
+ t.test('array limit tests', function (st) {
1089
+ st.test('does not throw error when array is within limit', function (sst) {
1090
+ var result = qs.parse('a[]=1&a[]=2&a[]=3', { arrayLimit: 5, throwOnLimitExceeded: true });
1091
+ sst.deepEqual(result, { a: ['1', '2', '3'] }, 'parses array without errors');
1092
+ sst.end();
1093
+ });
1094
+
1095
+ st.test('throws error when throwOnLimitExceeded is present but not boolean for array limit', function (sst) {
1096
+ sst['throws'](
1097
+ function () {
1098
+ qs.parse('a[]=1&a[]=2&a[]=3&a[]=4', { arrayLimit: 3, throwOnLimitExceeded: 'true' });
1099
+ },
1100
+ new TypeError('`throwOnLimitExceeded` option must be a boolean'),
1101
+ 'throws error when throwOnLimitExceeded is present and not boolean for array limit'
1102
+ );
1103
+ sst.end();
1104
+ });
1105
+
1106
+ st.test('throws error when array limit exceeded', function (sst) {
1107
+ sst['throws'](
1108
+ function () {
1109
+ qs.parse('a[]=1&a[]=2&a[]=3&a[]=4', { arrayLimit: 3, throwOnLimitExceeded: true });
1110
+ },
1111
+ new RangeError('Array limit exceeded. Only 3 elements allowed in an array.'),
1112
+ 'throws error when array limit is exceeded'
1113
+ );
1114
+ sst.end();
1115
+ });
1116
+
1117
+ st.test('converts array to object if length is greater than limit', function (sst) {
1118
+ var result = qs.parse('a[1]=1&a[2]=2&a[3]=3&a[4]=4&a[5]=5&a[6]=6', { arrayLimit: 5 });
1119
+
1120
+ sst.deepEqual(result, { a: { 1: '1', 2: '2', 3: '3', 4: '4', 5: '5', 6: '6' } }, 'parses into object if array length is greater than limit');
1121
+ sst.end();
1122
+ });
1123
+
1124
+ st.end();
1125
+ });
1126
+
1021
1127
  t.end();
1022
1128
  });
1023
1129
 
@@ -1076,7 +1182,7 @@ test('qs strictDepth option - throw cases', function (t) {
1076
1182
  qs.parse('a[b][c][d][e][f][g][h][i]=j', { depth: 1, strictDepth: true });
1077
1183
  },
1078
1184
  RangeError,
1079
- 'Should throw RangeError'
1185
+ 'throws RangeError'
1080
1186
  );
1081
1187
  st.end();
1082
1188
  });
@@ -1087,7 +1193,7 @@ test('qs strictDepth option - throw cases', function (t) {
1087
1193
  qs.parse('a[0][1][2][3][4]=b', { depth: 3, strictDepth: true });
1088
1194
  },
1089
1195
  RangeError,
1090
- 'Should throw RangeError'
1196
+ 'throws RangeError'
1091
1197
  );
1092
1198
  st.end();
1093
1199
  });
@@ -1098,7 +1204,7 @@ test('qs strictDepth option - throw cases', function (t) {
1098
1204
  qs.parse('a[b][c][0][d][e]=f', { depth: 3, strictDepth: true });
1099
1205
  },
1100
1206
  RangeError,
1101
- 'Should throw RangeError'
1207
+ 'throws RangeError'
1102
1208
  );
1103
1209
  st.end();
1104
1210
  });
@@ -1109,7 +1215,7 @@ test('qs strictDepth option - throw cases', function (t) {
1109
1215
  qs.parse('a[b][c][d][e]=true&a[b][c][d][f]=42', { depth: 3, strictDepth: true });
1110
1216
  },
1111
1217
  RangeError,
1112
- 'Should throw RangeError'
1218
+ 'throws RangeError'
1113
1219
  );
1114
1220
  st.end();
1115
1221
  });
@@ -1123,7 +1229,7 @@ test('qs strictDepth option - non-throw cases', function (t) {
1123
1229
  qs.parse('a[b][c][d][e]=true&a[b][c][d][f]=42', { depth: 0, strictDepth: true });
1124
1230
  },
1125
1231
  RangeError,
1126
- 'Should not throw RangeError'
1232
+ 'does not throw RangeError'
1127
1233
  );
1128
1234
  st.end();
1129
1235
  });
@@ -1132,7 +1238,7 @@ test('qs strictDepth option - non-throw cases', function (t) {
1132
1238
  st.doesNotThrow(
1133
1239
  function () {
1134
1240
  var result = qs.parse('a[b]=c', { depth: 1, strictDepth: true });
1135
- st.deepEqual(result, { a: { b: 'c' } }, 'Should parse correctly');
1241
+ st.deepEqual(result, { a: { b: 'c' } }, 'parses correctly');
1136
1242
  }
1137
1243
  );
1138
1244
  st.end();
@@ -1142,7 +1248,7 @@ test('qs strictDepth option - non-throw cases', function (t) {
1142
1248
  st.doesNotThrow(
1143
1249
  function () {
1144
1250
  var result = qs.parse('a[b][c][d][e][f][g][h][i]=j', { depth: 1 });
1145
- st.deepEqual(result, { a: { b: { '[c][d][e][f][g][h][i]': 'j' } } }, 'Should parse with depth limit');
1251
+ st.deepEqual(result, { a: { b: { '[c][d][e][f][g][h][i]': 'j' } } }, 'parses with depth limit');
1146
1252
  }
1147
1253
  );
1148
1254
  st.end();
@@ -1152,7 +1258,7 @@ test('qs strictDepth option - non-throw cases', function (t) {
1152
1258
  st.doesNotThrow(
1153
1259
  function () {
1154
1260
  var result = qs.parse('a[b]=c', { depth: 1 });
1155
- st.deepEqual(result, { a: { b: 'c' } }, 'Should parse correctly');
1261
+ st.deepEqual(result, { a: { b: 'c' } }, 'parses correctly');
1156
1262
  }
1157
1263
  );
1158
1264
  st.end();
@@ -1162,7 +1268,7 @@ test('qs strictDepth option - non-throw cases', function (t) {
1162
1268
  st.doesNotThrow(
1163
1269
  function () {
1164
1270
  var result = qs.parse('a[b][c]=d', { depth: 2, strictDepth: true });
1165
- st.deepEqual(result, { a: { b: { c: 'd' } } }, 'Should parse correctly');
1271
+ st.deepEqual(result, { a: { b: { c: 'd' } } }, 'parses correctly');
1166
1272
  }
1167
1273
  );
1168
1274
  st.end();
@@ -8,7 +8,8 @@ var SaferBuffer = require('safer-buffer').Buffer;
8
8
  var hasSymbols = require('has-symbols');
9
9
  var mockProperty = require('mock-property');
10
10
  var emptyTestCases = require('./empty-keys-cases').emptyTestCases;
11
- var hasBigInt = typeof BigInt === 'function';
11
+ var hasProto = require('has-proto')();
12
+ var hasBigInt = require('has-bigints')();
12
13
 
13
14
  test('stringify()', function (t) {
14
15
  t.test('stringifies a querystring object', function (st) {
@@ -650,10 +651,8 @@ test('stringify()', function (t) {
650
651
  st.end();
651
652
  });
652
653
 
653
- t.test('stringifies a null object', { skip: !Object.create }, function (st) {
654
- var obj = Object.create(null);
655
- obj.a = 'b';
656
- st.equal(qs.stringify(obj), 'a=b');
654
+ t.test('stringifies a null object', { skip: !hasProto }, function (st) {
655
+ st.equal(qs.stringify({ __proto__: null, a: 'b' }), 'a=b');
657
656
  st.end();
658
657
  });
659
658
 
@@ -665,11 +664,8 @@ test('stringify()', function (t) {
665
664
  st.end();
666
665
  });
667
666
 
668
- t.test('stringifies an object with a null object as a child', { skip: !Object.create }, function (st) {
669
- var obj = { a: Object.create(null) };
670
-
671
- obj.a.b = 'c';
672
- st.equal(qs.stringify(obj), 'a%5Bb%5D=c');
667
+ t.test('stringifies an object with a null object as a child', { skip: !hasProto }, function (st) {
668
+ st.equal(qs.stringify({ a: { __proto__: null, b: 'c' } }), 'a%5Bb%5D=c');
673
669
  st.end();
674
670
  });
675
671
 
@@ -1254,7 +1250,7 @@ test('stringify()', function (t) {
1254
1250
  };
1255
1251
 
1256
1252
  st.equal(
1257
- qs.stringify(obj, { arrayFormat: 'bracket', charset: 'utf-8' }),
1253
+ qs.stringify(obj, { arrayFormat: 'brackets', charset: 'utf-8' }),
1258
1254
  'foo=' + expected.join('')
1259
1255
  );
1260
1256
 
@@ -1295,4 +1291,16 @@ test('stringifies empty keys', function (t) {
1295
1291
 
1296
1292
  st.end();
1297
1293
  });
1294
+
1295
+ t.test('stringifies non-string keys', function (st) {
1296
+ var actual = qs.stringify({ a: 'b', 'false': {} }, {
1297
+ filter: ['a', false, null],
1298
+ allowDots: true,
1299
+ encodeDotInKeys: true
1300
+ });
1301
+
1302
+ st.equal(actual, 'a=b', 'stringifies correctly');
1303
+
1304
+ st.end();
1305
+ });
1298
1306
  });
@@ -4,6 +4,8 @@ var test = require('tape');
4
4
  var inspect = require('object-inspect');
5
5
  var SaferBuffer = require('safer-buffer').Buffer;
6
6
  var forEach = require('for-each');
7
+ var v = require('es-value-fixtures');
8
+
7
9
  var utils = require('../lib/utils');
8
10
 
9
11
  test('merge()', function (t) {
@@ -28,6 +30,20 @@ test('merge()', function (t) {
28
30
  var noOptionsNonObjectSource = utils.merge({ foo: 'baz' }, 'bar');
29
31
  t.deepEqual(noOptionsNonObjectSource, { foo: 'baz', bar: true });
30
32
 
33
+ var func = function f() {};
34
+ t.deepEqual(
35
+ utils.merge(func, { foo: 'bar' }),
36
+ [func, { foo: 'bar' }],
37
+ 'functions can not be merged into'
38
+ );
39
+
40
+ func.bar = 'baz';
41
+ t.deepEqual(
42
+ utils.merge({ foo: 'bar' }, func),
43
+ { foo: 'bar', bar: 'baz' },
44
+ 'functions can be merge sources'
45
+ );
46
+
31
47
  t.test(
32
48
  'avoids invoking array setters unnecessarily',
33
49
  { skip: typeof Object.defineProperty !== 'function' },
@@ -119,6 +135,104 @@ test('combine()', function (t) {
119
135
  t.end();
120
136
  });
121
137
 
138
+ test('decode', function (t) {
139
+ t.equal(
140
+ utils.decode('a+b'),
141
+ 'a b',
142
+ 'decodes + to space'
143
+ );
144
+
145
+ t.equal(
146
+ utils.decode('name%2Eobj'),
147
+ 'name.obj',
148
+ 'decodes a string'
149
+ );
150
+ t.equal(
151
+ utils.decode('name%2Eobj%2Efoo', null, 'iso-8859-1'),
152
+ 'name.obj.foo',
153
+ 'decodes a string in iso-8859-1'
154
+ );
155
+
156
+ t.end();
157
+ });
158
+
159
+ test('encode', function (t) {
160
+ forEach(v.nullPrimitives, function (nullish) {
161
+ t['throws'](
162
+ function () { utils.encode(nullish); },
163
+ TypeError,
164
+ inspect(nullish) + ' is not a string'
165
+ );
166
+ });
167
+
168
+ t.equal(utils.encode(''), '', 'empty string returns itself');
169
+ t.deepEqual(utils.encode([]), [], 'empty array returns itself');
170
+ t.deepEqual(utils.encode({ length: 0 }), { length: 0 }, 'empty arraylike returns itself');
171
+
172
+ t.test('symbols', { skip: !v.hasSymbols }, function (st) {
173
+ st.equal(utils.encode(Symbol('x')), 'Symbol%28x%29', 'symbol is encoded');
174
+
175
+ st.end();
176
+ });
177
+
178
+ t.equal(
179
+ utils.encode('(abc)'),
180
+ '%28abc%29',
181
+ 'encodes parentheses'
182
+ );
183
+ t.equal(
184
+ utils.encode({ toString: function () { return '(abc)'; } }),
185
+ '%28abc%29',
186
+ 'toStrings and encodes parentheses'
187
+ );
188
+
189
+ t.equal(
190
+ utils.encode('abc 123 💩', null, 'iso-8859-1'),
191
+ 'abc%20123%20%26%2355357%3B%26%2356489%3B',
192
+ 'encodes in iso-8859-1'
193
+ );
194
+
195
+ var longString = '';
196
+ var expectedString = '';
197
+ for (var i = 0; i < 1500; i++) {
198
+ longString += ' ';
199
+ expectedString += '%20';
200
+ }
201
+
202
+ t.equal(
203
+ utils.encode(longString),
204
+ expectedString,
205
+ 'encodes a long string'
206
+ );
207
+
208
+ t.equal(
209
+ utils.encode('\x28\x29'),
210
+ '%28%29',
211
+ 'encodes parens normally'
212
+ );
213
+ t.equal(
214
+ utils.encode('\x28\x29', null, null, null, 'RFC1738'),
215
+ '()',
216
+ 'does not encode parens in RFC1738'
217
+ );
218
+
219
+ // todo RFC1738 format
220
+
221
+ t.equal(
222
+ utils.encode('Āက豈'),
223
+ '%C4%80%E1%80%80%EF%A4%80',
224
+ 'encodes multibyte chars'
225
+ );
226
+
227
+ t.equal(
228
+ utils.encode('\uD83D \uDCA9'),
229
+ '%F0%9F%90%A0%F0%BA%90%80',
230
+ 'encodes lone surrogates'
231
+ );
232
+
233
+ t.end();
234
+ });
235
+
122
236
  test('isBuffer()', function (t) {
123
237
  forEach([null, undefined, true, false, '', 'abc', 42, 0, NaN, {}, [], function () {}, /a/g], function (x) {
124
238
  t.equal(utils.isBuffer(x), false, inspect(x) + ' is not a buffer');
@@ -134,3 +248,15 @@ test('isBuffer()', function (t) {
134
248
  t.equal(utils.isBuffer(buffer), true, 'real Buffer instance is a buffer');
135
249
  t.end();
136
250
  });
251
+
252
+ test('isRegExp()', function (t) {
253
+ t.equal(utils.isRegExp(/a/g), true, 'RegExp is a RegExp');
254
+ t.equal(utils.isRegExp(new RegExp('a', 'g')), true, 'new RegExp is a RegExp');
255
+ t.equal(utils.isRegExp(new Date()), false, 'Date is not a RegExp');
256
+
257
+ forEach(v.primitives, function (primitive) {
258
+ t.equal(utils.isRegExp(primitive), false, inspect(primitive) + ' is not a RegExp');
259
+ });
260
+
261
+ t.end();
262
+ });