UNPKG

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