All files / packages/hooks/src apiQuery.ts

100% Statements 10/10
100% Branches 2/2
100% Functions 5/5
100% Lines 10/10

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60                                                1x       5x 4x     1x     1x                 11x           5x 5x 5x       5x      
import { QueryKey, useQuery } from "@tanstack/react-query";
 
import { REQUEST_POLICY, runRequestEffect } from "@repo/services/effectRequest";
 
type ApiDataResponse<T> = {
  data: T;
};
 
export interface HttpReadableClient {
  get<T>(endpoint: string): Promise<{ data: T }>;
}
 
export type RequestGuard = <T>(requestFn: () => Promise<T>) => Promise<T>;
 
export interface UseApiDataQueryParams {
  queryKey: QueryKey;
  endpoint: string;
  httpClient: HttpReadableClient;
  requestGuard?: RequestGuard;
  enabled?: boolean;
  staleTime?: number;
  gcTime?: number;
}
 
const runGuardedRequest = async <T>(
  requestFn: () => Promise<T>,
  requestGuard?: RequestGuard,
) => {
  if (!requestGuard) {
    return requestFn();
  }
 
  return requestGuard(requestFn);
};
 
export const useApiDataQuery = <TData>({
  queryKey,
  endpoint,
  httpClient,
  requestGuard,
  enabled,
  staleTime,
  gcTime,
}: UseApiDataQueryParams) =>
  useQuery<TData>({
    queryKey,
    enabled,
    staleTime,
    gcTime,
    queryFn: () =>
      runRequestEffect(async () => {
        const response = await runGuardedRequest(
          () => httpClient.get<ApiDataResponse<TData>>(endpoint),
          requestGuard,
        );
 
        return response.data.data;
      }, REQUEST_POLICY.READ),
  });