1 | ;
|
2 |
|
3 | var bind = require('./helpers/bind');
|
4 |
|
5 | // utils is a library of generic helper functions non-specific to axios
|
6 |
|
7 | var 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 | */
|
15 | function 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 | */
|
25 | function 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 | */
|
35 | function 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 | */
|
46 | function 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 | */
|
56 | function 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 | */
|
66 | function 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 | */
|
82 | function 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 | */
|
92 | function 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 | */
|
102 | function 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 | */
|
112 | function 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 | */
|
127 | function 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 | */
|
137 | function 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 | */
|
147 | function 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 | */
|
157 | function 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 | */
|
167 | function 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 | */
|
177 | function 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 | */
|
187 | function 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 | */
|
206 | function 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 | */
|
230 | function 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 | */
|
274 | function 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 | */
|
302 | function 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 | */
|
319 | function stripBOM(content) {
|
320 | if (content.charCodeAt(0) === 0xFEFF) {
|
321 | content = content.slice(1);
|
322 | }
|
323 | return content;
|
324 | }
|
325 |
|
326 | module.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 | };
|