UNPKG

@gaddario98/react-queries

Version:
274 lines (266 loc) 13.7 kB
import { useQuery, useQueries, useMutation, queryClient } from '@gaddario98/react-providers'; import { useMemo, useCallback } from 'react'; import axios from 'axios'; import { useNotification } from '@gaddario98/react-notifications'; import { useAuthValue } from '@gaddario98/react-auth'; let endpoints = { custom: '', }; const setEndpoints = (data) => { endpoints = Object.assign(Object.assign({}, endpoints), data); }; // Crea un'istanza di Axios const apiClient = axios.create(); const url = ''; // Aggiungi un interceptor di richiesta apiClient.interceptors.request.use(async (config) => { config.baseURL = url; return config; }, async (error) => { return await Promise.reject(error); }); apiClient.interceptors.response.use((response) => { return response; }, (error) => { var _a, _b; if (error.response) { throw new Error(((_a = error.response.data) === null || _a === void 0 ? void 0 : _a.message) || ((_b = error.response.data) === null || _b === void 0 ? void 0 : _b.error) || `Error ${error.response.status}`); } else if (error.request) { throw new Error('No response from server - request timeout or network issue'); } else { throw new Error('Request configuration error'); } }); const apiRequest = async (url, method, body, headers, converter) => { var _a, _b; try { const data = converter && body ? converter(body) : body; const response = await apiClient({ url, method, data, headers, }); if (response.status >= 200 && response.status < 300) { return response.data; } throw new Error((_b = (_a = response.data) === null || _a === void 0 ? void 0 : _a.error) !== null && _b !== void 0 ? _b : 'Error'); } catch (error) { if (error instanceof Error) { throw error; } throw new Error('Unknown error occurred'); } }; const fetchRequest = async (url, headers) => { return apiRequest(url, 'GET', undefined, headers); }; let validateApi = () => { return true; }; const setValidateApi = (validate) => { validateApi = validate; }; const useQueryApi = (props) => { const { enabled, endpoint, queryKey, customQueryFn, headers, disableAuthControl, onDataChanged, } = props; const auth = useAuthValue(); const base = useMemo(() => endpoints[endpoint[0]], [endpoint]); const queryResult = useQuery({ queryKey, queryFn: async () => { var _a, _b, _c; const res = await ((_a = customQueryFn === null || customQueryFn === void 0 ? void 0 : customQueryFn()) !== null && _a !== void 0 ? _a : fetchRequest(`${base ? base + "/" : ""}${(_b = endpoint === null || endpoint === void 0 ? void 0 : endpoint[1]) !== null && _b !== void 0 ? _b : ""}`, Object.assign({ Authorization: (auth === null || auth === void 0 ? void 0 : auth.token) ? `Bearer ${(_c = auth === null || auth === void 0 ? void 0 : auth.token) !== null && _c !== void 0 ? _c : ""}` : "" }, headers))); onDataChanged === null || onDataChanged === void 0 ? void 0 : onDataChanged(res); return res; }, enabled: !!enabled && (disableAuthControl || (!!(auth === null || auth === void 0 ? void 0 : auth.isLogged) && validateApi())), retry: 1, retryDelay: 1000, }); return queryResult; }; const useMultipleQuery = (settings = []) => { const auth = useAuthValue(); const results = useQueries({ queries: settings.map(({ enabled, endpoint: endpointArr, queryKey, customQueryFn, headers, disableAuthControl, onDataChanged, }) => { const [key, path] = endpointArr; const baseUrl = endpoints[key]; const fullEndpoint = [baseUrl, path].filter(Boolean).join("/"); return { queryKey, queryFn: async () => { var _a; const res = await ((_a = customQueryFn === null || customQueryFn === void 0 ? void 0 : customQueryFn()) !== null && _a !== void 0 ? _a : fetchRequest(fullEndpoint, Object.assign({ Authorization: (auth === null || auth === void 0 ? void 0 : auth.token) ? `Bearer ${auth.token}` : "" }, headers))); onDataChanged === null || onDataChanged === void 0 ? void 0 : onDataChanged(res); return res; }, enabled: !!enabled && (disableAuthControl || (!!(auth === null || auth === void 0 ? void 0 : auth.isLogged) && validateApi())), retry: 1, retryDelay: 1000, }; }), combine: useCallback((results) => results.reduce((prev, result, index) => { var _a; return Object.assign(Object.assign({}, prev), { [settings[index].keyToMap]: { data: result.data, isLoadingMapped: !((_a = settings[index]) === null || _a === void 0 ? void 0 : _a.disableLoading) && result.isLoading, isLoading: result.isLoading, isFetching: result.isFetching, isPending: result.isPending, } }); }, {}), [settings]), }); /* const prevOnDataChangedMappedRef = useRef< Array<{ keyToMap: Q[number]["key"]; onDataChanged: ((data: Q[number]["response"]) => void) | undefined; }> >([]); const onDataChangedMapped = useMemo(() => { const data = settings.map(({ keyToMap, onDataChanged }) => { return { keyToMap, onDataChanged, }; }); if ( JSON.stringify(prevOnDataChangedMappedRef.current) !== JSON.stringify(data) ) { prevOnDataChangedMappedRef.current = data; } prevOnDataChangedMappedRef.current = data; return prevOnDataChangedMappedRef.current; }, [settings]); onDataChangedMapped.forEach((data) => { const { onDataChanged, keyToMap } = data; const result = useMemo(() => results[keyToMap], [results, keyToMap]); useEffect(() => { if ( onDataChanged && result.data !== undefined && !result.isLoading && !result.isFetching && !result.isPending ) { onDataChanged(result.data); } }, [ result.data, onDataChanged, result.isLoading, result.isFetching, result.isPending, ]); });*/ return results; }; const useMutateApi = ({ endpoint, queryKeyToInvalidate, converter, customRequest, headers, isTest, mutateOptions, method, notification, }) => { const { showNotification } = useNotification(); const auth = useAuthValue(); return useMutation(Object.assign(Object.assign({ mutationFn: async (data) => { var _a, _b; if (isTest) { return "test"; } if ((auth === null || auth === void 0 ? void 0 : auth.isLogged) && !validateApi()) throw new Error("Utente non autenticato"); return (customRequest !== null && customRequest !== void 0 ? customRequest : (apiRequest))(`${endpoints[endpoint[0]]}/${(_a = endpoint === null || endpoint === void 0 ? void 0 : endpoint[1]) !== null && _a !== void 0 ? _a : ""}`, method, data, Object.assign({ Authorization: (auth === null || auth === void 0 ? void 0 : auth.token) ? `Bearer ${(_b = auth === null || auth === void 0 ? void 0 : auth.token) !== null && _b !== void 0 ? _b : ""}` : "" }, headers), converter); } }, (mutateOptions || {})), { onSuccess: (data, variables, context) => { var _a, _b; (_a = mutateOptions === null || mutateOptions === void 0 ? void 0 : mutateOptions.onSuccess) === null || _a === void 0 ? void 0 : _a.call(mutateOptions, data, variables, context); queryKeyToInvalidate === null || queryKeyToInvalidate === void 0 ? void 0 : queryKeyToInvalidate.forEach((queryKey) => { queryClient.invalidateQueries({ queryKey: [queryKey], exact: false }); }); const notificationProps = typeof (notification === null || notification === void 0 ? void 0 : notification.success) === "function" ? notification.success(data) : notification === null || notification === void 0 ? void 0 : notification.success; if (notificationProps === null || notificationProps === void 0 ? void 0 : notificationProps.message) { showNotification(Object.assign({ message: notificationProps.message, type: (_b = notificationProps === null || notificationProps === void 0 ? void 0 : notificationProps.type) !== null && _b !== void 0 ? _b : "success" }, notificationProps)); } }, onError(error, variables, context) { var _a, _b, _c, _d, _e; (_a = mutateOptions === null || mutateOptions === void 0 ? void 0 : mutateOptions.onError) === null || _a === void 0 ? void 0 : _a.call(mutateOptions, error, variables, context); if (error === null || error === void 0 ? void 0 : error.message) { const notificationProps = typeof (notification === null || notification === void 0 ? void 0 : notification.error) === "function" ? notification.error((_b = error === null || error === void 0 ? void 0 : error.message) !== null && _b !== void 0 ? _b : "Error") : notification === null || notification === void 0 ? void 0 : notification.error; showNotification(Object.assign({ message: (_d = (_c = notificationProps === null || notificationProps === void 0 ? void 0 : notificationProps.message) !== null && _c !== void 0 ? _c : error === null || error === void 0 ? void 0 : error.message) !== null && _d !== void 0 ? _d : "An unexpected error occurred", type: (_e = notificationProps === null || notificationProps === void 0 ? void 0 : notificationProps.type) !== null && _e !== void 0 ? _e : "error" }, notificationProps)); } } })); }; const useApi = (configs) => { var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k; // Filter and prepare query configurations const queryItems = useMemo(() => configs === null || configs === void 0 ? void 0 : configs.filter((q) => q.type === "query"), [configs]); const queryConfigs = useMemo(() => { return queryItems .map((item) => item.queryConfig ? Object.assign(Object.assign({}, item.queryConfig), { keyToMap: item.key }) : null) .filter(Boolean); }, [queryItems]); // Execute all queries with a single hook const queriesResult = useMultipleQuery(queryConfigs); // Filter mutation configs const mutationItems = useMemo(() => configs === null || configs === void 0 ? void 0 : configs.filter((q) => q.type === "mutation" && !!q.mutationConfig), [configs]); // Define a default config for empty slots const defaultMutationConfig = { endpoint: ["default"], method: "POST", }; // Create mutation hooks - each must be declared separately to follow React's rules of hooks const mutation1 = useMutateApi(((_a = mutationItems[0]) === null || _a === void 0 ? void 0 : _a.mutationConfig) || defaultMutationConfig); const mutation2 = useMutateApi(((_b = mutationItems[1]) === null || _b === void 0 ? void 0 : _b.mutationConfig) || defaultMutationConfig); const mutation3 = useMutateApi(((_c = mutationItems[2]) === null || _c === void 0 ? void 0 : _c.mutationConfig) || defaultMutationConfig); const mutation4 = useMutateApi(((_d = mutationItems[3]) === null || _d === void 0 ? void 0 : _d.mutationConfig) || defaultMutationConfig); const mutation5 = useMutateApi(((_e = mutationItems[4]) === null || _e === void 0 ? void 0 : _e.mutationConfig) || defaultMutationConfig); const mutation6 = useMutateApi(((_f = mutationItems[5]) === null || _f === void 0 ? void 0 : _f.mutationConfig) || defaultMutationConfig); const mutation7 = useMutateApi(((_g = mutationItems[6]) === null || _g === void 0 ? void 0 : _g.mutationConfig) || defaultMutationConfig); const mutation8 = useMutateApi(((_h = mutationItems[7]) === null || _h === void 0 ? void 0 : _h.mutationConfig) || defaultMutationConfig); const mutation9 = useMutateApi(((_j = mutationItems[8]) === null || _j === void 0 ? void 0 : _j.mutationConfig) || defaultMutationConfig); const mutation10 = useMutateApi(((_k = mutationItems[9]) === null || _k === void 0 ? void 0 : _k.mutationConfig) || defaultMutationConfig); // Store all mutation instances in an array for mapping const mutationInstances = useMemo(() => [ mutation1, mutation2, mutation3, mutation4, mutation5, mutation6, mutation7, mutation8, mutation9, mutation10, ], [ mutation1, mutation10, mutation2, mutation3, mutation4, mutation5, mutation6, mutation7, mutation8, mutation9, ]); // Map mutations to their keys const allMutation = useMemo(() => { const result = {}; mutationItems.forEach((item, index) => { if (index < mutationInstances.length) { result[item.key] = mutationInstances[index]; } }); return result; }, [mutationItems, mutationInstances]); // Return both queries and mutations return { allMutation, allQuery: queriesResult }; }; export { endpoints, setEndpoints, setValidateApi, useApi, useMultipleQuery, useMutateApi, useQueryApi }; //# sourceMappingURL=index.mjs.map