utils.js 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349
  1. 'use strict';
  2. var bind = require('./helpers/bind');
  3. // utils is a library of generic helper functions non-specific to axios
  4. var toString = Object.prototype.toString;
  5. /**
  6. * Determine if a value is an Array
  7. *
  8. * @param {Object} val The value to test
  9. * @returns {boolean} True if value is an Array, otherwise false
  10. */
  11. function isArray(val) {
  12. return Array.isArray(val);
  13. }
  14. /**
  15. * Determine if a value is undefined
  16. *
  17. * @param {Object} val The value to test
  18. * @returns {boolean} True if the value is undefined, otherwise false
  19. */
  20. function isUndefined(val) {
  21. return typeof val === 'undefined';
  22. }
  23. /**
  24. * Determine if a value is a Buffer
  25. *
  26. * @param {Object} val The value to test
  27. * @returns {boolean} True if value is a Buffer, otherwise false
  28. */
  29. function isBuffer(val) {
  30. return val !== null && !isUndefined(val) && val.constructor !== null && !isUndefined(val.constructor)
  31. && typeof val.constructor.isBuffer === 'function' && val.constructor.isBuffer(val);
  32. }
  33. /**
  34. * Determine if a value is an ArrayBuffer
  35. *
  36. * @param {Object} val The value to test
  37. * @returns {boolean} True if value is an ArrayBuffer, otherwise false
  38. */
  39. function isArrayBuffer(val) {
  40. return toString.call(val) === '[object ArrayBuffer]';
  41. }
  42. /**
  43. * Determine if a value is a FormData
  44. *
  45. * @param {Object} val The value to test
  46. * @returns {boolean} True if value is an FormData, otherwise false
  47. */
  48. function isFormData(val) {
  49. return toString.call(val) === '[object FormData]';
  50. }
  51. /**
  52. * Determine if a value is a view on an ArrayBuffer
  53. *
  54. * @param {Object} val The value to test
  55. * @returns {boolean} True if value is a view on an ArrayBuffer, otherwise false
  56. */
  57. function isArrayBufferView(val) {
  58. var result;
  59. if ((typeof ArrayBuffer !== 'undefined') && (ArrayBuffer.isView)) {
  60. result = ArrayBuffer.isView(val);
  61. } else {
  62. result = (val) && (val.buffer) && (isArrayBuffer(val.buffer));
  63. }
  64. return result;
  65. }
  66. /**
  67. * Determine if a value is a String
  68. *
  69. * @param {Object} val The value to test
  70. * @returns {boolean} True if value is a String, otherwise false
  71. */
  72. function isString(val) {
  73. return typeof val === 'string';
  74. }
  75. /**
  76. * Determine if a value is a Number
  77. *
  78. * @param {Object} val The value to test
  79. * @returns {boolean} True if value is a Number, otherwise false
  80. */
  81. function isNumber(val) {
  82. return typeof val === 'number';
  83. }
  84. /**
  85. * Determine if a value is an Object
  86. *
  87. * @param {Object} val The value to test
  88. * @returns {boolean} True if value is an Object, otherwise false
  89. */
  90. function isObject(val) {
  91. return val !== null && typeof val === 'object';
  92. }
  93. /**
  94. * Determine if a value is a plain Object
  95. *
  96. * @param {Object} val The value to test
  97. * @return {boolean} True if value is a plain Object, otherwise false
  98. */
  99. function isPlainObject(val) {
  100. if (toString.call(val) !== '[object Object]') {
  101. return false;
  102. }
  103. var prototype = Object.getPrototypeOf(val);
  104. return prototype === null || prototype === Object.prototype;
  105. }
  106. /**
  107. * Determine if a value is a Date
  108. *
  109. * @param {Object} val The value to test
  110. * @returns {boolean} True if value is a Date, otherwise false
  111. */
  112. function isDate(val) {
  113. return toString.call(val) === '[object Date]';
  114. }
  115. /**
  116. * Determine if a value is a File
  117. *
  118. * @param {Object} val The value to test
  119. * @returns {boolean} True if value is a File, otherwise false
  120. */
  121. function isFile(val) {
  122. return toString.call(val) === '[object File]';
  123. }
  124. /**
  125. * Determine if a value is a Blob
  126. *
  127. * @param {Object} val The value to test
  128. * @returns {boolean} True if value is a Blob, otherwise false
  129. */
  130. function isBlob(val) {
  131. return toString.call(val) === '[object Blob]';
  132. }
  133. /**
  134. * Determine if a value is a Function
  135. *
  136. * @param {Object} val The value to test
  137. * @returns {boolean} True if value is a Function, otherwise false
  138. */
  139. function isFunction(val) {
  140. return toString.call(val) === '[object Function]';
  141. }
  142. /**
  143. * Determine if a value is a Stream
  144. *
  145. * @param {Object} val The value to test
  146. * @returns {boolean} True if value is a Stream, otherwise false
  147. */
  148. function isStream(val) {
  149. return isObject(val) && isFunction(val.pipe);
  150. }
  151. /**
  152. * Determine if a value is a URLSearchParams object
  153. *
  154. * @param {Object} val The value to test
  155. * @returns {boolean} True if value is a URLSearchParams object, otherwise false
  156. */
  157. function isURLSearchParams(val) {
  158. return toString.call(val) === '[object URLSearchParams]';
  159. }
  160. /**
  161. * Trim excess whitespace off the beginning and end of a string
  162. *
  163. * @param {String} str The String to trim
  164. * @returns {String} The String freed of excess whitespace
  165. */
  166. function trim(str) {
  167. return str.trim ? str.trim() : str.replace(/^\s+|\s+$/g, '');
  168. }
  169. /**
  170. * Determine if we're running in a standard browser environment
  171. *
  172. * This allows axios to run in a web worker, and react-native.
  173. * Both environments support XMLHttpRequest, but not fully standard globals.
  174. *
  175. * web workers:
  176. * typeof window -> undefined
  177. * typeof document -> undefined
  178. *
  179. * react-native:
  180. * navigator.product -> 'ReactNative'
  181. * nativescript
  182. * navigator.product -> 'NativeScript' or 'NS'
  183. */
  184. function isStandardBrowserEnv() {
  185. if (typeof navigator !== 'undefined' && (navigator.product === 'ReactNative' ||
  186. navigator.product === 'NativeScript' ||
  187. navigator.product === 'NS')) {
  188. return false;
  189. }
  190. return (
  191. typeof window !== 'undefined' &&
  192. typeof document !== 'undefined'
  193. );
  194. }
  195. /**
  196. * Iterate over an Array or an Object invoking a function for each item.
  197. *
  198. * If `obj` is an Array callback will be called passing
  199. * the value, index, and complete array for each item.
  200. *
  201. * If 'obj' is an Object callback will be called passing
  202. * the value, key, and complete object for each property.
  203. *
  204. * @param {Object|Array} obj The object to iterate
  205. * @param {Function} fn The callback to invoke for each item
  206. */
  207. function forEach(obj, fn) {
  208. // Don't bother if no value provided
  209. if (obj === null || typeof obj === 'undefined') {
  210. return;
  211. }
  212. // Force an array if not already something iterable
  213. if (typeof obj !== 'object') {
  214. /*eslint no-param-reassign:0*/
  215. obj = [obj];
  216. }
  217. if (isArray(obj)) {
  218. // Iterate over array values
  219. for (var i = 0, l = obj.length; i < l; i++) {
  220. fn.call(null, obj[i], i, obj);
  221. }
  222. } else {
  223. // Iterate over object keys
  224. for (var key in obj) {
  225. if (Object.prototype.hasOwnProperty.call(obj, key)) {
  226. fn.call(null, obj[key], key, obj);
  227. }
  228. }
  229. }
  230. }
  231. /**
  232. * Accepts varargs expecting each argument to be an object, then
  233. * immutably merges the properties of each object and returns result.
  234. *
  235. * When multiple objects contain the same key the later object in
  236. * the arguments list will take precedence.
  237. *
  238. * Example:
  239. *
  240. * ```js
  241. * var result = merge({foo: 123}, {foo: 456});
  242. * console.log(result.foo); // outputs 456
  243. * ```
  244. *
  245. * @param {Object} obj1 Object to merge
  246. * @returns {Object} Result of all merge properties
  247. */
  248. function merge(/* obj1, obj2, obj3, ... */) {
  249. var result = {};
  250. function assignValue(val, key) {
  251. if (isPlainObject(result[key]) && isPlainObject(val)) {
  252. result[key] = merge(result[key], val);
  253. } else if (isPlainObject(val)) {
  254. result[key] = merge({}, val);
  255. } else if (isArray(val)) {
  256. result[key] = val.slice();
  257. } else {
  258. result[key] = val;
  259. }
  260. }
  261. for (var i = 0, l = arguments.length; i < l; i++) {
  262. forEach(arguments[i], assignValue);
  263. }
  264. return result;
  265. }
  266. /**
  267. * Extends object a by mutably adding to it the properties of object b.
  268. *
  269. * @param {Object} a The object to be extended
  270. * @param {Object} b The object to copy properties from
  271. * @param {Object} thisArg The object to bind function to
  272. * @return {Object} The resulting value of object a
  273. */
  274. function extend(a, b, thisArg) {
  275. forEach(b, function assignValue(val, key) {
  276. if (thisArg && typeof val === 'function') {
  277. a[key] = bind(val, thisArg);
  278. } else {
  279. a[key] = val;
  280. }
  281. });
  282. return a;
  283. }
  284. /**
  285. * Remove byte order marker. This catches EF BB BF (the UTF-8 BOM)
  286. *
  287. * @param {string} content with BOM
  288. * @return {string} content value without BOM
  289. */
  290. function stripBOM(content) {
  291. if (content.charCodeAt(0) === 0xFEFF) {
  292. content = content.slice(1);
  293. }
  294. return content;
  295. }
  296. module.exports = {
  297. isArray: isArray,
  298. isArrayBuffer: isArrayBuffer,
  299. isBuffer: isBuffer,
  300. isFormData: isFormData,
  301. isArrayBufferView: isArrayBufferView,
  302. isString: isString,
  303. isNumber: isNumber,
  304. isObject: isObject,
  305. isPlainObject: isPlainObject,
  306. isUndefined: isUndefined,
  307. isDate: isDate,
  308. isFile: isFile,
  309. isBlob: isBlob,
  310. isFunction: isFunction,
  311. isStream: isStream,
  312. isURLSearchParams: isURLSearchParams,
  313. isStandardBrowserEnv: isStandardBrowserEnv,
  314. forEach: forEach,
  315. merge: merge,
  316. extend: extend,
  317. trim: trim,
  318. stripBOM: stripBOM
  319. };