UNPKG

react-query-factory

Version:

Create API client for your React app with just one line of code, using React Query!

63 lines (62 loc) 4 kB
import { QueryKey } from '@tanstack/react-query'; import { UseMutationFnWithParams, UseMutationFnWithoutParams } from './create-use-mutation'; import { ServiceFunction, UseQueryFnWithParams, UseQueryFnWithoutParams } from './create-use-query'; type FunctionConstraint<T> = { [K in keyof T]: (...args: any[]) => any; }; /** * Dynamically generates query and mutation hooks, along with query key generators, * for each function in a given service object. This utility function facilitates the * integration of service layer functions with React Query's useQuery and useMutation hooks. * * @template T The type of the service object, constrained to an object where each property * is a function that might take any number of arguments and return a Promise of any type. * @param {T} service An object containing service functions. Each function in this object * represents a distinct API call or data fetching logic that can be transformed into * a query or a mutation. * @param {string} queryKeyPrefix A string prefix used to construct the query keys for * each generated query. This prefix helps in namespacing the queries and avoiding key collisions. * * @returns {Queries} An object where each key corresponds to a key in the input service object, * and each value is an object containing: * - `useQuery`: A custom hook generated by `createUseQuery`, tailored to invoke the corresponding * service function. If the service function does not expect parameters, `useQuery` will be a * function that takes optional React Query options. If the service function expects parameters, * `useQuery` will be a function that expects those parameters followed by optional React Query options. * - `useMutation`: A custom hook generated by `createUseMutation`, tailored to invoke the corresponding * service function. Similar to `useQuery`, the shape of `useMutation` depends on whether the service * function expects parameters. * - `queryKey`: A function that generates a query key for the corresponding service function. The generated * query key is an array consisting of the `queryKeyPrefix`, the key corresponding to the service function, * and the parameters passed to the service function, if any. * * The `Queries` type is a mapped type where each property of the input service object is mapped to an object * containing the `useQuery`, `useMutation`, and `queryKey` properties as described above. * * @example * ```tsx * const userService = { * getUser: (params: {id: string}) => fetch(`/api/users/${params.id}`).then(res => res.json()), * updateUser: (userId, userData) => fetch(`/api/users/${userId}`, { * method: 'POST', * body: JSON.stringify(userData), * }).then(res => res.json()), * }; * * const { getUser, updateUser } = createQueriesFromService(userService, 'user'); * * // Inside a component * const Foo = () => { * const { data: user, isLoading } = getUser.useQuery({ id: "123" }); * const { mutate: updateUser } = updateUser.useMutation(); * * return <div>...</div> * } * ``` */ declare function createQueriesFromService<T extends FunctionConstraint<T>>(service: T, queryKeyPrefix: string): { [K in keyof T]: { useQuery: T[K] extends infer T_1 ? T_1 extends T[K] ? T_1 extends ServiceFunction<infer TParams, infer TResult> ? Parameters<T[K]> extends infer T_2 ? T_2 extends Parameters<T[K]> ? T_2 extends [] ? UseQueryFnWithoutParams<TResult> : UseQueryFnWithParams<TParams, TResult> : never : never : never : never : never; useMutation: T[K] extends infer T_3 ? T_3 extends T[K] ? T_3 extends ServiceFunction<infer TParams_1, infer TResult_1> ? Parameters<T[K]> extends infer T_4 ? T_4 extends Parameters<T[K]> ? T_4 extends [] ? UseMutationFnWithoutParams<TResult_1> : UseMutationFnWithParams<TParams_1, TResult_1> : never : never : never : never : never; queryKey: (params: Parameters<T[K]> extends [infer Params] ? Params : void) => QueryKey; }; }; export { createQueriesFromService };