Download frontend/src/api/github-axios-instance.ts from ar08/zzz: direct link, hf CLI and curl.
- Browser
- Download file 2.93 kB
-
https://huggingface.co/spaces/ar08/zzz/resolve/main/frontend/src/api/github-axios-instance.ts
- Command line
-
hf download hf://spaces/ar08/zzz/frontend/src/api/github-axios-instance.ts
-
curl -L -o github-axios-instance.ts https://huggingface.co/spaces/ar08/zzz/resolve/main/frontend/src/api/github-axios-instance.ts
2.93 kB
| 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; | |
| } | |
| }; | |
| /** | |
| * Checks if response has attributes to perform refresh | |
| */ | |
| const canRefresh = (error: unknown): boolean => | |
| !!( | |
| error instanceof AxiosError && | |
| error.config && | |
| error.response && | |
| error.response.status | |
| ); | |
| /** | |
| * Checks if the data is a GitHub error response | |
| * @param data The data to check | |
| * @returns Boolean indicating if the data is a GitHub error response | |
| */ | |
| export const isGitHubErrorReponse = <T extends object | Array<unknown>>( | |
| data: T | GitHubErrorReponse | null, | |
| ): data is GitHubErrorReponse => | |
| !!data && "message" in data && data.message !== undefined; | |
| // Axios interceptor to handle token refresh | |
| const setupAxiosInterceptors = ( | |
| appMode: string, | |
| refreshToken: () => Promise<boolean>, | |
| logout: () => void, | |
| ) => { | |
| github.interceptors.response.use( | |
| // Pass successful responses through | |
| (response) => { | |
| const parsedData = response.data; | |
| if (isGitHubErrorReponse(parsedData)) { | |
| const error = new AxiosError( | |
| "Failed", | |
| "", | |
| response.config, | |
| response.request, | |
| response, | |
| ); | |
| throw error; | |
| } | |
| return response; | |
| }, | |
| // Retry request exactly once if token is expired | |
| async (error) => { | |
| if (!canRefresh(error)) { | |
| return Promise.reject(new Error("Failed to refresh token")); | |
| } | |
| const originalRequest = error.config; | |
| // Check if the error is due to an expired token | |
| if ( | |
| error.response.status === 401 && | |
| !originalRequest._retry // Prevent infinite retry loops | |
| ) { | |
| 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) { | |
| // If token refresh fails, evict the user | |
| logout(); | |
| return Promise.reject(refreshError); | |
| } | |
| } | |
| } | |
| // If the error is not due to an expired token, propagate the error | |
| return Promise.reject(error); | |
| }, | |
| ); | |
| }; | |
| export { | |
| github, | |
| setAuthTokenHeader, | |
| removeAuthTokenHeader, | |
| setupAxiosInterceptors, | |
| }; | |