All files / api graphqlClient.ts

80.95% Statements 17/21
50% Branches 4/8
75% Functions 3/4
82.35% Lines 14/17

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          3x   3x           1x 1x 1x                     1x 3x 1x             1x       1x   1x     1x   1x       1x    
interface GraphQLResponse<T> {
  data?: T;
  errors?: { message: string }[];
}
 
const defaultGraphqlUrl = 'http://localhost:8080/graphql';
 
export function getGraphqlUrl(): string {
  const envUrl = import.meta.env.VITE_GRAPHQL_URL as string | undefined;
  if (envUrl) {
    return envUrl;
  }
 
  if (typeof window !== 'undefined') {
    const url = new URL(window.location.origin);
    url.port = '8080';
    url.pathname = '/graphql';
    return url.toString();
  }
 
  return defaultGraphqlUrl;
}
 
export async function graphqlRequest<TData>(
  query: string,
  variables?: Record<string, unknown>
): Promise<TData> {
  const response = await fetch(getGraphqlUrl(), {
    method: 'POST',
    headers: {
      'content-type': 'application/json',
    },
    body: JSON.stringify({ query, variables }),
  });
 
  if (!response.ok) {
    throw new Error(`GraphQL request failed with status ${String(response.status)}`);
  }
 
  const payload = (await response.json()) as GraphQLResponse<TData>;
 
  if (payload.errors?.length) {
    const message = payload.errors.map((error) => error.message).join('; ');
    throw new Error(message);
  }
 
  if (!payload.data) {
    throw new Error('GraphQL response did not include data');
  }
 
  return payload.data;
}