55 lines
1.4 KiB
JavaScript
55 lines
1.4 KiB
JavaScript
|
|
/**
|
||
|
|
* Unified safeFetch wrapper for API requests.
|
||
|
|
* Handles authentication headers, credentials, and error mapping consistently across all endpoints.
|
||
|
|
*/
|
||
|
|
|
||
|
|
import { API_KEY } from './config.js'
|
||
|
|
|
||
|
|
/** Build headers for JSON API requests with optional X-API-Key */
|
||
|
|
function buildHeaders(extra = {}) {
|
||
|
|
return API_KEY
|
||
|
|
? { 'X-API-Key': API_KEY, ...extra }
|
||
|
|
: { ...extra }
|
||
|
|
}
|
||
|
|
|
||
|
|
/** Parse JSON response from fetch result, handling non-OK status codes */
|
||
|
|
async function parseJsonResponse(res) {
|
||
|
|
if (!res.ok) {
|
||
|
|
let message = `HTTP ${res.status}`
|
||
|
|
try {
|
||
|
|
const data = await res.json()
|
||
|
|
message = data.detail || data.error || message
|
||
|
|
} catch {
|
||
|
|
const text = await res.text()
|
||
|
|
if (text) message = text
|
||
|
|
}
|
||
|
|
throw new Error(message)
|
||
|
|
}
|
||
|
|
return res.json()
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Fetch wrapper that handles:
|
||
|
|
* - Authentication headers (X-API-Key)
|
||
|
|
* - Credentials (include cookies)
|
||
|
|
* - Error mapping (HTTP status → meaningful message)
|
||
|
|
*/
|
||
|
|
export async function safeFetch(url, options = {}) {
|
||
|
|
const headers = buildHeaders(options.headers || {})
|
||
|
|
const res = await fetch(url, {
|
||
|
|
...options,
|
||
|
|
headers,
|
||
|
|
credentials: 'include',
|
||
|
|
})
|
||
|
|
|
||
|
|
if (!res.ok) {
|
||
|
|
const errorText = await res.text()
|
||
|
|
throw new Error(`HTTP ${res.status}: ${errorText}`)
|
||
|
|
}
|
||
|
|
|
||
|
|
return res
|
||
|
|
}
|
||
|
|
|
||
|
|
/** Export helper functions for use in other modules */
|
||
|
|
export { buildHeaders, parseJsonResponse }
|