axios 1.18.1 → 1.19.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.
@@ -1,11 +1,9 @@
1
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: compute the exact percent-decoded UTF-8 byte length.
6
- *
7
- * @param {string} url
8
- * @returns {number}
2
+ * Estimate data: URL byte lengths *without* allocating large buffers.
3
+ * - Fetch percent-decodes a base64 body before decoding it.
4
+ * - Node's Buffer.from(body, 'base64') sizes its backing allocation from the
5
+ * raw body, including ignored characters and content after padding.
6
+ * - Non-base64 data is percent-decoded and then encoded as UTF-8.
9
7
  */
10
8
  const isHexDigit = (charCode) =>
11
9
  (charCode >= 48 && charCode <= 57) ||
@@ -15,7 +13,89 @@ const isHexDigit = (charCode) =>
15
13
  const isPercentEncodedByte = (str, i, len) =>
16
14
  i + 2 < len && isHexDigit(str.charCodeAt(i + 1)) && isHexDigit(str.charCodeAt(i + 2));
17
15
 
18
- export default function estimateDataURLDecodedBytes(url) {
16
+ const hexValue = (charCode) => (charCode <= 57 ? charCode - 48 : (charCode & 0xdf) - 55);
17
+
18
+ const isBase64Char = (charCode) =>
19
+ (charCode >= 65 && charCode <= 90) || // A-Z
20
+ (charCode >= 97 && charCode <= 122) || // a-z
21
+ (charCode >= 48 && charCode <= 57) || // 0-9
22
+ charCode === 43 || // +
23
+ charCode === 47 || // /
24
+ charCode === 45 || // - (base64url)
25
+ charCode === 95; // _ (base64url)
26
+
27
+ const isBase64Whitespace = (charCode) =>
28
+ charCode === 9 || charCode === 10 || charCode === 12 || charCode === 13 || charCode === 32;
29
+
30
+ const base64Bytes = (significant) => {
31
+ const groups = Math.floor(significant / 4);
32
+ const remainder = significant % 4;
33
+ return groups * 3 + (remainder === 2 ? 1 : remainder === 3 ? 2 : 0);
34
+ };
35
+
36
+ // Buffer.byteLength(body, 'base64') uses the raw string length as an allocation
37
+ // upper bound even when Buffer.from later ignores characters or stops at '='.
38
+ const estimateBase64BufferAllocation = (body) => {
39
+ const len = body.length;
40
+ let padding = 0;
41
+
42
+ if (len > 0 && body.charCodeAt(len - 1) === 61 /* '=' */) {
43
+ padding++;
44
+
45
+ if (len > 1 && body.charCodeAt(len - 2) === 61 /* '=' */) {
46
+ padding++;
47
+ }
48
+ }
49
+
50
+ return Math.floor(((len - padding) * 3) / 4);
51
+ };
52
+
53
+ const estimatePercentDecodedBase64Bytes = (body) => {
54
+ const len = body.length;
55
+ let significant = 0;
56
+ let padding = 0;
57
+ let invalid = false;
58
+
59
+ for (let i = 0; i < len; i++) {
60
+ let code = body.charCodeAt(i);
61
+
62
+ if (code === 37 /* '%' */ && isPercentEncodedByte(body, i, len)) {
63
+ code = hexValue(body.charCodeAt(i + 1)) * 16 + hexValue(body.charCodeAt(i + 2));
64
+ i += 2;
65
+ }
66
+
67
+ if (isBase64Whitespace(code)) {
68
+ continue;
69
+ }
70
+
71
+ if (code === 61 /* '=' */) {
72
+ padding++;
73
+ continue;
74
+ }
75
+
76
+ if (!isBase64Char(code) || padding > 0) {
77
+ invalid = true;
78
+ continue;
79
+ }
80
+
81
+ significant++;
82
+ }
83
+
84
+ // Fetch rejects malformed forgiving-base64 input. Returning the raw-size
85
+ // allocation bound keeps that invalid input from becoming a pre-check bypass.
86
+ if (
87
+ invalid ||
88
+ padding > 2 ||
89
+ (padding > 0 && (significant + padding) % 4 !== 0) ||
90
+ significant % 4 === 1
91
+ ) {
92
+ return estimateBase64BufferAllocation(body);
93
+ }
94
+
95
+ return base64Bytes(significant);
96
+ };
97
+
98
+ const estimateDataURLBytes = (url, estimateBase64) => {
19
99
  if (!url || typeof url !== 'string') return 0;
20
100
  if (!url.startsWith('data:')) return 0;
21
101
 
@@ -27,52 +107,7 @@ export default function estimateDataURLDecodedBytes(url) {
27
107
  const isBase64 = /;base64/i.test(meta);
28
108
 
29
109
  if (isBase64) {
30
- let effectiveLen = body.length;
31
- const len = body.length; // cache length
32
-
33
- for (let i = 0; i < len; i++) {
34
- if (body.charCodeAt(i) === 37 /* '%' */ && i + 2 < len) {
35
- const a = body.charCodeAt(i + 1);
36
- const b = body.charCodeAt(i + 2);
37
- const isHex = isHexDigit(a) && isHexDigit(b);
38
-
39
- if (isHex) {
40
- effectiveLen -= 2;
41
- i += 2;
42
- }
43
- }
44
- }
45
-
46
- let pad = 0;
47
- let idx = len - 1;
48
-
49
- const tailIsPct3D = (j) =>
50
- j >= 2 &&
51
- body.charCodeAt(j - 2) === 37 && // '%'
52
- body.charCodeAt(j - 1) === 51 && // '3'
53
- (body.charCodeAt(j) === 68 || body.charCodeAt(j) === 100); // 'D' or 'd'
54
-
55
- if (idx >= 0) {
56
- if (body.charCodeAt(idx) === 61 /* '=' */) {
57
- pad++;
58
- idx--;
59
- } else if (tailIsPct3D(idx)) {
60
- pad++;
61
- idx -= 3;
62
- }
63
- }
64
-
65
- if (pad === 1 && idx >= 0) {
66
- if (body.charCodeAt(idx) === 61 /* '=' */) {
67
- pad++;
68
- } else if (tailIsPct3D(idx)) {
69
- pad++;
70
- }
71
- }
72
-
73
- const groups = Math.floor(effectiveLen / 4);
74
- const bytes = groups * 3 - (pad || 0);
75
- return bytes > 0 ? bytes : 0;
110
+ return estimateBase64(body);
76
111
  }
77
112
 
78
113
  // Compute UTF-8 byte length directly from UTF-16 code units without allocating
@@ -102,4 +137,30 @@ export default function estimateDataURLDecodedBytes(url) {
102
137
  }
103
138
  }
104
139
  return bytes;
140
+ };
141
+
142
+ /**
143
+ * Estimate the percent-decoded payload size used by Fetch data: URLs.
144
+ *
145
+ * @param {string} url
146
+ * @returns {number}
147
+ */
148
+ export default function estimateDataURLDecodedBytes(url) {
149
+ // Fetch removes URL fragments before processing a data: URL.
150
+ const fragmentIndex = typeof url === 'string' ? url.indexOf('#') : -1;
151
+
152
+ return estimateDataURLBytes(
153
+ fragmentIndex === -1 ? url : url.slice(0, fragmentIndex),
154
+ estimatePercentDecodedBase64Bytes
155
+ );
156
+ }
157
+
158
+ /**
159
+ * Estimate the Buffer backing allocation used by Node's raw base64 decoder.
160
+ *
161
+ * @param {string} url
162
+ * @returns {number}
163
+ */
164
+ export function estimateDataURLBufferAllocation(url) {
165
+ return estimateDataURLBytes(url, estimateBase64BufferAllocation);
105
166
  }
@@ -23,12 +23,18 @@ function throwIfDepthExceeded(index) {
23
23
  * @returns An array of strings.
24
24
  */
25
25
  function parsePropPath(name) {
26
- // foo[x][y][z]
27
- // foo.x.y.z
28
- // foo-x-y-z
29
- // foo x y z
26
+ // foo[x][y][z] -> ['foo', 'x', 'y', 'z']
27
+ // foo.x.y.z -> ['foo', 'x', 'y', 'z']
28
+ // A path is split on `.` and on `[...]` groups. A segment — whether written
29
+ // in dot notation or captured inside brackets — may contain any character
30
+ // except `.`, `[` and `]`, so a key like `user-name` or `user name` is kept
31
+ // literal instead of being split (#5402). `.`, `[` and `]` keep their existing
32
+ // meaning, e.g. `foo[bar.baz]` -> ['foo', 'bar', 'baz'] and `[]` is an array push.
33
+ // Excluding `[` from the bracket group also makes the match fail fast at the
34
+ // next `[`, so a malformed name cannot rescan to the end of the string from
35
+ // every unmatched `[` — parsing stays linear in the length of the name.
30
36
  const path = [];
31
- const pattern = /\w+|\[(\w*)]/g;
37
+ const pattern = /[^.[\]]+|\[([^.[\]]*)]/g;
32
38
  let match;
33
39
 
34
40
  while ((match = pattern.exec(name)) !== null) {
@@ -50,18 +50,20 @@ export default (rawHeaders) => {
50
50
  key = line.substring(0, i).trim().toLowerCase();
51
51
  val = line.substring(i + 1).trim();
52
52
 
53
- if (!key || (parsed[key] && ignoreDuplicateOf[key])) {
53
+ const hasKey = utils.hasOwnProp(parsed, key);
54
+
55
+ if (!key || (hasKey && utils.hasOwnProp(ignoreDuplicateOf, key))) {
54
56
  return;
55
57
  }
56
58
 
57
59
  if (key === 'set-cookie') {
58
- if (parsed[key]) {
60
+ if (hasKey) {
59
61
  parsed[key].push(val);
60
62
  } else {
61
63
  parsed[key] = [val];
62
64
  }
63
65
  } else {
64
- parsed[key] = parsed[key] ? parsed[key] + ', ' + val : val;
66
+ parsed[key] = hasKey ? parsed[key] + ', ' + val : val;
65
67
  }
66
68
  });
67
69
 
@@ -12,7 +12,7 @@ export const progressEventReducer = (listener, isDownloadStream, freq = 3) => {
12
12
  }
13
13
  const rawLoaded = e.loaded;
14
14
  const total = e.lengthComputable ? e.total : undefined;
15
- const loaded = total != null ? Math.min(rawLoaded, total) : rawLoaded;
15
+ const loaded = Math.max(0, total != null ? Math.min(rawLoaded, total) : rawLoaded);
16
16
  const progressBytes = Math.max(0, loaded - bytesNotified);
17
17
  const rate = _speedometer(progressBytes);
18
18
 
@@ -49,6 +49,6 @@ export const progressEventDecorator = (total, throttled) => {
49
49
  };
50
50
 
51
51
  export const asyncDecorator =
52
- (fn) =>
52
+ (fn, scheduler = utils.asap) =>
53
53
  (...args) =>
54
- utils.asap(() => fn(...args));
54
+ scheduler(() => fn(...args));
@@ -6,23 +6,9 @@ import cookies from './cookies.js';
6
6
  import buildFullPath from '../core/buildFullPath.js';
7
7
  import mergeConfig from '../core/mergeConfig.js';
8
8
  import AxiosHeaders from '../core/AxiosHeaders.js';
9
+ import setFormDataHeaders from '../core/setFormDataHeaders.js';
9
10
  import buildURL from './buildURL.js';
10
11
 
11
- const FORM_DATA_CONTENT_HEADERS = ['content-type', 'content-length'];
12
-
13
- function setFormDataHeaders(headers, formHeaders, policy) {
14
- if (policy !== 'content-only') {
15
- headers.set(formHeaders);
16
- return;
17
- }
18
-
19
- Object.entries(formHeaders || {}).forEach(([key, val]) => {
20
- if (FORM_DATA_CONTENT_HEADERS.includes(key.toLowerCase())) {
21
- headers.set(key, val);
22
- }
23
- });
24
- }
25
-
26
12
  /**
27
13
  * Encode a UTF-8 string to a Latin-1 byte string for use with btoa().
28
14
  * This is a modern replacement for the deprecated unescape(encodeURIComponent(str)) pattern.
@@ -7,6 +7,112 @@ const isIPv4Loopback = (host) => {
7
7
  return parts.every((p) => /^\d+$/.test(p) && Number(p) >= 0 && Number(p) <= 255);
8
8
  };
9
9
 
10
+ /**
11
+ * Canonicalize an IPv4 address written in shorthand, octal, or hex form into
12
+ * dotted-decimal. IPv6 addresses and non-IP strings are returned unchanged so
13
+ * the existing IPv4-mapped IPv6 unmap path and the isLoopback path can still
14
+ * see them.
15
+ *
16
+ * Shorthand expansion mirrors Node's URL parser: literal parts fill from the
17
+ * left, the final part fills the remaining octets from the right with
18
+ * zero-padding on the left.
19
+ * 127.1 -> 127.0.0.1
20
+ * 127.0.1 -> 127.0.0.1
21
+ * 1.2.3 -> 1.2.0.3
22
+ *
23
+ * Each octet is parsed with an explicit base: 16 for `0x`/`0X` prefix, 8 for
24
+ * zero-prefixed multi-digit all-`0-7` parts, 10 otherwise. Zero-prefixed
25
+ * decimal-looking parts that contain `8` or `9` are rejected to match Node's
26
+ * URL parser, and the comparison layer falls through to non-bypass if either
27
+ * side rejects the form (fail-safe).
28
+ *
29
+ * Returns the input unchanged on any parse failure, out-of-range octet, or
30
+ * unusual shape (1-part, 5+ parts) so the comparison layer fails closed.
31
+ */
32
+ const parseIPv4Octet = (text) => {
33
+ if (/^0[xX][0-9a-fA-F]+$/.test(text)) {
34
+ const n = parseInt(text.slice(2), 16);
35
+ return Number.isFinite(n) ? n : null;
36
+ }
37
+ if (text.length > 1 && /^0[0-7]+$/.test(text)) {
38
+ const n = parseInt(text, 8);
39
+ return Number.isFinite(n) ? n : null;
40
+ }
41
+ if (text.length > 1 && /^0[0-9]+$/.test(text)) {
42
+ return null;
43
+ }
44
+ if (/^[0-9]+$/.test(text)) {
45
+ const n = parseInt(text, 10);
46
+ return Number.isFinite(n) ? n : null;
47
+ }
48
+ return null;
49
+ };
50
+
51
+ const normalizeIPAddress = (host) => {
52
+ if (typeof host !== 'string' || !host || host.indexOf(':') !== -1) {
53
+ return host;
54
+ }
55
+
56
+ let h = host;
57
+ if (h.charAt(0) === '[' && h.charAt(h.length - 1) === ']') {
58
+ h = h.slice(1, -1);
59
+ }
60
+ h = h.replace(/\.+$/, '');
61
+
62
+ // Allowed characters for any IPv4 shape: digits, dot, 'x', 'X', hex digits.
63
+ if (!/^[0-9.xXa-fA-F]+$/.test(h)) return host;
64
+
65
+ const parts = h.split('.');
66
+
67
+ // No part may be empty (e.g. "127..0.1" or "127.0.0."). Trailing dots are
68
+ // already stripped above; this guards against the empty-middle case.
69
+ if (parts.some((p) => p === '')) return host;
70
+
71
+ if (parts.length === 4) {
72
+ // Full IPv4 form: each part is an octet.
73
+ const octets = parts.map(parseIPv4Octet);
74
+ if (octets.some((n) => n === null || n < 0 || n > 255)) return host;
75
+ return octets.join('.');
76
+ }
77
+
78
+ if (parts.length > 4) {
79
+ return host;
80
+ }
81
+
82
+ // Shorthand: 1..3 parts. Node's URL parser treats a 1-part input as a 32-bit
83
+ // integer split into octets, which has surprising semantics (e.g. "127" ->
84
+ // "0.0.0.127"). Reject 1-part inputs to keep the helper predictable: the
85
+ // fail-safe returns the input unchanged and the comparison layer falls
86
+ // through to non-bypass.
87
+ if (parts.length === 1) return host;
88
+
89
+ // 2..3 parts: literal parts fill from the left, tail fills remaining octets
90
+ // from the right with zero-padding.
91
+ const literalOctets = parts.slice(0, -1);
92
+ const tail = parts[parts.length - 1];
93
+ const tailSlots = 4 - literalOctets.length;
94
+
95
+ // Tail is parsed as a full IPv4 number (hex/octal/decimal) and packed
96
+ // low-byte-right into the remaining octets, matching Node's URL parser.
97
+ // e.g. 127.65535 (tail 0xFFFF into 3 slots) -> 127.0.255.255;
98
+ // 127.0x00ff (tail 0xFF into 3 slots) -> 127.0.0.255;
99
+ // 127.0.65535 (tail 0xFFFF into 2 slots) -> 127.0.255.255.
100
+ const tailValue = parseIPv4Octet(tail);
101
+ if (tailValue === null) return host;
102
+ const maxTail = (1 << (8 * tailSlots)) - 1;
103
+ if (tailValue < 0 || tailValue > maxTail) return host;
104
+
105
+ const tailOctets = new Array(tailSlots).fill(0);
106
+ for (let i = tailSlots - 1, v = tailValue; i >= 0; i--, v >>= 8) {
107
+ tailOctets[i] = v & 0xff;
108
+ }
109
+
110
+ const literal = literalOctets.map(parseIPv4Octet);
111
+ if (literal.some((n) => n === null || n < 0 || n > 255)) return host;
112
+
113
+ return [...literal, ...tailOctets].join('.');
114
+ };
115
+
10
116
  const isIPv6ZeroGroup = (group) => /^0{1,4}$/.test(group);
11
117
 
12
118
  // The unspecified address (IPv4 0.0.0.0 / IPv6 ::) resolves to the local host
@@ -153,7 +259,16 @@ const normalizeNoProxyHost = (hostname) => {
153
259
  hostname = hostname.slice(1, -1);
154
260
  }
155
261
 
156
- return unmapIPv4MappedIPv6(hostname.replace(/\.+$/, ''));
262
+ const trimmed = hostname.replace(/\.+$/, '');
263
+
264
+ // IPv4 shorthand/octal/hex → dotted-decimal; helper is a no-op for inputs
265
+ // containing ':' (IPv6 and IPv4-mapped IPv6) so we fall through to unmap.
266
+ const ipv4 = normalizeIPAddress(trimmed);
267
+ if (ipv4 !== trimmed) {
268
+ return ipv4;
269
+ }
270
+
271
+ return unmapIPv4MappedIPv6(trimmed);
157
272
  };
158
273
 
159
274
  export default function shouldBypassProxy(location) {
@@ -185,6 +300,10 @@ export default function shouldBypassProxy(location) {
185
300
  return false;
186
301
  }
187
302
 
303
+ if (entry === '*') {
304
+ return true;
305
+ }
306
+
188
307
  let [entryHost, entryPort] = parseNoProxyEntry(entry);
189
308
 
190
309
  entryHost = normalizeNoProxyHost(entryHost);
@@ -4,6 +4,7 @@ import utils from '../utils.js';
4
4
  import AxiosError from '../core/AxiosError.js';
5
5
  // temporary hotfix to avoid circular references until AxiosURLSearchParams is refactored
6
6
  import PlatformFormData from '../platform/node/classes/FormData.js';
7
+ import PlatformBuffer from '../platform/node/classes/Buffer.js';
7
8
 
8
9
  // Default nesting limit shared with the inverse transform (formDataToJSON) so
9
10
  // the FormData <-> JSON round-trip stays symmetric.
@@ -146,8 +147,8 @@ function toFormData(obj, formData, options) {
146
147
  if (useBlob && typeof _Blob === 'function') {
147
148
  return new _Blob([value]);
148
149
  }
149
- if (typeof Buffer !== 'undefined') {
150
- return Buffer.from(value);
150
+ if (PlatformBuffer && PlatformBuffer.isBufferAvailable()) {
151
+ return PlatformBuffer.from(value);
151
152
  }
152
153
  throw new AxiosError('Blob is not supported. Use a Buffer instead.', AxiosError.ERR_NOT_SUPPORT);
153
154
  }
@@ -0,0 +1,11 @@
1
+ 'use strict';
2
+
3
+ export default {
4
+ isBufferAvailable() {
5
+ return typeof Buffer !== 'undefined';
6
+ },
7
+
8
+ from(value) {
9
+ return Buffer.from(value);
10
+ }
11
+ };
package/lib/utils.js CHANGED
@@ -282,6 +282,7 @@ const isBlob = kindOfTest('Blob');
282
282
  * @returns {boolean} True if value is a FileList, otherwise false
283
283
  */
284
284
  const isFileList = kindOfTest('FileList');
285
+ const isSet = kindOfTest('Set');
285
286
 
286
287
  /**
287
288
  * Determine if a value is a Stream
@@ -847,12 +848,23 @@ const toJSONObject = (obj) => {
847
848
  if (!('toJSON' in source)) {
848
849
  // add-on descent / delete-on-ascent: preserves path semantics, so DAG nodes serialise at every occurrence (see #7230).
849
850
  visited.add(source);
850
- const target = isArray(source) ? [] : {};
851
851
 
852
- forEach(source, (value, key) => {
853
- const reducedValue = visit(value);
854
- !isUndefined(reducedValue) && (target[key] = reducedValue);
855
- });
852
+ let target;
853
+
854
+ if (isSet(source)) {
855
+ target = [];
856
+ for (const value of source) {
857
+ const reducedValue = visit(value);
858
+ !isUndefined(reducedValue) && target.push(reducedValue);
859
+ }
860
+ } else {
861
+ target = isArray(source) ? [] : {};
862
+
863
+ forEach(source, (value, key) => {
864
+ const reducedValue = visit(value);
865
+ !isUndefined(reducedValue) && (target[key] = reducedValue);
866
+ });
867
+ }
856
868
 
857
869
  visited.delete(source);
858
870
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "axios",
3
- "version": "1.18.1",
3
+ "version": "1.19.0",
4
4
  "description": "Promise based HTTP client for the browser and node.js",
5
5
  "main": "./dist/node/axios.cjs",
6
6
  "module": "./index.js",
@@ -51,12 +51,14 @@
51
51
  "./dist/node/axios.cjs": "./dist/browser/axios.cjs",
52
52
  "./lib/adapters/http.js": "./lib/helpers/null.js",
53
53
  "./lib/platform/node/index.js": "./lib/platform/browser/index.js",
54
+ "./lib/platform/node/classes/Buffer.js": "./lib/helpers/null.js",
54
55
  "./lib/platform/node/classes/FormData.js": "./lib/helpers/null.js"
55
56
  },
56
57
  "react-native": {
57
58
  "./dist/node/axios.cjs": "./dist/browser/axios.cjs",
58
59
  "./lib/adapters/http.js": "./lib/helpers/null.js",
59
60
  "./lib/platform/node/index.js": "./lib/platform/browser/index.js",
61
+ "./lib/platform/node/classes/Buffer.js": "./lib/helpers/null.js",
60
62
  "./lib/platform/node/classes/FormData.js": "./lib/helpers/null.js"
61
63
  },
62
64
  "repository": {
@@ -114,7 +116,7 @@
114
116
  "dist/node/axios.cjs"
115
117
  ],
116
118
  "scripts": {
117
- "build": "gulp clear && cross-env NODE_ENV=production rollup -c -m",
119
+ "build": "gulp clear && cross-env NODE_ENV=production rollup -c",
118
120
  "version": "npm run build && git add package.json",
119
121
  "preversion": "gulp version",
120
122
  "test": "npm run test:vitest",
@@ -138,50 +140,50 @@
138
140
  },
139
141
  "dependencies": {
140
142
  "follow-redirects": "^1.16.0",
141
- "form-data": "^4.0.5",
143
+ "form-data": "^4.0.6",
142
144
  "https-proxy-agent": "^5.0.1",
143
145
  "proxy-from-env": "^2.1.0"
144
146
  },
145
147
  "devDependencies": {
146
148
  "@babel/core": "^7.29.0",
147
149
  "@babel/preset-env": "^7.29.5",
148
- "@commitlint/cli": "^21.0.1",
149
- "@commitlint/config-conventional": "^21.0.1",
150
+ "@commitlint/cli": "^21.2.0",
151
+ "@commitlint/config-conventional": "^21.2.0",
150
152
  "@eslint/js": "^10.0.1",
151
153
  "@rollup/plugin-alias": "^6.0.0",
152
- "@rollup/plugin-babel": "^7.0.0",
153
- "@rollup/plugin-commonjs": "^29.0.2",
154
+ "@rollup/plugin-babel": "^7.1.0",
155
+ "@rollup/plugin-commonjs": "^29.0.3",
154
156
  "@rollup/plugin-json": "^6.1.0",
155
157
  "@rollup/plugin-node-resolve": "^16.0.3",
156
158
  "@rollup/plugin-terser": "^1.0.0",
157
- "@vitest/browser": "^4.1.7",
158
- "@vitest/browser-playwright": "^4.1.7",
159
+ "@vitest/browser": "^4.1.9",
160
+ "@vitest/browser-playwright": "^4.1.9",
159
161
  "abortcontroller-polyfill": "^1.7.8",
160
- "acorn": "^8.16.0",
161
- "body-parser": "^2.2.2",
162
+ "acorn": "^8.17.0",
163
+ "body-parser": "^2.3.0",
162
164
  "chalk": "^5.6.2",
163
165
  "cross-env": "^10.1.0",
164
166
  "dev-null": "^0.1.1",
165
- "eslint": "^10.4.0",
167
+ "eslint": "^10.6.0",
166
168
  "express": "^5.2.1",
167
169
  "formdata-node": "^6.0.3",
168
170
  "formidable": "^3.5.4",
169
- "fs-extra": "^11.3.4",
171
+ "fs-extra": "^11.3.6",
170
172
  "get-stream": "^9.0.1",
171
- "globals": "^17.6.0",
173
+ "globals": "^17.7.0",
172
174
  "gulp": "^5.0.1",
173
175
  "husky": "^9.1.7",
174
- "lint-staged": "^17.0.5",
176
+ "lint-staged": "^17.0.8",
175
177
  "minimist": "^1.2.8",
176
- "multer": "^2.1.1",
177
- "playwright": "^1.60.0",
178
- "prettier": "^3.8.3",
178
+ "multer": "^2.2.0",
179
+ "playwright": "^1.61.1",
180
+ "prettier": "^3.9.4",
179
181
  "rollup": "^4.60.4",
180
182
  "rollup-plugin-bundle-size": "^1.0.3",
181
183
  "selfsigned": "^5.5.0",
182
184
  "stream-throttle": "^0.1.3",
183
185
  "typescript": "^5.9.3",
184
- "vitest": "^4.1.7"
186
+ "vitest": "^4.1.9"
185
187
  },
186
188
  "commitlint": {
187
189
  "rules": {