axios 0.21.4 → 0.30.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/CHANGELOG.md +318 -54
  2. package/README.md +378 -64
  3. package/SECURITY.md +3 -3
  4. package/UPGRADE_GUIDE.md +41 -13
  5. package/bin/check-build-version.js +19 -0
  6. package/bin/ssl_hotfix.js +22 -0
  7. package/dist/axios.js +2072 -1878
  8. package/dist/axios.js.map +1 -0
  9. package/dist/axios.min.js +2 -3
  10. package/dist/axios.min.js.map +1 -0
  11. package/dist/esm/axios.js +2379 -0
  12. package/dist/esm/axios.js.map +1 -0
  13. package/dist/esm/axios.min.js +2 -0
  14. package/dist/esm/axios.min.js.map +1 -0
  15. package/index.d.ts +219 -46
  16. package/lib/adapters/http.js +262 -130
  17. package/lib/adapters/xhr.js +59 -22
  18. package/lib/axios.js +19 -7
  19. package/lib/cancel/CancelToken.js +65 -4
  20. package/lib/cancel/CanceledError.js +24 -0
  21. package/lib/core/Axios.js +45 -17
  22. package/lib/core/AxiosError.js +97 -0
  23. package/lib/core/InterceptorManager.js +9 -0
  24. package/lib/core/buildFullPath.js +5 -2
  25. package/lib/core/dispatchRequest.js +13 -1
  26. package/lib/core/mergeConfig.js +54 -38
  27. package/lib/core/settle.js +3 -3
  28. package/lib/core/transformData.js +4 -3
  29. package/lib/{defaults.js → defaults/index.js} +64 -23
  30. package/lib/defaults/transitional.js +7 -0
  31. package/lib/env/README.md +3 -0
  32. package/lib/env/classes/FormData.js +2 -0
  33. package/lib/env/data.js +3 -0
  34. package/lib/helpers/AxiosURLSearchParams.js +42 -0
  35. package/lib/helpers/bind.js +1 -5
  36. package/lib/helpers/buildURL.js +18 -33
  37. package/lib/helpers/combineURLs.js +1 -1
  38. package/lib/helpers/formDataToJSON.js +74 -0
  39. package/lib/helpers/fromDataURI.js +51 -0
  40. package/lib/helpers/isAbsoluteURL.js +1 -1
  41. package/lib/helpers/isAxiosError.js +3 -1
  42. package/lib/helpers/isURLSameOrigin.js +12 -12
  43. package/lib/helpers/null.js +2 -0
  44. package/lib/helpers/parseHeaders.js +2 -2
  45. package/lib/helpers/parseProtocol.js +6 -0
  46. package/lib/helpers/toFormData.js +179 -0
  47. package/lib/helpers/toURLEncodedForm.js +18 -0
  48. package/lib/helpers/validator.js +14 -33
  49. package/lib/platform/browser/classes/FormData.js +3 -0
  50. package/lib/platform/browser/classes/URLSearchParams.js +5 -0
  51. package/lib/platform/browser/index.js +11 -0
  52. package/lib/platform/index.js +3 -0
  53. package/lib/platform/node/classes/FormData.js +3 -0
  54. package/lib/platform/node/classes/URLSearchParams.js +5 -0
  55. package/lib/platform/node/index.js +11 -0
  56. package/lib/utils.js +210 -37
  57. package/package.json +42 -26
  58. package/rollup.config.js +60 -0
  59. package/tsconfig.json +14 -0
  60. package/tslint.json +6 -0
  61. package/dist/axios.map +0 -1
  62. package/dist/axios.min.map +0 -1
  63. package/lib/cancel/Cancel.js +0 -19
  64. package/lib/core/createError.js +0 -18
  65. package/lib/core/enhanceError.js +0 -42
package/lib/utils.js CHANGED
@@ -6,6 +6,22 @@ var bind = require('./helpers/bind');
6
6
 
7
7
  var toString = Object.prototype.toString;
8
8
 
