You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

351 lines
8.7 KiB

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