All Downloads are FREE. Search and download functionalities are using the official Maven repository.

package.initializers.axiosInitializer.index.js Maven / Gradle / Ivy

Go to download

A package encapsulating common code across neeto projects including initializers, utility functions, common components and hooks and so on.

There is a newer version: 4.12.3
Show newest version
import _defineProperty from "@babel/runtime/helpers/defineProperty";
import _typeof from "@babel/runtime/helpers/typeof";
import axios from "axios";
import i18next from "i18next";
import { isNotEmpty, keysToCamelCase, matches, serializeKeysToSnakeCase } from "@bigbinary/neeto-cist";
import Toastr from "@bigbinary/neetoui/Toastr";
import { dissoc, evolve, omit } from "ramda";
import { toast } from "react-toastify";
import { useErrorDisplayStore } from "../../react-utils/useDisplayErrorPage";
import { resetAuthTokens } from "../../utils/axios";
import setParamsSerializer from "./paramsSerializer";
import { HEADERS_KEYS, MAXIMUM_OFFLINE_DURATION } from "../constants";
var checkOnlineInterval = null;
var requestErrorToasts = {};
var shouldNot = function shouldNot(skip) {
  return _typeof(skip) === "object" || !skip;
};
var shouldShowToastr = function shouldShowToastr(response) {
  return typeof response === "string" && isNotEmpty(response) || _typeof(response) === "object" && ((response === null || response === void 0 ? void 0 : response.notice) || (response === null || response === void 0 ? void 0 : response.noticeCode));
};
var setAuthHeaders = function setAuthHeaders() {
  var _document$querySelect, _axios$defaults$heade;
  // @ts-ignore
  axios.defaults.headers = (_axios$defaults$heade = {}, _defineProperty(_axios$defaults$heade, HEADERS_KEYS.accept, "application/json"), _defineProperty(_axios$defaults$heade, HEADERS_KEYS.contentType, "application/json"), _defineProperty(_axios$defaults$heade, HEADERS_KEYS.xCsrfToken, (_document$querySelect = document.querySelector('[name="csrf-token"]')) === null || _document$querySelect === void 0 ? void 0 : _document$querySelect.getAttribute("content")), _axios$defaults$heade);
};