9
+ // eslint-disable-next-line func-names
10
+ var kindOf = (function(cache) {
11
+ // eslint-disable-next-line func-names
12
+ return function(thing) {
13
+ var str = toString.call(thing);
14
+ return cache[str] || (cache[str] = str.slice(8, -1).toLowerCase());
15
+ };
16
+ })(Object.create(null));
17
+
18
+ function kindOfTest(type) {
19
+ type = type.toLowerCase();
20
+ return function isKindOf(thing) {
21
+ return kindOf(thing) === type;
22
+ };
23
+ }
24
+
9
25
  /**
10
26
  * Determine if a value is an Array
11
27
  *
@@ -13,7 +29,7 @@ var toString = Object.prototype.toString;
13
29
  * @returns {boolean} True if value is an Array, otherwise false
14
30
  */
15
31
  function isArray(val) {
16
- return toString.call(val) === '[object Array]';
32
+ return Array.isArray(val);
17
33
  }
18
34
 
19
35
  /**
@@ -40,22 +56,12 @@ function isBuffer(val) {
40
56
  /**
41
57
  * Determine if a value is an ArrayBuffer
42
58
  *
59
+ * @function
43
60
  * @param {Object} val The value to test
44
61
  * @returns {boolean} True if value is an ArrayBuffer, otherwise false
45
62
  */
46
- function isArrayBuffer(val) {
47
- return toString.call(val) === '[object ArrayBuffer]';
48
- }
63
+ var isArrayBuffer = kindOfTest('ArrayBuffer');
49
64
 
50
- /**
51
- * Determine if a value is a FormData
52
- *
53
- * @param {Object} val The value to test
54
- * @returns {boolean} True if value is an FormData, otherwise false
55
- */
56
- function isFormData(val) {
57
- return (typeof FormData !== 'undefined') && (val instanceof FormData);
58
- }
59
65
 
60
66
  /**
61
67
  * Determine if a value is a view on an ArrayBuffer
@@ -68,7 +74,7 @@ function isArrayBufferView(val) {
68
74
  if ((typeof ArrayBuffer !== 'undefined') && (ArrayBuffer.isView)) {
69
75
  result = ArrayBuffer.isView(val);
70
76
  } else {
71
- result = (val) && (val.buffer) && (val.buffer instanceof ArrayBuffer);
77
+ result = (val) && (val.buffer) && (isArrayBuffer(val.buffer));
72
78
  }
73
79
  return result;
74
80
  }
@@ -110,7 +116,7 @@ function isObject(val) {
110
116
  * @return {boolean} True if value is a plain Object, otherwise false
111
117
  */
