utils.js 7.3 KB

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