Files
frontend/app/composables/useApiFetch.ts
T

50 lines
1.5 KiB
TypeScript

import { defu } from 'defu'
export const useApiFetch = <T>(request: string, options: Parameters<typeof $fetch>[1] = {}) => {
const config = useRuntimeConfig()
const nuxtApp = useNuxtApp()
const tokenCookie = useCookie('auth_token', { path: '/' })
const tokenState = useState<string | null>('auth_token_state')
const tokenValue = tokenState.value ?? tokenCookie.value
const defaults: Parameters<typeof $fetch>[1] = {
baseURL: config.public.api as string,
headers: tokenValue ? { Authorization: `Bearer ${tokenValue}` } : {},
}
const params = defu(options, defaults)
try {
if (params?.body && typeof FormData !== 'undefined' && params.body instanceof FormData) {
if (params.headers && 'Content-Type' in params.headers) {
delete params.headers['Content-Type']
}
}
} catch (e) {}
return $fetch<T>(request, params).catch((err: any) => {
const status = err?.statusCode || err?.status || err?.response?.status
if (status === 401 || status === 403) {
try {
tokenCookie.value = null
tokenState.value = null
const authUser = useState('auth_user')
authUser.value = null
console.error(`[API] Authentication error (${status}) - token cleared`)
} catch (e) {
console.error('[API] Error clearing auth state:', e)
}
try {
nuxtApp.runWithContext(() => navigateTo('/auth/login'))
} catch (e) {
console.error('[API] Error navigating to login:', e)
}
}
throw err
})
}