112
118
  function isPlainObject(val) {
113
- if (toString.call(val) !== '[object Object]') {
119
+ if (kindOf(val) !== 'object') {
114
120
  return false;
115
121
  }
116
122
 
@@ -118,35 +124,51 @@ function isPlainObject(val) {
118
124
  return prototype === null || prototype === Object.prototype;
119
125
  }
120
126
 
127
+ /**
128
+ * Determine if a value is a empty Object
129
+ *
130
+ * @param {Object} val The value to test
131
+ * @return {boolean} True if value is a empty Object, otherwise false
132
+ */
133
+ function isEmptyObject(val) {
134
+ return val && Object.keys(val).length === 0 && Object.getPrototypeOf(val) === Object.prototype;
135
+ }
136
+
121
137
  /**
122
138
  * Determine if a value is a Date
123
139
  *
140
+ * @function
124
141
  * @param {Object} val The value to test
125
142
  * @returns {boolean} True if value is a Date, otherwise false
126
143
  */
127
- function isDate(val) {
128
- return toString.call(val) === '[object Date]';
129
- }
144
+ var isDate = kindOfTest('Date');
130
145
 
131
146
  /**
132
147
  * Determine if a value is a File
133
148
  *
149
+ * @function
134
150
  * @param {Object} val The value to test
135
151
  * @returns {boolean} True if value is a File, otherwise false
136
152
  */
137
- function isFile(val) {
138
- return toString.call(val) === '[object File]';
139
- }
153
+ var isFile = kindOfTest('File');
140
154
 
141
155
  /**
142
156
  * Determine if a value is a Blob
143
157
  *
158
+ * @function
144
159
  * @param {Object} val The value to test
145
160
  * @returns {boolean} True if value is a Blob, otherwise false
146
161
  */
147
- function isBlob(val) {
148
- return toString.call(val) === '[object Blob]';
149
- }
162
+ var isBlob = kindOfTest('Blob');
163
+
164
+ /**
165
+ * Determine if a value is a FileList
166
+ *
167
+ * @function
168
+ * @param {Object} val The value to test
169
+ * @returns {boolean} True if value is a File, otherwise false
170
+ */
171
+ var isFileList = kindOfTest('FileList');
150
172
 
151
173
  /**
152
174
  * Determine if a value is a Function
@@ -169,14 +191,27 @@ function isStream(val) {
169
191
  }
170
192
 
171
193
  /**
172
- * Determine if a value is a URLSearchParams object
194
+ * Determine if a value is a FormData
173
195
  *
196
+ * @param {Object} thing The value to test
197
+ * @returns {boolean} True if value is an FormData, otherwise false
198
+ */
199
+ function isFormData(thing) {
200
+ var pattern = '[object FormData]';
201
+ return thing && (
202
+ (typeof FormData === 'function' && thing instanceof FormData) ||
203
+ toString.call(thing) === pattern ||
204
+ (isFunction(thing.toString) && thing.toString() === pattern)
205
+ );
206
+ }
207
+
208
+ /**
209
+ * Determine if a value is a URLSearchParams object
210
+ * @function
174
211
  * @param {Object} val The value to test
175
212
  * @returns {boolean} True if value is a URLSearchParams object, otherwise false
176
213
  */
177
- function isURLSearchParams(val) {
178
- return typeof URLSearchParams !== 'undefined' && val instanceof URLSearchParams;
179
- }
214
+ var isURLSearchParams = kindOfTest('URLSearchParams');
180
215
 
181
216
  /**
182
217
  * Trim excess whitespace off the beginning and end of a string
@@ -185,7 +220,7 @@ function isURLSearchParams(val) {
185
220
  * @returns {String} The String freed of excess whitespace
186
221
  */
187
222
  function trim(str) {
188
- return str.trim ? str.trim() : str.replace(/^\s+|\s+$/g, '');
223
+ return str.trim ? str.trim() : str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '');
189
224
  }
190
225
 
191
226
  /**
@@ -204,15 +239,16 @@ function trim(str) {
204
239
  * navigator.product -> 'NativeScript' or 'NS'
205
240
  */
206
241
  function isStandardBrowserEnv() {
207
- if (typeof navigator !== 'undefined' && (navigator.product === 'ReactNative' ||
208
- navigator.product === 'NativeScript' ||
209
- navigator.product === 'NS')) {
242
+ var product;
243
+ if (typeof navigator !== 'undefined' && (
244
+ (product = navigator.product) === 'ReactNative' ||
245
+ product === 'NativeScript' ||
246
+ product === 'NS')
247
+ ) {
210
248
  return false;
211
249
  }
212
- return (
213
- typeof window !== 'undefined' &&
214
- typeof document !== 'undefined'
215
- );
250
+
251
+ return typeof window !== 'undefined' && typeof document !== 'undefined';
216
252
  }
217
253
 
218
254
  /**
@@ -323,6 +359,130 @@ function stripBOM(content) {
323
359
  return content;
324
360
  }
325
361
 
362
+ /**
363
+ * Inherit the prototype methods from one constructor into another
364
+ * @param {function} constructor
365
+ * @param {function} superConstructor
366
+ * @param {object} [props]
367
+ * @param {object} [descriptors]
368
+ */
369
+
370
+ function inherits(constructor, superConstructor, props, descriptors) {
371
+ constructor.prototype = Object.create(superConstructor.prototype, descriptors);
372
+ constructor.prototype.constructor = constructor;
373
+ props && Object.assign(constructor.prototype, props);
374
+ }
375
+
376
+ /**
377
+ * Resolve object with deep prototype chain to a flat object
378
+ * @param {Object} sourceObj source object
379
+ * @param {Object} [destObj]
380
+ * @param {Function|Boolean} [filter]
381
+ * @param {Function} [propFilter]
382
+ * @returns {Object}
383
+ */
384
+
385
+ function toFlatObject(sourceObj, destObj, filter, propFilter) {
386
+ var props;
387
+ var i;
388
+ var prop;
389
+ var merged = {};
390
+
391
+ destObj = destObj || {};
392
+ // eslint-disable-next-line no-eq-null,eqeqeq
393
+ if (sourceObj == null) return destObj;
394
+
395
+ do {
396
+ props = Object.getOwnPropertyNames(sourceObj);
397
+ i = props.length;
398
+ while (i-- > 0) {
399
+ prop = props[i];
400
+ if ((!propFilter || propFilter(prop, sourceObj, destObj)) && !merged[prop]) {
401
+ destObj[prop] = sourceObj[prop];
402
+ merged[prop] = true;
403
+ }
404
+ }
405
+ sourceObj = filter !== false && Object.getPrototypeOf(sourceObj);
406
+ } while (sourceObj && (!filter || filter(sourceObj, destObj)) && sourceObj !== Object.prototype);
407
+
408
+ return destObj;
409
+ }
410
+
411
+ /*
412
+ * determines whether a string ends with the characters of a specified string
413
+ * @param {String} str
414
+ * @param {String} searchString
415
+ * @param {Number} [position= 0]
416
+ * @returns {boolean}
417
+ */
418
+ function endsWith(str, searchString, position) {
419
+ str = String(str);
420
+ if (position === undefined || position > str.length) {
421
+ position = str.length;
422
+ }
423
+ position -= searchString.length;
424
+ var lastIndex = str.indexOf(searchString, position);
425
+ return lastIndex !== -1 && lastIndex === position;
426
+ }
427
+
428
+
429
+ /**
430
+ * Returns new array from array like object or null if failed
431
+ * @param {*} [thing]
432
+ * @returns {?Array}
433
+ */
434
+ function toArray(thing) {
435
+ if (!thing) return null;
436
+ if (isArray(thing)) return thing;
437
+ var i = thing.length;
438
+ if (!isNumber(i)) return null;
439
+ var arr = new Array(i);
440
+ while (i-- > 0) {
441
+ arr[i] = thing[i];
442
+ }
443
+ return arr;
444
+ }
445
+
446
+ // eslint-disable-next-line func-names
447
+ var isTypedArray = (function(TypedArray) {
448
+ // eslint-disable-next-line func-names
449
+ return function(thing) {
450
+ return TypedArray && thing instanceof TypedArray;
451
+ };
452
+ })(typeof Uint8Array !== 'undefined' && Object.getPrototypeOf(Uint8Array));
453
+
454
+ function forEachEntry(obj, fn) {
455
+ var generator = obj && obj[Symbol.iterator];
456
+
457
+ var iterator = generator.call(obj);
458
+
459
+ var result;
460
+
461
+ while ((result = iterator.next()) && !result.done) {
462
+ var pair = result.value;
463
+ fn.call(obj, pair[0], pair[1]);
464
+ }
465
+ }
466
+
467
+ function matchAll(regExp, str) {
468
+ var matches;
469
+ var arr = [];
470
+
471
+ while ((matches = regExp.exec(str)) !== null) {
472
+ arr.push(matches);
473
+ }
474
+
475
+ return arr;
476
+ }
477
+
478
+ var isHTMLForm = kindOfTest('HTMLFormElement');
479
+
480
+ var hasOwnProperty = (function resolver(_hasOwnProperty) {
481
+ return function(obj, prop) {
482
+ return _hasOwnProperty.call(obj, prop);
483
+ };
484
+ })(Object.prototype.hasOwnProperty);
485
+
326
486
  module.exports = {
327
487
  isArray: isArray,
328
488
  isArrayBuffer: isArrayBuffer,
@@ -333,6 +493,7 @@ module.exports = {
333
493
  isNumber: isNumber,
334
494
  isObject: isObject,
335
495
  isPlainObject: isPlainObject,
496
+ isEmptyObject: isEmptyObject,
336
497
  isUndefined: isUndefined,
337
498
  isDate: isDate,
338
499
  isFile: isFile,
@@ -345,5 +506,17 @@ module.exports = {
345
506
  merge: merge,
346
507
  extend: extend,
347
508
  trim: trim,
348
- stripBOM: stripBOM
509
+ stripBOM: stripBOM,
510
+ inherits: inherits,
511
+ toFlatObject: toFlatObject,
512
+ kindOf: kindOf,
513
+ kindOfTest: kindOfTest,
514
+ endsWith: endsWith,
515
+ toArray: toArray,
516
+ isTypedArray: isTypedArray,
517
+ isFileList: isFileList,
518
+ forEachEntry: forEachEntry,
519
+ matchAll: matchAll,
520
+ isHTMLForm: isHTMLForm,
521
+ hasOwnProperty: hasOwnProperty
349
522
  };
package/package.json CHANGED
@@ -1,15 +1,14 @@
1
1
  {
2
2
  "name": "axios",
3
- "version": "0.21.4",
3
+ "version": "0.30.0",
4
4
  "description": "Promise based HTTP client for the browser and node.js",
5
5
  "main": "index.js",
6
+ "types": "index.d.ts",
6
7
  "scripts": {
7
- "test": "grunt test",
8
+ "test": "node bin/ssl_hotfix.js grunt test && node bin/ssl_hotfix.js dtslint --localTs node_modules/typescript/lib",
8
9
  "start": "node ./sandbox/server.js",
9
- "build": "NODE_ENV=production grunt build",
10
- "preversion": "npm test",
11
- "version": "npm run build && grunt version && git add -A dist && git add CHANGELOG.md bower.json package.json",
12
- "postversion": "git push && git push --tags",
10
+ "preversion": "grunt version && npm test",
11
+ "build": "cross-env NODE_ENV=production grunt build",
13
12
  "examples": "node ./examples/server.js",
14
13
  "coveralls": "cat coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js",
15
14
  "fix": "eslint --fix lib/**/*.js"
@@ -32,23 +31,34 @@
32
31
  },
33
32
  "homepage": "https://axios-http.com",
34
33
  "devDependencies": {
35
- "coveralls": "^3.0.0",
36
- "es6-promise": "^4.2.4",
37
- "grunt": "^1.3.0",
34
+ "@rollup/plugin-babel": "^5.3.0",
35
+ "@rollup/plugin-commonjs": "^15.1.0",
36
+ "@rollup/plugin-json": "^4.1.0",
37
+ "@rollup/plugin-multi-entry": "^4.0.0",
38
+ "@rollup/plugin-node-resolve": "^9.0.0",
39
+ "abortcontroller-polyfill": "^1.7.3",
40
+ "body-parser": "^1.20.0",
41
+ "coveralls": "^3.1.1",
42
+ "cross-env": "^7.0.3",
43
+ "dtslint": "^4.2.1",
44
+ "es6-promise": "^4.2.8",
45
+ "express": "^4.18.1",
46
+ "formidable": "^2.0.1",
47
+ "grunt": "^1.4.1",
38
48
  "grunt-banner": "^0.6.0",
39
- "grunt-cli": "^1.2.0",
40
- "grunt-contrib-clean": "^1.1.0",
41
- "grunt-contrib-watch": "^1.0.0",
42
- "grunt-eslint": "^23.0.0",
43
- "grunt-karma": "^4.0.0",
49
+ "grunt-cli": "^1.4.3",
50
+ "grunt-contrib-clean": "^2.0.0",
51
+ "grunt-contrib-watch": "^1.1.0",
52
+ "grunt-eslint": "^24.0.0",
53
+ "grunt-karma": "^4.0.2",
44
54
  "grunt-mocha-test": "^0.13.3",
45
- "grunt-ts": "^6.0.0-beta.19",
46
- "grunt-webpack": "^4.0.2",
47
- "istanbul-instrumenter-loader": "^1.0.0",
55
+ "grunt-shell": "^3.0.1",
56
+ "grunt-webpack": "^5.0.0",
57
+ "istanbul-instrumenter-loader": "^3.0.1",
48
58
  "jasmine-core": "^2.4.1",
49
- "karma": "^6.3.2",
50
- "karma-chrome-launcher": "^3.1.0",
51
- "karma-firefox-launcher": "^2.1.0",
59
+ "karma": "^6.3.17",
60
+ "karma-chrome-launcher": "^3.1.1",
61
+ "karma-firefox-launcher": "^2.1.2",
52
62
  "karma-jasmine": "^1.1.1",
53
63
  "karma-jasmine-ajax": "^0.1.13",
54
64
  "karma-safari-launcher": "^1.0.0",
@@ -56,24 +66,30 @@
56
66
  "karma-sinon": "^1.0.5",
57
67
  "karma-sourcemap-loader": "^0.3.8",
58
68
  "karma-webpack": "^4.0.2",
59
- "load-grunt-tasks": "^3.5.2",
60
- "minimist": "^1.2.0",
69
+ "load-grunt-tasks": "^5.1.0",
70
+ "minimist": "^1.2.6",
61
71
  "mocha": "^8.2.1",
72
+ "multer": "^1.4.4",
73
+ "rollup": "^2.67.0",
74
+ "rollup-plugin-terser": "^7.0.2",
62
75
  "sinon": "^4.5.0",
63
76
  "terser-webpack-plugin": "^4.2.3",
64
- "typescript": "^4.0.5",
77
+ "typescript": "^4.6.3",
65
78
  "url-search-params": "^0.10.0",
66
79
  "webpack": "^4.44.2",
67
80
  "webpack-dev-server": "^3.11.0"
68
81
  },
69
82
  "browser": {
70
- "./lib/adapters/http.js": "./lib/adapters/xhr.js"
83
+ "./lib/adapters/http.js": "./lib/adapters/xhr.js",
84
+ "./lib/platform/node/index.js": "./lib/platform/browser/index.js"
71
85
  },
72
86
  "jsdelivr": "dist/axios.min.js",
73
87
  "unpkg": "dist/axios.min.js",
74
88
  "typings": "./index.d.ts",
75
89
  "dependencies": {
76
- "follow-redirects": "^1.14.0"
90
+ "follow-redirects": "^1.15.4",
91
+ "form-data": "^4.0.0",
92
+ "proxy-from-env": "^1.1.0"
77
93
  },
78
94
  "bundlesize": [
79
95
  {
@@ -81,4 +97,4 @@
81
97
  "threshold": "5kB"
82
98
  }
83
99
  ]
84
- }
100
+ }
@@ -0,0 +1,60 @@
1
+ import resolve from '@rollup/plugin-node-resolve';
2
+ import commonjs from '@rollup/plugin-commonjs';
3
+ import {terser} from "rollup-plugin-terser";
4
+ import json from '@rollup/plugin-json';
5
+
6
+ const lib = require("./package.json");
7
+ const outputFileName = 'axios';
8
+ const name = "axios";
9
+ const input = './lib/axios.js';
10
+
11
+ const buildConfig = (config) => {
12
+
13
+ const build = ({minified}) => ({
14
+ input,
15
+ ...config,
16
+ output: {
17
+ ...config.output,
18
+ file: `${config.output.file}.${minified ? "min.js" : "js"}`
19
+ },
20
+ plugins: [
21
+ json(),
22
+ resolve({browser: true}),
23
+ commonjs(),
24
+ minified && terser(),
25
+ ...(config.plugins || []),
26
+ ]
27
+ });
28
+
29
+ return [
30
+ build({minified: false}),
31
+ build({minified: true}),
32
+ ];
33
+ };
34
+
35
+ export default async () => {
36
+ const year = new Date().getFullYear();
37
+ const banner = `// ${lib.name} v${lib.version} Copyright (c) ${year} ${lib.author}`;
38
+
39
+ return [
40
+ ...buildConfig({
41
+ output: {
42
+ file: `dist/${outputFileName}`,
43
+ name,
44
+ format: "umd",
45
+ exports: "default",
46
+ banner
47
+ }
48
+ }),
49
+
50
+ ...buildConfig({
51
+ output: {
52
+ file: `dist/esm/${outputFileName}`,
53
+ format: "esm",
54
+ preferConst: true,
55
+ exports: "named",
56
+ banner
57
+ }
58
+ })
59
+ ]
60
+ };
package/tsconfig.json ADDED
@@ -0,0 +1,14 @@
1
+ {
2
+ "compilerOptions": {
3
+ "module": "es2015",
4
+ "lib": ["dom", "es2015"],
5
+ "types": [],
6
+ "moduleResolution": "node",
7
+ "strict": true,
8
+ "noEmit": true,
9
+ "baseUrl": ".",
10
+ "paths": {
11
+ "axios": ["."]
12
+ }
13
+ }
14
+ }
package/tslint.json ADDED
@@ -0,0 +1,6 @@
1
+ {
2
+ "extends": "dtslint/dtslint.json",
3
+ "rules": {
4
+ "no-unnecessary-generics": false
5
+ }
6
+ }