import * as reactQuery from '@tanstack/react-query'; import {QueryClientConfig} from '@tanstack/react-query'; import RequestError from 'sentry/utils/requestError/requestError'; import useApi from 'sentry/utils/useApi'; type QueryKeyEndpointOptions = { query?: Record; }; type QueryKey = | readonly [url: string] | readonly [url: string, options: QueryKeyEndpointOptions]; type UseQueryOptions = Omit< reactQuery.UseQueryOptions, 'queryKey' | 'queryFn' >; // We are not overriding any defaults options for stale time, retries, etc. // See https://tanstack.com/query/v4/docs/guides/important-defaults const DEFAULT_QUERY_CLIENT_CONFIG: QueryClientConfig = {}; function isQueryFn( queryFnOrQueryOptions?: | reactQuery.QueryFunction | UseQueryOptions ): queryFnOrQueryOptions is reactQuery.QueryFunction { return typeof queryFnOrQueryOptions === 'function'; } /** * Wraps React Query's useQuery for consistent usage in the Sentry app. * Query keys should be an array which include an endpoint URL and options such as query params. * This wrapper will execute the request using the query key URL, but if you need custom behavior * you may supply your own query function as the second argument. * * See https://tanstack.com/query/v4/docs/overview for docs on React Query. * * Example usage: * * const { data, isLoading, isError } = useQuery(['/events', { query: { limit: 50 }}]) */ function useQuery( queryKey: QueryKey, queryOptions?: UseQueryOptions ): reactQuery.UseQueryResult; /** * Example usage with custom query function: * * const { data, isLoading, isError } = useQuery(['events'], () => api.requestPromise(...)) */ function useQuery( queryKey: QueryKey, queryFn?: reactQuery.QueryFunction, queryOptions?: UseQueryOptions ): reactQuery.UseQueryResult; function useQuery( queryKey: QueryKey, queryFnOrQueryOptions?: | reactQuery.QueryFunction | UseQueryOptions, queryOptions?: UseQueryOptions ): reactQuery.UseQueryResult { const api = useApi(); const [path, endpointOptions] = queryKey; const defaultQueryFn: reactQuery.QueryFunction = () => api.requestPromise(path, { method: 'GET', query: endpointOptions?.query, }); const queryFn = isQueryFn(queryFnOrQueryOptions) ? queryFnOrQueryOptions : defaultQueryFn; const options = queryOptions ?? (isQueryFn(queryFnOrQueryOptions) ? undefined : queryFnOrQueryOptions); return reactQuery.useQuery(queryKey, queryFn, options); } // eslint-disable-next-line import/export export * from '@tanstack/react-query'; // eslint-disable-next-line import/export export {DEFAULT_QUERY_CLIENT_CONFIG, useQuery, UseQueryOptions};