@mornya/restful-libs
Version:
The project of wrapped library for RESTful API processing module.
460 lines (459 loc) • 22.9 kB
JavaScript
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
var __read = (this && this.__read) || function (o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
};
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
};
var __values = (this && this.__values) || function(o) {
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
if (m) return m.call(o);
if (o && typeof o.length === "number") return {
next: function () {
if (o && i >= o.length) o = void 0;
return { value: o && o[i++], done: !o };
}
};
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
};
import Axios from 'axios';
import { setupCache, } from 'axios-cache-interceptor';
import AxiosRetry from 'axios-retry';
import deepmerge from 'deepmerge';
import { isPlainObject } from 'is-plain-object';
import Constants from './Constants';
import { RequestPool } from './RequestPool';
import { getTag } from './Tag';
export { AxiosRetry };
var defaultOption = {
isShowLog: true,
isLogFullResponse: false,
truncateLogThreshold: 0,
isThrowsOnError: true,
isCancelDuplicateRequests: false,
requestsThreshold: 100,
onAuthorize: function () {
},
onRequest: function (_) { return _; },
onResponse: function (_) { return _; },
onRequestError: function () { },
onResponseError: function () { },
onInvalidate: function () { },
};
var retryCondition = function (error) {
return error.response
? error.response.status >= 500
: true;
};
var resolveRequestUrlPrefixes = [];
var initialAxiosDefaults = __assign({}, Axios.defaults);
var axiosInstance;
var option = __assign({}, defaultOption);
function initializeDefaults() {
if (axiosInstance) {
axiosInstance.defaults.headers.common = __assign(__assign({}, initialAxiosDefaults.headers.common), { 'Content-Encoding': 'UTF-8', 'Content-Type': Constants.CT_JSON });
axiosInstance.defaults.headers.get = __assign(__assign({}, initialAxiosDefaults.headers.get), { 'Content-Type': Constants.CT_JSON });
axiosInstance.defaults.headers.head = __assign(__assign({}, initialAxiosDefaults.headers.head), { 'Content-Type': Constants.CT_JSON });
axiosInstance.defaults.headers.patch = __assign(__assign({}, initialAxiosDefaults.headers.patch), { 'Content-Type': Constants.CT_FORM });
axiosInstance.defaults.headers.post = __assign(__assign({}, initialAxiosDefaults.headers.post), { 'Content-Type': Constants.CT_FORM });
axiosInstance.defaults.headers.put = __assign(__assign({}, initialAxiosDefaults.headers.put), { 'Content-Type': Constants.CT_FORM });
axiosInstance.defaults.headers.delete = __assign(__assign({}, initialAxiosDefaults.headers.delete), { 'Content-Type': Constants.CT_FORM });
axiosInstance.defaults.method = 'get';
axiosInstance.defaults.withCredentials = true;
axiosInstance.defaults.timeout = 5000;
axiosInstance.defaults.baseURL = undefined;
axiosInstance.interceptors.request.use();
axiosInstance.interceptors.response.use();
}
}
export function getInstance(instanceOption) {
if (!axiosInstance || !!instanceOption) {
if (instanceOption) {
option = deepmerge(option, instanceOption);
}
if (option.resolveRequestURL) {
Object.keys(option.resolveRequestURL).forEach(function (key) { return resolveRequestUrlPrefixes.push(key); });
}
axiosInstance = setupCache(Axios.create());
initializeDefaults();
axiosInstance.interceptors.request.use(function (config) {
var _a, _b;
var currentRequests = RequestPool.increaseRequest();
if (option.requestsThreshold && currentRequests > option.requestsThreshold) {
throw new Axios.Cancel(Constants.CANCELLED_BY_MAXCOUNT);
}
if (resolveRequestUrlPrefixes.length) {
var _c = resolveRequestUrl(config.baseURL, config.url), baseURL = _c.baseURL, url = _c.url;
config.baseURL = baseURL;
config.url = url;
}
logRequest(config);
return (_b = (_a = option.onRequest) === null || _a === void 0 ? void 0 : _a.call(option, config, currentRequests)) !== null && _b !== void 0 ? _b : config;
}, function (error) {
var _a, _b;
var currentRequests = RequestPool.decreaseRequest();
logRequestError(error);
(_a = option.onRequestError) === null || _a === void 0 ? void 0 : _a.call(option, error, currentRequests);
(_b = option.onInvalidate) === null || _b === void 0 ? void 0 : _b.call(option, 'request', error);
if (option.isThrowsOnError) {
throw error;
}
});
axiosInstance.interceptors.response.use(function (response) {
var _a, _b;
var currentRequests = RequestPool.decreaseRequest();
if (response) {
logResponse(response);
if (response.config.ignoreResponseCallback) {
return response;
}
else {
return (_b = (_a = option.onResponse) === null || _a === void 0 ? void 0 : _a.call(option, response, currentRequests)) !== null && _b !== void 0 ? _b : response;
}
}
throw new Error(Constants.NO_RESPONSES);
}, function (error) {
var _a, _b, _c, _d, _e, _f;
var currentRequests = RequestPool.decreaseRequest();
var _g = ((_b = (_a = error.config) === null || _a === void 0 ? void 0 : _a['axios-retry']) !== null && _b !== void 0 ? _b : {}), _h = _g.retryCount, retryCount = _h === void 0 ? 0 : _h, _j = _g.retries, retries = _j === void 0 ? 0 : _j;
if (retries > 0 && (retryCondition === null || retryCondition === void 0 ? void 0 : retryCondition(error))) {
if (retryCount === retries) {
logResponseError(error);
(_c = option.onResponseError) === null || _c === void 0 ? void 0 : _c.call(option, error, currentRequests);
(_d = option.onInvalidate) === null || _d === void 0 ? void 0 : _d.call(option, 'response', error);
}
}
else {
logResponseError(error);
(_e = option.onResponseError) === null || _e === void 0 ? void 0 : _e.call(option, error, currentRequests);
(_f = option.onInvalidate) === null || _f === void 0 ? void 0 : _f.call(option, 'response', error);
}
if (option.isThrowsOnError) {
throw error;
}
});
}
return axiosInstance;
}
export function reset() {
var tid;
return new Promise(function (resolve) {
var execute = function () {
if (!RequestPool.getCurrentRequests()) {
clearInterval(tid);
tid = undefined;
resolveRequestUrlPrefixes.length = 0;
option = __assign({}, defaultOption);
initializeDefaults();
RequestPool.burstCancelBooks();
resolve();
}
};
tid = setInterval(execute, 100);
execute();
});
}
export function restApi(requestConfig) {
var _a, _b, _c, _d, _e, _f, _g, _h;
if (!axiosInstance) {
console.info.apply(console, __spreadArray(__spreadArray([], __read(getTag('WARN', 'black', 'yellow')), false), ["".concat(requestConfig.method ? requestConfig.method.toUpperCase() : 'GET', " ").concat((_a = requestConfig.baseURL) !== null && _a !== void 0 ? _a : '').concat((_b = requestConfig.url) !== null && _b !== void 0 ? _b : '')], false));
console.warn(Constants.UNINITIALIZED_DEFAULT_CONFIG);
getInstance();
}
if (requestConfig.baseURL && !requestConfig.url) {
requestConfig.url = requestConfig.baseURL;
delete requestConfig.baseURL;
}
if (option.isCancelDuplicateRequests && RequestPool.hasCancelBook(requestConfig)) {
logRequestError(Constants.CANCELLED_BY_DUPS);
}
else {
var ignoreCancel = requestConfig.ignoreCancel, restAxiosConfig = __rest(requestConfig, ["ignoreCancel"]);
var method = (_d = (_c = requestConfig.method) === null || _c === void 0 ? void 0 : _c.toLowerCase()) !== null && _d !== void 0 ? _d : 'get';
var axiosConfig = __assign(__assign({}, restAxiosConfig), { method: method });
var authorization = (_f = (_e = option.onAuthorize) === null || _e === void 0 ? void 0 : _e.call(option, requestConfig)) !== null && _f !== void 0 ? _f : '';
if (!axiosConfig.headers) {
axiosConfig.headers = {};
}
if (!axiosConfig.headers.authorization && !axiosConfig.headers.Authorization) {
axiosConfig.headers.authorization = authorization;
}
if (!ignoreCancel) {
var cancel = RequestPool.addCancelBook(axiosConfig, ignoreCancel ? function () { } : undefined);
axiosConfig.cancelToken = cancel.token;
}
if (axiosConfig['axios-retry']) {
setAxiosRetry(axiosConfig['axios-retry']);
}
else if ((_g = axiosInstance === null || axiosInstance === void 0 ? void 0 : axiosInstance.defaults) === null || _g === void 0 ? void 0 : _g['axios-retry']) {
setAxiosRetry((_h = axiosInstance === null || axiosInstance === void 0 ? void 0 : axiosInstance.defaults) === null || _h === void 0 ? void 0 : _h['axios-retry']);
}
return axiosInstance(axiosConfig);
}
return Promise.resolve(null);
}
export function restApis(requestConfigs) {
var _a, _b;
if (!axiosInstance) {
var firstRequest = requestConfigs[0];
console.info.apply(console, __spreadArray(__spreadArray([], __read(getTag('WARN', 'black', 'yellow')), false), ["".concat(firstRequest.method ? firstRequest.method.toUpperCase() : 'GET', " ").concat((_a = firstRequest.baseURL) !== null && _a !== void 0 ? _a : '').concat((_b = firstRequest.url) !== null && _b !== void 0 ? _b : '').concat(requestConfigs.length > 1 ? " and other ".concat(requestConfigs.length - 1) : '')], false));
console.warn(Constants.UNINITIALIZED_DEFAULT_CONFIG);
getInstance();
}
if (requestConfigs.length) {
var filteredConfigs = requestConfigs.filter(function (config) { return !RequestPool.hasCancelBook(config); });
var cancel_1 = RequestPool.addCancelBook(requestConfigs[0]);
return Axios.all(filteredConfigs.map(function (config) {
var _a, _b, _c, _d, _e, _f;
var ignoreCancel = config.ignoreCancel, restAxiosConfig = __rest(config, ["ignoreCancel"]);
var method = (_b = (_a = config.method) === null || _a === void 0 ? void 0 : _a.toLowerCase()) !== null && _b !== void 0 ? _b : 'get';
var axiosConfig = __assign(__assign({}, restAxiosConfig), { method: method });
var authorization = (_d = (_c = option.onAuthorize) === null || _c === void 0 ? void 0 : _c.call(option, config)) !== null && _d !== void 0 ? _d : '';
if (!axiosConfig.headers) {
axiosConfig.headers = {};
}
if (!axiosConfig.headers.authorization && !axiosConfig.headers.Authorization) {
axiosConfig.headers.authorization = authorization;
}
if (axiosConfig.baseURL && !axiosConfig.url) {
axiosConfig.url = axiosConfig.baseURL;
delete axiosConfig.baseURL;
}
if (!ignoreCancel) {
axiosConfig.cancelToken = cancel_1.token;
}
if (axiosConfig['axios-retry']) {
setAxiosRetry(axiosConfig['axios-retry']);
}
else if ((_e = axiosInstance === null || axiosInstance === void 0 ? void 0 : axiosInstance.defaults) === null || _e === void 0 ? void 0 : _e['axios-retry']) {
setAxiosRetry((_f = axiosInstance === null || axiosInstance === void 0 ? void 0 : axiosInstance.defaults) === null || _f === void 0 ? void 0 : _f['axios-retry']);
}
return axiosInstance(axiosConfig);
}));
}
return Promise.resolve(null);
}
export function cancelAllRequests(message) {
var currentRequests = RequestPool.getCurrentRequests();
if (currentRequests) {
if (option.isShowLog) {
var cancelBooks = RequestPool.getCancelBooks();
if (cancelBooks.length) {
console.info.apply(console, __spreadArray(__spreadArray([], __read(getTag('STOP', 'black', 'darkgray')), false), [message !== null && message !== void 0 ? message : "".concat(currentRequests === 1 ? 'A request was' : "".concat(currentRequests, " requests were"), " cancelled by user.")], false));
cancelBooks.forEach(function (item) {
return console.info.apply(console, __spreadArray(['%c❌', 'margin-right:-6px;'], __read(getRequestParamsData(item.config)), false));
});
}
}
RequestPool.burstCancelBooks();
}
}
export function isCancelled(error) {
return Axios.isCancel(error);
}
function setAxiosRetry(axiosRetryConfig) {
if (!!axiosRetryConfig && !!axiosInstance) {
AxiosRetry(axiosInstance, __assign({ retries: 0, retryCondition: retryCondition }, axiosRetryConfig));
}
}
function getRequestParamsData(config, responseStatus) {
var _a, _b, _c;
if (responseStatus === void 0) { responseStatus = 0; }
if (config) {
var requestParamsData = {};
var isResponse = responseStatus > 0;
var configUrl = (_a = config.url) !== null && _a !== void 0 ? _a : '/';
var url = Constants.REGEX_HAS_BASEURL.test(configUrl) ? configUrl : "".concat((_b = config.baseURL) !== null && _b !== void 0 ? _b : '').concat(config.url);
var method = config.method ? config.method.toUpperCase() : 'GET';
var isEmpty = true;
if (config.data) {
requestParamsData.data =
typeof config.data === 'string' && Constants.REGEX_IS_JSON.test(config.data)
? JSON.parse(config.data)
: config.data;
isEmpty = false;
}
if (config.params) {
requestParamsData.params =
typeof config.params === 'string' && Constants.REGEX_IS_JSON.test(config.params)
? JSON.parse(config.params)
: config.params;
isEmpty = false;
}
if (isResponse) {
var lastRequestTime = ((_c = config['axios-retry']) !== null && _c !== void 0 ? _c : {}).lastRequestTime;
var elapsedTime = void 0;
if (lastRequestTime) {
var timeDiff = Date.now() - lastRequestTime;
var reqTime = timeDiff > 1000 ? Number(timeDiff / 1000).toFixed(2) : timeDiff;
var reqUnit = timeDiff > 1000 ? 's' : 'ms';
elapsedTime = "(".concat(reqTime).concat(reqUnit, ")");
}
return [
[
Math.floor(responseStatus / 100) !== 2 ? "(".concat(responseStatus, ")") : undefined,
method,
url,
elapsedTime,
].filter(Boolean).join(' '),
isEmpty ? undefined : requestParamsData,
].filter(Boolean);
}
else {
return [
"".concat(method, " ").concat(url),
isEmpty ? undefined : requestParamsData,
].filter(Boolean);
}
}
return [];
}
function resolveRequestUrl(baseURL, url) {
var e_1, _a, e_2, _b;
var _c, _d, _e, _f, _g;
var resolved = { baseURL: baseURL, url: url };
if (baseURL) {
var tempUrl = "".concat(baseURL, "/");
try {
for (var resolveRequestUrlPrefixes_1 = __values(resolveRequestUrlPrefixes), resolveRequestUrlPrefixes_1_1 = resolveRequestUrlPrefixes_1.next(); !resolveRequestUrlPrefixes_1_1.done; resolveRequestUrlPrefixes_1_1 = resolveRequestUrlPrefixes_1.next()) {
var key = resolveRequestUrlPrefixes_1_1.value;
if (tempUrl.startsWith("".concat(key, "/"))) {
resolved.baseURL = baseURL.replace(key, (_d = (_c = option.resolveRequestURL) === null || _c === void 0 ? void 0 : _c[key]) !== null && _d !== void 0 ? _d : '');
break;
}
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (resolveRequestUrlPrefixes_1_1 && !resolveRequestUrlPrefixes_1_1.done && (_a = resolveRequestUrlPrefixes_1.return)) _a.call(resolveRequestUrlPrefixes_1);
}
finally { if (e_1) throw e_1.error; }
}
}
if (url && url !== '/') {
var tempUrl = "".concat(url, "/");
try {
for (var resolveRequestUrlPrefixes_2 = __values(resolveRequestUrlPrefixes), resolveRequestUrlPrefixes_2_1 = resolveRequestUrlPrefixes_2.next(); !resolveRequestUrlPrefixes_2_1.done; resolveRequestUrlPrefixes_2_1 = resolveRequestUrlPrefixes_2.next()) {
var key = resolveRequestUrlPrefixes_2_1.value;
if (tempUrl.startsWith("".concat(key, "/"))) {
resolved.url = url.replace(key, (_f = (_e = option.resolveRequestURL) === null || _e === void 0 ? void 0 : _e[key]) !== null && _f !== void 0 ? _f : '');
break;
}
}
}
catch (e_2_1) { e_2 = { error: e_2_1 }; }
finally {
try {
if (resolveRequestUrlPrefixes_2_1 && !resolveRequestUrlPrefixes_2_1.done && (_b = resolveRequestUrlPrefixes_2.return)) _b.call(resolveRequestUrlPrefixes_2);
}
finally { if (e_2) throw e_2.error; }
}
}
if (!!resolved.baseURL && ((_g = resolved.url) === null || _g === void 0 ? void 0 : _g.startsWith(resolved.baseURL))) {
resolved.url = resolved.url.replace(resolved.baseURL, '');
}
return resolved;
}
function getShorten(obj, maxBytes) {
if (maxBytes === void 0) { maxBytes = 1024; }
var threshold = 0;
var result = JSON.stringify(obj, function (_key, value) {
var _a;
if (threshold <= ((_a = option.truncateLogThreshold) !== null && _a !== void 0 ? _a : Infinity)) {
threshold++;
}
else if (typeof value === 'string') {
return value.length > 10 ? "".concat(value.slice(0, 10), "...") : value;
}
else if (isPlainObject(obj)) {
return '[object]';
}
else if (Array.isArray(obj)) {
return '[array]';
}
return value;
});
return result.length > maxBytes ? "".concat(result.slice(0, maxBytes), "...(truncated)") : result;
}
function logRequest(config) {
var _a;
if (option.isShowLog) {
var _b = ((_a = config === null || config === void 0 ? void 0 : config['axios-retry']) !== null && _a !== void 0 ? _a : {}), _c = _b.retryCount, retryCount = _c === void 0 ? 0 : _c, _d = _b.retries, retries = _d === void 0 ? 0 : _d;
var retryStatus = retryCount > 0 && retries > 0 ? "[".concat(retryCount, "/").concat(retries, "]") : '';
if (retryStatus) {
console.info.apply(console, __spreadArray(__spreadArray(__spreadArray([], __read(getTag('REQ', 'white', 'blue')), false), [retryStatus], false), __read(getRequestParamsData(config)), false));
}
else {
console.info.apply(console, __spreadArray(__spreadArray([], __read(getTag('REQ', 'white', 'blue')), false), __read(getRequestParamsData(config)), false));
}
}
}
function logResponse(response) {
if (option.isShowLog) {
var responseMessage = void 0;
if (option.isLogFullResponse) {
responseMessage = option.truncateLogThreshold ? __assign(__assign({}, response), { data: getShorten(response.data) }) : response;
}
else {
responseMessage = option.truncateLogThreshold ? getShorten(response.data) : response.data;
}
if (response.cached) {
response.config.method = 'CACHED';
}
console.info.apply(console, __spreadArray(__spreadArray(__spreadArray([], __read(getTag('SUCC', 'white', 'green')), false), __read(getRequestParamsData(response.config, response.status)), false), [responseMessage], false));
}
}
function logRequestError(error) {
if (option.isShowLog && error) {
if (!isCancelled(error)) {
console.info.apply(console, __spreadArray(__spreadArray([], __read(getTag('INV', 'black', 'yellow')), false), [error], false));
}
}
}
function logResponseError(error) {
var _a, _b;
if (option.isShowLog && error.config) {
console.info.apply(console, __spreadArray(__spreadArray(__spreadArray([], __read((isCancelled(error) ? getTag('STOP', 'white', 'brown') : getTag('ERR', 'black', 'red'))), false), __read(getRequestParamsData(error.config)), false), [(_b = (_a = error.response) === null || _a === void 0 ? void 0 : _a.status) !== null && _b !== void 0 ? _b : ''], false));
}
}