73 lines
2.1 KiB
TypeScript
73 lines
2.1 KiB
TypeScript
import { ofetch } from "ofetch";
|
|
|
|
export interface RequestOptions<T> extends RequestInit {
|
|
onErrorOccured?: (error: Error, statusCode: number) => Promise<void>;
|
|
onSuccess?: (data: T, statusCode: number) => void;
|
|
onStart?: () => void;
|
|
}
|
|
|
|
/**
|
|
* @function useMyFetch
|
|
*
|
|
* @description
|
|
* Makes a request to a given url, handles cookies and errors.
|
|
*
|
|
* @param {string} url - The url to make a request to.
|
|
* @param {RequestOptions} [options] - The options to use for the request.
|
|
*
|
|
* @returns {Promise<T | undefined>} - A promise resolving to the response data
|
|
* or undefined if an error occurred.
|
|
*
|
|
* @example
|
|
* const { data } = useMyFetch<{ name: string }>('/api/user')
|
|
*/
|
|
export const useMyFetch = async <T>(
|
|
url: string,
|
|
options?: RequestOptions<T>
|
|
): Promise<T> => {
|
|
if (options?.onStart) options.onStart();
|
|
let response = null;
|
|
try {
|
|
const event = useRequestEvent();
|
|
|
|
if (options == null) options = {};
|
|
|
|
options.credentials = "include";
|
|
|
|
if (import.meta.server) {
|
|
const api_uri =
|
|
event?.node.req.headers["api-uri"] || "http://localhost:4000";
|
|
url = api_uri + url;
|
|
options.headers = event?.headers;
|
|
}
|
|
|
|
response = await ofetch.raw(url, options);
|
|
if (import.meta.server && !event?.handled) {
|
|
for (const cookie of response.headers.getSetCookie()) {
|
|
event?.headers.set("Cookie", cookie);
|
|
event?.node.res.setHeader("set-cookie", cookie);
|
|
}
|
|
}
|
|
|
|
// handle errors if any
|
|
if (!response.ok && typeof options.onErrorOccured == "function") {
|
|
options.onErrorOccured(new Error(response.statusText), response.status);
|
|
}
|
|
|
|
// handle success to be able clearly marked that request has finished
|
|
if (response.ok && typeof options.onSuccess == "function") {
|
|
options.onSuccess(response._data, response.status);
|
|
}
|
|
|
|
return response._data as T;
|
|
} catch (e) {
|
|
// handle errors if any
|
|
if (typeof options?.onErrorOccured == "function") {
|
|
options.onErrorOccured(e as Error, response?.status || 500);
|
|
} else {
|
|
console.error(e);
|
|
}
|
|
return {} as T;
|
|
}
|
|
};
|