import type { AxiosError, AxiosResponse, Method, RawAxiosRequestHeaders, } from 'axios'; import axios from 'axios'; import LinkHeader from 'http-link-header'; import { getAccessToken } from './initial_state'; import ready from './ready'; export const getLinks = (response: AxiosResponse) => { const value = response.headers.link as string | undefined; if (!value) { return new LinkHeader(); } return LinkHeader.parse(value); }; const csrfHeader: RawAxiosRequestHeaders = {}; const setCSRFHeader = () => { const csrfToken = document.querySelector( 'meta[name=csrf-token]', ); if (csrfToken) { csrfHeader['X-CSRF-Token'] = csrfToken.content; } }; void ready(setCSRFHeader); const authorizationTokenFromInitialState = (): RawAxiosRequestHeaders => { const accessToken = getAccessToken(); if (!accessToken) return {}; return { Authorization: `Bearer ${accessToken}`, }; }; // eslint-disable-next-line import/no-default-export export default function api(withAuthorization = true) { const instance = axios.create({ transitional: { clarifyTimeoutError: true, }, headers: { ...csrfHeader, ...(withAuthorization ? authorizationTokenFromInitialState() : {}), }, transformResponse: [ function (data: unknown) { try { return JSON.parse(data as string) as unknown; } catch { return data; } }, ], }); instance.interceptors.response.use( (response: AxiosResponse) => { if (response.headers.deprecation) { console.warn( `Deprecated request: ${response.config.method} ${response.config.url}`, ); } return response; }, (error: AxiosError) => { return Promise.reject(error); }, ); return instance; } type RequestParamsOrData = Record; export async function apiRequest( method: Method, url: string, args: { signal?: AbortSignal; params?: RequestParamsOrData; data?: RequestParamsOrData; timeout?: number; } = {}, ) { const { data } = await api().request({ method, url: '/api/' + url, ...args, }); return data; } export async function apiRequestGet( url: string, params?: RequestParamsOrData, ) { return apiRequest('GET', url, { params }); } export async function apiRequestPost( url: string, data?: RequestParamsOrData, ) { return apiRequest('POST', url, { data }); } export async function apiRequestPut( url: string, data?: RequestParamsOrData, ) { return apiRequest('PUT', url, { data }); } export async function apiRequestDelete( url: string, params?: RequestParamsOrData, ) { return apiRequest('DELETE', url, { params }); }