utils.js 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029
  1. 'use strict';
  2. import bind from './helpers/bind.js';
  3. // utils is a library of generic helper functions non-specific to axios
  4. const { toString } = Object.prototype;
  5. const { getPrototypeOf } = Object;
  6. const { iterator, toStringTag } = Symbol;
  7. /* Creating a function that will check if an object has a property. */
  8. const hasOwnProperty = (
  9. ({ hasOwnProperty }) =>
  10. (obj, prop) =>
  11. hasOwnProperty.call(obj, prop)
  12. )(Object.prototype);
  13. /**
  14. * Walk the prototype chain (excluding the shared Object.prototype) looking for
  15. * an own `prop`. This distinguishes genuine own/inherited members — including
  16. * class accessors and template prototypes — from members injected via
  17. * Object.prototype pollution (e.g. `Object.prototype.username = '...'`), which
  18. * live on Object.prototype itself and are therefore never matched.
  19. *
  20. * @param {*} thing The value whose chain to inspect
  21. * @param {string|symbol} prop The property key to look for
  22. *
  23. * @returns {boolean} True when `prop` is owned below Object.prototype
  24. */
  25. const hasOwnInPrototypeChain = (thing, prop) => {
  26. let obj = thing;
  27. const seen = [];
  28. while (obj != null && obj !== Object.prototype) {
  29. if (seen.indexOf(obj) !== -1) {
  30. return false;
  31. }
  32. seen.push(obj);
  33. if (hasOwnProperty(obj, prop)) {
  34. return true;
  35. }
  36. obj = getPrototypeOf(obj);
  37. }
  38. return false;
  39. };
  40. /**
  41. * Read `obj[prop]` only when it is safe from Object.prototype pollution. Own
  42. * properties and members inherited from a non-Object.prototype source (a class
  43. * instance or template object) are honored; a value reachable only through a
  44. * polluted Object.prototype is ignored and `undefined` is returned.
  45. *
  46. * @param {*} obj The source object
  47. * @param {string|symbol} prop The property key to read
  48. *
  49. * @returns {*} The resolved value, or undefined when unsafe/absent
  50. */
  51. const getSafeProp = (obj, prop) =>
  52. obj != null && hasOwnInPrototypeChain(obj, prop) ? obj[prop] : undefined;
  53. const kindOf = ((cache) => (thing) => {
  54. const str = toString.call(thing);
  55. return cache[str] || (cache[str] = str.slice(8, -1).toLowerCase());
  56. })(Object.create(null));
  57. const kindOfTest = (type) => {
  58. type = type.toLowerCase();
  59. return (thing) => kindOf(thing) === type;
  60. };
  61. const typeOfTest = (type) => (thing) => typeof thing === type;
  62. /**
  63. * Determine if a value is a non-null object
  64. *
  65. * @param {Object} val The value to test
  66. *
  67. * @returns {boolean} True if value is an Array, otherwise false
  68. */
  69. const { isArray } = Array;
  70. /**
  71. * Determine if a value is undefined
  72. *
  73. * @param {*} val The value to test
  74. *
  75. * @returns {boolean} True if the value is undefined, otherwise false
  76. */
  77. const isUndefined = typeOfTest('undefined');
  78. /**
  79. * Determine if a value is a Buffer
  80. *
  81. * @param {*} val The value to test
  82. *
  83. * @returns {boolean} True if value is a Buffer, otherwise false
  84. */
  85. function isBuffer(val) {
  86. return (
  87. val !== null &&
  88. !isUndefined(val) &&
  89. val.constructor !== null &&
  90. !isUndefined(val.constructor) &&
  91. isFunction(val.constructor.isBuffer) &&
  92. val.constructor.isBuffer(val)
  93. );
  94. }
  95. /**
  96. * Determine if a value is an ArrayBuffer
  97. *
  98. * @param {*} val The value to test
  99. *
  100. * @returns {boolean} True if value is an ArrayBuffer, otherwise false
  101. */
  102. const isArrayBuffer = kindOfTest('ArrayBuffer');
  103. /**
  104. * Determine if a value is a view on an ArrayBuffer
  105. *
  106. * @param {*} val The value to test
  107. *
  108. * @returns {boolean} True if value is a view on an ArrayBuffer, otherwise false
  109. */
  110. function isArrayBufferView(val) {
  111. let result;
  112. if (typeof ArrayBuffer !== 'undefined' && ArrayBuffer.isView) {
  113. result = ArrayBuffer.isView(val);
  114. } else {
  115. result = val && val.buffer && isArrayBuffer(val.buffer);
  116. }
  117. return result;
  118. }
  119. /**
  120. * Determine if a value is a String
  121. *
  122. * @param {*} val The value to test
  123. *
  124. * @returns {boolean} True if value is a String, otherwise false
  125. */
  126. const isString = typeOfTest('string');
  127. /**
  128. * Determine if a value is a Function
  129. *
  130. * @param {*} val The value to test
  131. * @returns {boolean} True if value is a Function, otherwise false
  132. */
  133. const isFunction = typeOfTest('function');
  134. /**
  135. * Determine if a value is a Number
  136. *
  137. * @param {*} val The value to test
  138. *
  139. * @returns {boolean} True if value is a Number, otherwise false
  140. */
  141. const isNumber = typeOfTest('number');
  142. /**
  143. * Determine if a value is an Object
  144. *
  145. * @param {*} thing The value to test
  146. *
  147. * @returns {boolean} True if value is an Object, otherwise false
  148. */
  149. const isObject = (thing) => thing !== null && typeof thing === 'object';
  150. /**
  151. * Determine if a value is a Boolean
  152. *
  153. * @param {*} thing The value to test
  154. * @returns {boolean} True if value is a Boolean, otherwise false
  155. */
  156. const isBoolean = (thing) => thing === true || thing === false;
  157. /**
  158. * Determine if a value is a plain Object
  159. *
  160. * @param {*} val The value to test
  161. *
  162. * @returns {boolean} True if value is a plain Object, otherwise false
  163. */
  164. const isPlainObject = (val) => {
  165. if (!isObject(val)) {
  166. return false;
  167. }
  168. const prototype = getPrototypeOf(val);
  169. return (
  170. (prototype === null ||
  171. prototype === Object.prototype ||
  172. getPrototypeOf(prototype) === null) &&
  173. // Treat any genuine (non-Object.prototype-polluted) Symbol.toStringTag or
  174. // Symbol.iterator as evidence the value is a tagged/iterable type rather
  175. // than a plain object, while ignoring keys injected onto Object.prototype.
  176. !hasOwnInPrototypeChain(val, toStringTag) &&
  177. !hasOwnInPrototypeChain(val, iterator)
  178. );
  179. };
  180. /**
  181. * Determine if a value is an empty object (safely handles Buffers)
  182. *
  183. * @param {*} val The value to test
  184. *
  185. * @returns {boolean} True if value is an empty object, otherwise false
  186. */
  187. const isEmptyObject = (val) => {
  188. // Early return for non-objects or Buffers to prevent RangeError
  189. if (!isObject(val) || isBuffer(val)) {
  190. return false;
  191. }
  192. try {
  193. return Object.keys(val).length === 0 && Object.getPrototypeOf(val) === Object.prototype;
  194. } catch (e) {
  195. // Fallback for any other objects that might cause RangeError with Object.keys()
  196. return false;
  197. }
  198. };
  199. /**
  200. * Determine if a value is a Date
  201. *
  202. * @param {*} val The value to test
  203. *
  204. * @returns {boolean} True if value is a Date, otherwise false
  205. */
  206. const isDate = kindOfTest('Date');
  207. /**
  208. * Determine if a value is a File
  209. *
  210. * @param {*} val The value to test
  211. *
  212. * @returns {boolean} True if value is a File, otherwise false
  213. */
  214. const isFile = kindOfTest('File');
  215. /**
  216. * Determine if a value is a React Native Blob
  217. * React Native "blob": an object with a `uri` attribute. Optionally, it can
  218. * also have a `name` and `type` attribute to specify filename and content type
  219. *
  220. * @see https://github.com/facebook/react-native/blob/26684cf3adf4094eb6c405d345a75bf8c7c0bf88/Libraries/Network/FormData.js#L68-L71
  221. *
  222. * @param {*} value The value to test
  223. *
  224. * @returns {boolean} True if value is a React Native Blob, otherwise false
  225. */
  226. const isReactNativeBlob = (value) => {
  227. return !!(value && typeof value.uri !== 'undefined');
  228. };
  229. /**
  230. * Determine if environment is React Native
  231. * ReactNative `FormData` has a non-standard `getParts()` method
  232. *
  233. * @param {*} formData The formData to test
  234. *
  235. * @returns {boolean} True if environment is React Native, otherwise false
  236. */
  237. const isReactNative = (formData) => formData && typeof formData.getParts !== 'undefined';
  238. /**
  239. * Determine if a value is a Blob
  240. *
  241. * @param {*} val The value to test
  242. *
  243. * @returns {boolean} True if value is a Blob, otherwise false
  244. */
  245. const isBlob = kindOfTest('Blob');
  246. /**
  247. * Determine if a value is a FileList
  248. *
  249. * @param {*} val The value to test
  250. *
  251. * @returns {boolean} True if value is a FileList, otherwise false
  252. */
  253. const isFileList = kindOfTest('FileList');
  254. const isSet = kindOfTest('Set');
  255. /**
  256. * Determine if a value is a Stream
  257. *
  258. * @param {*} val The value to test
  259. *
  260. * @returns {boolean} True if value is a Stream, otherwise false
  261. */
  262. const isStream = (val) => isObject(val) && isFunction(val.pipe);
  263. /**
  264. * Determine if a value is a FormData
  265. *
  266. * @param {*} thing The value to test
  267. *
  268. * @returns {boolean} True if value is an FormData, otherwise false
  269. */
  270. function getGlobal() {
  271. if (typeof globalThis !== 'undefined') return globalThis;
  272. if (typeof self !== 'undefined') return self;
  273. if (typeof window !== 'undefined') return window;
  274. if (typeof global !== 'undefined') return global;
  275. return {};
  276. }
  277. const G = getGlobal();
  278. const FormDataCtor = typeof G.FormData !== 'undefined' ? G.FormData : undefined;
  279. const isFormData = (thing) => {
  280. if (!thing) return false;
  281. if (FormDataCtor && thing instanceof FormDataCtor) return true;
  282. // Reject plain objects inheriting directly from Object.prototype so prototype-pollution gadgets can't spoof FormData.
  283. const proto = getPrototypeOf(thing);
  284. if (!proto || proto === Object.prototype) return false;
  285. if (!isFunction(thing.append)) return false;
  286. const kind = kindOf(thing);
  287. return (
  288. kind === 'formdata' ||
  289. // detect form-data instance
  290. (kind === 'object' && isFunction(thing.toString) && thing.toString() === '[object FormData]')
  291. );
  292. };
  293. /**
  294. * Determine if a value is a URLSearchParams object
  295. *
  296. * @param {*} val The value to test
  297. *
  298. * @returns {boolean} True if value is a URLSearchParams object, otherwise false
  299. */
  300. const isURLSearchParams = kindOfTest('URLSearchParams');
  301. const [isReadableStream, isRequest, isResponse, isHeaders] = [
  302. 'ReadableStream',
  303. 'Request',
  304. 'Response',
  305. 'Headers',
  306. ].map(kindOfTest);
  307. /**
  308. * Trim excess whitespace off the beginning and end of a string
  309. *
  310. * @param {String} str The String to trim
  311. *
  312. * @returns {String} The String freed of excess whitespace
  313. */
  314. const trim = (str) => {
  315. return str.trim ? str.trim() : str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '');
  316. };
  317. /**
  318. * Iterate over an Array or an Object invoking a function for each item.
  319. *
  320. * If `obj` is an Array callback will be called passing
  321. * the value, index, and complete array for each item.
  322. *
  323. * If 'obj' is an Object callback will be called passing
  324. * the value, key, and complete object for each property.
  325. *
  326. * @param {Object|Array<unknown>} obj The object to iterate
  327. * @param {Function} fn The callback to invoke for each item
  328. *
  329. * @param {Object} [options]
  330. * @param {Boolean} [options.allOwnKeys = false]
  331. * @returns {any}
  332. */
  333. function forEach(obj, fn, { allOwnKeys = false } = {}) {
  334. // Don't bother if no value provided
  335. if (obj === null || typeof obj === 'undefined') {
  336. return;
  337. }
  338. let i;
  339. let l;
  340. // Force an array if not already something iterable
  341. if (typeof obj !== 'object') {
  342. /*eslint no-param-reassign:0*/
  343. obj = [obj];
  344. }
  345. if (isArray(obj)) {
  346. // Iterate over array values
  347. for (i = 0, l = obj.length; i < l; i++) {
  348. fn.call(null, obj[i], i, obj);
  349. }
  350. } else {
  351. // Buffer check
  352. if (isBuffer(obj)) {
  353. return;
  354. }
  355. // Iterate over object keys
  356. const keys = allOwnKeys ? Object.getOwnPropertyNames(obj) : Object.keys(obj);
  357. const len = keys.length;
  358. let key;
  359. for (i = 0; i < len; i++) {
  360. key = keys[i];
  361. fn.call(null, obj[key], key, obj);
  362. }
  363. }
  364. }
  365. /**
  366. * Finds a key in an object, case-insensitive, returning the actual key name.
  367. * Returns null if the object is a Buffer or if no match is found.
  368. *
  369. * @param {Object} obj - The object to search.
  370. * @param {string} key - The key to find (case-insensitive).
  371. * @returns {?string} The actual key name if found, otherwise null.
  372. */
  373. function findKey(obj, key) {
  374. if (isBuffer(obj)) {
  375. return null;
  376. }
  377. key = key.toLowerCase();
  378. const keys = Object.keys(obj);
  379. let i = keys.length;
  380. let _key;
  381. while (i-- > 0) {
  382. _key = keys[i];
  383. if (key === _key.toLowerCase()) {
  384. return _key;
  385. }
  386. }
  387. return null;
  388. }
  389. const _global = (() => {
  390. /*eslint no-undef:0*/
  391. if (typeof globalThis !== 'undefined') return globalThis;
  392. return typeof self !== 'undefined' ? self : typeof window !== 'undefined' ? window : global;
  393. })();
  394. const isContextDefined = (context) => !isUndefined(context) && context !== _global;
  395. /**
  396. * Accepts varargs expecting each argument to be an object, then
  397. * immutably merges the properties of each object and returns result.
  398. *
  399. * When multiple objects contain the same key the later object in
  400. * the arguments list will take precedence.
  401. *
  402. * Example:
  403. *
  404. * ```js
  405. * const result = merge({foo: 123}, {foo: 456});
  406. * console.log(result.foo); // outputs 456
  407. * ```
  408. *
  409. * @param {Object} obj1 Object to merge
  410. *
  411. * @returns {Object} Result of all merge properties
  412. */
  413. function merge(...objs) {
  414. const { caseless, skipUndefined } = (isContextDefined(this) && this) || {};
  415. const result = {};
  416. const assignValue = (val, key) => {
  417. // Skip dangerous property names to prevent prototype pollution
  418. if (key === '__proto__' || key === 'constructor' || key === 'prototype') {
  419. return;
  420. }
  421. // findKey lowercases the key, so caseless lookup only applies to strings —
  422. // symbol keys are identity-matched.
  423. const targetKey = (caseless && typeof key === 'string' && findKey(result, key)) || key;
  424. // Read via own-prop only — a bare `result[targetKey]` walks the prototype
  425. // chain, so a polluted Object.prototype value could surface here and get
  426. // copied into the merged result.
  427. const existing = hasOwnProperty(result, targetKey) ? result[targetKey] : undefined;
  428. if (isPlainObject(existing) && isPlainObject(val)) {
  429. result[targetKey] = merge(existing, val);
  430. } else if (isPlainObject(val)) {
  431. result[targetKey] = merge({}, val);
  432. } else if (isArray(val)) {
  433. result[targetKey] = val.slice();
  434. } else if (!skipUndefined || !isUndefined(val)) {
  435. result[targetKey] = val;
  436. }
  437. };
  438. for (let i = 0, l = objs.length; i < l; i++) {
  439. const source = objs[i];
  440. if (!source || isBuffer(source)) {
  441. continue;
  442. }
  443. forEach(source, assignValue);
  444. if (typeof source !== 'object' || isArray(source)) {
  445. continue;
  446. }
  447. const symbols = Object.getOwnPropertySymbols(source);
  448. for (let j = 0; j < symbols.length; j++) {
  449. const symbol = symbols[j];
  450. if (propertyIsEnumerable.call(source, symbol)) {
  451. assignValue(source[symbol], symbol);
  452. }
  453. }
  454. }
  455. return result;
  456. }
  457. /**
  458. * Extends object a by mutably adding to it the properties of object b.
  459. *
  460. * @param {Object} a The object to be extended
  461. * @param {Object} b The object to copy properties from
  462. * @param {Object} thisArg The object to bind function to
  463. *
  464. * @param {Object} [options]
  465. * @param {Boolean} [options.allOwnKeys]
  466. * @returns {Object} The resulting value of object a
  467. */
  468. const extend = (a, b, thisArg, { allOwnKeys } = {}) => {
  469. forEach(
  470. b,
  471. (val, key) => {
  472. if (thisArg && isFunction(val)) {
  473. Object.defineProperty(a, key, {
  474. // Null-proto descriptor so a polluted Object.prototype.get cannot
  475. // hijack defineProperty's accessor-vs-data resolution.
  476. __proto__: null,
  477. value: bind(val, thisArg),
  478. writable: true,
  479. enumerable: true,
  480. configurable: true,
  481. });
  482. } else {
  483. Object.defineProperty(a, key, {
  484. __proto__: null,
  485. value: val,
  486. writable: true,
  487. enumerable: true,
  488. configurable: true,
  489. });
  490. }
  491. },
  492. { allOwnKeys }
  493. );
  494. return a;
  495. };
  496. /**
  497. * Remove byte order marker. This catches EF BB BF (the UTF-8 BOM)
  498. *
  499. * @param {string} content with BOM
  500. *
  501. * @returns {string} content value without BOM
  502. */
  503. const stripBOM = (content) => {
  504. if (content.charCodeAt(0) === 0xfeff) {
  505. content = content.slice(1);
  506. }
  507. return content;
  508. };
  509. /**
  510. * Inherit the prototype methods from one constructor into another
  511. * @param {function} constructor
  512. * @param {function} superConstructor
  513. * @param {object} [props]
  514. * @param {object} [descriptors]
  515. *
  516. * @returns {void}
  517. */
  518. const inherits = (constructor, superConstructor, props, descriptors) => {
  519. constructor.prototype = Object.create(superConstructor.prototype, descriptors);
  520. Object.defineProperty(constructor.prototype, 'constructor', {
  521. __proto__: null,
  522. value: constructor,
  523. writable: true,
  524. enumerable: false,
  525. configurable: true,
  526. });
  527. Object.defineProperty(constructor, 'super', {
  528. __proto__: null,
  529. value: superConstructor.prototype,
  530. });
  531. props && Object.assign(constructor.prototype, props);
  532. };
  533. /**
  534. * Resolve object with deep prototype chain to a flat object
  535. * @param {Object} sourceObj source object
  536. * @param {Object} [destObj]
  537. * @param {Function|Boolean} [filter]
  538. * @param {Function} [propFilter]
  539. *
  540. * @returns {Object}
  541. */
  542. const toFlatObject = (sourceObj, destObj, filter, propFilter) => {
  543. let props;
  544. let i;
  545. let prop;
  546. const merged = {};
  547. destObj = destObj || {};
  548. // eslint-disable-next-line no-eq-null,eqeqeq
  549. if (sourceObj == null) return destObj;
  550. do {
  551. props = Object.getOwnPropertyNames(sourceObj);
  552. i = props.length;
  553. while (i-- > 0) {
  554. prop = props[i];
  555. if ((!propFilter || propFilter(prop, sourceObj, destObj)) && !merged[prop]) {
  556. destObj[prop] = sourceObj[prop];
  557. merged[prop] = true;
  558. }
  559. }
  560. sourceObj = filter !== false && getPrototypeOf(sourceObj);
  561. } while (sourceObj && (!filter || filter(sourceObj, destObj)) && sourceObj !== Object.prototype);
  562. return destObj;
  563. };
  564. /**
  565. * Determines whether a string ends with the characters of a specified string
  566. *
  567. * @param {String} str
  568. * @param {String} searchString
  569. * @param {Number} [position= 0]
  570. *
  571. * @returns {boolean}
  572. */
  573. const endsWith = (str, searchString, position) => {
  574. str = String(str);
  575. if (position === undefined || position > str.length) {
  576. position = str.length;
  577. }
  578. position -= searchString.length;
  579. const lastIndex = str.indexOf(searchString, position);
  580. return lastIndex !== -1 && lastIndex === position;
  581. };
  582. /**
  583. * Returns new array from array like object or null if failed
  584. *
  585. * @param {*} [thing]
  586. *
  587. * @returns {?Array}
  588. */
  589. const toArray = (thing) => {
  590. if (!thing) return null;
  591. if (isArray(thing)) return thing;
  592. let i = thing.length;
  593. if (!isNumber(i)) return null;
  594. const arr = new Array(i);
  595. while (i-- > 0) {
  596. arr[i] = thing[i];
  597. }
  598. return arr;
  599. };
  600. /**
  601. * Checking if the Uint8Array exists and if it does, it returns a function that checks if the
  602. * thing passed in is an instance of Uint8Array
  603. *
  604. * @param {TypedArray}
  605. *
  606. * @returns {Array}
  607. */
  608. // eslint-disable-next-line func-names
  609. const isTypedArray = ((TypedArray) => {
  610. // eslint-disable-next-line func-names
  611. return (thing) => {
  612. return TypedArray && thing instanceof TypedArray;
  613. };
  614. })(typeof Uint8Array !== 'undefined' && getPrototypeOf(Uint8Array));
  615. /**
  616. * For each entry in the object, call the function with the key and value.
  617. *
  618. * @param {Object<any, any>} obj - The object to iterate over.
  619. * @param {Function} fn - The function to call for each entry.
  620. *
  621. * @returns {void}
  622. */
  623. const forEachEntry = (obj, fn) => {
  624. const generator = obj && obj[iterator];
  625. const _iterator = generator.call(obj);
  626. let result;
  627. while ((result = _iterator.next()) && !result.done) {
  628. const pair = result.value;
  629. fn.call(obj, pair[0], pair[1]);
  630. }
  631. };
  632. /**
  633. * It takes a regular expression and a string, and returns an array of all the matches
  634. *
  635. * @param {string} regExp - The regular expression to match against.
  636. * @param {string} str - The string to search.
  637. *
  638. * @returns {Array<boolean>}
  639. */
  640. const matchAll = (regExp, str) => {
  641. let matches;
  642. const arr = [];
  643. while ((matches = regExp.exec(str)) !== null) {
  644. arr.push(matches);
  645. }
  646. return arr;
  647. };
  648. /* Checking if the kindOfTest function returns true when passed an HTMLFormElement. */
  649. const isHTMLForm = kindOfTest('HTMLFormElement');
  650. const toCamelCase = (str) => {
  651. return str.toLowerCase().replace(/[-_\s]([a-z\d])(\w*)/g, function replacer(m, p1, p2) {
  652. return p1.toUpperCase() + p2;
  653. });
  654. };
  655. const { propertyIsEnumerable } = Object.prototype;
  656. /**
  657. * Determine if a value is a RegExp object
  658. *
  659. * @param {*} val The value to test
  660. *
  661. * @returns {boolean} True if value is a RegExp object, otherwise false
  662. */
  663. const isRegExp = kindOfTest('RegExp');
  664. const reduceDescriptors = (obj, reducer) => {
  665. const descriptors = Object.getOwnPropertyDescriptors(obj);
  666. const reducedDescriptors = {};
  667. forEach(descriptors, (descriptor, name) => {
  668. let ret;
  669. if ((ret = reducer(descriptor, name, obj)) !== false) {
  670. reducedDescriptors[name] = ret || descriptor;
  671. }
  672. });
  673. Object.defineProperties(obj, reducedDescriptors);
  674. };
  675. /**
  676. * Makes all methods read-only
  677. * @param {Object} obj
  678. */
  679. const freezeMethods = (obj) => {
  680. reduceDescriptors(obj, (descriptor, name) => {
  681. // skip restricted props in strict mode
  682. if (isFunction(obj) && ['arguments', 'caller', 'callee'].includes(name)) {
  683. return false;
  684. }
  685. const value = obj[name];
  686. if (!isFunction(value)) return;
  687. descriptor.enumerable = false;
  688. if ('writable' in descriptor) {
  689. descriptor.writable = false;
  690. return;
  691. }
  692. if (!descriptor.set) {
  693. descriptor.set = () => {
  694. throw Error("Can not rewrite read-only method '" + name + "'");
  695. };
  696. }
  697. });
  698. };
  699. /**
  700. * Converts an array or a delimited string into an object set with values as keys and true as values.
  701. * Useful for fast membership checks.
  702. *
  703. * @param {Array|string} arrayOrString - The array or string to convert.
  704. * @param {string} delimiter - The delimiter to use if input is a string.
  705. * @returns {Object} An object with keys from the array or string, values set to true.
  706. */
  707. const toObjectSet = (arrayOrString, delimiter) => {
  708. const obj = {};
  709. const define = (arr) => {
  710. arr.forEach((value) => {
  711. obj[value] = true;
  712. });
  713. };
  714. isArray(arrayOrString) ? define(arrayOrString) : define(String(arrayOrString).split(delimiter));
  715. return obj;
  716. };
  717. const noop = () => {};
  718. const toFiniteNumber = (value, defaultValue) => {
  719. return value != null && Number.isFinite((value = +value)) ? value : defaultValue;
  720. };
  721. /**
  722. * If the thing is a FormData object, return true, otherwise return false.
  723. *
  724. * @param {unknown} thing - The thing to check.
  725. *
  726. * @returns {boolean}
  727. */
  728. function isSpecCompliantForm(thing) {
  729. return !!(
  730. thing &&
  731. isFunction(thing.append) &&
  732. thing[toStringTag] === 'FormData' &&
  733. thing[iterator]
  734. );
  735. }
  736. /**
  737. * Recursively converts an object to a JSON-compatible object, handling circular references and Buffers.
  738. *
  739. * @param {Object} obj - The object to convert.
  740. * @returns {Object} The JSON-compatible object.
  741. */
  742. const toJSONObject = (obj) => {
  743. const visited = new WeakSet();
  744. const visit = (source) => {
  745. if (isObject(source)) {
  746. if (visited.has(source)) {
  747. return;
  748. }
  749. //Buffer check
  750. if (isBuffer(source)) {
  751. return source;
  752. }
  753. if (!('toJSON' in source)) {
  754. // add-on descent / delete-on-ascent: preserves path semantics, so DAG nodes serialise at every occurrence (see #7230).
  755. visited.add(source);
  756. let target;
  757. if (isSet(source)) {
  758. target = [];
  759. for (const value of source) {
  760. const reducedValue = visit(value);
  761. !isUndefined(reducedValue) && target.push(reducedValue);
  762. }
  763. } else {
  764. target = isArray(source) ? [] : {};
  765. forEach(source, (value, key) => {
  766. const reducedValue = visit(value);
  767. !isUndefined(reducedValue) && (target[key] = reducedValue);
  768. });
  769. }
  770. visited.delete(source);
  771. return target;
  772. }
  773. }
  774. return source;
  775. };
  776. return visit(obj);
  777. };
  778. /**
  779. * Determines if a value is an async function.
  780. *
  781. * @param {*} thing - The value to test.
  782. * @returns {boolean} True if value is an async function, otherwise false.
  783. */
  784. const isAsyncFn = kindOfTest('AsyncFunction');
  785. /**
  786. * Determines if a value is thenable (has then and catch methods).
  787. *
  788. * @param {*} thing - The value to test.
  789. * @returns {boolean} True if value is thenable, otherwise false.
  790. */
  791. const isThenable = (thing) =>
  792. thing &&
  793. (isObject(thing) || isFunction(thing)) &&
  794. isFunction(thing.then) &&
  795. isFunction(thing.catch);
  796. // original code
  797. // https://github.com/DigitalBrainJS/AxiosPromise/blob/16deab13710ec09779922131f3fa5954320f83ab/lib/utils.js#L11-L34
  798. /**
  799. * Provides a cross-platform setImmediate implementation.
  800. * Uses native setImmediate if available, otherwise falls back to postMessage or setTimeout.
  801. *
  802. * @param {boolean} setImmediateSupported - Whether setImmediate is supported.
  803. * @param {boolean} postMessageSupported - Whether postMessage is supported.
  804. * @returns {Function} A function to schedule a callback asynchronously.
  805. */
  806. const _setImmediate = ((setImmediateSupported, postMessageSupported) => {
  807. if (setImmediateSupported) {
  808. return setImmediate;
  809. }
  810. return postMessageSupported
  811. ? ((token, callbacks) => {
  812. _global.addEventListener(
  813. 'message',
  814. ({ source, data }) => {
  815. if (source === _global && data === token) {
  816. callbacks.length && callbacks.shift()();
  817. }
  818. },
  819. false
  820. );
  821. return (cb) => {
  822. callbacks.push(cb);
  823. _global.postMessage(token, '*');
  824. };
  825. })(`axios@${Math.random()}`, [])
  826. : (cb) => setTimeout(cb);
  827. })(typeof setImmediate === 'function', isFunction(_global.postMessage));
  828. /**
  829. * Schedules a microtask or asynchronous callback as soon as possible.
  830. * Uses queueMicrotask if available, otherwise falls back to process.nextTick or _setImmediate.
  831. *
  832. * @type {Function}
  833. */
  834. const asap =
  835. typeof queueMicrotask !== 'undefined'
  836. ? queueMicrotask.bind(_global)
  837. : (typeof process !== 'undefined' && process.nextTick) || _setImmediate;
  838. // *********************
  839. const isIterable = (thing) => thing != null && isFunction(thing[iterator]);
  840. /**
  841. * Determine if a value is iterable via an iterator that is NOT sourced solely
  842. * from a polluted Object.prototype. Use this instead of `isIterable` whenever
  843. * the iterable comes from untrusted input (e.g. user-supplied header sources),
  844. * so `Object.prototype[Symbol.iterator] = ...` cannot turn an ordinary object
  845. * into an attacker-controlled entries iterator.
  846. *
  847. * @param {*} thing The value to test
  848. *
  849. * @returns {boolean} True if value has a non-polluted iterator
  850. */
  851. const isSafeIterable = (thing) =>
  852. thing != null && hasOwnInPrototypeChain(thing, iterator) && isIterable(thing);
  853. export default {
  854. isArray,
  855. isArrayBuffer,
  856. isBuffer,
  857. isFormData,
  858. isArrayBufferView,
  859. isString,
  860. isNumber,
  861. isBoolean,
  862. isObject,
  863. isPlainObject,
  864. isEmptyObject,
  865. isReadableStream,
  866. isRequest,
  867. isResponse,
  868. isHeaders,
  869. isUndefined,
  870. isDate,
  871. isFile,
  872. isReactNativeBlob,
  873. isReactNative,
  874. isBlob,
  875. isRegExp,
  876. isFunction,
  877. isStream,
  878. isURLSearchParams,
  879. isTypedArray,
  880. isFileList,
  881. forEach,
  882. merge,
  883. extend,
  884. trim,
  885. stripBOM,
  886. inherits,
  887. toFlatObject,
  888. kindOf,
  889. kindOfTest,
  890. endsWith,
  891. toArray,
  892. forEachEntry,
  893. matchAll,
  894. isHTMLForm,
  895. hasOwnProperty,
  896. hasOwnProp: hasOwnProperty, // an alias to avoid ESLint no-prototype-builtins detection
  897. hasOwnInPrototypeChain,
  898. getSafeProp,
  899. reduceDescriptors,
  900. freezeMethods,
  901. toObjectSet,
  902. toCamelCase,
  903. noop,
  904. toFiniteNumber,
  905. findKey,
  906. global: _global,
  907. isContextDefined,
  908. isSpecCompliantForm,
  909. toJSONObject,
  910. isAsyncFn,
  911. isThenable,
  912. setImmediate: _setImmediate,
  913. asap,
  914. isIterable,
  915. isSafeIterable,
  916. };