All checks were successful
Dev Build & Deploy Portal / build-deploy (push) Successful in 2m30s
52 lines
2.0 KiB
TypeScript
52 lines
2.0 KiB
TypeScript
import type { FetchOptions } from 'ofetch'
|
|
|
|
/**
|
|
* Wrapper para chamadas autenticadas ao core-api via BFF proxy.
|
|
*
|
|
* - Todas as requests passam por `/api/proxy/**` (que injeta Bearer + tenant headers no server)
|
|
* - Headers CSRF (`X-Requested-With: fetch`) sempre injetados — exigido pelo middleware do BFF em mutating methods
|
|
*
|
|
* Uso típico:
|
|
* const api = useApi()
|
|
* const debitos = await api.get<DebitoDTO[]>('portal/contribuinte/debitos')
|
|
* const novo = await api.post<DebitoDTO>('portal/contribuinte/debitos', payload)
|
|
*/
|
|
export function useApi() {
|
|
function buildUrl(path: string): string {
|
|
const clean = path.startsWith('/') ? path : `/${path}`
|
|
return `/api/proxy${clean}`
|
|
}
|
|
|
|
async function request<T>(path: string, options: FetchOptions = {}): Promise<T> {
|
|
try {
|
|
return await $fetch<T>(buildUrl(path), {
|
|
...options,
|
|
headers: {
|
|
'X-Requested-With': 'fetch',
|
|
...(options.headers ?? {}),
|
|
},
|
|
})
|
|
} catch (err: unknown) {
|
|
if (import.meta.dev) {
|
|
const e = err as { status?: number; data?: unknown }
|
|
console.error(`[api] ${(options.method ?? 'GET').toUpperCase()} ${path} → ${e.status}`, e.data)
|
|
}
|
|
throw err
|
|
}
|
|
}
|
|
|
|
return {
|
|
request,
|
|
get: <T>(path: string, opts?: FetchOptions) =>
|
|
request<T>(path, { ...opts, method: 'GET' }),
|
|
post: <T>(path: string, body?: unknown, opts?: FetchOptions) =>
|
|
request<T>(path, { ...opts, method: 'POST', body }),
|
|
put: <T>(path: string, body?: unknown, opts?: FetchOptions) =>
|
|
request<T>(path, { ...opts, method: 'PUT', body }),
|
|
patch: <T>(path: string, body?: unknown, opts?: FetchOptions) =>
|
|
request<T>(path, { ...opts, method: 'PATCH', body }),
|
|
delete: <T>(path: string, opts?: FetchOptions) =>
|
|
request<T>(path, { ...opts, method: 'DELETE' }),
|
|
}
|
|
}
|