'use strict';12var bind = require('./helpers/bind');34// utils is a library of generic helper functions non-specific to axios56var toString = Object.prototype.toString;78/**9* Determine if a value is an Array10*11* @param {Object} val The value to test12* @returns {boolean} True if value is an Array, otherwise false13*/14function isArray(val) {15return toString.call(val) === '[object Array]';16}1718/**19* Determine if a value is undefined20*21* @param {Object} val The value to test22* @returns {boolean} True if the value is undefined, otherwise false23*/24function isUndefined(val) {25return typeof val === 'undefined';26}2728/**29* Determine if a value is a Buffer30*31* @param {Object} val The value to test32* @returns {boolean} True if value is a Buffer, otherwise false33*/34function isBuffer(val) {35return val !== null && !isUndefined(val) && val.constructor !== null && !isUndefined(val.constructor)36&& typeof val.constructor.isBuffer === 'function' && val.constructor.isBuffer(val);37}3839/**40* Determine if a value is an ArrayBuffer41*42* @param {Object} val The value to test43* @returns {boolean} True if value is an ArrayBuffer, otherwise false44*/45function isArrayBuffer(val) {46return toString.call(val) === '[object ArrayBuffer]';47}4849/**50* Determine if a value is a FormData51*52* @param {Object} val The value to test53* @returns {boolean} True if value is an FormData, otherwise false54*/55function isFormData(val) {56return (typeof FormData !== 'undefined') && (val instanceof FormData);57}5859/**60* Determine if a value is a view on an ArrayBuffer61*62* @param {Object} val The value to test63* @returns {boolean} True if value is a view on an ArrayBuffer, otherwise false64*/65function isArrayBufferView(val) {66var result;67if ((typeof ArrayBuffer !== 'undefined') && (ArrayBuffer.isView)) {68result = ArrayBuffer.isView(val);69} else {70result = (val) && (val.buffer) && (val.buffer instanceof ArrayBuffer);71}72return result;73}7475/**76* Determine if a value is a String77*78* @param {Object} val The value to test79* @returns {boolean} True if value is a String, otherwise false80*/81function isString(val) {82return typeof val === 'string';83}8485/**86* Determine if a value is a Number87*88* @param {Object} val The value to test89* @returns {boolean} True if value is a Number, otherwise false90*/91function isNumber(val) {92return typeof val === 'number';93}9495/**96* Determine if a value is an Object97*98* @param {Object} val The value to test99* @returns {boolean} True if value is an Object, otherwise false100*/101function isObject(val) {102return val !== null && typeof val === 'object';103}104105/**106* Determine if a value is a plain Object107*108* @param {Object} val The value to test109* @return {boolean} True if value is a plain Object, otherwise false110*/111function isPlainObject(val) {112if (toString.call(val) !== '[object Object]') {113return false;114}115116var prototype = Object.getPrototypeOf(val);117return prototype === null || prototype === Object.prototype;118}119120/**121* Determine if a value is a Date122*123* @param {Object} val The value to test124* @returns {boolean} True if value is a Date, otherwise false125*/126function isDate(val) {127return toString.call(val) === '[object Date]';128}129130/**131* Determine if a value is a File132*133* @param {Object} val The value to test134* @returns {boolean} True if value is a File, otherwise false135*/136function isFile(val) {137return toString.call(val) === '[object File]';138}139140/**141* Determine if a value is a Blob142*143* @param {Object} val The value to test144* @returns {boolean} True if value is a Blob, otherwise false145*/146function isBlob(val) {147return toString.call(val) === '[object Blob]';148}149150/**151* Determine if a value is a Function152*153* @param {Object} val The value to test154* @returns {boolean} True if value is a Function, otherwise false155*/156function isFunction(val) {157return toString.call(val) === '[object Function]';158}159160/**161* Determine if a value is a Stream162*163* @param {Object} val The value to test164* @returns {boolean} True if value is a Stream, otherwise false165*/166function isStream(val) {167return isObject(val) && isFunction(val.pipe);168}169170/**171* Determine if a value is a URLSearchParams object172*173* @param {Object} val The value to test174* @returns {boolean} True if value is a URLSearchParams object, otherwise false175*/176function isURLSearchParams(val) {177return typeof URLSearchParams !== 'undefined' && val instanceof URLSearchParams;178}179180/**181* Trim excess whitespace off the beginning and end of a string182*183* @param {String} str The String to trim184* @returns {String} The String freed of excess whitespace185*/186function trim(str) {187return str.trim ? str.trim() : str.replace(/^\s+|\s+$/g, '');188}189190/**191* Determine if we're running in a standard browser environment192*193* This allows axios to run in a web worker, and react-native.194* Both environments support XMLHttpRequest, but not fully standard globals.195*196* web workers:197* typeof window -> undefined198* typeof document -> undefined199*200* react-native:201* navigator.product -> 'ReactNative'202* nativescript203* navigator.product -> 'NativeScript' or 'NS'204*/205function isStandardBrowserEnv() {206if (typeof navigator !== 'undefined' && (navigator.product === 'ReactNative' ||207navigator.product === 'NativeScript' ||208navigator.product === 'NS')) {209return false;210}211return (212typeof window !== 'undefined' &&213typeof document !== 'undefined'214);215}216217/**218* Iterate over an Array or an Object invoking a function for each item.219*220* If `obj` is an Array callback will be called passing221* the value, index, and complete array for each item.222*223* If 'obj' is an Object callback will be called passing224* the value, key, and complete object for each property.225*226* @param {Object|Array} obj The object to iterate227* @param {Function} fn The callback to invoke for each item228*/229function forEach(obj, fn) {230// Don't bother if no value provided231if (obj === null || typeof obj === 'undefined') {232return;233}234235// Force an array if not already something iterable236if (typeof obj !== 'object') {237/*eslint no-param-reassign:0*/238obj = [obj];239}240241if (isArray(obj)) {242// Iterate over array values243for (var i = 0, l = obj.length; i < l; i++) {244fn.call(null, obj[i], i, obj);245}246} else {247// Iterate over object keys248for (var key in obj) {249if (Object.prototype.hasOwnProperty.call(obj, key)) {250fn.call(null, obj[key], key, obj);251}252}253}254}255256/**257* Accepts varargs expecting each argument to be an object, then258* immutably merges the properties of each object and returns result.259*260* When multiple objects contain the same key the later object in261* the arguments list will take precedence.262*263* Example:264*265* ```js266* var result = merge({foo: 123}, {foo: 456});267* console.log(result.foo); // outputs 456268* ```269*270* @param {Object} obj1 Object to merge271* @returns {Object} Result of all merge properties272*/273function merge(/* obj1, obj2, obj3, ... */) {274var result = {};275function assignValue(val, key) {276if (isPlainObject(result[key]) && isPlainObject(val)) {277result[key] = merge(result[key], val);278} else if (isPlainObject(val)) {279result[key] = merge({}, val);280} else if (isArray(val)) {281result[key] = val.slice();282} else {283result[key] = val;284}285}286287for (var i = 0, l = arguments.length; i < l; i++) {288forEach(arguments[i], assignValue);289}290return result;291}292293/**294* Extends object a by mutably adding to it the properties of object b.295*296* @param {Object} a The object to be extended297* @param {Object} b The object to copy properties from298* @param {Object} thisArg The object to bind function to299* @return {Object} The resulting value of object a300*/301function extend(a, b, thisArg) {302forEach(b, function assignValue(val, key) {303if (thisArg && typeof val === 'function') {304a[key] = bind(val, thisArg);305} else {306a[key] = val;307}308});309return a;310}311312/**313* Remove byte order marker. This catches EF BB BF (the UTF-8 BOM)314*315* @param {string} content with BOM316* @return {string} content value without BOM317*/318function stripBOM(content) {319if (content.charCodeAt(0) === 0xFEFF) {320content = content.slice(1);321}322return content;323}324325module.exports = {326isArray: isArray,327isArrayBuffer: isArrayBuffer,328isBuffer: isBuffer,329isFormData: isFormData,330isArrayBufferView: isArrayBufferView,331isString: isString,332isNumber: isNumber,333isObject: isObject,334isPlainObject: isPlainObject,335isUndefined: isUndefined,336isDate: isDate,337isFile: isFile,338isBlob: isBlob,339isFunction: isFunction,340isStream: isStream,341isURLSearchParams: isURLSearchParams,342isStandardBrowserEnv: isStandardBrowserEnv,343forEach: forEach,344merge: merge,345extend: extend,346trim: trim,347stripBOM: stripBOM348};349350351