🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
920 lines
23 KiB
JavaScript
Executable File
920 lines
23 KiB
JavaScript
Executable File
'use strict';
|
|
|
|
import bind from './helpers/bind.js';
|
|
|
|
// utils is a library of generic helper functions non-specific to axios
|
|
|
|
const { toString } = Object.prototype;
|
|
const { getPrototypeOf } = Object;
|
|
const { iterator, toStringTag } = Symbol;
|
|
|
|
const kindOf = ((cache) => (thing) => {
|
|
const str = toString.call(thing);
|
|
return cache[str] || (cache[str] = str.slice(8, -1).toLowerCase());
|
|
})(Object.create(null));
|
|
|
|
const kindOfTest = (type) => {
|
|
type = type.toLowerCase();
|
|
return (thing) => kindOf(thing) === type;
|
|
};
|
|
|
|
const typeOfTest = (type) => (thing) => typeof thing === type;
|
|
|
|
/**
|
|
* Determine if a value is a non-null object
|
|
*
|
|
* @param {Object} val The value to test
|
|
*
|
|
* @returns {boolean} True if value is an Array, otherwise false
|
|
*/
|
|
const { isArray } = Array;
|
|
|
|
/**
|
|
* Determine if a value is undefined
|
|
*
|
|
* @param {*} val The value to test
|
|
*
|
|
* @returns {boolean} True if the value is undefined, otherwise false
|
|
*/
|
|
const isUndefined = typeOfTest('undefined');
|
|
|
|
/**
|
|
* Determine if a value is a Buffer
|
|
*
|
|
* @param {*} val The value to test
|
|
*
|
|
* @returns {boolean} True if value is a Buffer, otherwise false
|
|
*/
|
|
function isBuffer(val) {
|
|
return (
|
|
val !== null &&
|
|
!isUndefined(val) &&
|
|
val.constructor !== null &&
|
|
!isUndefined(val.constructor) &&
|
|
isFunction(val.constructor.isBuffer) &&
|
|
val.constructor.isBuffer(val)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Determine if a value is an ArrayBuffer
|
|
*
|
|
* @param {*} val The value to test
|
|
*
|
|
* @returns {boolean} True if value is an ArrayBuffer, otherwise false
|
|
*/
|
|
const isArrayBuffer = kindOfTest('ArrayBuffer');
|
|
|
|
/**
|
|
* Determine if a value is a view on an ArrayBuffer
|
|
*
|
|
* @param {*} val The value to test
|
|
*
|
|
* @returns {boolean} True if value is a view on an ArrayBuffer, otherwise false
|
|
*/
|
|
function isArrayBufferView(val) {
|
|
let result;
|
|
if (typeof ArrayBuffer !== 'undefined' && ArrayBuffer.isView) {
|
|
result = ArrayBuffer.isView(val);
|
|
} else {
|
|
result = val && val.buffer && isArrayBuffer(val.buffer);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Determine if a value is a String
|
|
*
|
|
* @param {*} val The value to test
|
|
*
|
|
* @returns {boolean} True if value is a String, otherwise false
|
|
*/
|
|
const isString = typeOfTest('string');
|
|
|
|
/**
|
|
* Determine if a value is a Function
|
|
*
|
|
* @param {*} val The value to test
|
|
* @returns {boolean} True if value is a Function, otherwise false
|
|
*/
|
|
const isFunction = typeOfTest('function');
|
|
|
|
/**
|
|
* Determine if a value is a Number
|
|
*
|
|
* @param {*} val The value to test
|
|
*
|
|
* @returns {boolean} True if value is a Number, otherwise false
|
|
*/
|
|
const isNumber = typeOfTest('number');
|
|
|
|
/**
|
|
* Determine if a value is an Object
|
|
*
|
|
* @param {*} thing The value to test
|
|
*
|
|
* @returns {boolean} True if value is an Object, otherwise false
|
|
*/
|
|
const isObject = (thing) => thing !== null && typeof thing === 'object';
|
|
|
|
/**
|
|
* Determine if a value is a Boolean
|
|
*
|
|
* @param {*} thing The value to test
|
|
* @returns {boolean} True if value is a Boolean, otherwise false
|
|
*/
|
|
const isBoolean = (thing) => thing === true || thing === false;
|
|
|
|
/**
|
|
* Determine if a value is a plain Object
|
|
*
|
|
* @param {*} val The value to test
|
|
*
|
|
* @returns {boolean} True if value is a plain Object, otherwise false
|
|
*/
|
|
const isPlainObject = (val) => {
|
|
if (kindOf(val) !== 'object') {
|
|
return false;
|
|
}
|
|
|
|
const prototype = getPrototypeOf(val);
|
|
return (
|
|
(prototype === null ||
|
|
prototype === Object.prototype ||
|
|
Object.getPrototypeOf(prototype) === null) &&
|
|
!(toStringTag in val) &&
|
|
!(iterator in val)
|
|
);
|
|
};
|
|
|
|
/**
|
|
* Determine if a value is an empty object (safely handles Buffers)
|
|
*
|
|
* @param {*} val The value to test
|
|
*
|
|
* @returns {boolean} True if value is an empty object, otherwise false
|
|
*/
|
|
const isEmptyObject = (val) => {
|
|
// Early return for non-objects or Buffers to prevent RangeError
|
|
if (!isObject(val) || isBuffer(val)) {
|
|
return false;
|
|
}
|
|
|
|
try {
|
|
return Object.keys(val).length === 0 && Object.getPrototypeOf(val) === Object.prototype;
|
|
} catch (e) {
|
|
// Fallback for any other objects that might cause RangeError with Object.keys()
|
|
return false;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Determine if a value is a Date
|
|
*
|
|
* @param {*} val The value to test
|
|
*
|
|
* @returns {boolean} True if value is a Date, otherwise false
|
|
*/
|
|
const isDate = kindOfTest('Date');
|
|
|
|
/**
|
|
* Determine if a value is a File
|
|
*
|
|
* @param {*} val The value to test
|
|
*
|
|
* @returns {boolean} True if value is a File, otherwise false
|
|
*/
|
|
const isFile = kindOfTest('File');
|
|
|
|
/**
|
|
* Determine if a value is a React Native Blob
|
|
* React Native "blob": an object with a `uri` attribute. Optionally, it can
|
|
* also have a `name` and `type` attribute to specify filename and content type
|
|
*
|
|
* @see https://github.com/facebook/react-native/blob/26684cf3adf4094eb6c405d345a75bf8c7c0bf88/Libraries/Network/FormData.js#L68-L71
|
|
*
|
|
* @param {*} value The value to test
|
|
*
|
|
* @returns {boolean} True if value is a React Native Blob, otherwise false
|
|
*/
|
|
const isReactNativeBlob = (value) => {
|
|
return !!(value && typeof value.uri !== 'undefined');
|
|
}
|
|
|
|
/**
|
|
* Determine if environment is React Native
|
|
* ReactNative `FormData` has a non-standard `getParts()` method
|
|
*
|
|
* @param {*} formData The formData to test
|
|
*
|
|
* @returns {boolean} True if environment is React Native, otherwise false
|
|
*/
|
|
const isReactNative = (formData) => formData && typeof formData.getParts !== 'undefined';
|
|
|
|
/**
|
|
* Determine if a value is a Blob
|
|
*
|
|
* @param {*} val The value to test
|
|
*
|
|
* @returns {boolean} True if value is a Blob, otherwise false
|
|
*/
|
|
const isBlob = kindOfTest('Blob');
|
|
|
|
/**
|
|
* Determine if a value is a FileList
|
|
*
|
|
* @param {*} val The value to test
|
|
*
|
|
* @returns {boolean} True if value is a File, otherwise false
|
|
*/
|
|
const isFileList = kindOfTest('FileList');
|
|
|
|
/**
|
|
* Determine if a value is a Stream
|
|
*
|
|
* @param {*} val The value to test
|
|
*
|
|
* @returns {boolean} True if value is a Stream, otherwise false
|
|
*/
|
|
const isStream = (val) => isObject(val) && isFunction(val.pipe);
|
|
|
|
/**
|
|
* Determine if a value is a FormData
|
|
*
|
|
* @param {*} thing The value to test
|
|
*
|
|
* @returns {boolean} True if value is an FormData, otherwise false
|
|
*/
|
|
function getGlobal() {
|
|
if (typeof globalThis !== 'undefined') return globalThis;
|
|
if (typeof self !== 'undefined') return self;
|
|
if (typeof window !== 'undefined') return window;
|
|
if (typeof global !== 'undefined') return global;
|
|
return {};
|
|
}
|
|
|
|
const G = getGlobal();
|
|
const FormDataCtor = typeof G.FormData !== 'undefined' ? G.FormData : undefined;
|
|
|
|
const isFormData = (thing) => {
|
|
let kind;
|
|
return thing && (
|
|
(FormDataCtor && thing instanceof FormDataCtor) || (
|
|
isFunction(thing.append) && (
|
|
(kind = kindOf(thing)) === 'formdata' ||
|
|
// detect form-data instance
|
|
(kind === 'object' && isFunction(thing.toString) && thing.toString() === '[object FormData]')
|
|
)
|
|
)
|
|
);
|
|
};
|
|
|
|
/**
|
|
* Determine if a value is a URLSearchParams object
|
|
*
|
|
* @param {*} val The value to test
|
|
*
|
|
* @returns {boolean} True if value is a URLSearchParams object, otherwise false
|
|
*/
|
|
const isURLSearchParams = kindOfTest('URLSearchParams');
|
|
|
|
const [isReadableStream, isRequest, isResponse, isHeaders] = [
|
|
'ReadableStream',
|
|
'Request',
|
|
'Response',
|
|
'Headers',
|
|
].map(kindOfTest);
|
|
|
|
/**
|
|
* Trim excess whitespace off the beginning and end of a string
|
|
*
|
|
* @param {String} str The String to trim
|
|
*
|
|
* @returns {String} The String freed of excess whitespace
|
|
*/
|
|
const trim = (str) => {
|
|
return str.trim ? str.trim() : str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '');
|
|
};
|
|
/**
|
|
* Iterate over an Array or an Object invoking a function for each item.
|
|
*
|
|
* If `obj` is an Array callback will be called passing
|
|
* the value, index, and complete array for each item.
|
|
*
|
|
* If 'obj' is an Object callback will be called passing
|
|
* the value, key, and complete object for each property.
|
|
*
|
|
* @param {Object|Array<unknown>} obj The object to iterate
|
|
* @param {Function} fn The callback to invoke for each item
|
|
*
|
|
* @param {Object} [options]
|
|
* @param {Boolean} [options.allOwnKeys = false]
|
|
* @returns {any}
|
|
*/
|
|
function forEach(obj, fn, { allOwnKeys = false } = {}) {
|
|
// Don't bother if no value provided
|
|
if (obj === null || typeof obj === 'undefined') {
|
|
return;
|
|
}
|
|
|
|
let i;
|
|
let l;
|
|
|
|
// Force an array if not already something iterable
|
|
if (typeof obj !== 'object') {
|
|
/*eslint no-param-reassign:0*/
|
|
obj = [obj];
|
|
}
|
|
|
|
if (isArray(obj)) {
|
|
// Iterate over array values
|
|
for (i = 0, l = obj.length; i < l; i++) {
|
|
fn.call(null, obj[i], i, obj);
|
|
}
|
|
} else {
|
|
// Buffer check
|
|
if (isBuffer(obj)) {
|
|
return;
|
|
}
|
|
|
|
// Iterate over object keys
|
|
const keys = allOwnKeys ? Object.getOwnPropertyNames(obj) : Object.keys(obj);
|
|
const len = keys.length;
|
|
let key;
|
|
|
|
for (i = 0; i < len; i++) {
|
|
key = keys[i];
|
|
fn.call(null, obj[key], key, obj);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Finds a key in an object, case-insensitive, returning the actual key name.
|
|
* Returns null if the object is a Buffer or if no match is found.
|
|
*
|
|
* @param {Object} obj - The object to search.
|
|
* @param {string} key - The key to find (case-insensitive).
|
|
* @returns {?string} The actual key name if found, otherwise null.
|
|
*/
|
|
function findKey(obj, key) {
|
|
if (isBuffer(obj)) {
|
|
return null;
|
|
}
|
|
|
|
key = key.toLowerCase();
|
|
const keys = Object.keys(obj);
|
|
let i = keys.length;
|
|
let _key;
|
|
while (i-- > 0) {
|
|
_key = keys[i];
|
|
if (key === _key.toLowerCase()) {
|
|
return _key;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
const _global = (() => {
|
|
/*eslint no-undef:0*/
|
|
if (typeof globalThis !== 'undefined') return globalThis;
|
|
return typeof self !== 'undefined' ? self : typeof window !== 'undefined' ? window : global;
|
|
})();
|
|
|
|
const isContextDefined = (context) => !isUndefined(context) && context !== _global;
|
|
|
|
/**
|
|
* Accepts varargs expecting each argument to be an object, then
|
|
* immutably merges the properties of each object and returns result.
|
|
*
|
|
* When multiple objects contain the same key the later object in
|
|
* the arguments list will take precedence.
|
|
*
|
|
* Example:
|
|
*
|
|
* ```js
|
|
* const result = merge({foo: 123}, {foo: 456});
|
|
* console.log(result.foo); // outputs 456
|
|
* ```
|
|
*
|
|
* @param {Object} obj1 Object to merge
|
|
*
|
|
* @returns {Object} Result of all merge properties
|
|
*/
|
|
function merge(/* obj1, obj2, obj3, ... */) {
|
|
const { caseless, skipUndefined } = (isContextDefined(this) && this) || {};
|
|
const result = {};
|
|
const assignValue = (val, key) => {
|
|
// Skip dangerous property names to prevent prototype pollution
|
|
if (key === '__proto__' || key === 'constructor' || key === 'prototype') {
|
|
return;
|
|
}
|
|
|
|
const targetKey = (caseless && findKey(result, key)) || key;
|
|
if (isPlainObject(result[targetKey]) && isPlainObject(val)) {
|
|
result[targetKey] = merge(result[targetKey], val);
|
|
} else if (isPlainObject(val)) {
|
|
result[targetKey] = merge({}, val);
|
|
} else if (isArray(val)) {
|
|
result[targetKey] = val.slice();
|
|
} else if (!skipUndefined || !isUndefined(val)) {
|
|
result[targetKey] = val;
|
|
}
|
|
};
|
|
|
|
for (let i = 0, l = arguments.length; i < l; i++) {
|
|
arguments[i] && forEach(arguments[i], assignValue);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Extends object a by mutably adding to it the properties of object b.
|
|
*
|
|
* @param {Object} a The object to be extended
|
|
* @param {Object} b The object to copy properties from
|
|
* @param {Object} thisArg The object to bind function to
|
|
*
|
|
* @param {Object} [options]
|
|
* @param {Boolean} [options.allOwnKeys]
|
|
* @returns {Object} The resulting value of object a
|
|
*/
|
|
const extend = (a, b, thisArg, { allOwnKeys } = {}) => {
|
|
forEach(
|
|
b,
|
|
(val, key) => {
|
|
if (thisArg && isFunction(val)) {
|
|
Object.defineProperty(a, key, {
|
|
value: bind(val, thisArg),
|
|
writable: true,
|
|
enumerable: true,
|
|
configurable: true,
|
|
});
|
|
} else {
|
|
Object.defineProperty(a, key, {
|
|
value: val,
|
|
writable: true,
|
|
enumerable: true,
|
|
configurable: true,
|
|
});
|
|
}
|
|
},
|
|
{ allOwnKeys }
|
|
);
|
|
return a;
|
|
};
|
|
|
|
/**
|
|
* Remove byte order marker. This catches EF BB BF (the UTF-8 BOM)
|
|
*
|
|
* @param {string} content with BOM
|
|
*
|
|
* @returns {string} content value without BOM
|
|
*/
|
|
const stripBOM = (content) => {
|
|
if (content.charCodeAt(0) === 0xfeff) {
|
|
content = content.slice(1);
|
|
}
|
|
return content;
|
|
};
|
|
|
|
/**
|
|
* Inherit the prototype methods from one constructor into another
|
|
* @param {function} constructor
|
|
* @param {function} superConstructor
|
|
* @param {object} [props]
|
|
* @param {object} [descriptors]
|
|
*
|
|
* @returns {void}
|
|
*/
|
|
const inherits = (constructor, superConstructor, props, descriptors) => {
|
|
constructor.prototype = Object.create(superConstructor.prototype, descriptors);
|
|
Object.defineProperty(constructor.prototype, 'constructor', {
|
|
value: constructor,
|
|
writable: true,
|
|
enumerable: false,
|
|
configurable: true,
|
|
});
|
|
Object.defineProperty(constructor, 'super', {
|
|
value: superConstructor.prototype,
|
|
});
|
|
props && Object.assign(constructor.prototype, props);
|
|
};
|
|
|
|
/**
|
|
* Resolve object with deep prototype chain to a flat object
|
|
* @param {Object} sourceObj source object
|
|
* @param {Object} [destObj]
|
|
* @param {Function|Boolean} [filter]
|
|
* @param {Function} [propFilter]
|
|
*
|
|
* @returns {Object}
|
|
*/
|
|
const toFlatObject = (sourceObj, destObj, filter, propFilter) => {
|
|
let props;
|
|
let i;
|
|
let prop;
|
|
const merged = {};
|
|
|
|
destObj = destObj || {};
|
|
// eslint-disable-next-line no-eq-null,eqeqeq
|
|
if (sourceObj == null) return destObj;
|
|
|
|
do {
|
|
props = Object.getOwnPropertyNames(sourceObj);
|
|
i = props.length;
|
|
while (i-- > 0) {
|
|
prop = props[i];
|
|
if ((!propFilter || propFilter(prop, sourceObj, destObj)) && !merged[prop]) {
|
|
destObj[prop] = sourceObj[prop];
|
|
merged[prop] = true;
|
|
}
|
|
}
|
|
sourceObj = filter !== false && getPrototypeOf(sourceObj);
|
|
} while (sourceObj && (!filter || filter(sourceObj, destObj)) && sourceObj !== Object.prototype);
|
|
|
|
return destObj;
|
|
};
|
|
|
|
/**
|
|
* Determines whether a string ends with the characters of a specified string
|
|
*
|
|
* @param {String} str
|
|
* @param {String} searchString
|
|
* @param {Number} [position= 0]
|
|
*
|
|
* @returns {boolean}
|
|
*/
|
|
const endsWith = (str, searchString, position) => {
|
|
str = String(str);
|
|
if (position === undefined || position > str.length) {
|
|
position = str.length;
|
|
}
|
|
position -= searchString.length;
|
|
const lastIndex = str.indexOf(searchString, position);
|
|
return lastIndex !== -1 && lastIndex === position;
|
|
};
|
|
|
|
/**
|
|
* Returns new array from array like object or null if failed
|
|
*
|
|
* @param {*} [thing]
|
|
*
|
|
* @returns {?Array}
|
|
*/
|
|
const toArray = (thing) => {
|
|
if (!thing) return null;
|
|
if (isArray(thing)) return thing;
|
|
let i = thing.length;
|
|
if (!isNumber(i)) return null;
|
|
const arr = new Array(i);
|
|
while (i-- > 0) {
|
|
arr[i] = thing[i];
|
|
}
|
|
return arr;
|
|
};
|
|
|
|
/**
|
|
* Checking if the Uint8Array exists and if it does, it returns a function that checks if the
|
|
* thing passed in is an instance of Uint8Array
|
|
*
|
|
* @param {TypedArray}
|
|
*
|
|
* @returns {Array}
|
|
*/
|
|
// eslint-disable-next-line func-names
|
|
const isTypedArray = ((TypedArray) => {
|
|
// eslint-disable-next-line func-names
|
|
return (thing) => {
|
|
return TypedArray && thing instanceof TypedArray;
|
|
};
|
|
})(typeof Uint8Array !== 'undefined' && getPrototypeOf(Uint8Array));
|
|
|
|
/**
|
|
* For each entry in the object, call the function with the key and value.
|
|
*
|
|
* @param {Object<any, any>} obj - The object to iterate over.
|
|
* @param {Function} fn - The function to call for each entry.
|
|
*
|
|
* @returns {void}
|
|
*/
|
|
const forEachEntry = (obj, fn) => {
|
|
const generator = obj && obj[iterator];
|
|
|
|
const _iterator = generator.call(obj);
|
|
|
|
let result;
|
|
|
|
while ((result = _iterator.next()) && !result.done) {
|
|
const pair = result.value;
|
|
fn.call(obj, pair[0], pair[1]);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* It takes a regular expression and a string, and returns an array of all the matches
|
|
*
|
|
* @param {string} regExp - The regular expression to match against.
|
|
* @param {string} str - The string to search.
|
|
*
|
|
* @returns {Array<boolean>}
|
|
*/
|
|
const matchAll = (regExp, str) => {
|
|
let matches;
|
|
const arr = [];
|
|
|
|
while ((matches = regExp.exec(str)) !== null) {
|
|
arr.push(matches);
|
|
}
|
|
|
|
return arr;
|
|
};
|
|
|
|
/* Checking if the kindOfTest function returns true when passed an HTMLFormElement. */
|
|
const isHTMLForm = kindOfTest('HTMLFormElement');
|
|
|
|
const toCamelCase = (str) => {
|
|
return str.toLowerCase().replace(/[-_\s]([a-z\d])(\w*)/g, function replacer(m, p1, p2) {
|
|
return p1.toUpperCase() + p2;
|
|
});
|
|
};
|
|
|
|
/* Creating a function that will check if an object has a property. */
|
|
const hasOwnProperty = (
|
|
({ hasOwnProperty }) =>
|
|
(obj, prop) =>
|
|
hasOwnProperty.call(obj, prop)
|
|
)(Object.prototype);
|
|
|
|
/**
|
|
* Determine if a value is a RegExp object
|
|
*
|
|
* @param {*} val The value to test
|
|
*
|
|
* @returns {boolean} True if value is a RegExp object, otherwise false
|
|
*/
|
|
const isRegExp = kindOfTest('RegExp');
|
|
|
|
const reduceDescriptors = (obj, reducer) => {
|
|
const descriptors = Object.getOwnPropertyDescriptors(obj);
|
|
const reducedDescriptors = {};
|
|
|
|
forEach(descriptors, (descriptor, name) => {
|
|
let ret;
|
|
if ((ret = reducer(descriptor, name, obj)) !== false) {
|
|
reducedDescriptors[name] = ret || descriptor;
|
|
}
|
|
});
|
|
|
|
Object.defineProperties(obj, reducedDescriptors);
|
|
};
|
|
|
|
/**
|
|
* Makes all methods read-only
|
|
* @param {Object} obj
|
|
*/
|
|
|
|
const freezeMethods = (obj) => {
|
|
reduceDescriptors(obj, (descriptor, name) => {
|
|
// skip restricted props in strict mode
|
|
if (isFunction(obj) && ['arguments', 'caller', 'callee'].indexOf(name) !== -1) {
|
|
return false;
|
|
}
|
|
|
|
const value = obj[name];
|
|
|
|
if (!isFunction(value)) return;
|
|
|
|
descriptor.enumerable = false;
|
|
|
|
if ('writable' in descriptor) {
|
|
descriptor.writable = false;
|
|
return;
|
|
}
|
|
|
|
if (!descriptor.set) {
|
|
descriptor.set = () => {
|
|
throw Error("Can not rewrite read-only method '" + name + "'");
|
|
};
|
|
}
|
|
});
|
|
};
|
|
|
|
/**
|
|
* Converts an array or a delimited string into an object set with values as keys and true as values.
|
|
* Useful for fast membership checks.
|
|
*
|
|
* @param {Array|string} arrayOrString - The array or string to convert.
|
|
* @param {string} delimiter - The delimiter to use if input is a string.
|
|
* @returns {Object} An object with keys from the array or string, values set to true.
|
|
*/
|
|
const toObjectSet = (arrayOrString, delimiter) => {
|
|
const obj = {};
|
|
|
|
const define = (arr) => {
|
|
arr.forEach((value) => {
|
|
obj[value] = true;
|
|
});
|
|
};
|
|
|
|
isArray(arrayOrString) ? define(arrayOrString) : define(String(arrayOrString).split(delimiter));
|
|
|
|
return obj;
|
|
};
|
|
|
|
const noop = () => {};
|
|
|
|
const toFiniteNumber = (value, defaultValue) => {
|
|
return value != null && Number.isFinite((value = +value)) ? value : defaultValue;
|
|
};
|
|
|
|
/**
|
|
* If the thing is a FormData object, return true, otherwise return false.
|
|
*
|
|
* @param {unknown} thing - The thing to check.
|
|
*
|
|
* @returns {boolean}
|
|
*/
|
|
function isSpecCompliantForm(thing) {
|
|
return !!(
|
|
thing &&
|
|
isFunction(thing.append) &&
|
|
thing[toStringTag] === 'FormData' &&
|
|
thing[iterator]
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Recursively converts an object to a JSON-compatible object, handling circular references and Buffers.
|
|
*
|
|
* @param {Object} obj - The object to convert.
|
|
* @returns {Object} The JSON-compatible object.
|
|
*/
|
|
const toJSONObject = (obj) => {
|
|
const stack = new Array(10);
|
|
|
|
const visit = (source, i) => {
|
|
if (isObject(source)) {
|
|
if (stack.indexOf(source) >= 0) {
|
|
return;
|
|
}
|
|
|
|
//Buffer check
|
|
if (isBuffer(source)) {
|
|
return source;
|
|
}
|
|
|
|
if (!('toJSON' in source)) {
|
|
stack[i] = source;
|
|
const target = isArray(source) ? [] : {};
|
|
|
|
forEach(source, (value, key) => {
|
|
const reducedValue = visit(value, i + 1);
|
|
!isUndefined(reducedValue) && (target[key] = reducedValue);
|
|
});
|
|
|
|
stack[i] = undefined;
|
|
|
|
return target;
|
|
}
|
|
}
|
|
|
|
return source;
|
|
};
|
|
|
|
return visit(obj, 0);
|
|
};
|
|
|
|
/**
|
|
* Determines if a value is an async function.
|
|
*
|
|
* @param {*} thing - The value to test.
|
|
* @returns {boolean} True if value is an async function, otherwise false.
|
|
*/
|
|
const isAsyncFn = kindOfTest('AsyncFunction');
|
|
|
|
/**
|
|
* Determines if a value is thenable (has then and catch methods).
|
|
*
|
|
* @param {*} thing - The value to test.
|
|
* @returns {boolean} True if value is thenable, otherwise false.
|
|
*/
|
|
const isThenable = (thing) =>
|
|
thing &&
|
|
(isObject(thing) || isFunction(thing)) &&
|
|
isFunction(thing.then) &&
|
|
isFunction(thing.catch);
|
|
|
|
// original code
|
|
// https://github.com/DigitalBrainJS/AxiosPromise/blob/16deab13710ec09779922131f3fa5954320f83ab/lib/utils.js#L11-L34
|
|
|
|
/**
|
|
* Provides a cross-platform setImmediate implementation.
|
|
* Uses native setImmediate if available, otherwise falls back to postMessage or setTimeout.
|
|
*
|
|
* @param {boolean} setImmediateSupported - Whether setImmediate is supported.
|
|
* @param {boolean} postMessageSupported - Whether postMessage is supported.
|
|
* @returns {Function} A function to schedule a callback asynchronously.
|
|
*/
|
|
const _setImmediate = ((setImmediateSupported, postMessageSupported) => {
|
|
if (setImmediateSupported) {
|
|
return setImmediate;
|
|
}
|
|
|
|
return postMessageSupported
|
|
? ((token, callbacks) => {
|
|
_global.addEventListener(
|
|
'message',
|
|
({ source, data }) => {
|
|
if (source === _global && data === token) {
|
|
callbacks.length && callbacks.shift()();
|
|
}
|
|
},
|
|
false
|
|
);
|
|
|
|
return (cb) => {
|
|
callbacks.push(cb);
|
|
_global.postMessage(token, '*');
|
|
};
|
|
})(`axios@${Math.random()}`, [])
|
|
: (cb) => setTimeout(cb);
|
|
})(typeof setImmediate === 'function', isFunction(_global.postMessage));
|
|
|
|
/**
|
|
* Schedules a microtask or asynchronous callback as soon as possible.
|
|
* Uses queueMicrotask if available, otherwise falls back to process.nextTick or _setImmediate.
|
|
*
|
|
* @type {Function}
|
|
*/
|
|
const asap =
|
|
typeof queueMicrotask !== 'undefined'
|
|
? queueMicrotask.bind(_global)
|
|
: (typeof process !== 'undefined' && process.nextTick) || _setImmediate;
|
|
|
|
// *********************
|
|
|
|
const isIterable = (thing) => thing != null && isFunction(thing[iterator]);
|
|
|
|
export default {
|
|
isArray,
|
|
isArrayBuffer,
|
|
isBuffer,
|
|
isFormData,
|
|
isArrayBufferView,
|
|
isString,
|
|
isNumber,
|
|
isBoolean,
|
|
isObject,
|
|
isPlainObject,
|
|
isEmptyObject,
|
|
isReadableStream,
|
|
isRequest,
|
|
isResponse,
|
|
isHeaders,
|
|
isUndefined,
|
|
isDate,
|
|
isFile,
|
|
isReactNativeBlob,
|
|
isReactNative,
|
|
isBlob,
|
|
isRegExp,
|
|
isFunction,
|
|
isStream,
|
|
isURLSearchParams,
|
|
isTypedArray,
|
|
isFileList,
|
|
forEach,
|
|
merge,
|
|
extend,
|
|
trim,
|
|
stripBOM,
|
|
inherits,
|
|
toFlatObject,
|
|
kindOf,
|
|
kindOfTest,
|
|
endsWith,
|
|
toArray,
|
|
forEachEntry,
|
|
matchAll,
|
|
isHTMLForm,
|
|
hasOwnProperty,
|
|
hasOwnProp: hasOwnProperty, // an alias to avoid ESLint no-prototype-builtins detection
|
|
reduceDescriptors,
|
|
freezeMethods,
|
|
toObjectSet,
|
|
toCamelCase,
|
|
noop,
|
|
toFiniteNumber,
|
|
findKey,
|
|
global: _global,
|
|
isContextDefined,
|
|
isSpecCompliantForm,
|
|
toJSONObject,
|
|
isAsyncFn,
|
|
isThenable,
|
|
setImmediate: _setImmediate,
|
|
asap,
|
|
isIterable,
|
|
};
|