|
|
import { useAuth } from '@/composables/useAuth' |
|
|
|
|
|
interface FetchOptions extends RequestInit { |
|
|
params?: Record<string, string | number | boolean | undefined>; |
|
|
} |
|
|
|
|
|
export async function http(url: string, options: FetchOptions = {}) { |
|
|
const { logout } = useAuth() |
|
|
|
|
|
const headers = new Headers(options.headers) |
|
|
|
|
|
|
|
|
let fullUrl = url |
|
|
if (options.params) { |
|
|
const searchParams = new URLSearchParams() |
|
|
Object.entries(options.params).forEach(([key, value]) => { |
|
|
if (value !== undefined && value !== null) { |
|
|
searchParams.append(key, String(value)) |
|
|
} |
|
|
}) |
|
|
const queryString = searchParams.toString() |
|
|
if (queryString) { |
|
|
fullUrl += (url.includes('?') ? '&' : '?') + queryString |
|
|
} |
|
|
} |
|
|
|
|
|
const config: RequestInit = { |
|
|
...options, |
|
|
headers, |
|
|
} |
|
|
|
|
|
const response = await fetch(fullUrl, config) |
|
|
|
|
|
if (response.status === 401) { |
|
|
|
|
|
logout() |
|
|
|
|
|
throw new Error('Unauthorized') |
|
|
} |
|
|
|
|
|
if (!response.ok) { |
|
|
const errorData = await response.json().catch(() => ({})) |
|
|
throw new Error(errorData.detail || `HTTP error! status: ${response.status}`) |
|
|
} |
|
|
|
|
|
|
|
|
if (response.status === 204) { |
|
|
return null |
|
|
} |
|
|
|
|
|
return response.json() |
|
|
} |
|
|
|