UNPKG

@ts-rest/react-query

Version:

react-query client integration for @ts-rest

175 lines (170 loc) 7.32 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var reactQuery = require('@tanstack/react-query'); var core = require('@ts-rest/core'); const apiFetcher = (route, clientArgs, abortSignal) => { return async (requestData) => { const fetchApiArgs = core.evaluateFetchApiArgs(route, clientArgs, requestData); const result = await core.fetchApi({ ...fetchApiArgs, fetchOptions: { ...(abortSignal && { signal: abortSignal }), ...fetchApiArgs.fetchOptions, }, }); // If the response is not a 2XX, throw an error to be handled by react-query if (core.isErrorResponse(result)) { throw result; } return result; }; }; function createBaseQueryOptions(route, clientArgs, options) { const { queryData: queryDataOrFunction, ...rqOptions } = options; return { ...rqOptions, queryFn: queryDataOrFunction === reactQuery.skipToken ? reactQuery.skipToken : (context) => { const requestData = typeof queryDataOrFunction === 'function' ? queryDataOrFunction(context) : queryDataOrFunction; return apiFetcher(route, clientArgs, context === null || context === void 0 ? void 0 : context.signal)(requestData); }, }; } const appendTsRestResult = (result, tsResult) => ({ ...result, ...tsResult, }); const tanstackQueryHooks = { query: { useQuery: reactQuery.useQuery, useSuspenseQuery: reactQuery.useSuspenseQuery, useInfiniteQuery: reactQuery.useInfiniteQuery, useSuspenseInfiniteQuery: reactQuery.useSuspenseInfiniteQuery, }, queries: { useQueries: reactQuery.useQueries, useSuspenseQueries: reactQuery.useSuspenseQueries, }, prefetch: { usePrefetchQuery: reactQuery.usePrefetchQuery, usePrefetchInfiniteQuery: reactQuery.usePrefetchInfiniteQuery, }, }; const wrapHooks = (hooks, getWrapper) => { return Object.fromEntries(Object.entries(hooks).map(([hookName, hook]) => [ hookName, getWrapper(hook), ])); }; const wrapAllHooks = (appRoute, clientOptions) => { return { ...wrapHooks(tanstackQueryHooks.query, (hook) => (options, queryClient) => { return appendTsRestResult(hook(createBaseQueryOptions(appRoute, clientOptions, options), queryClient), { contractEndpoint: appRoute, }); }), ...wrapHooks(tanstackQueryHooks.queries, (hook) => (options, queryClient) => { return hook({ ...options, queries: options.queries.map((queryOptions) => createBaseQueryOptions(appRoute, clientOptions, queryOptions)), }, queryClient); }), ...wrapHooks(tanstackQueryHooks.prefetch, (hook) => (options) => { return hook(createBaseQueryOptions(appRoute, clientOptions, options)); }), }; }; const initHooksContainer = (contract, clientOptions) => { const recursiveInit = (innerRouter) => { return Object.fromEntries(Object.entries(innerRouter).map(([key, subRouter]) => { if (core.isAppRoute(subRouter)) { if (core.isAppRouteQuery(subRouter)) { return [ key, { query: core.getRouteQuery(subRouter, clientOptions), ...wrapAllHooks(subRouter, clientOptions), }, ]; } else { return [ key, { mutate: core.getRouteQuery(subRouter, clientOptions), useMutation: (options) => { return appendTsRestResult(reactQuery.useMutation({ ...options, mutationFn: apiFetcher(subRouter, clientOptions), }), { contractEndpoint: subRouter, }); }, }, ]; } } else { return [key, recursiveInit(subRouter)]; } })); }; return recursiveInit(contract); }; const initQueryClient = (contract, clientOptions, queryClient) => { const recursiveInit = (innerRouter) => { return Object.fromEntries(Object.entries(innerRouter).map(([key, subRouter]) => { if (core.isAppRoute(subRouter)) { if (core.isAppRouteQuery(subRouter)) { return [ key, { getQueryData: (queryKey) => { return queryClient.getQueryData(queryKey); }, ensureQueryData: (options) => { return queryClient.ensureQueryData(createBaseQueryOptions(subRouter, clientOptions, options)); }, getQueriesData: (filters) => { return queryClient.getQueriesData(filters); }, setQueryData: (queryKey, updater, options) => { return queryClient.setQueryData(queryKey, updater, options); }, setQueriesData: (filters, updater, options) => { return queryClient.setQueriesData(filters, updater, options); }, getQueryState: (queryKey) => { return queryClient.getQueryState(queryKey); }, fetchQuery: (options) => { return queryClient.fetchQuery(createBaseQueryOptions(subRouter, clientOptions, options)); }, prefetchQuery: (options) => { return queryClient.prefetchQuery(createBaseQueryOptions(subRouter, clientOptions, options)); }, fetchInfiniteQuery: (options) => { return queryClient.fetchInfiniteQuery(createBaseQueryOptions(subRouter, clientOptions, options)); }, prefetchInfiniteQuery: (options) => { return queryClient.prefetchInfiniteQuery(createBaseQueryOptions(subRouter, clientOptions, options)); }, }, ]; } else { return [key, undefined]; } } else { return [key, recursiveInit(subRouter)]; } })); }; return Object.assign(queryClient, recursiveInit(contract)); }; exports.initHooksContainer = initHooksContainer; exports.initQueryClient = initQueryClient;