68 lines
1.8 KiB
TypeScript
68 lines
1.8 KiB
TypeScript
export const API_BASE_URL = (import.meta.env.VITE_API_URL as string | undefined) ?? 'http://localhost:8081'
|
|
|
|
export function buildUrl(path: string) {
|
|
return `${API_BASE_URL}${path}`
|
|
}
|
|
|
|
export function getAuthToken(): string | null {
|
|
const storedUser = localStorage.getItem('user')
|
|
if (storedUser) {
|
|
try {
|
|
const userData = JSON.parse(storedUser)
|
|
if (userData?.jwt) {
|
|
return userData.jwt
|
|
}
|
|
} catch {
|
|
// Ignora erro de parsing
|
|
}
|
|
}
|
|
return null
|
|
}
|
|
|
|
type RequestOptions = Omit<RequestInit, 'body'> & {
|
|
body?: unknown
|
|
skipAuth?: boolean
|
|
}
|
|
|
|
export async function apiFetch<T>(path: string, options: RequestOptions = {}): Promise<T> {
|
|
const { body, headers, skipAuth, ...rest } = options
|
|
|
|
let authHeader: Record<string, string> = {}
|
|
if (!skipAuth) {
|
|
const token = getAuthToken()
|
|
if (token) {
|
|
authHeader = { Authorization: `Bearer ${token}` }
|
|
}
|
|
}
|
|
|
|
const isFormData = body instanceof FormData
|
|
const defaultHeaders: Record<string, string> = isFormData ? {} : { 'Content-Type': 'application/json' }
|
|
|
|
const response = await fetch(buildUrl(path), {
|
|
...rest,
|
|
headers: {
|
|
...defaultHeaders,
|
|
...authHeader,
|
|
...((headers as Record<string, string>) || {}),
|
|
},
|
|
body: isFormData ? body : (body !== undefined && body !== null ? JSON.stringify(body) : undefined),
|
|
})
|
|
|
|
const text = await response.text()
|
|
if (!response.ok) {
|
|
let errorMessage = text || 'Não foi possível concluir a requisição.'
|
|
try {
|
|
const parsed = JSON.parse(text)
|
|
if (parsed.message) {
|
|
errorMessage = parsed.message
|
|
} else if (parsed.error) {
|
|
errorMessage = parsed.error
|
|
}
|
|
} catch {
|
|
// Usar texto puro
|
|
}
|
|
throw new Error(errorMessage)
|
|
}
|
|
|
|
return text ? (JSON.parse(text) as T) : (undefined as T)
|
|
}
|