UIKit/src/api/createMakeRequest.ts

72 lines
2.1 KiB
TypeScript
Raw Normal View History

2023-06-06 10:02:17 +00:00
import axios, { AxiosResponse, Method } from "axios";
interface MakeRequestArgs<T> {
method?: Method;
url: string;
body?: T;
/** Send access token */
useToken?: boolean;
contentType?: boolean;
signal?: AbortSignal;
/** Send refresh token */
withCredentials?: boolean;
}
export const createMakeRequest = (getToken: () => string, setToken: (token: string) => void) => async <TRequest = unknown, TResponse = unknown>({
method = "post",
url,
body,
useToken = true,
contentType = false,
signal,
withCredentials,
}: MakeRequestArgs<TRequest>): Promise<TResponse> => {
const headers: Record<string, string> = {};
if (useToken) headers["Authorization"] = `Bearer ${getToken()}`;
if (contentType) headers["Content-Type"] = "application/json";
try {
const response = await axios<TRequest, AxiosResponse<TResponse & { accessToken?: string; }>>({
url,
method,
headers,
data: body,
signal,
withCredentials,
});
if (response.data?.accessToken) {
setToken(response.data.accessToken);
}
return response.data;
} catch (error) {
if (axios.isAxiosError(error) && error.response?.status === 401 && !withCredentials) {
const refreshResponse = await refresh(getToken());
if (refreshResponse.data?.accessToken) setToken(refreshResponse.data.accessToken);
headers["Authorization"] = refreshResponse.data.accessToken;
const response = await axios.request<TRequest, AxiosResponse<TResponse>>({
url,
method,
headers,
data: body,
signal,
});
return response.data;
}
throw error;
}
};
function refresh(token: string) {
return axios<never, AxiosResponse<{ accessToken: string; }>>("https://admin.pena.digital/auth/refresh", {
headers: {
"Authorization": token,
"Content-Type": "application/json",
},
});
}