|
import axios, { AxiosError } from "axios";
|
|
|
|
const github = axios.create({
|
|
baseURL: "https://api.github.com",
|
|
headers: {
|
|
Accept: "application/vnd.github+json",
|
|
"X-GitHub-Api-Version": "2022-11-28",
|
|
},
|
|
});
|
|
|
|
const setAuthTokenHeader = (token: string) => {
|
|
github.defaults.headers.common.Authorization = `Bearer ${token}`;
|
|
};
|
|
|
|
const removeAuthTokenHeader = () => {
|
|
if (github.defaults.headers.common.Authorization) {
|
|
delete github.defaults.headers.common.Authorization;
|
|
}
|
|
};
|
|
|
|
|
|
|
|
|
|
const canRefresh = (error: unknown): boolean =>
|
|
!!(
|
|
error instanceof AxiosError &&
|
|
error.config &&
|
|
error.response &&
|
|
error.response.status
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export const isGitHubErrorReponse = <T extends object | Array<unknown>>(
|
|
data: T | GitHubErrorReponse | null,
|
|
): data is GitHubErrorReponse =>
|
|
!!data && "message" in data && data.message !== undefined;
|
|
|
|
|
|
const setupAxiosInterceptors = (
|
|
appMode: string,
|
|
refreshToken: () => Promise<boolean>,
|
|
logout: () => void,
|
|
) => {
|
|
github.interceptors.response.use(
|
|
|
|
(response) => {
|
|
const parsedData = response.data;
|
|
if (isGitHubErrorReponse(parsedData)) {
|
|
const error = new AxiosError(
|
|
"Failed",
|
|
"",
|
|
response.config,
|
|
response.request,
|
|
response,
|
|
);
|
|
throw error;
|
|
}
|
|
return response;
|
|
},
|
|
|
|
async (error) => {
|
|
if (!canRefresh(error)) {
|
|
return Promise.reject(new Error("Failed to refresh token"));
|
|
}
|
|
|
|
const originalRequest = error.config;
|
|
|
|
|
|
if (
|
|
error.response.status === 401 &&
|
|
!originalRequest._retry
|
|
) {
|
|
originalRequest._retry = true;
|
|
|
|
if (appMode === "saas") {
|
|
try {
|
|
const refreshed = await refreshToken();
|
|
if (refreshed) {
|
|
return await github(originalRequest);
|
|
}
|
|
|
|
logout();
|
|
return await Promise.reject(new Error("Failed to refresh token"));
|
|
} catch (refreshError) {
|
|
|
|
logout();
|
|
return Promise.reject(refreshError);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
return Promise.reject(error);
|
|
},
|
|
);
|
|
};
|
|
|
|
export {
|
|
github,
|
|
setAuthTokenHeader,
|
|
removeAuthTokenHeader,
|
|
setupAxiosInterceptors,
|
|
};
|
|
|