2024-04-01 13:10:08 +02:00
|
|
|
type RequestResult<
|
|
|
|
|
T = void,
|
|
|
|
|
TType extends 'json' | 'void' = 'json'
|
|
|
|
|
> = TType extends 'void' ? undefined : TType extends 'json' ? T : void
|
|
|
|
|
|
2022-08-21 22:27:31 +02:00
|
|
|
export class RequestError extends Error {
|
|
|
|
|
constructor(public response: Response, message: string) {
|
|
|
|
|
super(message)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export class ResponseEmptyError extends RequestError {
|
|
|
|
|
constructor(response: Response, message: string) {
|
|
|
|
|
super(response, message)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-01 13:10:08 +02:00
|
|
|
export const request = async <
|
|
|
|
|
TResult = void,
|
|
|
|
|
TType extends 'json' | 'void' = 'json'
|
|
|
|
|
>(
|
2022-08-21 22:27:31 +02:00
|
|
|
url: string,
|
|
|
|
|
options?: RequestInit,
|
2024-04-01 13:10:08 +02:00
|
|
|
type?: TType
|
|
|
|
|
): Promise<RequestResult<TResult, TType>> => {
|
2022-08-21 22:27:31 +02:00
|
|
|
const response = await fetch(url, options)
|
|
|
|
|
|
|
|
|
|
if (!response.ok) {
|
|
|
|
|
throw new RequestError(
|
|
|
|
|
response,
|
|
|
|
|
`${response.status} ${response.statusText}`
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (type === 'void') {
|
2024-04-01 13:10:08 +02:00
|
|
|
return undefined as RequestResult<TResult, TType>
|
2022-08-21 22:27:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const text = await response.text()
|
|
|
|
|
|
|
|
|
|
if (!text) {
|
2024-04-01 13:10:08 +02:00
|
|
|
if (!type || type === 'json') {
|
2022-08-21 22:27:31 +02:00
|
|
|
throw new ResponseEmptyError(
|
|
|
|
|
response,
|
|
|
|
|
'Expected json, got empty response'
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-01 13:10:08 +02:00
|
|
|
return undefined as RequestResult<TResult, TType>
|
2022-08-21 22:27:31 +02:00
|
|
|
}
|
|
|
|
|
|
2024-04-01 13:10:08 +02:00
|
|
|
return JSON.parse(text) as RequestResult<TResult, TType>
|
2022-08-21 22:27:31 +02:00
|
|
|
}
|