Files
tp/main_dc/yalarba/yalarba-nuxt/app/composables/useApi.ts
T
2026-06-12 00:29:34 +05:00

90 lines
2.5 KiB
TypeScript

import type { ApiError } from '~/types'
export const useApi = () => {
const config = useRuntimeConfig()
const authStore = useAuthStore()
const baseURL = config.public.apiBase as string
const request = async <T>(
endpoint: string,
options: RequestInit = {}
): Promise<T> => {
const headers: HeadersInit = {
'Content-Type': 'application/json',
...options.headers,
}
if (authStore.token) {
headers['Authorization'] = `Bearer ${authStore.token}`
}
const response = await fetch(`${baseURL}${endpoint}`, {
...options,
headers,
credentials: 'include',
})
if (response.status === 401) {
try {
const refreshed = await authStore.refreshToken()
if (refreshed) {
headers['Authorization'] = `Bearer ${authStore.token}`
const retryResponse = await fetch(`${baseURL}${endpoint}`, {
...options,
headers,
credentials: 'include',
})
if (!retryResponse.ok) {
const retryError = await retryResponse.json().catch(() => ({}))
throw {
message: retryError.message || 'Request failed',
status: retryResponse.status,
} as ApiError
}
return retryResponse.json()
}
} catch {
authStore.logout()
navigateTo('/auth/login')
throw { message: 'Session expired', status: 401 } as ApiError
}
}
if (!response.ok) {
const error: ApiError = await response.json().catch(() => ({
message: 'Network error',
}))
error.status = response.status
throw error
}
if (response.status === 204) {
return {} as T
}
return response.json()
}
return {
get: <T>(endpoint: string) => request<T>(endpoint),
post: <T>(endpoint: string, body?: unknown) =>
request<T>(endpoint, { method: 'POST', body: body ? JSON.stringify(body) : undefined }),
put: <T>(endpoint: string, body?: unknown) =>
request<T>(endpoint, { method: 'PUT', body: body ? JSON.stringify(body) : undefined }),
delete: <T>(endpoint: string) =>
request<T>(endpoint, { method: 'DELETE' }),
upload: <T>(endpoint: string, formData: FormData) => {
const headers: HeadersInit = {}
if (authStore.token) {
headers['Authorization'] = `Bearer ${authStore.token}`
}
return request<T>(endpoint, {
method: 'POST',
body: formData,
headers,
})
},
}
}