mirror of
https://github.com/azaion/ui.git
synced 2026-04-22 05:26:35 +00:00
66 lines
2.1 KiB
TypeScript
66 lines
2.1 KiB
TypeScript
let accessToken: string | null = null
|
|
|
|
export function setToken(token: string | null) {
|
|
accessToken = token
|
|
}
|
|
|
|
export function getToken() {
|
|
return accessToken
|
|
}
|
|
|
|
async function handleResponse<T>(res: Response): Promise<T> {
|
|
if (res.status === 204) return undefined as T
|
|
if (!res.ok) {
|
|
const text = await res.text().catch(() => '')
|
|
throw new Error(`${res.status}: ${text || res.statusText}`)
|
|
}
|
|
return res.json()
|
|
}
|
|
|
|
async function request<T>(url: string, options: RequestInit = {}): Promise<T> {
|
|
const headers = new Headers(options.headers)
|
|
if (accessToken) headers.set('Authorization', `Bearer ${accessToken}`)
|
|
if (options.body && typeof options.body === 'string') headers.set('Content-Type', 'application/json')
|
|
|
|
let res = await fetch(url, { ...options, headers })
|
|
|
|
if (res.status === 401 && accessToken) {
|
|
const refreshed = await refreshToken()
|
|
if (refreshed) {
|
|
headers.set('Authorization', `Bearer ${accessToken}`)
|
|
res = await fetch(url, { ...options, headers })
|
|
} else {
|
|
setToken(null)
|
|
window.location.href = '/login'
|
|
throw new Error('Session expired')
|
|
}
|
|
}
|
|
|
|
return handleResponse<T>(res)
|
|
}
|
|
|
|
async function refreshToken(): Promise<boolean> {
|
|
try {
|
|
const res = await fetch('/api/admin/auth/refresh', { method: 'POST', credentials: 'include' })
|
|
if (!res.ok) return false
|
|
const data = await res.json()
|
|
setToken(data.token)
|
|
return true
|
|
} catch {
|
|
return false
|
|
}
|
|
}
|
|
|
|
export const api = {
|
|
get: <T>(url: string) => request<T>(url),
|
|
post: <T>(url: string, body?: unknown) =>
|
|
request<T>(url, { method: 'POST', body: body ? JSON.stringify(body) : undefined }),
|
|
put: <T>(url: string, body?: unknown) =>
|
|
request<T>(url, { method: 'PUT', body: body ? JSON.stringify(body) : undefined }),
|
|
patch: <T>(url: string, body?: unknown) =>
|
|
request<T>(url, { method: 'PATCH', body: body ? JSON.stringify(body) : undefined }),
|
|
delete: <T>(url: string) => request<T>(url, { method: 'DELETE' }),
|
|
upload: <T>(url: string, formData: FormData) =>
|
|
request<T>(url, { method: 'POST', body: formData }),
|
|
}
|