64 lines
1.5 KiB
TypeScript
64 lines
1.5 KiB
TypeScript
|
|
export interface FetchRequestContext {
|
||
|
|
url: string
|
||
|
|
init: RequestInit
|
||
|
|
}
|
||
|
|
|
||
|
|
export interface FetchRequestInterceptor {
|
||
|
|
onRequest?(
|
||
|
|
context: FetchRequestContext,
|
||
|
|
): Promise<FetchRequestContext> | FetchRequestContext
|
||
|
|
onResponse?(
|
||
|
|
context: FetchRequestContext,
|
||
|
|
response: Response,
|
||
|
|
): Promise<Response> | Response
|
||
|
|
onError?(context: FetchRequestContext, error: unknown): Promise<void> | void
|
||
|
|
}
|
||
|
|
|
||
|
|
function mergeHeaders(
|
||
|
|
currentHeaders: HeadersInit | undefined,
|
||
|
|
newHeaders: HeadersInit,
|
||
|
|
): Headers {
|
||
|
|
const mergedHeaders = new Headers(currentHeaders)
|
||
|
|
const incomingHeaders = new Headers(newHeaders)
|
||
|
|
|
||
|
|
incomingHeaders.forEach((value, key) => {
|
||
|
|
mergedHeaders.set(key, value)
|
||
|
|
})
|
||
|
|
|
||
|
|
return mergedHeaders
|
||
|
|
}
|
||
|
|
|
||
|
|
export function createHeaderRequestInterceptor(
|
||
|
|
headers: HeadersInit,
|
||
|
|
): FetchRequestInterceptor {
|
||
|
|
return {
|
||
|
|
onRequest(context) {
|
||
|
|
return {
|
||
|
|
...context,
|
||
|
|
init: {
|
||
|
|
...context.init,
|
||
|
|
headers: mergeHeaders(context.init.headers, headers),
|
||
|
|
},
|
||
|
|
}
|
||
|
|
},
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
export function createEnsureSuccessResponseInterceptor(): FetchRequestInterceptor {
|
||
|
|
return {
|
||
|
|
async onResponse(_, response) {
|
||
|
|
if (response.ok) {
|
||
|
|
return response
|
||
|
|
}
|
||
|
|
|
||
|
|
const errorBody = await response.text().catch(() => '')
|
||
|
|
const normalizedBody = errorBody
|
||
|
|
return Promise.reject({
|
||
|
|
status: response.status,
|
||
|
|
statusText: response.statusText,
|
||
|
|
body: normalizedBody,
|
||
|
|
})
|
||
|
|
},
|
||
|
|
}
|
||
|
|
}
|