mirror of
https://github.com/tenrok/axios.git
synced 2026-06-17 19:21:29 +03:00
Axios ES2017 (#4787)
* Added AxiosHeaders class; * Fixed README.md href; * Fixed a potential bug with headers normalization; * Fixed a potential bug with headers normalization; Refactored accessor building routine; Refactored default transforms; Removed `normalizeHeaderName` helper; * Added `Content-Length` accessor; Added missed `has` accessor to TS types; * Added `AxiosTransformStream` class; Added progress capturing ability for node.js environment; Added `maxRate` option to limit the data rate in node.js environment; Refactored event handled by `onUploadProgress` && `onDownloadProgress` listeners in browser environment; Added progress & data rate tests for the http adapter; Added response stream aborting test; Added a manual progress capture test for the browser; Updated TS types; Added TS tests; Refactored request abort logic for the http adapter; Added ability to abort the response stream; * Remove `stream/promises` & `timers/promises` modules usage in tests; * Use `abortcontroller-polyfill`; * Fixed AxiosTransformStream dead-lock in legacy node versions; Fixed CancelError emitting in streams; * Reworked AxiosTransformStream internal logic to optimize memory consumption; Added throwing an error if the request stream was silently destroying (without error) Refers to #3966; * Treat the destruction of the request stream as a cancellation of the request; Fixed tests; * Emit `progress` event in the next tick; * Initial refactoring; * Refactored Mocha tests to use ESM; * Refactored Karma tests to use rollup preprocessor & ESM; Replaced grunt with gulp; Improved dev scripts; Added Babel for rollup build; * Added default commonjs package export for Node build; Added automatic contributors list generator for package.json; Co-authored-by: Jay <jasonsaayman@gmail.com>
This commit is contained in:
@@ -0,0 +1,191 @@
|
||||
'use strict';
|
||||
|
||||
import stream from 'stream';
|
||||
import utils from '../utils.js';
|
||||
import throttle from './throttle.js';
|
||||
import speedometer from './speedometer.js';
|
||||
|
||||
const kInternals = Symbol('internals');
|
||||
|
||||
class AxiosTransformStream extends stream.Transform{
|
||||
constructor(options) {
|
||||
options = utils.toFlatObject(options, {
|
||||
maxRate: 0,
|
||||
chunkSize: 64 * 1024,
|
||||
minChunkSize: 100,
|
||||
timeWindow: 500,
|
||||
ticksRate: 2,
|
||||
samplesCount: 15
|
||||
}, null, (prop, source) => {
|
||||
return !utils.isUndefined(source[prop]);
|
||||
});
|
||||
|
||||
super({
|
||||
readableHighWaterMark: options.chunkSize
|
||||
});
|
||||
|
||||
const self = this;
|
||||
|
||||
const internals = this[kInternals] = {
|
||||
length: options.length,
|
||||
timeWindow: options.timeWindow,
|
||||
ticksRate: options.ticksRate,
|
||||
chunkSize: options.chunkSize,
|
||||
maxRate: options.maxRate,
|
||||
minChunkSize: options.minChunkSize,
|
||||
bytesSeen: 0,
|
||||
isCaptured: false,
|
||||
notifiedBytesLoaded: 0,
|
||||
ts: Date.now(),
|
||||
bytes: 0,
|
||||
onReadCallback: null
|
||||
};
|
||||
|
||||
const _speedometer = speedometer(internals.ticksRate * options.samplesCount, internals.timeWindow);
|
||||
|
||||
this.on('newListener', event => {
|
||||
if (event === 'progress') {
|
||||
if (!internals.isCaptured) {
|
||||
internals.isCaptured = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let bytesNotified = 0;
|
||||
|
||||
internals.updateProgress = throttle(function throttledHandler() {
|
||||
const totalBytes = internals.length;
|
||||
const bytesTransferred = internals.bytesSeen;
|
||||
const progressBytes = bytesTransferred - bytesNotified;
|
||||
if (!progressBytes || self.destroyed) return;
|
||||
|
||||
const rate = _speedometer(progressBytes);
|
||||
|
||||
bytesNotified = bytesTransferred;
|
||||
|
||||
process.nextTick(() => {
|
||||
self.emit('progress', {
|
||||
'loaded': bytesTransferred,
|
||||
'total': totalBytes,
|
||||
'progress': totalBytes ? (bytesTransferred / totalBytes) : undefined,
|
||||
'bytes': progressBytes,
|
||||
'rate': rate ? rate : undefined,
|
||||
'estimated': rate && totalBytes && bytesTransferred <= totalBytes ?
|
||||
(totalBytes - bytesTransferred) / rate : undefined
|
||||
});
|
||||
});
|
||||
}, internals.ticksRate);
|
||||
|
||||
const onFinish = () => {
|
||||
internals.updateProgress(true);
|
||||
};
|
||||
|
||||
this.once('end', onFinish);
|
||||
this.once('error', onFinish);
|
||||
}
|
||||
|
||||
_read(size) {
|
||||
const internals = this[kInternals];
|
||||
|
||||
if (internals.onReadCallback) {
|
||||
internals.onReadCallback();
|
||||
}
|
||||
|
||||
return super._read(size);
|
||||
}
|
||||
|
||||
_transform(chunk, encoding, callback) {
|
||||
const self = this;
|
||||
const internals = this[kInternals];
|
||||
const maxRate = internals.maxRate;
|
||||
|
||||
const readableHighWaterMark = this.readableHighWaterMark;
|
||||
|
||||
const timeWindow = internals.timeWindow;
|
||||
|
||||
const divider = 1000 / timeWindow;
|
||||
const bytesThreshold = (maxRate / divider);
|
||||
const minChunkSize = internals.minChunkSize !== false ? Math.max(internals.minChunkSize, bytesThreshold * 0.01) : 0;
|
||||
|
||||
function pushChunk(_chunk, _callback) {
|
||||
const bytes = Buffer.byteLength(_chunk);
|
||||
internals.bytesSeen += bytes;
|
||||
internals.bytes += bytes;
|
||||
|
||||
if (internals.isCaptured) {
|
||||
internals.updateProgress();
|
||||
}
|
||||
|
||||
if (self.push(_chunk)) {
|
||||
process.nextTick(_callback);
|
||||
} else {
|
||||
internals.onReadCallback = () => {
|
||||
internals.onReadCallback = null;
|
||||
process.nextTick(_callback);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
const transformChunk = (_chunk, _callback) => {
|
||||
const chunkSize = Buffer.byteLength(_chunk);
|
||||
let chunkRemainder = null;
|
||||
let maxChunkSize = readableHighWaterMark;
|
||||
let bytesLeft;
|
||||
let passed = 0;
|
||||
|
||||
if (maxRate) {
|
||||
const now = Date.now();
|
||||
|
||||
if (!internals.ts || (passed = (now - internals.ts)) >= timeWindow) {
|
||||
internals.ts = now;
|
||||
bytesLeft = bytesThreshold - internals.bytes;
|
||||
internals.bytes = bytesLeft < 0 ? -bytesLeft : 0;
|
||||
passed = 0;
|
||||
}
|
||||
|
||||
bytesLeft = bytesThreshold - internals.bytes;
|
||||
}
|
||||
|
||||
if (maxRate) {
|
||||
if (bytesLeft <= 0) {
|
||||
// next time window
|
||||
return setTimeout(() => {
|
||||
_callback(null, _chunk);
|
||||
}, timeWindow - passed);
|
||||
}
|
||||
|
||||
if (bytesLeft < maxChunkSize) {
|
||||
maxChunkSize = bytesLeft;
|
||||
}
|
||||
}
|
||||
|
||||
if (maxChunkSize && chunkSize > maxChunkSize && (chunkSize - maxChunkSize) > minChunkSize) {
|
||||
chunkRemainder = _chunk.subarray(maxChunkSize);
|
||||
_chunk = _chunk.subarray(0, maxChunkSize);
|
||||
}
|
||||
|
||||
pushChunk(_chunk, chunkRemainder ? () => {
|
||||
process.nextTick(_callback, null, chunkRemainder);
|
||||
} : _callback);
|
||||
};
|
||||
|
||||
transformChunk(chunk, function transformNextChunk(err, _chunk) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
if (_chunk) {
|
||||
transformChunk(_chunk, transformNextChunk);
|
||||
} else {
|
||||
callback(null);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
setLength(length) {
|
||||
this[kInternals].length = +length;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
export default AxiosTransformStream;
|
||||
@@ -1,6 +1,6 @@
|
||||
'use strict';
|
||||
|
||||
var toFormData = require('./toFormData');
|
||||
import toFormData from './toFormData.js';
|
||||
|
||||
/**
|
||||
* It encodes a string by replacing all characters that are not in the unreserved set with
|
||||
@@ -11,7 +11,7 @@ var toFormData = require('./toFormData');
|
||||
* @returns {string} The encoded string.
|
||||
*/
|
||||
function encode(str) {
|
||||
var charMap = {
|
||||
const charMap = {
|
||||
'!': '%21',
|
||||
"'": '%27',
|
||||
'(': '%28',
|
||||
@@ -20,7 +20,7 @@ function encode(str) {
|
||||
'%20': '+',
|
||||
'%00': '\x00'
|
||||
};
|
||||
return encodeURIComponent(str).replace(/[!'\(\)~]|%20|%00/g, function replacer(match) {
|
||||
return encodeURIComponent(str).replace(/[!'()~]|%20|%00/g, function replacer(match) {
|
||||
return charMap[match];
|
||||
});
|
||||
}
|
||||
@@ -39,14 +39,14 @@ function AxiosURLSearchParams(params, options) {
|
||||
params && toFormData(params, this, options);
|
||||
}
|
||||
|
||||
var prototype = AxiosURLSearchParams.prototype;
|
||||
const prototype = AxiosURLSearchParams.prototype;
|
||||
|
||||
prototype.append = function append(name, value) {
|
||||
this._pairs.push([name, value]);
|
||||
};
|
||||
|
||||
prototype.toString = function toString(encoder) {
|
||||
var _encode = encoder ? function(value) {
|
||||
const _encode = encoder ? function(value) {
|
||||
return encoder.call(this, value, encode);
|
||||
} : encode;
|
||||
|
||||
@@ -55,4 +55,4 @@ prototype.toString = function toString(encoder) {
|
||||
}, '').join('&');
|
||||
};
|
||||
|
||||
module.exports = AxiosURLSearchParams;
|
||||
export default AxiosURLSearchParams;
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
module.exports = function bind(fn, thisArg) {
|
||||
export default function bind(fn, thisArg) {
|
||||
return function wrap() {
|
||||
return fn.apply(thisArg, arguments);
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
var utils = require('../utils');
|
||||
var AxiosURLSearchParams = require('../helpers/AxiosURLSearchParams');
|
||||
import utils from '../utils.js';
|
||||
import AxiosURLSearchParams from '../helpers/AxiosURLSearchParams.js';
|
||||
|
||||
/**
|
||||
* It replaces all instances of the characters `:`, `$`, `,`, `+`, `[`, and `]` with their
|
||||
@@ -30,21 +30,21 @@ function encode(val) {
|
||||
*
|
||||
* @returns {string} The formatted url
|
||||
*/
|
||||
module.exports = function buildURL(url, params, options) {
|
||||
export default function buildURL(url, params, options) {
|
||||
/*eslint no-param-reassign:0*/
|
||||
if (!params) {
|
||||
return url;
|
||||
}
|
||||
|
||||
var hashmarkIndex = url.indexOf('#');
|
||||
const hashmarkIndex = url.indexOf('#');
|
||||
|
||||
if (hashmarkIndex !== -1) {
|
||||
url = url.slice(0, hashmarkIndex);
|
||||
}
|
||||
|
||||
var _encode = options && options.encode || encode;
|
||||
const _encode = options && options.encode || encode;
|
||||
|
||||
var serializerParams = utils.isURLSearchParams(params) ?
|
||||
const serializerParams = utils.isURLSearchParams(params) ?
|
||||
params.toString() :
|
||||
new AxiosURLSearchParams(params, options).toString(_encode);
|
||||
|
||||
@@ -53,4 +53,4 @@ module.exports = function buildURL(url, params, options) {
|
||||
}
|
||||
|
||||
return url;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
*
|
||||
* @returns {string} The combined URL
|
||||
*/
|
||||
module.exports = function combineURLs(baseURL, relativeURL) {
|
||||
export default function combineURLs(baseURL, relativeURL) {
|
||||
return relativeURL
|
||||
? baseURL.replace(/\/+$/, '') + '/' + relativeURL.replace(/^\/+/, '')
|
||||
: baseURL;
|
||||
};
|
||||
}
|
||||
|
||||
+44
-46
@@ -1,53 +1,51 @@
|
||||
'use strict';
|
||||
|
||||
var utils = require('./../utils');
|
||||
import utils from './../utils.js';
|
||||
|
||||
module.exports = (
|
||||
utils.isStandardBrowserEnv() ?
|
||||
export default utils.isStandardBrowserEnv() ?
|
||||
|
||||
// Standard browser envs support document.cookie
|
||||
(function standardBrowserEnv() {
|
||||
return {
|
||||
write: function write(name, value, expires, path, domain, secure) {
|
||||
var cookie = [];
|
||||
cookie.push(name + '=' + encodeURIComponent(value));
|
||||
// Standard browser envs support document.cookie
|
||||
(function standardBrowserEnv() {
|
||||
return {
|
||||
write: function write(name, value, expires, path, domain, secure) {
|
||||
const cookie = [];
|
||||
cookie.push(name + '=' + encodeURIComponent(value));
|
||||
|
||||
if (utils.isNumber(expires)) {
|
||||
cookie.push('expires=' + new Date(expires).toGMTString());
|
||||
}
|
||||
|
||||
if (utils.isString(path)) {
|
||||
cookie.push('path=' + path);
|
||||
}
|
||||
|
||||
if (utils.isString(domain)) {
|
||||
cookie.push('domain=' + domain);
|
||||
}
|
||||
|
||||
if (secure === true) {
|
||||
cookie.push('secure');
|
||||
}
|
||||
|
||||
document.cookie = cookie.join('; ');
|
||||
},
|
||||
|
||||
read: function read(name) {
|
||||
var match = document.cookie.match(new RegExp('(^|;\\s*)(' + name + ')=([^;]*)'));
|
||||
return (match ? decodeURIComponent(match[3]) : null);
|
||||
},
|
||||
|
||||
remove: function remove(name) {
|
||||
this.write(name, '', Date.now() - 86400000);
|
||||
if (utils.isNumber(expires)) {
|
||||
cookie.push('expires=' + new Date(expires).toGMTString());
|
||||
}
|
||||
};
|
||||
})() :
|
||||
|
||||
// Non standard browser env (web workers, react-native) lack needed support.
|
||||
(function nonStandardBrowserEnv() {
|
||||
return {
|
||||
write: function write() {},
|
||||
read: function read() { return null; },
|
||||
remove: function remove() {}
|
||||
};
|
||||
})()
|
||||
);
|
||||
if (utils.isString(path)) {
|
||||
cookie.push('path=' + path);
|
||||
}
|
||||
|
||||
if (utils.isString(domain)) {
|
||||
cookie.push('domain=' + domain);
|
||||
}
|
||||
|
||||
if (secure === true) {
|
||||
cookie.push('secure');
|
||||
}
|
||||
|
||||
document.cookie = cookie.join('; ');
|
||||
},
|
||||
|
||||
read: function read(name) {
|
||||
const match = document.cookie.match(new RegExp('(^|;\\s*)(' + name + ')=([^;]*)'));
|
||||
return (match ? decodeURIComponent(match[3]) : null);
|
||||
},
|
||||
|
||||
remove: function remove(name) {
|
||||
this.write(name, '', Date.now() - 86400000);
|
||||
}
|
||||
};
|
||||
})() :
|
||||
|
||||
// Non standard browser env (web workers, react-native) lack needed support.
|
||||
(function nonStandardBrowserEnv() {
|
||||
return {
|
||||
write: function write() {},
|
||||
read: function read() { return null; },
|
||||
remove: function remove() {}
|
||||
};
|
||||
})();
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
module.exports = function deprecatedMethod(method, instead, docs) {
|
||||
export default function deprecatedMethod(method, instead, docs) {
|
||||
try {
|
||||
console.warn(
|
||||
'DEPRECATED method `' + method + '`.' +
|
||||
@@ -23,4 +23,4 @@ module.exports = function deprecatedMethod(method, instead, docs) {
|
||||
console.warn('For more information about usage see ' + docs);
|
||||
}
|
||||
} catch (e) { /* Ignore */ }
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
'use strict';
|
||||
|
||||
var utils = require('../utils');
|
||||
import utils from '../utils.js';
|
||||
|
||||
/**
|
||||
* It takes a string like `foo[x][y][z]` and returns an array like `['foo', 'x', 'y', 'z']
|
||||
@@ -14,7 +14,7 @@ function parsePropPath(name) {
|
||||
// foo.x.y.z
|
||||
// foo-x-y-z
|
||||
// foo x y z
|
||||
return utils.matchAll(/\w+|\[(\w*)]/g, name).map(function(match) {
|
||||
return utils.matchAll(/\w+|\[(\w*)]/g, name).map(match => {
|
||||
return match[0] === '[]' ? '' : match[1] || match[0];
|
||||
});
|
||||
}
|
||||
@@ -27,11 +27,11 @@ function parsePropPath(name) {
|
||||
* @returns An object with the same keys and values as the array.
|
||||
*/
|
||||
function arrayToObject(arr) {
|
||||
var obj = {};
|
||||
var keys = Object.keys(arr);
|
||||
var i;
|
||||
var len = keys.length;
|
||||
var key;
|
||||
const obj = {};
|
||||
const keys = Object.keys(arr);
|
||||
let i;
|
||||
const len = keys.length;
|
||||
let key;
|
||||
for (i = 0; i < len; i++) {
|
||||
key = keys[i];
|
||||
obj[key] = arr[key];
|
||||
@@ -48,13 +48,13 @@ function arrayToObject(arr) {
|
||||
*/
|
||||
function formDataToJSON(formData) {
|
||||
function buildPath(path, value, target, index) {
|
||||
var name = path[index++];
|
||||
var isNumericKey = Number.isFinite(+name);
|
||||
var isLast = index >= path.length;
|
||||
let name = path[index++];
|
||||
const isNumericKey = Number.isFinite(+name);
|
||||
const isLast = index >= path.length;
|
||||
name = !name && utils.isArray(target) ? target.length : name;
|
||||
|
||||
if (isLast) {
|
||||
if (utils.hasOwnProperty(target, name)) {
|
||||
if (utils.hasOwnProp(target, name)) {
|
||||
target[name] = [target[name], value];
|
||||
} else {
|
||||
target[name] = value;
|
||||
@@ -67,7 +67,7 @@ function formDataToJSON(formData) {
|
||||
target[name] = [];
|
||||
}
|
||||
|
||||
var result = buildPath(path, value, target[name], index);
|
||||
const result = buildPath(path, value, target[name], index);
|
||||
|
||||
if (result && utils.isArray(target[name])) {
|
||||
target[name] = arrayToObject(target[name]);
|
||||
@@ -77,9 +77,9 @@ function formDataToJSON(formData) {
|
||||
}
|
||||
|
||||
if (utils.isFormData(formData) && utils.isFunction(formData.entries)) {
|
||||
var obj = {};
|
||||
const obj = {};
|
||||
|
||||
utils.forEachEntry(formData, function(name, value) {
|
||||
utils.forEachEntry(formData, (name, value) => {
|
||||
buildPath(parsePropPath(name), value, obj, 0);
|
||||
});
|
||||
|
||||
@@ -89,4 +89,4 @@ function formDataToJSON(formData) {
|
||||
return null;
|
||||
}
|
||||
|
||||
module.exports = formDataToJSON;
|
||||
export default formDataToJSON;
|
||||
|
||||
+13
-13
@@ -1,10 +1,10 @@
|
||||
'use strict';
|
||||
|
||||
var AxiosError = require('../core/AxiosError');
|
||||
var parseProtocol = require('./parseProtocol');
|
||||
var platform = require('../platform');
|
||||
import AxiosError from '../core/AxiosError.js';
|
||||
import parseProtocol from './parseProtocol.js';
|
||||
import platform from '../platform/index.js';
|
||||
|
||||
var DATA_URL_PATTERN = /^(?:([^;]+);)?(?:[^;]+;)?(base64|),([\s\S]*)$/;
|
||||
const DATA_URL_PATTERN = /^(?:([^;]+);)?(?:[^;]+;)?(base64|),([\s\S]*)$/;
|
||||
|
||||
/**
|
||||
* Parse data uri to a Buffer or Blob
|
||||
@@ -16,9 +16,9 @@ var DATA_URL_PATTERN = /^(?:([^;]+);)?(?:[^;]+;)?(base64|),([\s\S]*)$/;
|
||||
*
|
||||
* @returns {Buffer|Blob}
|
||||
*/
|
||||
module.exports = function fromDataURI(uri, asBlob, options) {
|
||||
var _Blob = options && options.Blob || platform.classes.Blob;
|
||||
var protocol = parseProtocol(uri);
|
||||
export default function fromDataURI(uri, asBlob, options) {
|
||||
const _Blob = options && options.Blob || platform.classes.Blob;
|
||||
const protocol = parseProtocol(uri);
|
||||
|
||||
if (asBlob === undefined && _Blob) {
|
||||
asBlob = true;
|
||||
@@ -27,16 +27,16 @@ module.exports = function fromDataURI(uri, asBlob, options) {
|
||||
if (protocol === 'data') {
|
||||
uri = protocol.length ? uri.slice(protocol.length + 1) : uri;
|
||||
|
||||
var match = DATA_URL_PATTERN.exec(uri);
|
||||
const match = DATA_URL_PATTERN.exec(uri);
|
||||
|
||||
if (!match) {
|
||||
throw new AxiosError('Invalid URL', AxiosError.ERR_INVALID_URL);
|
||||
}
|
||||
|
||||
var mime = match[1];
|
||||
var isBase64 = match[2];
|
||||
var body = match[3];
|
||||
var buffer = Buffer.from(decodeURIComponent(body), isBase64 ? 'base64' : 'utf8');
|
||||
const mime = match[1];
|
||||
const isBase64 = match[2];
|
||||
const body = match[3];
|
||||
const buffer = Buffer.from(decodeURIComponent(body), isBase64 ? 'base64' : 'utf8');
|
||||
|
||||
if (asBlob) {
|
||||
if (!_Blob) {
|
||||
@@ -50,4 +50,4 @@ module.exports = function fromDataURI(uri, asBlob, options) {
|
||||
}
|
||||
|
||||
throw new AxiosError('Unsupported protocol ' + protocol, AxiosError.ERR_NOT_SUPPORT);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -7,9 +7,9 @@
|
||||
*
|
||||
* @returns {boolean} True if the specified URL is absolute, otherwise false
|
||||
*/
|
||||
module.exports = function isAbsoluteURL(url) {
|
||||
export default function isAbsoluteURL(url) {
|
||||
// A URL is considered absolute if it begins with "<scheme>://" or "//" (protocol-relative URL).
|
||||
// RFC 3986 defines scheme name as a sequence of characters beginning with a letter and followed
|
||||
// by any combination of letters, digits, plus, period, or hyphen.
|
||||
return /^([a-z][a-z\d+\-.]*:)?\/\//i.test(url);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
'use strict';
|
||||
|
||||
var utils = require('./../utils');
|
||||
import utils from './../utils.js';
|
||||
|
||||
/**
|
||||
* Determines whether the payload is an error thrown by Axios
|
||||
@@ -9,6 +9,6 @@ var utils = require('./../utils');
|
||||
*
|
||||
* @returns {boolean} True if the payload is an error thrown by Axios, otherwise false
|
||||
*/
|
||||
module.exports = function isAxiosError(payload) {
|
||||
export default function isAxiosError(payload) {
|
||||
return utils.isObject(payload) && (payload.isAxiosError === true);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,68 +1,66 @@
|
||||
'use strict';
|
||||
|
||||
var utils = require('./../utils');
|
||||
import utils from './../utils.js';
|
||||
|
||||
module.exports = (
|
||||
utils.isStandardBrowserEnv() ?
|
||||
export default utils.isStandardBrowserEnv() ?
|
||||
|
||||
// Standard browser envs have full support of the APIs needed to test
|
||||
// whether the request URL is of the same origin as current location.
|
||||
(function standardBrowserEnv() {
|
||||
var msie = /(msie|trident)/i.test(navigator.userAgent);
|
||||
var urlParsingNode = document.createElement('a');
|
||||
var originURL;
|
||||
// Standard browser envs have full support of the APIs needed to test
|
||||
// whether the request URL is of the same origin as current location.
|
||||
(function standardBrowserEnv() {
|
||||
const msie = /(msie|trident)/i.test(navigator.userAgent);
|
||||
const urlParsingNode = document.createElement('a');
|
||||
let originURL;
|
||||
|
||||
/**
|
||||
* Parse a URL to discover it's components
|
||||
*
|
||||
* @param {String} url The URL to be parsed
|
||||
* @returns {Object}
|
||||
*/
|
||||
function resolveURL(url) {
|
||||
var href = url;
|
||||
|
||||
if (msie) {
|
||||
// IE needs attribute set twice to normalize properties
|
||||
urlParsingNode.setAttribute('href', href);
|
||||
href = urlParsingNode.href;
|
||||
}
|
||||
/**
|
||||
* Parse a URL to discover it's components
|
||||
*
|
||||
* @param {String} url The URL to be parsed
|
||||
* @returns {Object}
|
||||
*/
|
||||
function resolveURL(url) {
|
||||
let href = url;
|
||||
|
||||
if (msie) {
|
||||
// IE needs attribute set twice to normalize properties
|
||||
urlParsingNode.setAttribute('href', href);
|
||||
|
||||
// urlParsingNode provides the UrlUtils interface - http://url.spec.whatwg.org/#urlutils
|
||||
return {
|
||||
href: urlParsingNode.href,
|
||||
protocol: urlParsingNode.protocol ? urlParsingNode.protocol.replace(/:$/, '') : '',
|
||||
host: urlParsingNode.host,
|
||||
search: urlParsingNode.search ? urlParsingNode.search.replace(/^\?/, '') : '',
|
||||
hash: urlParsingNode.hash ? urlParsingNode.hash.replace(/^#/, '') : '',
|
||||
hostname: urlParsingNode.hostname,
|
||||
port: urlParsingNode.port,
|
||||
pathname: (urlParsingNode.pathname.charAt(0) === '/') ?
|
||||
urlParsingNode.pathname :
|
||||
'/' + urlParsingNode.pathname
|
||||
};
|
||||
href = urlParsingNode.href;
|
||||
}
|
||||
|
||||
originURL = resolveURL(window.location.href);
|
||||
urlParsingNode.setAttribute('href', href);
|
||||
|
||||
/**
|
||||
* Determine if a URL shares the same origin as the current location
|
||||
*
|
||||
* @param {String} requestURL The URL to test
|
||||
* @returns {boolean} True if URL shares the same origin, otherwise false
|
||||
*/
|
||||
return function isURLSameOrigin(requestURL) {
|
||||
var parsed = (utils.isString(requestURL)) ? resolveURL(requestURL) : requestURL;
|
||||
return (parsed.protocol === originURL.protocol &&
|
||||
parsed.host === originURL.host);
|
||||
// urlParsingNode provides the UrlUtils interface - http://url.spec.whatwg.org/#urlutils
|
||||
return {
|
||||
href: urlParsingNode.href,
|
||||
protocol: urlParsingNode.protocol ? urlParsingNode.protocol.replace(/:$/, '') : '',
|
||||
host: urlParsingNode.host,
|
||||
search: urlParsingNode.search ? urlParsingNode.search.replace(/^\?/, '') : '',
|
||||
hash: urlParsingNode.hash ? urlParsingNode.hash.replace(/^#/, '') : '',
|
||||
hostname: urlParsingNode.hostname,
|
||||
port: urlParsingNode.port,
|
||||
pathname: (urlParsingNode.pathname.charAt(0) === '/') ?
|
||||
urlParsingNode.pathname :
|
||||
'/' + urlParsingNode.pathname
|
||||
};
|
||||
})() :
|
||||
}
|
||||
|
||||
// Non standard browser envs (web workers, react-native) lack needed support.
|
||||
(function nonStandardBrowserEnv() {
|
||||
return function isURLSameOrigin() {
|
||||
return true;
|
||||
};
|
||||
})()
|
||||
);
|
||||
originURL = resolveURL(window.location.href);
|
||||
|
||||
/**
|
||||
* Determine if a URL shares the same origin as the current location
|
||||
*
|
||||
* @param {String} requestURL The URL to test
|
||||
* @returns {boolean} True if URL shares the same origin, otherwise false
|
||||
*/
|
||||
return function isURLSameOrigin(requestURL) {
|
||||
const parsed = (utils.isString(requestURL)) ? resolveURL(requestURL) : requestURL;
|
||||
return (parsed.protocol === originURL.protocol &&
|
||||
parsed.host === originURL.host);
|
||||
};
|
||||
})() :
|
||||
|
||||
// Non standard browser envs (web workers, react-native) lack needed support.
|
||||
(function nonStandardBrowserEnv() {
|
||||
return function isURLSameOrigin() {
|
||||
return true;
|
||||
};
|
||||
})();
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
var utils = require('../utils');
|
||||
|
||||
module.exports = function normalizeHeaderName(headers, normalizedName) {
|
||||
utils.forEach(headers, function processHeader(value, name) {
|
||||
if (name !== normalizedName && name.toUpperCase() === normalizedName.toUpperCase()) {
|
||||
headers[normalizedName] = value;
|
||||
delete headers[name];
|
||||
}
|
||||
});
|
||||
};
|
||||
+1
-1
@@ -1,2 +1,2 @@
|
||||
// eslint-disable-next-line strict
|
||||
module.exports = null;
|
||||
export default null;
|
||||
|
||||
+23
-22
@@ -1,15 +1,15 @@
|
||||
'use strict';
|
||||
|
||||
var utils = require('./../utils');
|
||||
import utils from './../utils.js';
|
||||
|
||||
// Headers whose duplicates are ignored by node
|
||||
// RawAxiosHeaders whose duplicates are ignored by node
|
||||
// c.f. https://nodejs.org/api/http.html#http_message_headers
|
||||
var ignoreDuplicateOf = [
|
||||
const ignoreDuplicateOf = utils.toObjectSet([
|
||||
'age', 'authorization', 'content-length', 'content-type', 'etag',
|
||||
'expires', 'from', 'host', 'if-modified-since', 'if-unmodified-since',
|
||||
'last-modified', 'location', 'max-forwards', 'proxy-authorization',
|
||||
'referer', 'retry-after', 'user-agent'
|
||||
];
|
||||
]);
|
||||
|
||||
/**
|
||||
* Parse headers into an object
|
||||
@@ -21,32 +21,33 @@ var ignoreDuplicateOf = [
|
||||
* Transfer-Encoding: chunked
|
||||
* ```
|
||||
*
|
||||
* @param {String} headers Headers needing to be parsed
|
||||
* @param {String} rawHeaders Headers needing to be parsed
|
||||
*
|
||||
* @returns {Object} Headers parsed into an object
|
||||
*/
|
||||
module.exports = function parseHeaders(headers) {
|
||||
var parsed = {};
|
||||
var key;
|
||||
var val;
|
||||
var i;
|
||||
export default rawHeaders => {
|
||||
const parsed = {};
|
||||
let key;
|
||||
let val;
|
||||
let i;
|
||||
|
||||
if (!headers) { return parsed; }
|
||||
|
||||
utils.forEach(headers.split('\n'), function parser(line) {
|
||||
rawHeaders && rawHeaders.split('\n').forEach(function parser(line) {
|
||||
i = line.indexOf(':');
|
||||
key = utils.trim(line.slice(0, i)).toLowerCase();
|
||||
val = utils.trim(line.slice(i + 1));
|
||||
key = line.substring(0, i).trim().toLowerCase();
|
||||
val = line.substring(i + 1).trim();
|
||||
|
||||
if (key) {
|
||||
if (parsed[key] && ignoreDuplicateOf.indexOf(key) >= 0) {
|
||||
return;
|
||||
}
|
||||
if (key === 'set-cookie') {
|
||||
parsed[key] = (parsed[key] ? parsed[key] : []).concat([val]);
|
||||
if (!key || (parsed[key] && ignoreDuplicateOf[key])) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (key === 'set-cookie') {
|
||||
if (parsed[key]) {
|
||||
parsed[key].push(val);
|
||||
} else {
|
||||
parsed[key] = parsed[key] ? parsed[key] + ', ' + val : val;
|
||||
parsed[key] = [val];
|
||||
}
|
||||
} else {
|
||||
parsed[key] = parsed[key] ? parsed[key] + ', ' + val : val;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
'use strict';
|
||||
|
||||
module.exports = function parseProtocol(url) {
|
||||
var match = /^([-+\w]{1,25})(:?\/\/|:)/.exec(url);
|
||||
export default function parseProtocol(url) {
|
||||
const match = /^([-+\w]{1,25})(:?\/\/|:)/.exec(url);
|
||||
return match && match[1] || '';
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Calculate data maxRate
|
||||
* @param {Number} [samplesCount= 10]
|
||||
* @param {Number} [min= 1000]
|
||||
* @returns {Function}
|
||||
*/
|
||||
function speedometer(samplesCount, min) {
|
||||
samplesCount = samplesCount || 10;
|
||||
const bytes = new Array(samplesCount);
|
||||
const timestamps = new Array(samplesCount);
|
||||
let head = 0;
|
||||
let tail = 0;
|
||||
let firstSampleTS;
|
||||
|
||||
min = min !== undefined ? min : 1000;
|
||||
|
||||
return function push(chunkLength) {
|
||||
const now = Date.now();
|
||||
|
||||
const startedAt = timestamps[tail];
|
||||
|
||||
if (!firstSampleTS) {
|
||||
firstSampleTS = now;
|
||||
}
|
||||
|
||||
bytes[head] = chunkLength;
|
||||
timestamps[head] = now;
|
||||
|
||||
let i = tail;
|
||||
let bytesCount = 0;
|
||||
|
||||
while (i !== head) {
|
||||
bytesCount += bytes[i++];
|
||||
i = i % samplesCount;
|
||||
}
|
||||
|
||||
head = (head + 1) % samplesCount;
|
||||
|
||||
if (head === tail) {
|
||||
tail = (tail + 1) % samplesCount;
|
||||
}
|
||||
|
||||
if (now - firstSampleTS < min) {
|
||||
return;
|
||||
}
|
||||
|
||||
const passed = startedAt && now - startedAt;
|
||||
|
||||
return passed ? Math.round(bytesCount * 1000 / passed) : undefined;
|
||||
};
|
||||
}
|
||||
|
||||
export default speedometer;
|
||||
@@ -21,8 +21,8 @@
|
||||
*
|
||||
* @returns {Function}
|
||||
*/
|
||||
module.exports = function spread(callback) {
|
||||
export default function spread(callback) {
|
||||
return function wrap(arr) {
|
||||
return callback.apply(null, arr);
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Throttle decorator
|
||||
* @param {Function} fn
|
||||
* @param {Number} freq
|
||||
* @return {Function}
|
||||
*/
|
||||
function throttle(fn, freq) {
|
||||
let timestamp = 0;
|
||||
const threshold = 1000 / freq;
|
||||
let timer = null;
|
||||
return function throttled(force, args) {
|
||||
const now = Date.now();
|
||||
if (force || now - timestamp > threshold) {
|
||||
if (timer) {
|
||||
clearTimeout(timer);
|
||||
timer = null;
|
||||
}
|
||||
timestamp = now;
|
||||
return fn.apply(null, args);
|
||||
}
|
||||
if (!timer) {
|
||||
timer = setTimeout(() => {
|
||||
timer = null;
|
||||
timestamp = Date.now();
|
||||
return fn.apply(null, args);
|
||||
}, threshold - (now - timestamp));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export default throttle;
|
||||
+18
-18
@@ -1,8 +1,8 @@
|
||||
'use strict';
|
||||
|
||||
var utils = require('../utils');
|
||||
var AxiosError = require('../core/AxiosError');
|
||||
var envFormData = require('../env/classes/FormData');
|
||||
import utils from '../utils.js';
|
||||
import AxiosError from '../core/AxiosError.js';
|
||||
import envFormData from '../env/classes/FormData.js';
|
||||
|
||||
/**
|
||||
* Determines if the given thing is a array or js object.
|
||||
@@ -55,7 +55,7 @@ function isFlatArray(arr) {
|
||||
return utils.isArray(arr) && !arr.some(isVisitable);
|
||||
}
|
||||
|
||||
var predicates = utils.toFlatObject(utils, {}, null, function filter(prop) {
|
||||
const predicates = utils.toFlatObject(utils, {}, null, function filter(prop) {
|
||||
return /^is[A-Z]/.test(prop);
|
||||
});
|
||||
|
||||
@@ -111,13 +111,13 @@ function toFormData(obj, formData, options) {
|
||||
return !utils.isUndefined(source[option]);
|
||||
});
|
||||
|
||||
var metaTokens = options.metaTokens;
|
||||
const metaTokens = options.metaTokens;
|
||||
// eslint-disable-next-line no-use-before-define
|
||||
var visitor = options.visitor || defaultVisitor;
|
||||
var dots = options.dots;
|
||||
var indexes = options.indexes;
|
||||
var _Blob = options.Blob || typeof Blob !== 'undefined' && Blob;
|
||||
var useBlob = _Blob && isSpecCompliant(formData);
|
||||
const visitor = options.visitor || defaultVisitor;
|
||||
const dots = options.dots;
|
||||
const indexes = options.indexes;
|
||||
const _Blob = options.Blob || typeof Blob !== 'undefined' && Blob;
|
||||
const useBlob = _Blob && isSpecCompliant(formData);
|
||||
|
||||
if (!utils.isFunction(visitor)) {
|
||||
throw new TypeError('visitor must be a function');
|
||||
@@ -152,7 +152,7 @@ function toFormData(obj, formData, options) {
|
||||
* @returns {boolean} return true to visit the each prop of the value recursively
|
||||
*/
|
||||
function defaultVisitor(value, key, path) {
|
||||
var arr = value;
|
||||
let arr = value;
|
||||
|
||||
if (value && !path && typeof value === 'object') {
|
||||
if (utils.endsWith(key, '{}')) {
|
||||
@@ -187,12 +187,12 @@ function toFormData(obj, formData, options) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var stack = [];
|
||||
const stack = [];
|
||||
|
||||
var exposedHelpers = Object.assign(predicates, {
|
||||
defaultVisitor: defaultVisitor,
|
||||
convertValue: convertValue,
|
||||
isVisitable: isVisitable
|
||||
const exposedHelpers = Object.assign(predicates, {
|
||||
defaultVisitor,
|
||||
convertValue,
|
||||
isVisitable
|
||||
});
|
||||
|
||||
function build(value, path) {
|
||||
@@ -205,7 +205,7 @@ function toFormData(obj, formData, options) {
|
||||
stack.push(value);
|
||||
|
||||
utils.forEach(value, function each(el, key) {
|
||||
var result = !utils.isUndefined(el) && visitor.call(
|
||||
const result = !utils.isUndefined(el) && visitor.call(
|
||||
formData, el, utils.isString(key) ? key.trim() : key, path, exposedHelpers
|
||||
);
|
||||
|
||||
@@ -226,4 +226,4 @@ function toFormData(obj, formData, options) {
|
||||
return formData;
|
||||
}
|
||||
|
||||
module.exports = toFormData;
|
||||
export default toFormData;
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
'use strict';
|
||||
|
||||
var utils = require('../utils');
|
||||
var toFormData = require('./toFormData');
|
||||
var platform = require('../platform/');
|
||||
import utils from '../utils.js';
|
||||
import toFormData from './toFormData.js';
|
||||
import platform from '../platform/index.js';
|
||||
|
||||
module.exports = function toURLEncodedForm(data, options) {
|
||||
export default function toURLEncodedForm(data, options) {
|
||||
return toFormData(data, new platform.classes.URLSearchParams(), Object.assign({
|
||||
visitor: function(value, key, path, helpers) {
|
||||
if (platform.isNode && utils.isBuffer(value)) {
|
||||
@@ -15,4 +15,4 @@ module.exports = function toURLEncodedForm(data, options) {
|
||||
return helpers.defaultVisitor.apply(this, arguments);
|
||||
}
|
||||
}, options));
|
||||
};
|
||||
}
|
||||
|
||||
+15
-15
@@ -1,18 +1,18 @@
|
||||
'use strict';
|
||||
|
||||
var VERSION = require('../env/data').version;
|
||||
var AxiosError = require('../core/AxiosError');
|
||||
import {VERSION} from '../env/data.js';
|
||||
import AxiosError from '../core/AxiosError.js';
|
||||
|
||||
var validators = {};
|
||||
const validators = {};
|
||||
|
||||
// eslint-disable-next-line func-names
|
||||
['object', 'boolean', 'number', 'function', 'string', 'symbol'].forEach(function(type, i) {
|
||||
['object', 'boolean', 'number', 'function', 'string', 'symbol'].forEach((type, i) => {
|
||||
validators[type] = function validator(thing) {
|
||||
return typeof thing === type || 'a' + (i < 1 ? 'n ' : ' ') + type;
|
||||
};
|
||||
});
|
||||
|
||||
var deprecatedWarnings = {};
|
||||
const deprecatedWarnings = {};
|
||||
|
||||
/**
|
||||
* Transitional option validator
|
||||
@@ -29,7 +29,7 @@ validators.transitional = function transitional(validator, version, message) {
|
||||
}
|
||||
|
||||
// eslint-disable-next-line func-names
|
||||
return function(value, opt, opts) {
|
||||
return (value, opt, opts) => {
|
||||
if (validator === false) {
|
||||
throw new AxiosError(
|
||||
formatMessage(opt, ' has been removed' + (version ? ' in ' + version : '')),
|
||||
@@ -66,14 +66,14 @@ function assertOptions(options, schema, allowUnknown) {
|
||||
if (typeof options !== 'object') {
|
||||
throw new AxiosError('options must be an object', AxiosError.ERR_BAD_OPTION_VALUE);
|
||||
}
|
||||
var keys = Object.keys(options);
|
||||
var i = keys.length;
|
||||
const keys = Object.keys(options);
|
||||
let i = keys.length;
|
||||
while (i-- > 0) {
|
||||
var opt = keys[i];
|
||||
var validator = schema[opt];
|
||||
const opt = keys[i];
|
||||
const validator = schema[opt];
|
||||
if (validator) {
|
||||
var value = options[opt];
|
||||
var result = value === undefined || validator(value, opt, options);
|
||||
const value = options[opt];
|
||||
const result = value === undefined || validator(value, opt, options);
|
||||
if (result !== true) {
|
||||
throw new AxiosError('option ' + opt + ' must be ' + result, AxiosError.ERR_BAD_OPTION_VALUE);
|
||||
}
|
||||
@@ -85,7 +85,7 @@ function assertOptions(options, schema, allowUnknown) {
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
assertOptions: assertOptions,
|
||||
validators: validators
|
||||
export default {
|
||||
assertOptions,
|
||||
validators
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user