axios 1.4.0 → 1.6.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.

Potentially problematic release.


This version of axios might be problematic. Click here for more details.

package/index.d.cts CHANGED
@@ -8,6 +8,8 @@ type MethodsHeaders = Partial<{
8
8
 
9
9
  type AxiosHeaderMatcher = (this: AxiosHeaders, value: string, name: string, headers: RawAxiosHeaders) => boolean;
10
10
 
11
+ type AxiosHeaderParser = (this: AxiosHeaders, value: axios.AxiosHeaderValue, header: string) => any;
12
+
11
13
  type CommonRequestHeadersList = 'Accept' | 'Content-Length' | 'User-Agent'| 'Content-Encoding' | 'Authorization';
12
14
 
13
15
  type ContentType = axios.AxiosHeaderValue | 'text/html' | 'text/plain' | 'multipart/form-data' | 'application/json' | 'application/x-www-form-urlencoded' | 'application/octet-stream';
@@ -16,18 +18,18 @@ type CommonResponseHeadersList = 'Server' | 'Content-Type' | 'Content-Length' |
16
18
 
17
19
  declare class AxiosHeaders {
18
20
  constructor(
19
- headers?: RawAxiosHeaders | AxiosHeaders
21
+ headers?: RawAxiosHeaders | AxiosHeaders | string
20
22
  );
21
23
 
22
24
  [key: string]: any;
23
25
 
24
26
  set(headerName?: string, value?: axios.AxiosHeaderValue, rewrite?: boolean | AxiosHeaderMatcher): AxiosHeaders;
25
- set(headers?: RawAxiosHeaders | AxiosHeaders, rewrite?: boolean): AxiosHeaders;
27
+ set(headers?: RawAxiosHeaders | AxiosHeaders | string, rewrite?: boolean): AxiosHeaders;
26
28
 
27
29
  get(headerName: string, parser: RegExp): RegExpExecArray | null;
28
- get(headerName: string, matcher?: true | AxiosHeaderMatcher): axios.AxiosHeaderValue;
30
+ get(headerName: string, matcher?: true | AxiosHeaderParser): axios.AxiosHeaderValue;
29
31
 
30
- has(header: string, matcher?: true | AxiosHeaderMatcher): boolean;
32
+ has(header: string, matcher?: AxiosHeaderMatcher): boolean;
31
33
 
32
34
  delete(header: string | string[], matcher?: AxiosHeaderMatcher): boolean;
33
35
 
@@ -244,10 +246,7 @@ declare namespace axios {
244
246
  interface AxiosProxyConfig {
245
247
  host: string;
246
248
  port: number;
247
- auth?: {
248
- username: string;
249
- password: string;
250
- };
249
+ auth?: AxiosBasicCredentials;
251
250
  protocol?: string;
252
251
  }
253
252
 
@@ -362,6 +361,15 @@ declare namespace axios {
362
361
 
363
362
  type AxiosAdapterConfig = AxiosAdapter | AxiosAdapterName;
364
363
 
364
+ type AddressFamily = 4 | 6 | undefined;
365
+
366
+ interface LookupAddressEntry {
367
+ address: string;
368
+ family?: AddressFamily;
369
+ }
370
+
371
+ type LookupAddress = string | LookupAddressEntry;
372
+
365
373
  interface AxiosRequestConfig<D = any> {
366
374
  url?: string;
367
375
  method?: Method | string;
@@ -403,9 +411,9 @@ declare namespace axios {
403
411
  FormData?: new (...args: any[]) => object;
404
412
  };
405
413
  formSerializer?: FormSerializerOptions;
406
- family?: 4 | 6 | undefined;
407
- lookup?: ((hostname: string, options: object, cb: (err: Error | null, address: string, family: number) => void) => void) |
408
- ((hostname: string, options: object) => Promise<[address: string, family: number] | string>);
414
+ family?: AddressFamily;
415
+ lookup?: ((hostname: string, options: object, cb: (err: Error | null, address: LookupAddress | LookupAddress[], family?: AddressFamily) => void) => void) |
416
+ ((hostname: string, options: object) => Promise<[address: LookupAddressEntry | LookupAddressEntry[], family?: AddressFamily] | LookupAddress>);
409
417
  }
410
418
 
411
419
  // Alias
@@ -523,6 +531,7 @@ declare namespace axios {
523
531
  isAxiosError<T = any, D = any>(payload: any): payload is AxiosError<T, D>;
524
532
  toFormData(sourceObj: object, targetFormData?: GenericFormData, options?: FormSerializerOptions): GenericFormData;
525
533
  formToJSON(form: GenericFormData|GenericHTMLFormElement): object;
534
+ getAdapter(adapters: AxiosAdapterConfig | AxiosAdapterConfig[] | undefined): AxiosAdapter;
526
535
  AxiosHeaders: typeof AxiosHeaders;
527
536
  }
528
537
  }
package/index.d.ts CHANGED
@@ -9,22 +9,24 @@ type MethodsHeaders = Partial<{
9
9
  [Key in Method as Lowercase<Key>]: AxiosHeaders;
10
10
  } & {common: AxiosHeaders}>;
11
11
 
12
- type AxiosHeaderMatcher = (this: AxiosHeaders, value: string, name: string, headers: RawAxiosHeaders) => boolean;
12
+ type AxiosHeaderMatcher = string | RegExp | ((this: AxiosHeaders, value: string, name: string) => boolean);
13
+
14
+ type AxiosHeaderParser = (this: AxiosHeaders, value: AxiosHeaderValue, header: string) => any;
13
15
 
14
16
  export class AxiosHeaders {
15
17
  constructor(
16
- headers?: RawAxiosHeaders | AxiosHeaders
18
+ headers?: RawAxiosHeaders | AxiosHeaders | string
17
19
  );
18
20
 
19
21
  [key: string]: any;
20
22
 
21
23
  set(headerName?: string, value?: AxiosHeaderValue, rewrite?: boolean | AxiosHeaderMatcher): AxiosHeaders;
22
- set(headers?: RawAxiosHeaders | AxiosHeaders, rewrite?: boolean): AxiosHeaders;
24
+ set(headers?: RawAxiosHeaders | AxiosHeaders | string, rewrite?: boolean): AxiosHeaders;
23
25
 
24
26
  get(headerName: string, parser: RegExp): RegExpExecArray | null;
25
- get(headerName: string, matcher?: true | AxiosHeaderMatcher): AxiosHeaderValue;
27
+ get(headerName: string, matcher?: true | AxiosHeaderParser): AxiosHeaderValue;
26
28
 
27
- has(header: string, matcher?: true | AxiosHeaderMatcher): boolean;
29
+ has(header: string, matcher?: AxiosHeaderMatcher): boolean;
28
30
 
29
31
  delete(header: string | string[], matcher?: AxiosHeaderMatcher): boolean;
30
32
 
@@ -119,10 +121,7 @@ export interface AxiosBasicCredentials {
119
121
  export interface AxiosProxyConfig {
120
122
  host: string;
121
123
  port: number;
122
- auth?: {
123
- username: string;
124
- password: string;
125
- };
124
+ auth?: AxiosBasicCredentials;
126
125
  protocol?: string;
127
126
  }
128
127
 
@@ -303,6 +302,15 @@ type AxiosAdapterName = 'xhr' | 'http' | string;
303
302
 
304
303
  type AxiosAdapterConfig = AxiosAdapter | AxiosAdapterName;
305
304
 
305
+ export type AddressFamily = 4 | 6 | undefined;
306
+
307
+ export interface LookupAddressEntry {
308
+ address: string;
309
+ family?: AddressFamily;
310
+ }
311
+
312
+ export type LookupAddress = string | LookupAddressEntry;
313
+
306
314
  export interface AxiosRequestConfig<D = any> {
307
315
  url?: string;
308
316
  method?: Method | string;
@@ -344,9 +352,9 @@ export interface AxiosRequestConfig<D = any> {
344
352
  FormData?: new (...args: any[]) => object;
345
353
  };
346
354
  formSerializer?: FormSerializerOptions;
347
- family?: 4 | 6 | undefined;
348
- lookup?: ((hostname: string, options: object, cb: (err: Error | null, address: string, family: number) => void) => void) |
349
- ((hostname: string, options: object) => Promise<[address: string, family: number] | string>);
355
+ family?: AddressFamily;
356
+ lookup?: ((hostname: string, options: object, cb: (err: Error | null, address: LookupAddress | LookupAddress[], family?: AddressFamily) => void) => void) |
357
+ ((hostname: string, options: object) => Promise<[address: LookupAddressEntry | LookupAddressEntry[], family?: AddressFamily] | LookupAddress>);
350
358
  }
351
359
 
352
360
  // Alias
@@ -512,6 +520,8 @@ export interface GenericHTMLFormElement {
512
520
  submit(): void;
513
521
  }
514
522
 
523
+ export function getAdapter(adapters: AxiosAdapterConfig | AxiosAdapterConfig[] | undefined): AxiosAdapter;
524
+
515
525
  export function toFormData(sourceObj: object, targetFormData?: GenericFormData, options?: FormSerializerOptions): GenericFormData;
516
526
 
517
527
  export function formToJSON(form: GenericFormData|GenericHTMLFormElement): object;
@@ -538,6 +548,7 @@ export interface AxiosStatic extends AxiosInstance {
538
548
  isAxiosError: typeof isAxiosError;
539
549
  toFormData: typeof toFormData;
540
550
  formToJSON: typeof formToJSON;
551
+ getAdapter: typeof getAdapter;
541
552
  CanceledError: typeof CanceledError;
542
553
  AxiosHeaders: typeof AxiosHeaders;
543
554
  }
package/index.js CHANGED
@@ -18,6 +18,7 @@ const {
18
18
  AxiosHeaders,
19
19
  HttpStatusCode,
20
20
  formToJSON,
21
+ getAdapter,
21
22
  mergeConfig
22
23
  } = axios;
23
24
 
@@ -37,5 +38,6 @@ export {
37
38
  AxiosHeaders,
38
39
  HttpStatusCode,
39
40
  formToJSON,
41
+ getAdapter,
40
42
  mergeConfig
41
43
  }
@@ -9,7 +9,7 @@ const knownAdapters = {
9
9
  }
10
10
 
11
11
  utils.forEach(knownAdapters, (fn, value) => {
12
- if(fn) {
12
+ if (fn) {
13
13
  try {
14
14
  Object.defineProperty(fn, 'name', {value});
15
15
  } catch (e) {
@@ -19,6 +19,10 @@ utils.forEach(knownAdapters, (fn, value) => {
19
19
  }
20
20
  });
21
21
 
22
+ const renderReason = (reason) => `- ${reason}`;
23
+
24
+ const isResolvedHandle = (adapter) => utils.isFunction(adapter) || adapter === null || adapter === false;
25
+
22
26
  export default {
23
27
  getAdapter: (adapters) => {
24
28
  adapters = utils.isArray(adapters) ? adapters : [adapters];
@@ -27,30 +31,44 @@ export default {
27
31
  let nameOrAdapter;
28
32
  let adapter;
29
33
 
34
+ const rejectedReasons = {};
35
+
30
36
  for (let i = 0; i < length; i++) {
31
37
  nameOrAdapter = adapters[i];
32
- if((adapter = utils.isString(nameOrAdapter) ? knownAdapters[nameOrAdapter.toLowerCase()] : nameOrAdapter)) {
38
+ let id;
39
+
40
+ adapter = nameOrAdapter;
41
+
42
+ if (!isResolvedHandle(nameOrAdapter)) {
43
+ adapter = knownAdapters[(id = String(nameOrAdapter)).toLowerCase()];
44
+
45
+ if (adapter === undefined) {
46
+ throw new AxiosError(`Unknown adapter '${id}'`);
47
+ }
48
+ }
49
+
50
+ if (adapter) {
33
51
  break;
34
52
  }
53
+
54
+ rejectedReasons[id || '#' + i] = adapter;
35
55
  }
36
56
 
37
57
  if (!adapter) {
38
- if (adapter === false) {
39
- throw new AxiosError(
40
- `Adapter ${nameOrAdapter} is not supported by the environment`,
41
- 'ERR_NOT_SUPPORT'
58
+
59
+ const reasons = Object.entries(rejectedReasons)
60
+ .map(([id, state]) => `adapter ${id} ` +
61
+ (state === false ? 'is not supported by the environment' : 'is not available in the build')
42
62
  );
43
- }
44
63
 
45
- throw new Error(
46
- utils.hasOwnProp(knownAdapters, nameOrAdapter) ?
47
- `Adapter '${nameOrAdapter}' is not available in the build` :
48
- `Unknown adapter '${nameOrAdapter}'`
49
- );
50
- }
64
+ let s = length ?
65
+ (reasons.length > 1 ? 'since :\n' + reasons.map(renderReason).join('\n') : ' ' + renderReason(reasons[0])) :
66
+ 'as no adapter specified';
51
67
 
52
- if (!utils.isFunction(adapter)) {
53
- throw new TypeError('adapter is not a function');
68
+ throw new AxiosError(
69
+ `There is no suitable adapter to dispatch the request ` + s,
70
+ 'ERR_NOT_SUPPORT'
71
+ );
54
72
  }
55
73
 
56
74
  return adapter;
@@ -144,6 +144,18 @@ const wrapAsync = (asyncExecutor) => {
144
144
  })
145
145
  };
146
146
 
147
+ const resolveFamily = ({address, family}) => {
148
+ if (!utils.isString(address)) {
149
+ throw TypeError('address must be a string');
150
+ }
151
+ return ({
152
+ address,
153
+ family: family || (address.indexOf('.') < 0 ? 6 : 4)
154
+ });
155
+ }
156
+
157
+ const buildAddressEntry = (address, family) => resolveFamily(utils.isObject(address) ? address : {address, family});
158
+
147
159
  /*eslint consistent-return:0*/
148
160
  export default isHttpAdapterSupported && function httpAdapter(config) {
149
161
  return wrapAsync(async function dispatchHttpRequest(resolve, reject, onDone) {
@@ -154,15 +166,16 @@ export default isHttpAdapterSupported && function httpAdapter(config) {
154
166
  let rejected = false;
155
167
  let req;
156
168
 
157
- if (lookup && utils.isAsyncFn(lookup)) {
158
- lookup = callbackify(lookup, (entry) => {
159
- if(utils.isString(entry)) {
160
- entry = [entry, entry.indexOf('.') < 0 ? 6 : 4]
161
- } else if (!utils.isArray(entry)) {
162
- throw new TypeError('lookup async function must return an array [ip: string, family: number]]')
163
- }
164
- return entry;
165
- })
169
+ if (lookup) {
170
+ const _lookup = callbackify(lookup, (value) => utils.isArray(value) ? value : [value]);
171
+ // hotfix to support opt.all option which is required for node 20.x
172
+ lookup = (hostname, opt, cb) => {
173
+ _lookup(hostname, opt, (err, arg0, arg1) => {
174
+ const addresses = utils.isArray(arg0) ? arg0.map(addr => buildAddressEntry(addr)) : [buildAddressEntry(arg0, arg1)];
175
+
176
+ opt.all ? cb(err, addresses) : cb(err, addresses[0].address, addresses[0].family);
177
+ });
178
+ }
166
179
  }
167
180
 
168
181
  // temporary internal emitter until the AxiosRequest class will be implemented
@@ -391,11 +404,13 @@ export default isHttpAdapterSupported && function httpAdapter(config) {
391
404
  auth,
392
405
  protocol,
393
406
  family,
394
- lookup,
395
407
  beforeRedirect: dispatchBeforeRedirect,
396
408
  beforeRedirects: {}
397
409
  };
398
410
 
411
+ // cacheable-lookup integration hotfix
412
+ !utils.isUndefined(lookup) && (options.lookup = lookup);
413
+
399
414
  if (config.socketPath) {
400
415
  options.socketPath = config.socketPath;
401
416
  } else {
@@ -469,7 +484,7 @@ export default isHttpAdapterSupported && function httpAdapter(config) {
469
484
  delete res.headers['content-encoding'];
470
485
  }
471
486
 
472
- switch (res.headers['content-encoding']) {
487
+ switch ((res.headers['content-encoding'] || '').toLowerCase()) {
473
488
  /*eslint default-case:0*/
474
489
  case 'gzip':
475
490
  case 'x-gzip':
@@ -565,7 +580,7 @@ export default isHttpAdapterSupported && function httpAdapter(config) {
565
580
  }
566
581
  response.data = responseData;
567
582
  } catch (err) {
568
- reject(AxiosError.from(err, null, config, response.request, response));
583
+ return reject(AxiosError.from(err, null, config, response.request, response));
569
584
  }
570
585
  settle(resolve, reject, response);
571
586
  });
@@ -602,7 +617,7 @@ export default isHttpAdapterSupported && function httpAdapter(config) {
602
617
  // This is forcing a int timeout to avoid problems if the `req` interface doesn't handle other types.
603
618
  const timeout = parseInt(config.timeout, 10);
604
619
 
605
- if (isNaN(timeout)) {
620
+ if (Number.isNaN(timeout)) {
606
621
  reject(new AxiosError(
607
622
  'error trying to parse `config.timeout` to int',
608
623
  AxiosError.ERR_BAD_OPTION_VALUE,
@@ -61,11 +61,16 @@ export default isXHRAdapterSupported && function (config) {
61
61
  }
62
62
  }
63
63
 
64
+ let contentType;
65
+
64
66
  if (utils.isFormData(requestData)) {
65
67
  if (platform.isStandardBrowserEnv || platform.isStandardBrowserWebWorkerEnv) {
66
68
  requestHeaders.setContentType(false); // Let the browser set it
67
- } else {
68
- requestHeaders.setContentType('multipart/form-data;', false); // mobile/desktop app frameworks
69
+ } else if(!requestHeaders.getContentType(/^\s*multipart\/form-data/)){
70
+ requestHeaders.setContentType('multipart/form-data'); // mobile/desktop app frameworks
71
+ } else if(utils.isString(contentType = requestHeaders.getContentType())){
72
+ // fix semicolon duplication issue for ReactNative FormData implementation
73
+ requestHeaders.setContentType(contentType.replace(/^\s*(multipart\/form-data);+/, '$1'))
69
74
  }
70
75
  }
71
76
 
@@ -183,8 +188,8 @@ export default isXHRAdapterSupported && function (config) {
183
188
  // Specifically not if we're in a web worker, or react-native.
184
189
  if (platform.isStandardBrowserEnv) {
185
190
  // Add xsrf header
186
- const xsrfValue = (config.withCredentials || isURLSameOrigin(fullPath))
187
- && config.xsrfCookieName && cookies.read(config.xsrfCookieName);
191
+ // regarding CVE-2023-45857 config.withCredentials condition was removed temporarily
192
+ const xsrfValue = isURLSameOrigin(fullPath) && config.xsrfCookieName && cookies.read(config.xsrfCookieName);
188
193
 
189
194
  if (xsrfValue) {
190
195
  requestHeaders.set(config.xsrfHeaderName, xsrfValue);
package/lib/axios.js CHANGED
@@ -15,6 +15,7 @@ import AxiosError from './core/AxiosError.js';
15
15
  import spread from './helpers/spread.js';
16
16
  import isAxiosError from './helpers/isAxiosError.js';
17
17
  import AxiosHeaders from "./core/AxiosHeaders.js";
18
+ import adapters from './adapters/adapters.js';
18
19
  import HttpStatusCode from './helpers/HttpStatusCode.js';
19
20
 
20
21
  /**
@@ -78,6 +79,8 @@ axios.AxiosHeaders = AxiosHeaders;
78
79
 
79
80
  axios.formToJSON = thing => formDataToJSON(utils.isHTMLForm(thing) ? new FormData(thing) : thing);
80
81
 
82
+ axios.getAdapter = adapters.getAdapter;
83
+
81
84
  axios.HttpStatusCode = HttpStatusCode;
82
85
 
83
86
  axios.default = axios;
package/lib/core/Axios.js CHANGED
@@ -73,15 +73,13 @@ class Axios {
73
73
  // Set config.method
74
74
  config.method = (config.method || this.defaults.method || 'get').toLowerCase();
75
75
 
76
- let contextHeaders;
77
-
78
76
  // Flatten headers
79
- contextHeaders = headers && utils.merge(
77
+ let contextHeaders = headers && utils.merge(
80
78
  headers.common,
81
79
  headers[config.method]
82
80
  );
83
81
 
84
- contextHeaders && utils.forEach(
82
+ headers && utils.forEach(
85
83
  ['delete', 'get', 'head', 'post', 'put', 'patch', 'common'],
86
84
  (method) => {
87
85
  delete headers[method];
@@ -282,7 +282,17 @@ class AxiosHeaders {
282
282
 
283
283
  AxiosHeaders.accessor(['Content-Type', 'Content-Length', 'Accept', 'Accept-Encoding', 'User-Agent', 'Authorization']);
284
284
 
285
- utils.freezeMethods(AxiosHeaders.prototype);
285
+ // reserved names hotfix
286
+ utils.reduceDescriptors(AxiosHeaders.prototype, ({value}, key) => {
287
+ let mapped = key[0].toUpperCase() + key.slice(1); // map `set` => `Set`
288
+ return {
289
+ get: () => value,
290
+ set(headerValue) {
291
+ this[mapped] = headerValue;
292
+ }
293
+ }
294
+ });
295
+
286
296
  utils.freezeMethods(AxiosHeaders);
287
297
 
288
298
  export default AxiosHeaders;
@@ -8,10 +8,6 @@ import toURLEncodedForm from '../helpers/toURLEncodedForm.js';
8
8
  import platform from '../platform/index.js';
9
9
  import formDataToJSON from '../helpers/formDataToJSON.js';
10
10
 
11
- const DEFAULT_CONTENT_TYPE = {
12
- 'Content-Type': undefined
13
- };
14
-
15
11
  /**
16
12
  * It takes a string, tries to parse it, and if it fails, it returns the stringified version
17
13
  * of the input
@@ -150,17 +146,14 @@ const defaults = {
150
146
 
151
147
  headers: {
152
148
  common: {
153
- 'Accept': 'application/json, text/plain, */*'
149
+ 'Accept': 'application/json, text/plain, */*',
150
+ 'Content-Type': undefined
154
151
  }
155
152
  }
156
153
  };
157
154
 
158
- utils.forEach(['delete', 'get', 'head'], function forEachMethodNoData(method) {
155
+ utils.forEach(['delete', 'get', 'head', 'post', 'put', 'patch'], (method) => {
159
156
  defaults.headers[method] = {};
160
157
  });
161
158
 
162
- utils.forEach(['post', 'put', 'patch'], function forEachMethodWithData(method) {
163
- defaults.headers[method] = utils.merge(DEFAULT_CONTENT_TYPE);
164
- });
165
-
166
159
  export default defaults;
package/lib/env/data.js CHANGED
@@ -1 +1 @@
1
- export const VERSION = "1.4.0";
1
+ export const VERSION = "1.6.0";
package/lib/utils.js CHANGED
@@ -540,8 +540,9 @@ const reduceDescriptors = (obj, reducer) => {
540
540
  const reducedDescriptors = {};
541
541
 
542
542
  forEach(descriptors, (descriptor, name) => {
543
- if (reducer(descriptor, name, obj) !== false) {
544
- reducedDescriptors[name] = descriptor;
543
+ let ret;
544
+ if ((ret = reducer(descriptor, name, obj)) !== false) {
545
+ reducedDescriptors[name] = ret || descriptor;
545
546
  }
546
547
  });
547
548
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "axios",
3
- "version": "1.4.0",
3
+ "version": "1.6.0",
4
4
  "description": "Promise based HTTP client for the browser and node.js",
5
5
  "main": "index.js",
6
6
  "exports": {
@@ -18,6 +18,8 @@
18
18
  "default": "./index.js"
19
19
  }
20
20
  },
21
+ "./lib/adapters/http.js": "./lib/adapters/http.js",
22
+ "./lib/adapters/xhr.js": "./lib/adapters/xhr.js",
21
23
  "./unsafe/*": "./lib/*",
22
24
  "./unsafe/core/settle.js": "./lib/core/settle.js",
23
25
  "./unsafe/core/buildFullPath.js": "./lib/core/buildFullPath.js",