All files / src/graphql client.ts

100% Statements 20/20
100% Branches 10/10
100% Functions 5/5
100% Lines 19/19

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 61 62 63 64 65 66 67 68 6910x   10x 10x             10x         21x 21x               18x     18x             18x                 17x 1x     16x   15x 3x     13x 1x     12x       6x       3x      
import { ExecutionResult, print } from "graphql";
import { TypedDocumentNode } from "@graphql-typed-document-node/core";
import { DEFAULT_HEADERS } from "../http-client";
import { enhancedFetch } from "../utils/fetch";
 
export interface GraphQLClientOptions {
  endpoint: string;
  headers?: Record<string, string>;
}
 
export class GraphQLClient {
  public readonly endpoint: string;
  private defaultHeaders: Record<string, string>;
 
  constructor(endpoint: string, options?: { headers?: Record<string, string> }) {
    this.endpoint = endpoint;
    this.defaultHeaders = options?.headers ?? {};
  }
 
  async request<TResult = unknown, TVariables = Record<string, unknown>>(
    document: TypedDocumentNode<TResult, TVariables>,
    variables?: TVariables,
    requestHeaders?: Record<string, string>
  ): Promise<TResult> {
    const query = print(document);
 
    // Prepare headers with authentication (enhancedFetch handles cookies automatically)
    const headers: Record<string, string> = {
      "Content-Type": "application/json",
      ...DEFAULT_HEADERS,
      ...this.defaultHeaders,
      ...requestHeaders,
    };
 
    const response = await enhancedFetch(this.endpoint, {
      method: "POST",
      headers,
      body: JSON.stringify({
        query,
        variables: variables ?? {},
      }),
    });
 
    if (!response.ok) {
      throw new Error(`GraphQL request failed: ${response.status} ${response.statusText}`);
    }
 
    const result: ExecutionResult<TResult> = (await response.json()) as ExecutionResult<TResult>;
 
    if (result.errors) {
      throw new Error(`GraphQL errors: ${result.errors.map(e => e.message).join(", ")}`);
    }
 
    if (!result.data) {
      throw new Error("GraphQL request returned no data");
    }
 
    return result.data;
  }
 
  setHeaders(headers: Record<string, string>): void {
    this.defaultHeaders = { ...this.defaultHeaders, ...headers };
  }
 
  setAuthToken(token: string): void {
    this.setHeaders({ Authorization: `Bearer ${token}` });
  }
}