mirror of
https://github.com/OpenSquawk/OpenSquawk
synced 2026-08-04 08:06:26 +08:00
69 lines
2.0 KiB
TypeScript
69 lines
2.0 KiB
TypeScript
import { useAuthStore } from '~/stores/auth'
|
|
|
|
type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE'
|
|
|
|
interface ApiRequestOptions<T = any> {
|
|
method?: HttpMethod
|
|
body?: T
|
|
query?: Record<string, any>
|
|
headers?: HeadersInit
|
|
auth?: boolean
|
|
}
|
|
|
|
export function useApi() {
|
|
const auth = useAuthStore()
|
|
|
|
const execute = async <T>(path: string, options: ApiRequestOptions = {}) => {
|
|
const { method = 'GET', body, query, headers = {}, auth: requiresAuth = true } = options
|
|
|
|
const computedHeaders: Record<string, string> = {
|
|
Accept: 'application/json',
|
|
...(headers as Record<string, string>),
|
|
}
|
|
|
|
if (requiresAuth && auth.accessToken) {
|
|
computedHeaders.Authorization = `Bearer ${auth.accessToken}`
|
|
}
|
|
|
|
const requestOptions: any = {
|
|
method,
|
|
headers: computedHeaders,
|
|
query,
|
|
body,
|
|
}
|
|
|
|
if (body && !(body instanceof FormData)) {
|
|
computedHeaders['Content-Type'] = 'application/json'
|
|
requestOptions.body = body
|
|
}
|
|
|
|
try {
|
|
return await $fetch<T>(path, requestOptions)
|
|
} catch (error: any) {
|
|
const status = error?.status || error?.response?.status
|
|
if (status === 401 && requiresAuth) {
|
|
const refreshed = await auth.tryRefresh()
|
|
if (refreshed) {
|
|
if (auth.accessToken) {
|
|
computedHeaders.Authorization = `Bearer ${auth.accessToken}`
|
|
}
|
|
return await $fetch<T>(path, requestOptions)
|
|
}
|
|
await auth.logout()
|
|
}
|
|
throw error
|
|
}
|
|
}
|
|
|
|
return {
|
|
request: execute,
|
|
get: <T>(path: string, options: ApiRequestOptions = {}) => execute<T>(path, { ...options, method: 'GET' }),
|
|
post: <T>(path: string, body?: any, options: ApiRequestOptions = {}) =>
|
|
execute<T>(path, { ...options, method: 'POST', body }),
|
|
put: <T>(path: string, body?: any, options: ApiRequestOptions = {}) =>
|
|
execute<T>(path, { ...options, method: 'PUT', body }),
|
|
del: <T>(path: string, options: ApiRequestOptions = {}) => execute<T>(path, { ...options, method: 'DELETE' }),
|
|
}
|
|
}
|
|
|