Files
mem0/server/dashboard/src/utils/api.ts
T
2026-04-23 19:06:36 +05:30

114 lines
2.7 KiB
TypeScript

import axios, { AxiosError, AxiosInstance } from "axios";
let cachedToken: string | null = null;
const LOGIN_PATH = "/login";
export const setAccessToken = (token: string | null) => {
cachedToken = token;
};
export const getAccessToken = (): string | null => {
return cachedToken;
};
const handleTokenError = () => {
cachedToken = null;
};
const redirectToLogin = () => {
if (typeof window !== "undefined") {
window.location.href = LOGIN_PATH;
}
};
const refreshAccessToken = async () => {
const refreshResponse = await fetch("/api/auth/refresh", {
method: "POST",
credentials: "include",
});
if (!refreshResponse.ok) {
return null;
}
const data = await refreshResponse.json();
setAccessToken(data.access_token);
return data.access_token as string;
};
const createApi = (): AxiosInstance & {
postStream: (url: string, data: unknown) => Promise<Response>;
} => {
const api = axios.create({
baseURL: process.env.NEXT_PUBLIC_API_URL,
});
api.interceptors.request.use(
async (config) => {
if (cachedToken) {
config.headers = config.headers ?? {};
config.headers.Authorization = `Bearer ${cachedToken}`;
}
return config;
},
(error) => {
return Promise.reject(error);
},
);
api.interceptors.response.use(
(response) => response,
async (error: AxiosError<{ error?: string }>) => {
if (error.response?.status === 401) {
handleTokenError();
try {
const nextToken = await refreshAccessToken();
if (nextToken && error.config) {
error.config.headers = error.config.headers ?? {};
error.config.headers.Authorization = `Bearer ${nextToken}`;
return api.request(error.config);
}
} catch {}
handleTokenError();
redirectToLogin();
}
if (error.response?.data?.error) {
return Promise.reject(error.response.data.error);
}
return Promise.reject(error);
},
);
const postStream = async (url: string, data: unknown): Promise<Response> => {
const response = await fetch(`${process.env.NEXT_PUBLIC_API_URL}${url}`, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: cachedToken ? `Bearer ${cachedToken}` : "",
},
body: JSON.stringify(data),
});
if (response.status === 401) {
handleTokenError();
redirectToLogin();
throw new Error("Unauthorized");
}
if (!response.ok) {
const errorData = await response.json().catch(() => ({}));
throw new Error(errorData.error || "Request failed");
}
return response;
};
return Object.assign(api, { postStream });
};
export const api = createApi();