// pipe function from ramda doesn't accept array of functions.
// We can't use spread operator too. So this is a workaround.
var createPipe = function createPipe(functions) {
  return function (data) {
    return functions.reduce(function (acc, fn) {
      return fn(acc);
    }, data);
  };
};
var transformResponseKeysToCamelCase = function transformResponseKeysToCamelCase(response) {
  var _response$config$tran = response.config.transformResponseCase,
    transformResponseCase = _response$config$tran === void 0 ? true : _response$config$tran;
  if (response.data && transformResponseCase) {
    response.data = keysToCamelCase(response.data);
  }
  return response;
};
var transformErrorKeysToCamelCase = function transformErrorKeysToCamelCase(error) {
  var _error$config, _error$response;
  var _ref = (_error$config = error.config) !== null && _error$config !== void 0 ? _error$config : {},
    _ref$transformRespons = _ref.transformResponseCase,
    transformResponseCase = _ref$transformRespons === void 0 ? true : _ref$transformRespons;
  if ((_error$response = error.response) !== null && _error$response !== void 0 && _error$response.data && transformResponseCase) {
    error.response.data = keysToCamelCase(error.response.data);
  }
  return error;
};
var showSuccessToastr = function showSuccessToastr(response) {
  var _response$config = response.config,
    _response$config$show = _response$config.showToastr,
    showToastr = _response$config$show === void 0 ? true : _response$config$show,
    requestUrl = _response$config.url,
    requestMethod = _response$config.method;
  if (!showToastr) return response;
  var toastIdKey = "".concat(requestMethod, ":").concat(requestUrl);
  var errorToastId = requestErrorToasts[toastIdKey];
  if (errorToastId) {
    toast.dismiss(errorToastId);
    requestErrorToasts = dissoc(toastIdKey, requestErrorToasts);
  }
  if (matches({
    showThumbsUpToastr: true
  }, response.data)) {
    // @ts-ignore
    Toastr.success("", {
      icon: "👍",
      className: "w-20"
    });
  } else if (matches({
    noticeCode: "thumbs_up"
  }, response.data)) {
    // @ts-ignore
    Toastr.success("", {
      icon: "👍",
      className: "w-20"
    });
  } else if (shouldShowToastr(response.data)) {
    Toastr.success(response.data);
  }
  return response;
};
var pullDataFromResponse = function pullDataFromResponse(response) {
  var _response$config$incl = response.config.includeMetadataInResponse,
    includeMetadataInResponse = _response$config$incl === void 0 ? false : _response$config$incl;
  return includeMetadataInResponse ? response : response.data;
};
var buildSuccessResponseHandler = function buildSuccessResponseHandler(skip) {
  var interceptors = [];
  if (!(skip !== null && skip !== void 0 && skip.transformCase)) interceptors.push(transformResponseKeysToCamelCase);
  if (!(skip !== null && skip !== void 0 && skip.showToastr)) interceptors.push(showSuccessToastr);
  if (!(skip !== null && skip !== void 0 && skip.pullDataFromResponse)) interceptors.push(pullDataFromResponse);
  return createPipe(interceptors);
};
var handleUnauthorizedErrorResponse = function handleUnauthorizedErrorResponse(error) {
  var _error$response2, _error$config2;
  if (((_error$response2 = error.response) === null || _error$response2 === void 0 ? void 0 : _error$response2.status) !== 401) return error;
  resetAuthTokens();
  var _ref2 = (_error$config2 = error.config) !== null && _error$config2 !== void 0 ? _error$config2 : {},
    _ref2$redirectOnError = _ref2.redirectOnError,
    redirectOnError = _ref2$redirectOnError === void 0 ? true : _ref2$redirectOnError;
  if (redirectOnError) {
    setTimeout(function () {
      var redirectTo = window.location.pathname === "/login" ? "/login" : "/login?redirect_uri=".concat(encodeURIComponent(window.location.href));

      // eslint-disable-next-line  xss/no-location-href-assign
      window.location.href = redirectTo;
    }, 300);
  }
  return error;
};
var isOnline = function isOnline() {
  return window.navigator.onLine;
};
var showOfflineToastr = function showOfflineToastr() {
  var toastId = Toastr.error(i18next.t("neetoCommons.toastr.error.networkError"));
  if (toastId) {
    var dismissToastInterval = setInterval(function () {
      if (!isOnline()) return;
      toast.dismiss(toastId);
      clearInterval(dismissToastInterval);
      checkOnlineInterval = null;
    }, 1000);
  }
};
var handleNetworkError = function handleNetworkError(error) {
  if (checkOnlineInterval) return error;
  var startTime = Date.now();
  checkOnlineInterval = setInterval(function () {
    var elapsedTime = Date.now() - startTime;
    if (isOnline()) {
      clearInterval(checkOnlineInterval);
      checkOnlineInterval = null;
    } else if (elapsedTime >= MAXIMUM_OFFLINE_DURATION) {
      clearInterval(checkOnlineInterval);
      showOfflineToastr();
    }
  }, 1000);
  return error;
};
var showErrorToastr = function showErrorToastr(error) {
  var _error$config3, _error$response3;
  var _ref3 = (_error$config3 = error.config) !== null && _error$config3 !== void 0 ? _error$config3 : {},
    _ref3$showToastr = _ref3.showToastr,
    showToastr = _ref3$showToastr === void 0 ? true : _ref3$showToastr,
    _ref3$show422ErrorToa = _ref3.show422ErrorToastr,
    show422ErrorToastr = _ref3$show422ErrorToa === void 0 ? true : _ref3$show422ErrorToa,
    _ref3$url = _ref3.url,
    requestUrl = _ref3$url === void 0 ? "" : _ref3$url,
    _ref3$method = _ref3.method,
    requestMethod = _ref3$method === void 0 ? "" : _ref3$method;
  var _ref4 = (_error$response3 = error.response) !== null && _error$response3 !== void 0 ? _error$response3 : {},
    status = _ref4.status;
  if (!showToastr) return error;
  if (error.message === "Network Error") return handleNetworkError(error);
  if (error.code === "ECONNABORTED") {
    return error;
  }
  var shouldShowToastr = false,
    toastrContent = error;
  var skippedStatusCodes = [403, 404, 520, 422];
  if (!skippedStatusCodes.includes(status) && !axios.isCancel(error)) {
    // we already display a page in case of 403 & 404 and we don't want to show a toastr for cancelled requests.
    // We handle cloudflare error differently for production and other environments.
    shouldShowToastr = true;
  }
  if (status === 422 && show422ErrorToastr) shouldShowToastr = true;
  if (status === 520) {
    shouldShowToastr = true;
    if (globalProps.railsEnv === "production") {
      toastrContent = i18next.t("generic.error");
    }
  }
  var toastIdKey = "".concat(requestMethod, ":").concat(requestUrl);
  var errorToastId = requestErrorToasts[toastIdKey];
  if (errorToastId) toast.dismiss(errorToastId);
  if (shouldShowToastr) {
    if (errorToastId) {
      // if there's an existing toastr with the same message, the onClose callback in the neetoUI which
      // removes the toastr from the unique list will be fired only after the toast is completely removed
      // from the UI. If there's no delay, the new toastr will be considered as duplicate and ignored.
      setTimeout(function () {
        requestErrorToasts[toastIdKey] = Toastr.error(toastrContent);
      }, 1200);
    } else requestErrorToasts[toastIdKey] = Toastr.error(toastrContent);
  }
  return error;
};
var getUrlPathName = function getUrlPathName(url) {
  try {
    return new URL(url).pathname;
  } catch (_unused) {
    return url;
  }
};
var handle404ErrorResponse = function handle404ErrorResponse(error) {
  var _error$config4, _error$response4;
  var _ref5 = (_error$config4 = error.config) !== null && _error$config4 !== void 0 ? _error$config4 : {},
    _ref5$show404ErrorPag = _ref5.show404ErrorPage,
    show404ErrorPage = _ref5$show404ErrorPag === void 0 ? true : _ref5$show404ErrorPag,
    _ref5$show403ErrorPag = _ref5.show403ErrorPage,
    show403ErrorPage = _ref5$show403ErrorPag === void 0 ? true : _ref5$show403ErrorPag;
  var status = (_error$response4 = error.response) === null || _error$response4 === void 0 ? void 0 : _error$response4.status;
  if (status === 404 && show404ErrorPage || status === 403 && show403ErrorPage) {
    var _error$request;
    var fullUrl = ((_error$request = error.request) === null || _error$request === void 0 ? void 0 : _error$request.responseURL) || error.config.url;
    useErrorDisplayStore.setState({
      showErrorPage: true,
      statusCode: status,
      failedApiUrl: fullUrl,
      failedApiPath: getUrlPathName(fullUrl)
    });
  }
  return error;
};
var buildErrorResponseHandler = function buildErrorResponseHandler(skip) {
  var interceptors = [];
  if (!(skip !== null && skip !== void 0 && skip.transformCase)) interceptors.push(transformErrorKeysToCamelCase);
  if (!(skip !== null && skip !== void 0 && skip.show404ErrorPage)) interceptors.push(handle404ErrorResponse);
  if (!(skip !== null && skip !== void 0 && skip.logoutOn401)) interceptors.push(handleUnauthorizedErrorResponse);
  if (!(skip !== null && skip !== void 0 && skip.showToastr)) interceptors.push(showErrorToastr);
  interceptors.push(Promise.reject.bind(Promise));
  return createPipe(interceptors);
};
var cleanupCredentialsForCrossOrigin = function cleanupCredentialsForCrossOrigin(request) {
  if (!request.url.includes("://")) return request;
  if (request.url.includes(window.location.hostname)) return request;
  return evolve({
    headers: omit([HEADERS_KEYS.xCsrfToken])
  })(request);
};
var transformDataToSnakeCase = function transformDataToSnakeCase(request) {
  var _request$transformReq = request.transformRequestCase,
    transformRequestCase = _request$transformReq === void 0 ? true : _request$transformReq;
  if (!transformRequestCase) return request;
  return evolve({
    data: serializeKeysToSnakeCase,
    params: serializeKeysToSnakeCase
  }, request);
};
var addRequestInterceptors = function addRequestInterceptors(skip) {
  if (!(skip !== null && skip !== void 0 && skip.cleanCredentialsForCrossOrigin)) {
    axios.interceptors.request.use(cleanupCredentialsForCrossOrigin);
  }
  if (!(skip !== null && skip !== void 0 && skip.transformCase)) {
    axios.interceptors.request.use(transformDataToSnakeCase);
  }
};
var addResponseInterceptors = function addResponseInterceptors(skip) {
  axios.interceptors.response.use(buildSuccessResponseHandler(skip), buildErrorResponseHandler(skip));
};
var registerIntercepts = function registerIntercepts(skip) {
  if (shouldNot(skip === null || skip === void 0 ? void 0 : skip.request)) addRequestInterceptors(skip === null || skip === void 0 ? void 0 : skip.request);
  if (shouldNot(skip === null || skip === void 0 ? void 0 : skip.response)) addResponseInterceptors(skip === null || skip === void 0 ? void 0 : skip.response);
};
export default function initializeAxios(skip) {
  if (!(skip !== null && skip !== void 0 && skip.baseURL)) axios.defaults.baseURL = "/";
  if (!(skip !== null && skip !== void 0 && skip.authHeaders)) setAuthHeaders();
  if (!(skip !== null && skip !== void 0 && skip.paramsSerializer)) setParamsSerializer();
  if (shouldNot(skip === null || skip === void 0 ? void 0 : skip.interceptors)) registerIntercepts(skip === null || skip === void 0 ? void 0 : skip.interceptors);
}
//# sourceMappingURL=index.js.map




© 2015 - 2024 Weber Informatics LLC | Privacy Policy