src/utils/axios.js

import Axios from "axios";
import Qs from "qs";

import {version} from "PackageData";
import config from "./config";
import {SESSION_ID} from "./constants";

// ("https://patron.lunchbox.io");

const {LBX_PATRON_URL, LBX_PATRON_VERSION} = process.env;

const url = `${LBX_PATRON_URL}${
  LBX_PATRON_VERSION ? `/${LBX_PATRON_VERSION}` : ""
}`;
const tokenKey = config.local_storage_key;
const isMarketPlaceEnabled = config?.market_place?.enabled;

// if the build environment is test (i.e .rip tld) force all clients to blacktap.
// test env is for UI testing atm
const client = process.env.BUILD_ENV === "test" ? "blacktap" : config.id;

const AxiosInstance = Axios.create({
  baseURL: url,
  headers: {
    Client: client,
    OS: "Web",
    SessionId: SESSION_ID,
    Version: version,
    ...(isMarketPlaceEnabled ? {platform: "marketplace"} : {}),
  },
});

AxiosInstance.defaults.withCredientials = true;
AxiosInstance.defaults.paramsSerializer = (params) =>
  Qs.stringify(params, {
    arrayFormat: "brackets",
  });

// On each request we need to send auth headers
AxiosInstance.interceptors.request.use(
  (config) => {
    const token = localStorage !== null && localStorage.getItem(tokenKey);
    const location = localStorage !== null && localStorage.getItem("location");
    const {id = undefined} = JSON.parse(location) || {};

    const additionalHeaders = {};
    if (id) {
      additionalHeaders.locationId = id;
    }
    if (token) {
      additionalHeaders.authorization = token;
    }
    config.headers.common = {
      ...additionalHeaders,
      ...config.headers.common,
    };
    return config;
  },
  (error) => Promise.reject(error),
);

// On each response we need to grab the auth headers
AxiosInstance.interceptors.response.use(
  (response) => response,
  (error) => {
    if (
      error.response &&
      error.response.status &&
      error.response.status === 503
    ) {
      const event = new CustomEvent("alert", {
        detail: {
          message: error.response.data.message,
        },
      });
      document.dispatchEvent(event);
    }
    return Promise.reject(error);
  },
);

/**
 * helper method to perform an api requests
 *
 * @param path.method
 * @param path
 * @param method
 * @param data
 * @param headers
 * @param path.path
 * @param path.data
 * @param path.config
 * @returns {Promise<*>}
 */
const axiosRequest = async ({method = "GET", path, data = {}, config = {}}) => {
  try {
    method = method.toUpperCase();
    return AxiosInstance({
      method,
      url: path,
      [["GET"].includes(method) ? "params" : "data"]: data,
      ...config,
    });
  } catch (error) {
    throw error;
  }
};

const methods = {};
// Provide aliases for supported request methods
["delete", "get", "head", "options", "post", "put", "patch"].forEach(
  (method) => {
    methods[method] = (path, data, config) =>
      axiosRequest({
        config,
        data,
        method,
        path,
      });
  },
);

const handleError = (error) => {
  if (error.response) {
    const {data, status} = error.response;
    return {data: data.message, raw: data, status, type: "response"};
  }
  if (error.request) {
    return {data: "No Response Received", status: 408, type: "timeout"};
  }
  return {data: error.message, status: 0, type: "request"};
};

export {axiosRequest as axios, methods, handleError};
export default axiosRequest;