axios 1.10.0 → 1.12.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.
@@ -104,15 +104,18 @@ export default isXHRAdapterSupported && function (config) {
104
104
  };
105
105
 
106
106
  // Handle low level network errors
107
- request.onerror = function handleError() {
108
- // Real errors are hidden from us by the browser
109
- // onerror should only fire if it's a network error
110
- reject(new AxiosError('Network Error', AxiosError.ERR_NETWORK, config, request));
111
-
112
- // Clean up request
113
- request = null;
107
+ request.onerror = function handleError(event) {
108
+ // Browsers deliver a ProgressEvent in XHR onerror
109
+ // (message may be empty; when present, surface it)
110
+ // See https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/error_event
111
+ const msg = event && event.message ? event.message : 'Network Error';
112
+ const err = new AxiosError(msg, AxiosError.ERR_NETWORK, config, request);
113
+ // attach the underlying event for consumers who want details
114
+ err.event = event || null;
115
+ reject(err);
116
+ request = null;
114
117
  };
115
-
118
+
116
119
  // Handle timeout
117
120
  request.ontimeout = function handleTimeout() {
118
121
  let timeoutErrorMessage = _config.timeout ? 'timeout of ' + _config.timeout + 'ms exceeded' : 'timeout exceeded';
package/lib/core/Axios.js CHANGED
@@ -153,8 +153,8 @@ class Axios {
153
153
 
154
154
  if (!synchronousRequestInterceptors) {
155
155
  const chain = [dispatchRequest.bind(this), undefined];
156
- chain.unshift.apply(chain, requestInterceptorChain);
157
- chain.push.apply(chain, responseInterceptorChain);
156
+ chain.unshift(...requestInterceptorChain);
157
+ chain.push(...responseInterceptorChain);
158
158
  len = chain.length;
159
159
 
160
160
  promise = Promise.resolve(config);
@@ -89,11 +89,18 @@ AxiosError.from = (error, code, config, request, response, customProps) => {
89
89
  return prop !== 'isAxiosError';
90
90
  });
91
91
 
92
- AxiosError.call(axiosError, error.message, code, config, request, response);
92
+ const msg = error && error.message ? error.message : 'Error';
93
93
 
94
- axiosError.cause = error;
94
+ // Prefer explicit code; otherwise copy the low-level error's code (e.g. ECONNREFUSED)
95
+ const errCode = code == null && error ? error.code : code;
96
+ AxiosError.call(axiosError, msg, errCode, config, request, response);
95
97
 
96
- axiosError.name = error.name;
98
+ // Chain the original error on the standard field; non-enumerable to avoid JSON noise
99
+ if (error && axiosError.cause == null) {
100
+ Object.defineProperty(axiosError, 'cause', { value: error, configurable: true });
101
+ }
102
+
103
+ axiosError.name = (error && error.name) || 'Error';
97
104
 
98
105
  customProps && Object.assign(axiosError, customProps);
99
106
 
@@ -46,7 +46,7 @@ export default function dispatchRequest(config) {
46
46
  config.headers.setContentType('application/x-www-form-urlencoded', false);
47
47
  }
48
48
 
49
- const adapter = adapters.getAdapter(config.adapter || defaults.adapter);
49
+ const adapter = adapters.getAdapter(config.adapter || defaults.adapter, config);
50
50
 
51
51
  return adapter(config).then(function onAdapterResolution(response) {
52
52
  throwIfCancellationRequested(config);
@@ -96,7 +96,7 @@ export default function mergeConfig(config1, config2) {
96
96
  headers: (a, b , prop) => mergeDeepProperties(headersToObject(a), headersToObject(b),prop, true)
97
97
  };
98
98
 
99
- utils.forEach(Object.keys(Object.assign({}, config1, config2)), function computeConfigValue(prop) {
99
+ utils.forEach(Object.keys({...config1, ...config2}), function computeConfigValue(prop) {
100
100
  const merge = mergeMap[prop] || mergeDeepProperties;
101
101
  const configValue = merge(config1[prop], config2[prop], prop);
102
102
  (utils.isUndefined(configValue) && merge !== mergeDirectKeys) || (config[prop] = configValue);
@@ -111,7 +111,7 @@ const defaults = {
111
111
  const strictJSONParsing = !silentJSONParsing && JSONRequested;
112
112
 
113
113
  try {
114
- return JSON.parse(data);
114
+ return JSON.parse(data, this.parseReviver);
115
115
  } catch (e) {
116
116
  if (strictJSONParsing) {
117
117
  if (e.name === 'SyntaxError') {
package/lib/env/data.js CHANGED
@@ -1 +1 @@
1
- export const VERSION = "1.10.0";
1
+ export const VERSION = "1.12.0";
@@ -16,9 +16,7 @@ function encode(val) {
16
16
  replace(/%3A/gi, ':').
17
17
  replace(/%24/g, '$').
18
18
  replace(/%2C/gi, ',').
19
- replace(/%20/g, '+').
20
- replace(/%5B/gi, '[').
21
- replace(/%5D/gi, ']');
19
+ replace(/%20/g, '+');
22
20
  }
23
21
 
24
22
  /**
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Estimate decoded byte length of a data:// URL *without* allocating large buffers.
3
+ * - For base64: compute exact decoded size using length and padding;
4
+ * handle %XX at the character-count level (no string allocation).
5
+ * - For non-base64: use UTF-8 byteLength of the encoded body as a safe upper bound.
6
+ *
7
+ * @param {string} url
8
+ * @returns {number}
9
+ */
10
+ export default function estimateDataURLDecodedBytes(url) {
11
+ if (!url || typeof url !== 'string') return 0;
12
+ if (!url.startsWith('data:')) return 0;
13
+
14
+ const comma = url.indexOf(',');
15
+ if (comma < 0) return 0;
16
+
17
+ const meta = url.slice(5, comma);
18
+ const body = url.slice(comma + 1);
19
+ const isBase64 = /;base64/i.test(meta);
20
+
21
+ if (isBase64) {
22
+ let effectiveLen = body.length;
23
+ const len = body.length; // cache length
24
+
25
+ for (let i = 0; i < len; i++) {
26
+ if (body.charCodeAt(i) === 37 /* '%' */ && i + 2 < len) {
27
+ const a = body.charCodeAt(i + 1);
28
+ const b = body.charCodeAt(i + 2);
29
+ const isHex =
30
+ ((a >= 48 && a <= 57) || (a >= 65 && a <= 70) || (a >= 97 && a <= 102)) &&
31
+ ((b >= 48 && b <= 57) || (b >= 65 && b <= 70) || (b >= 97 && b <= 102));
32
+
33
+ if (isHex) {
34
+ effectiveLen -= 2;
35
+ i += 2;
36
+ }
37
+ }
38
+ }
39
+
40
+ let pad = 0;
41
+ let idx = len - 1;
42
+
43
+ const tailIsPct3D = (j) =>
44
+ j >= 2 &&
45
+ body.charCodeAt(j - 2) === 37 && // '%'
46
+ body.charCodeAt(j - 1) === 51 && // '3'
47
+ (body.charCodeAt(j) === 68 || body.charCodeAt(j) === 100); // 'D' or 'd'
48
+
49
+ if (idx >= 0) {
50
+ if (body.charCodeAt(idx) === 61 /* '=' */) {
51
+ pad++;
52
+ idx--;
53
+ } else if (tailIsPct3D(idx)) {
54
+ pad++;
55
+ idx -= 3;
56
+ }
57
+ }
58
+
59
+ if (pad === 1 && idx >= 0) {
60
+ if (body.charCodeAt(idx) === 61 /* '=' */) {
61
+ pad++;
62
+ } else if (tailIsPct3D(idx)) {
63
+ pad++;
64
+ }
65
+ }
66
+
67
+ const groups = Math.floor(effectiveLen / 4);
68
+ const bytes = groups * 3 - (pad || 0);
69
+ return bytes > 0 ? bytes : 0;
70
+ }
71
+
72
+ return Buffer.byteLength(body, 'utf8');
73
+ }
@@ -10,7 +10,7 @@ import buildURL from "./buildURL.js";
10
10
  export default (config) => {
11
11
  const newConfig = mergeConfig({}, config);
12
12
 
13
- let {data, withXSRFToken, xsrfHeaderName, xsrfCookieName, headers, auth} = newConfig;
13
+ let { data, withXSRFToken, xsrfHeaderName, xsrfCookieName, headers, auth } = newConfig;
14
14
 
15
15
  newConfig.headers = headers = AxiosHeaders.from(headers);
16
16
 
@@ -23,17 +23,21 @@ export default (config) => {
23
23
  );
24
24
  }
25
25
 
26
- let contentType;
27
-
28
26
  if (utils.isFormData(data)) {
29
27
  if (platform.hasStandardBrowserEnv || platform.hasStandardBrowserWebWorkerEnv) {
30
- headers.setContentType(undefined); // Let the browser set it
31
- } else if ((contentType = headers.getContentType()) !== false) {
32
- // fix semicolon duplication issue for ReactNative FormData implementation
33
- const [type, ...tokens] = contentType ? contentType.split(';').map(token => token.trim()).filter(Boolean) : [];
34
- headers.setContentType([type || 'multipart/form-data', ...tokens].join('; '));
28
+ headers.setContentType(undefined); // browser handles it
29
+ } else if (utils.isFunction(data.getHeaders)) {
30
+ // Node.js FormData (like form-data package)
31
+ const formHeaders = data.getHeaders();
32
+ // Only set safe headers to avoid overwriting security headers
33
+ const allowedHeaders = ['content-type', 'content-length'];
34
+ Object.entries(formHeaders).forEach(([key, val]) => {
35
+ if (allowedHeaders.includes(key.toLowerCase())) {
36
+ headers.set(key, val);
37
+ }
38
+ });
35
39
  }
36
- }
40
+ }
37
41
 
38
42
  // Add xsrf header
39
43
  // This is only done if running in a standard browser environment.
@@ -17,7 +17,7 @@ function throttle(fn, freq) {
17
17
  clearTimeout(timer);
18
18
  timer = null;
19
19
  }
20
- fn.apply(null, args);
20
+ fn(...args);
21
21
  }
22
22
 
23
23
  const throttled = (...args) => {
@@ -5,7 +5,7 @@ import toFormData from './toFormData.js';
5
5
  import platform from '../platform/index.js';
6
6
 
7
7
  export default function toURLEncodedForm(data, options) {
8
- return toFormData(data, new platform.classes.URLSearchParams(), Object.assign({
8
+ return toFormData(data, new platform.classes.URLSearchParams(), {
9
9
  visitor: function(value, key, path, helpers) {
10
10
  if (platform.isNode && utils.isBuffer(value)) {
11
11
  this.append(key, value.toString('base64'));
@@ -13,6 +13,7 @@ export default function toURLEncodedForm(data, options) {
13
13
  }
14
14
 
15
15
  return helpers.defaultVisitor.apply(this, arguments);
16
- }
17
- }, options));
16
+ },
17
+ ...options
18
+ });
18
19
  }
package/lib/utils.js CHANGED
@@ -136,6 +136,27 @@ const isPlainObject = (val) => {
136
136
  return (prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null) && !(toStringTag in val) && !(iterator in val);
137
137
  }
138
138
 
139
+ /**
140
+ * Determine if a value is an empty object (safely handles Buffers)
141
+ *
142
+ * @param {*} val The value to test
143
+ *
144
+ * @returns {boolean} True if value is an empty object, otherwise false
145
+ */
146
+ const isEmptyObject = (val) => {
147
+ // Early return for non-objects or Buffers to prevent RangeError
148
+ if (!isObject(val) || isBuffer(val)) {
149
+ return false;
150
+ }
151
+
152
+ try {
153
+ return Object.keys(val).length === 0 && Object.getPrototypeOf(val) === Object.prototype;
154
+ } catch (e) {
155
+ // Fallback for any other objects that might cause RangeError with Object.keys()
156
+ return false;
157
+ }
158
+ }
159
+
139
160
  /**
140
161
  * Determine if a value is a Date
141
162
  *
@@ -258,6 +279,11 @@ function forEach(obj, fn, {allOwnKeys = false} = {}) {
258
279
  fn.call(null, obj[i], i, obj);
259
280
  }
260
281
  } else {
282
+ // Buffer check
283
+ if (isBuffer(obj)) {
284
+ return;
285
+ }
286
+
261
287
  // Iterate over object keys
262
288
  const keys = allOwnKeys ? Object.getOwnPropertyNames(obj) : Object.keys(obj);
263
289
  const len = keys.length;
@@ -271,6 +297,10 @@ function forEach(obj, fn, {allOwnKeys = false} = {}) {
271
297
  }
272
298
 
273
299
  function findKey(obj, key) {
300
+ if (isBuffer(obj)){
301
+ return null;
302
+ }
303
+
274
304
  key = key.toLowerCase();
275
305
  const keys = Object.keys(obj);
276
306
  let i = keys.length;
@@ -311,7 +341,7 @@ const isContextDefined = (context) => !isUndefined(context) && context !== _glob
311
341
  * @returns {Object} Result of all merge properties
312
342
  */
313
343
  function merge(/* obj1, obj2, obj3, ... */) {
314
- const {caseless} = isContextDefined(this) && this || {};
344
+ const {caseless, skipUndefined} = isContextDefined(this) && this || {};
315
345
  const result = {};
316
346
  const assignValue = (val, key) => {
317
347
  const targetKey = caseless && findKey(result, key) || key;
@@ -322,7 +352,9 @@ function merge(/* obj1, obj2, obj3, ... */) {
322
352
  } else if (isArray(val)) {
323
353
  result[targetKey] = val.slice();
324
354
  } else {
325
- result[targetKey] = val;
355
+ if (!skipUndefined || !isUndefined(val)) {
356
+ result[targetKey] = val;
357
+ }
326
358
  }
327
359
  }
328
360
 
@@ -603,6 +635,8 @@ const toFiniteNumber = (value, defaultValue) => {
603
635
  return value != null && Number.isFinite(value = +value) ? value : defaultValue;
604
636
  }
605
637
 
638
+
639
+
606
640
  /**
607
641
  * If the thing is a FormData object, return true, otherwise return false.
608
642
  *
@@ -624,6 +658,11 @@ const toJSONObject = (obj) => {
624
658
  return;
625
659
  }
626
660
 
661
+ //Buffer check
662
+ if (isBuffer(source)) {
663
+ return source;
664
+ }
665
+
627
666
  if(!('toJSON' in source)) {
628
667
  stack[i] = source;
629
668
  const target = isArray(source) ? [] : {};
@@ -695,6 +734,7 @@ export default {
695
734
  isBoolean,
696
735
  isObject,
697
736
  isPlainObject,
737
+ isEmptyObject,
698
738
  isReadableStream,
699
739
  isRequest,
700
740
  isResponse,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "axios",
3
- "version": "1.10.0",
3
+ "version": "1.12.0",
4
4
  "description": "Promise based HTTP client for the browser and node.js",
5
5
  "main": "index.js",
6
6
  "exports": {
@@ -33,7 +33,9 @@
33
33
  "./unsafe/adapters/http.js": "./lib/adapters/http.js",
34
34
  "./unsafe/adapters/xhr.js": "./lib/adapters/xhr.js",
35
35
  "./unsafe/utils.js": "./lib/utils.js",
36
- "./package.json": "./package.json"
36
+ "./package.json": "./package.json",
37
+ "./dist/browser/axios.cjs": "./dist/browser/axios.cjs",
38
+ "./dist/node/axios.cjs": "./dist/node/axios.cjs"
37
39
  },
38
40
  "type": "module",
39
41
  "types": "index.d.ts",
@@ -49,7 +51,7 @@
49
51
  "test:build:version": "node ./bin/check-build-version.js",
50
52
  "start": "node ./sandbox/server.js",
51
53
  "preversion": "gulp version",
52
- "version": "npm run build && git add dist && git add package.json",
54
+ "version": "npm run build && git add package.json",
53
55
  "prepublishOnly": "npm run test:build:version",
54
56
  "postpublish": "git push && git push --tags",
55
57
  "build": "gulp clear && cross-env NODE_ENV=production rollup -c -m",
@@ -89,6 +91,7 @@
89
91
  "@commitlint/cli": "^17.8.1",
90
92
  "@commitlint/config-conventional": "^17.8.1",
91
93
  "@release-it/conventional-changelog": "^5.1.1",
94
+ "@rollup/plugin-alias": "^5.1.0",
92
95
  "@rollup/plugin-babel": "^5.3.1",
93
96
  "@rollup/plugin-commonjs": "^15.1.0",
94
97
  "@rollup/plugin-json": "^4.1.0",
@@ -110,7 +113,6 @@
110
113
  "fs-extra": "^10.1.0",
111
114
  "get-stream": "^3.0.0",
112
115
  "gulp": "^4.0.2",
113
- "gzip-size": "^7.0.0",
114
116
  "handlebars": "^4.7.8",
115
117
  "husky": "^8.0.3",
116
118
  "istanbul-instrumenter-loader": "^3.0.1",
@@ -129,6 +131,7 @@
129
131
  "minimist": "^1.2.8",
130
132
  "mocha": "^10.3.0",
131
133
  "multer": "^1.4.4",
134
+ "pacote": "^20.0.0",
132
135
  "pretty-bytes": "^6.1.1",
133
136
  "release-it": "^15.11.0",
134
137
  "rollup": "^2.79.1",
@@ -138,9 +141,9 @@
138
141
  "sinon": "^4.5.0",
139
142
  "stream-throttle": "^0.1.3",
140
143
  "string-replace-async": "^3.0.2",
144
+ "tar-stream": "^3.1.7",
141
145
  "terser-webpack-plugin": "^4.2.3",
142
- "typescript": "^4.9.5",
143
- "@rollup/plugin-alias": "^5.1.0"
146
+ "typescript": "^4.9.5"
144
147
  },
145
148
  "browser": {
146
149
  "./lib/adapters/http.js": "./lib/helpers/null.js",
@@ -157,7 +160,7 @@
157
160
  "typings": "./index.d.ts",
158
161
  "dependencies": {
159
162
  "follow-redirects": "^1.15.6",
160
- "form-data": "^4.0.0",
163
+ "form-data": "^4.0.4",
161
164
  "proxy-from-env": "^1.1.0"
162
165
  },
163
166
  "bundlesize": [
@@ -176,10 +179,10 @@
176
179
  "Justin Beckwith (https://github.com/JustinBeckwith)",
177
180
  "Martti Laine (https://github.com/codeclown)",
178
181
  "Xianming Zhong (https://github.com/chinesedfan)",
179
- "Rikki Gibson (https://github.com/RikkiGibson)",
180
182
  "Remco Haszing (https://github.com/remcohaszing)",
181
- "Yasu Flores (https://github.com/yasuf)",
182
- "Ben Carp (https://github.com/carpben)"
183
+ "Rikki Gibson (https://github.com/RikkiGibson)",
184
+ "Willian Agostini (https://github.com/WillianAgostini)",
185
+ "Yasu Flores (https://github.com/yasuf)"
183
186
  ],
184
187
  "sideEffects": false,
185
188
  "release-it": {
@@ -208,8 +211,8 @@
208
211
  },
209
212
  "hooks": {
210
213
  "before:init": "npm test",
211
- "after:bump": "gulp version --bump ${version} && npm run build && npm run test:build:version && git add ./dist && git add ./package-lock.json",
212
- "before:release": "npm run release:changelog:fix",
214
+ "after:bump": "gulp version --bump ${version} && npm run build && npm run test:build:version",
215
+ "before:release": "npm run release:changelog:fix && git add ./package-lock.json",
213
216
  "after:release": "echo Successfully released ${name} v${version} to ${repo.repository}."
214
217
  }
215
218
  },