axios 1.18.0 → 1.18.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.
- package/CHANGELOG.md +32 -0
- package/README.md +128 -23
- package/dist/axios.js +64 -15
- package/dist/axios.min.js +2 -2
- package/dist/axios.min.js.map +1 -1
- package/dist/browser/axios.cjs +70 -28
- package/dist/esm/axios.js +70 -28
- package/dist/esm/axios.min.js +2 -2
- package/dist/esm/axios.min.js.map +1 -1
- package/dist/node/axios.cjs +123 -33
- package/index.d.cts +17 -1
- package/index.d.ts +17 -1
- package/lib/adapters/adapters.js +1 -1
- package/lib/adapters/fetch.js +27 -12
- package/lib/adapters/http.js +88 -16
- package/lib/adapters/xhr.js +1 -0
- package/lib/core/AxiosError.js +13 -1
- package/lib/core/mergeConfig.js +1 -0
- package/lib/env/data.js +1 -1
- package/lib/helpers/AxiosURLSearchParams.js +1 -3
- package/lib/helpers/buildURL.js +1 -0
- package/lib/helpers/composeSignals.js +1 -1
- package/lib/helpers/cookies.js +5 -1
- package/lib/helpers/fromDataURI.js +4 -2
- package/lib/helpers/resolveConfig.js +10 -5
- package/lib/helpers/toFormData.js +7 -1
- package/lib/helpers/validator.js +1 -1
- package/package.json +2 -2
package/dist/browser/axios.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! Axios v1.18.
|
|
1
|
+
/*! Axios v1.18.1 Copyright (c) 2026 Matt Zabriskie and contributors */
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -1567,7 +1567,19 @@ function redactConfig(config, redactKeys) {
|
|
|
1567
1567
|
class AxiosError extends Error {
|
|
1568
1568
|
static from(error, code, config, request, response, customProps) {
|
|
1569
1569
|
const axiosError = new AxiosError(error.message, code || error.code, config, request, response);
|
|
1570
|
-
|
|
1570
|
+
// Match native `Error` `cause` semantics: non-enumerable. The wrapped
|
|
1571
|
+
// error often carries circular internals (sockets, requests, agents), so
|
|
1572
|
+
// an enumerable `cause` makes structured loggers (pino/winston) and any
|
|
1573
|
+
// own-property walk throw "Converting circular structure to JSON".
|
|
1574
|
+
// Regression from #6982; see #7205. `__proto__: null` mirrors the
|
|
1575
|
+
// `message` descriptor below (prototype-pollution-safe descriptor).
|
|
1576
|
+
Object.defineProperty(axiosError, 'cause', {
|
|
1577
|
+
__proto__: null,
|
|
1578
|
+
value: error,
|
|
1579
|
+
writable: true,
|
|
1580
|
+
enumerable: false,
|
|
1581
|
+
configurable: true,
|
|
1582
|
+
});
|
|
1571
1583
|
axiosError.name = error.name;
|
|
1572
1584
|
|
|
1573
1585
|
// Preserve status from the original error if not already set from response
|
|
@@ -1806,7 +1818,13 @@ function toFormData(obj, formData, options) {
|
|
|
1806
1818
|
}
|
|
1807
1819
|
|
|
1808
1820
|
if (utils$1.isArrayBuffer(value) || utils$1.isTypedArray(value)) {
|
|
1809
|
-
|
|
1821
|
+
if (useBlob && typeof _Blob === 'function') {
|
|
1822
|
+
return new _Blob([value]);
|
|
1823
|
+
}
|
|
1824
|
+
if (typeof Buffer !== 'undefined') {
|
|
1825
|
+
return Buffer.from(value);
|
|
1826
|
+
}
|
|
1827
|
+
throw new AxiosError('Blob is not supported. Use a Buffer instead.', AxiosError.ERR_NOT_SUPPORT);
|
|
1810
1828
|
}
|
|
1811
1829
|
|
|
1812
1830
|
return value;
|
|
@@ -1983,9 +2001,7 @@ prototype.append = function append(name, value) {
|
|
|
1983
2001
|
|
|
1984
2002
|
prototype.toString = function toString(encoder) {
|
|
1985
2003
|
const _encode = encoder
|
|
1986
|
-
?
|
|
1987
|
-
return encoder.call(this, value, encode$1);
|
|
1988
|
-
}
|
|
2004
|
+
? (value) => encoder.call(this, value, encode$1)
|
|
1989
2005
|
: encode$1;
|
|
1990
2006
|
|
|
1991
2007
|
return this._pairs
|
|
@@ -2024,6 +2040,7 @@ function buildURL(url, params, options) {
|
|
|
2024
2040
|
if (!params) {
|
|
2025
2041
|
return url;
|
|
2026
2042
|
}
|
|
2043
|
+
url = url || '';
|
|
2027
2044
|
|
|
2028
2045
|
const _options = utils$1.isFunction(options)
|
|
2029
2046
|
? {
|
|
@@ -2775,7 +2792,11 @@ var cookies = platform.hasStandardBrowserEnv
|
|
|
2775
2792
|
const cookie = cookies[i].replace(/^\s+/, '');
|
|
2776
2793
|
const eq = cookie.indexOf('=');
|
|
2777
2794
|
if (eq !== -1 && cookie.slice(0, eq) === name) {
|
|
2778
|
-
|
|
2795
|
+
try {
|
|
2796
|
+
return decodeURIComponent(cookie.slice(eq + 1));
|
|
2797
|
+
} catch (e) {
|
|
2798
|
+
return cookie.slice(eq + 1);
|
|
2799
|
+
}
|
|
2779
2800
|
}
|
|
2780
2801
|
}
|
|
2781
2802
|
return null;
|
|
@@ -2884,6 +2905,7 @@ const headersToObject = (thing) => (thing instanceof AxiosHeaders ? { ...thing }
|
|
|
2884
2905
|
*/
|
|
2885
2906
|
function mergeConfig(config1, config2) {
|
|
2886
2907
|
// eslint-disable-next-line no-param-reassign
|
|
2908
|
+
config1 = config1 || {};
|
|
2887
2909
|
config2 = config2 || {};
|
|
2888
2910
|
|
|
2889
2911
|
// Use a null-prototype object so that downstream reads such as `config.auth`
|
|
@@ -3033,7 +3055,7 @@ function setFormDataHeaders(headers, formHeaders, policy) {
|
|
|
3033
3055
|
return;
|
|
3034
3056
|
}
|
|
3035
3057
|
|
|
3036
|
-
Object.entries(formHeaders).forEach(([key, val]) => {
|
|
3058
|
+
Object.entries(formHeaders || {}).forEach(([key, val]) => {
|
|
3037
3059
|
if (FORM_DATA_CONTENT_HEADERS.includes(key.toLowerCase())) {
|
|
3038
3060
|
headers.set(key, val);
|
|
3039
3061
|
}
|
|
@@ -3083,10 +3105,14 @@ function resolveConfig(config) {
|
|
|
3083
3105
|
const username = utils$1.getSafeProp(auth, 'username') || '';
|
|
3084
3106
|
const password = utils$1.getSafeProp(auth, 'password') || '';
|
|
3085
3107
|
|
|
3086
|
-
|
|
3087
|
-
|
|
3088
|
-
|
|
3089
|
-
|
|
3108
|
+
try {
|
|
3109
|
+
headers.set(
|
|
3110
|
+
'Authorization',
|
|
3111
|
+
'Basic ' + btoa(username + ':' + (password ? encodeUTF8$1(password) : ''))
|
|
3112
|
+
);
|
|
3113
|
+
} catch (e) {
|
|
3114
|
+
throw AxiosError.from(e, AxiosError.ERR_BAD_OPTION_VALUE, config);
|
|
3115
|
+
}
|
|
3090
3116
|
}
|
|
3091
3117
|
|
|
3092
3118
|
if (utils$1.isFormData(data)) {
|
|
@@ -3337,6 +3363,7 @@ var xhrAdapter = isXHRAdapterSupported &&
|
|
|
3337
3363
|
config
|
|
3338
3364
|
)
|
|
3339
3365
|
);
|
|
3366
|
+
done();
|
|
3340
3367
|
return;
|
|
3341
3368
|
}
|
|
3342
3369
|
|
|
@@ -3388,7 +3415,7 @@ const composeSignals = (signals, timeout) => {
|
|
|
3388
3415
|
signals = null;
|
|
3389
3416
|
};
|
|
3390
3417
|
|
|
3391
|
-
signals.forEach((signal) => signal.addEventListener('abort', onabort));
|
|
3418
|
+
signals.forEach((signal) => signal.addEventListener('abort', onabort, { once: true }));
|
|
3392
3419
|
|
|
3393
3420
|
const { signal } = controller;
|
|
3394
3421
|
|
|
@@ -3593,7 +3620,7 @@ function estimateDataURLDecodedBytes(url) {
|
|
|
3593
3620
|
return bytes;
|
|
3594
3621
|
}
|
|
3595
3622
|
|
|
3596
|
-
const VERSION = "1.18.
|
|
3623
|
+
const VERSION = "1.18.1";
|
|
3597
3624
|
|
|
3598
3625
|
const DEFAULT_CHUNK_SIZE = 64 * 1024;
|
|
3599
3626
|
|
|
@@ -4137,7 +4164,17 @@ const factory = (env) => {
|
|
|
4137
4164
|
const canceledError = composedSignal.reason;
|
|
4138
4165
|
canceledError.config = config;
|
|
4139
4166
|
request && (canceledError.request = request);
|
|
4140
|
-
err !== canceledError
|
|
4167
|
+
if (err !== canceledError) {
|
|
4168
|
+
// Non-enumerable to match native Error `cause` semantics so loggers
|
|
4169
|
+
// don't recurse into circular fetch internals (see #7205).
|
|
4170
|
+
Object.defineProperty(canceledError, 'cause', {
|
|
4171
|
+
__proto__: null,
|
|
4172
|
+
value: err,
|
|
4173
|
+
writable: true,
|
|
4174
|
+
enumerable: false,
|
|
4175
|
+
configurable: true,
|
|
4176
|
+
});
|
|
4177
|
+
}
|
|
4141
4178
|
throw canceledError;
|
|
4142
4179
|
}
|
|
4143
4180
|
|
|
@@ -4159,18 +4196,23 @@ const factory = (env) => {
|
|
|
4159
4196
|
}
|
|
4160
4197
|
|
|
4161
4198
|
if (err && err.name === 'TypeError' && /Load failed|fetch/i.test(err.message)) {
|
|
4162
|
-
|
|
4163
|
-
|
|
4164
|
-
|
|
4165
|
-
|
|
4166
|
-
|
|
4167
|
-
|
|
4168
|
-
err && err.response
|
|
4169
|
-
),
|
|
4170
|
-
{
|
|
4171
|
-
cause: err.cause || err,
|
|
4172
|
-
}
|
|
4199
|
+
const networkError = new AxiosError(
|
|
4200
|
+
'Network Error',
|
|
4201
|
+
AxiosError.ERR_NETWORK,
|
|
4202
|
+
config,
|
|
4203
|
+
request,
|
|
4204
|
+
err && err.response
|
|
4173
4205
|
);
|
|
4206
|
+
// Non-enumerable to match native Error `cause` semantics so loggers
|
|
4207
|
+
// don't recurse into circular fetch internals (see #7205).
|
|
4208
|
+
Object.defineProperty(networkError, 'cause', {
|
|
4209
|
+
__proto__: null,
|
|
4210
|
+
value: err.cause || err,
|
|
4211
|
+
writable: true,
|
|
4212
|
+
enumerable: false,
|
|
4213
|
+
configurable: true,
|
|
4214
|
+
});
|
|
4215
|
+
throw networkError;
|
|
4174
4216
|
}
|
|
4175
4217
|
|
|
4176
4218
|
throw AxiosError.from(err, err && err.code, config, request, err && err.response);
|
|
@@ -4308,7 +4350,7 @@ function getAdapter(adapters, config) {
|
|
|
4308
4350
|
|
|
4309
4351
|
throw new AxiosError(
|
|
4310
4352
|
`There is no suitable adapter to dispatch the request ` + s,
|
|
4311
|
-
|
|
4353
|
+
AxiosError.ERR_NOT_SUPPORT
|
|
4312
4354
|
);
|
|
4313
4355
|
}
|
|
4314
4356
|
|
|
@@ -4489,7 +4531,7 @@ validators$1.spelling = function spelling(correctSpelling) {
|
|
|
4489
4531
|
*/
|
|
4490
4532
|
|
|
4491
4533
|
function assertOptions(options, schema, allowUnknown) {
|
|
4492
|
-
if (typeof options !== 'object') {
|
|
4534
|
+
if (typeof options !== 'object' || options === null) {
|
|
4493
4535
|
throw new AxiosError('options must be an object', AxiosError.ERR_BAD_OPTION_VALUE);
|
|
4494
4536
|
}
|
|
4495
4537
|
const keys = Object.keys(options);
|
package/dist/esm/axios.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! Axios v1.18.
|
|
1
|
+
/*! Axios v1.18.1 Copyright (c) 2026 Matt Zabriskie and contributors */
|
|
2
2
|
/**
|
|
3
3
|
* Create a bound version of a function with a specified `this` context
|
|
4
4
|
*
|
|
@@ -1565,7 +1565,19 @@ function redactConfig(config, redactKeys) {
|
|
|
1565
1565
|
let AxiosError$1 = class AxiosError extends Error {
|
|
1566
1566
|
static from(error, code, config, request, response, customProps) {
|
|
1567
1567
|
const axiosError = new AxiosError(error.message, code || error.code, config, request, response);
|
|
1568
|
-
|
|
1568
|
+
// Match native `Error` `cause` semantics: non-enumerable. The wrapped
|
|
1569
|
+
// error often carries circular internals (sockets, requests, agents), so
|
|
1570
|
+
// an enumerable `cause` makes structured loggers (pino/winston) and any
|
|
1571
|
+
// own-property walk throw "Converting circular structure to JSON".
|
|
1572
|
+
// Regression from #6982; see #7205. `__proto__: null` mirrors the
|
|
1573
|
+
// `message` descriptor below (prototype-pollution-safe descriptor).
|
|
1574
|
+
Object.defineProperty(axiosError, 'cause', {
|
|
1575
|
+
__proto__: null,
|
|
1576
|
+
value: error,
|
|
1577
|
+
writable: true,
|
|
1578
|
+
enumerable: false,
|
|
1579
|
+
configurable: true,
|
|
1580
|
+
});
|
|
1569
1581
|
axiosError.name = error.name;
|
|
1570
1582
|
|
|
1571
1583
|
// Preserve status from the original error if not already set from response
|
|
@@ -1804,7 +1816,13 @@ function toFormData$1(obj, formData, options) {
|
|
|
1804
1816
|
}
|
|
1805
1817
|
|
|
1806
1818
|
if (utils$1.isArrayBuffer(value) || utils$1.isTypedArray(value)) {
|
|
1807
|
-
|
|
1819
|
+
if (useBlob && typeof _Blob === 'function') {
|
|
1820
|
+
return new _Blob([value]);
|
|
1821
|
+
}
|
|
1822
|
+
if (typeof Buffer !== 'undefined') {
|
|
1823
|
+
return Buffer.from(value);
|
|
1824
|
+
}
|
|
1825
|
+
throw new AxiosError$1('Blob is not supported. Use a Buffer instead.', AxiosError$1.ERR_NOT_SUPPORT);
|
|
1808
1826
|
}
|
|
1809
1827
|
|
|
1810
1828
|
return value;
|
|
@@ -1981,9 +1999,7 @@ prototype.append = function append(name, value) {
|
|
|
1981
1999
|
|
|
1982
2000
|
prototype.toString = function toString(encoder) {
|
|
1983
2001
|
const _encode = encoder
|
|
1984
|
-
?
|
|
1985
|
-
return encoder.call(this, value, encode$1);
|
|
1986
|
-
}
|
|
2002
|
+
? (value) => encoder.call(this, value, encode$1)
|
|
1987
2003
|
: encode$1;
|
|
1988
2004
|
|
|
1989
2005
|
return this._pairs
|
|
@@ -2022,6 +2038,7 @@ function buildURL(url, params, options) {
|
|
|
2022
2038
|
if (!params) {
|
|
2023
2039
|
return url;
|
|
2024
2040
|
}
|
|
2041
|
+
url = url || '';
|
|
2025
2042
|
|
|
2026
2043
|
const _options = utils$1.isFunction(options)
|
|
2027
2044
|
? {
|
|
@@ -2773,7 +2790,11 @@ var cookies = platform.hasStandardBrowserEnv
|
|
|
2773
2790
|
const cookie = cookies[i].replace(/^\s+/, '');
|
|
2774
2791
|
const eq = cookie.indexOf('=');
|
|
2775
2792
|
if (eq !== -1 && cookie.slice(0, eq) === name) {
|
|
2776
|
-
|
|
2793
|
+
try {
|
|
2794
|
+
return decodeURIComponent(cookie.slice(eq + 1));
|
|
2795
|
+
} catch (e) {
|
|
2796
|
+
return cookie.slice(eq + 1);
|
|
2797
|
+
}
|
|
2777
2798
|
}
|
|
2778
2799
|
}
|
|
2779
2800
|
return null;
|
|
@@ -2882,6 +2903,7 @@ const headersToObject = (thing) => (thing instanceof AxiosHeaders$1 ? { ...thing
|
|
|
2882
2903
|
*/
|
|
2883
2904
|
function mergeConfig$1(config1, config2) {
|
|
2884
2905
|
// eslint-disable-next-line no-param-reassign
|
|
2906
|
+
config1 = config1 || {};
|
|
2885
2907
|
config2 = config2 || {};
|
|
2886
2908
|
|
|
2887
2909
|
// Use a null-prototype object so that downstream reads such as `config.auth`
|
|
@@ -3031,7 +3053,7 @@ function setFormDataHeaders(headers, formHeaders, policy) {
|
|
|
3031
3053
|
return;
|
|
3032
3054
|
}
|
|
3033
3055
|
|
|
3034
|
-
Object.entries(formHeaders).forEach(([key, val]) => {
|
|
3056
|
+
Object.entries(formHeaders || {}).forEach(([key, val]) => {
|
|
3035
3057
|
if (FORM_DATA_CONTENT_HEADERS.includes(key.toLowerCase())) {
|
|
3036
3058
|
headers.set(key, val);
|
|
3037
3059
|
}
|
|
@@ -3081,10 +3103,14 @@ function resolveConfig(config) {
|
|
|
3081
3103
|
const username = utils$1.getSafeProp(auth, 'username') || '';
|
|
3082
3104
|
const password = utils$1.getSafeProp(auth, 'password') || '';
|
|
3083
3105
|
|
|
3084
|
-
|
|
3085
|
-
|
|
3086
|
-
|
|
3087
|
-
|
|
3106
|
+
try {
|
|
3107
|
+
headers.set(
|
|
3108
|
+
'Authorization',
|
|
3109
|
+
'Basic ' + btoa(username + ':' + (password ? encodeUTF8$1(password) : ''))
|
|
3110
|
+
);
|
|
3111
|
+
} catch (e) {
|
|
3112
|
+
throw AxiosError$1.from(e, AxiosError$1.ERR_BAD_OPTION_VALUE, config);
|
|
3113
|
+
}
|
|
3088
3114
|
}
|
|
3089
3115
|
|
|
3090
3116
|
if (utils$1.isFormData(data)) {
|
|
@@ -3335,6 +3361,7 @@ var xhrAdapter = isXHRAdapterSupported &&
|
|
|
3335
3361
|
config
|
|
3336
3362
|
)
|
|
3337
3363
|
);
|
|
3364
|
+
done();
|
|
3338
3365
|
return;
|
|
3339
3366
|
}
|
|
3340
3367
|
|
|
@@ -3386,7 +3413,7 @@ const composeSignals = (signals, timeout) => {
|
|
|
3386
3413
|
signals = null;
|
|
3387
3414
|
};
|
|
3388
3415
|
|
|
3389
|
-
signals.forEach((signal) => signal.addEventListener('abort', onabort));
|
|
3416
|
+
signals.forEach((signal) => signal.addEventListener('abort', onabort, { once: true }));
|
|
3390
3417
|
|
|
3391
3418
|
const { signal } = controller;
|
|
3392
3419
|
|
|
@@ -3591,7 +3618,7 @@ function estimateDataURLDecodedBytes(url) {
|
|
|
3591
3618
|
return bytes;
|
|
3592
3619
|
}
|
|
3593
3620
|
|
|
3594
|
-
const VERSION$1 = "1.18.
|
|
3621
|
+
const VERSION$1 = "1.18.1";
|
|
3595
3622
|
|
|
3596
3623
|
const DEFAULT_CHUNK_SIZE = 64 * 1024;
|
|
3597
3624
|
|
|
@@ -4135,7 +4162,17 @@ const factory = (env) => {
|
|
|
4135
4162
|
const canceledError = composedSignal.reason;
|
|
4136
4163
|
canceledError.config = config;
|
|
4137
4164
|
request && (canceledError.request = request);
|
|
4138
|
-
err !== canceledError
|
|
4165
|
+
if (err !== canceledError) {
|
|
4166
|
+
// Non-enumerable to match native Error `cause` semantics so loggers
|
|
4167
|
+
// don't recurse into circular fetch internals (see #7205).
|
|
4168
|
+
Object.defineProperty(canceledError, 'cause', {
|
|
4169
|
+
__proto__: null,
|
|
4170
|
+
value: err,
|
|
4171
|
+
writable: true,
|
|
4172
|
+
enumerable: false,
|
|
4173
|
+
configurable: true,
|
|
4174
|
+
});
|
|
4175
|
+
}
|
|
4139
4176
|
throw canceledError;
|
|
4140
4177
|
}
|
|
4141
4178
|
|
|
@@ -4157,18 +4194,23 @@ const factory = (env) => {
|
|
|
4157
4194
|
}
|
|
4158
4195
|
|
|
4159
4196
|
if (err && err.name === 'TypeError' && /Load failed|fetch/i.test(err.message)) {
|
|
4160
|
-
|
|
4161
|
-
|
|
4162
|
-
|
|
4163
|
-
|
|
4164
|
-
|
|
4165
|
-
|
|
4166
|
-
err && err.response
|
|
4167
|
-
),
|
|
4168
|
-
{
|
|
4169
|
-
cause: err.cause || err,
|
|
4170
|
-
}
|
|
4197
|
+
const networkError = new AxiosError$1(
|
|
4198
|
+
'Network Error',
|
|
4199
|
+
AxiosError$1.ERR_NETWORK,
|
|
4200
|
+
config,
|
|
4201
|
+
request,
|
|
4202
|
+
err && err.response
|
|
4171
4203
|
);
|
|
4204
|
+
// Non-enumerable to match native Error `cause` semantics so loggers
|
|
4205
|
+
// don't recurse into circular fetch internals (see #7205).
|
|
4206
|
+
Object.defineProperty(networkError, 'cause', {
|
|
4207
|
+
__proto__: null,
|
|
4208
|
+
value: err.cause || err,
|
|
4209
|
+
writable: true,
|
|
4210
|
+
enumerable: false,
|
|
4211
|
+
configurable: true,
|
|
4212
|
+
});
|
|
4213
|
+
throw networkError;
|
|
4172
4214
|
}
|
|
4173
4215
|
|
|
4174
4216
|
throw AxiosError$1.from(err, err && err.code, config, request, err && err.response);
|
|
@@ -4306,7 +4348,7 @@ function getAdapter$1(adapters, config) {
|
|
|
4306
4348
|
|
|
4307
4349
|
throw new AxiosError$1(
|
|
4308
4350
|
`There is no suitable adapter to dispatch the request ` + s,
|
|
4309
|
-
|
|
4351
|
+
AxiosError$1.ERR_NOT_SUPPORT
|
|
4310
4352
|
);
|
|
4311
4353
|
}
|
|
4312
4354
|
|
|
@@ -4487,7 +4529,7 @@ validators$1.spelling = function spelling(correctSpelling) {
|
|
|
4487
4529
|
*/
|
|
4488
4530
|
|
|
4489
4531
|
function assertOptions(options, schema, allowUnknown) {
|
|
4490
|
-
if (typeof options !== 'object') {
|
|
4532
|
+
if (typeof options !== 'object' || options === null) {
|
|
4491
4533
|
throw new AxiosError$1('options must be an object', AxiosError$1.ERR_BAD_OPTION_VALUE);
|
|
4492
4534
|
}
|
|
4493
4535
|
const keys = Object.keys(options);
|