import type { 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<HTMLMetaElement>( '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) { return 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; } }, ], }); } type RequestParamsOrData = Record<string, unknown>; export async function apiRequest<ApiResponse = unknown>( method: Method, url: string, args: { params?: RequestParamsOrData; data?: RequestParamsOrData; } = {}, ) { const { data } = await api().request<ApiResponse>({ method, url: '/api/' + url, ...args, }); return data; } export async function apiRequestGet<ApiResponse = unknown>( url: string, params?: RequestParamsOrData, ) { return apiRequest<ApiResponse>('GET', url, { params }); } export async function apiRequestPost<ApiResponse = unknown>( url: string, data?: RequestParamsOrData, ) { return apiRequest<ApiResponse>('POST', url, { data }); } export async function apiRequestPut<ApiResponse = unknown>( url: string, data?: RequestParamsOrData, ) { return apiRequest<ApiResponse>('PUT', url, { data }); } export async function apiRequestDelete<ApiResponse = unknown>( url: string, params?: RequestParamsOrData, ) { return apiRequest<ApiResponse>('DELETE', url, { params }); }