2021-08-23 21:29:58 +08:00
|
|
|
import { RequestErrorBody } from '@logto/schemas';
|
2021-08-30 11:30:54 +08:00
|
|
|
import { HTTPError } from 'ky';
|
2022-04-08 10:12:26 +08:00
|
|
|
import { useState, useCallback, useContext } from 'react';
|
|
|
|
|
2022-04-21 14:08:16 +08:00
|
|
|
import { PageContext } from '@/hooks/use-page-context';
|
2021-08-23 21:29:58 +08:00
|
|
|
|
|
|
|
type UseApi<T extends any[], U> = {
|
|
|
|
result?: U;
|
2022-03-28 09:40:47 +08:00
|
|
|
error: RequestErrorBody | undefined;
|
2021-08-23 21:29:58 +08:00
|
|
|
run: (...args: T) => Promise<void>;
|
|
|
|
};
|
|
|
|
|
|
|
|
function useApi<Args extends any[], Response>(
|
|
|
|
api: (...args: Args) => Promise<Response>
|
|
|
|
): UseApi<Args, Response> {
|
2022-03-28 09:40:47 +08:00
|
|
|
const [error, setError] = useState<RequestErrorBody>();
|
2021-08-23 21:29:58 +08:00
|
|
|
const [result, setResult] = useState<Response>();
|
|
|
|
|
2022-04-08 10:12:26 +08:00
|
|
|
const { setLoading } = useContext(PageContext);
|
|
|
|
|
2021-12-21 13:28:14 +08:00
|
|
|
const run = useCallback(
|
|
|
|
async (...args: Args) => {
|
|
|
|
setLoading(true);
|
2022-03-28 09:40:47 +08:00
|
|
|
// eslint-disable-next-line unicorn/no-useless-undefined
|
|
|
|
setError(undefined);
|
2021-08-23 21:29:58 +08:00
|
|
|
|
2021-12-21 13:28:14 +08:00
|
|
|
try {
|
|
|
|
const result = await api(...args);
|
|
|
|
setResult(result);
|
|
|
|
} catch (error: unknown) {
|
2022-03-28 09:40:47 +08:00
|
|
|
if (error instanceof HTTPError && error.response.body) {
|
2021-12-21 13:28:14 +08:00
|
|
|
const kyError = await error.response.json<RequestErrorBody>();
|
|
|
|
setError(kyError);
|
2022-01-27 19:26:34 +08:00
|
|
|
|
2021-12-21 13:28:14 +08:00
|
|
|
return;
|
|
|
|
}
|
2021-08-23 21:29:58 +08:00
|
|
|
|
2022-03-28 09:40:47 +08:00
|
|
|
// TODO: handle unknown server error
|
2021-12-21 13:28:14 +08:00
|
|
|
throw error;
|
2022-03-28 09:40:47 +08:00
|
|
|
} finally {
|
|
|
|
setLoading(false);
|
2021-12-21 13:28:14 +08:00
|
|
|
}
|
|
|
|
},
|
2022-04-08 10:12:26 +08:00
|
|
|
[api, setLoading]
|
2021-12-21 13:28:14 +08:00
|
|
|
);
|
2021-08-23 21:29:58 +08:00
|
|
|
|
|
|
|
return {
|
|
|
|
error,
|
|
|
|
result,
|
|
|
|
run,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
export default useApi;
|