import type { RemoveIndex } from './helpers.js' import type { TypedDocumentNode } from '@graphql-typed-document-node/core' import type { fetch } from 'cross-fetch' import type { GraphQLError } from 'graphql/error/GraphQLError.js' import type { DocumentNode } from 'graphql/language/ast.js' export type Fetch = typeof fetch /** * 'None' will throw whenever the response contains errors * * 'Ignore' will ignore incoming errors and resolve like no errors occurred * * 'All' will return both the errors and data */ export type ErrorPolicy = 'none' | 'ignore' | 'all' export interface JsonSerializer { stringify: (obj: any) => string parse: (obj: string) => unknown } export interface AdditionalRequestOptions { jsonSerializer?: JsonSerializer /** * Decide how to handle GraphQLErrors in response */ errorPolicy?: ErrorPolicy } export interface FetchOptions extends RequestInit, AdditionalRequestOptions {} export type { GraphQLError } export type Variables = Record export type BatchVariables = (Record | undefined)[] export interface GraphQLResponse { data?: T errors?: GraphQLError[] extensions?: unknown status: number [key: string]: unknown } export interface GraphQLRequestContext { query: string | string[] variables?: V } export class ClientError extends Error { response: GraphQLResponse request: GraphQLRequestContext constructor(response: GraphQLResponse, request: GraphQLRequestContext) { const message = `${ClientError.extractMessage(response)}: ${JSON.stringify({ response, request, })}` super(message) Object.setPrototypeOf(this, ClientError.prototype) this.response = response this.request = request // this is needed as Safari doesn't support .captureStackTrace if (typeof Error.captureStackTrace === `function`) { Error.captureStackTrace(this, ClientError) } } private static extractMessage(response: GraphQLResponse): string { return response.errors?.[0]?.message ?? `GraphQL Error (Code: ${response.status})` } } export type MaybeLazy = T | (() => T) export type RequestDocument = string | DocumentNode export interface GraphQLClientResponse { status: number headers: Headers data: Data extensions?: unknown errors?: GraphQLError[] } export type HTTPMethodInput = 'GET' | 'POST' | 'get' | 'post' export interface RequestConfig extends Omit, AdditionalRequestOptions { fetch?: Fetch method?: HTTPMethodInput headers?: MaybeLazy requestMiddleware?: RequestMiddleware responseMiddleware?: ResponseMiddleware jsonSerializer?: JsonSerializer } export type BatchRequestDocument = { document: RequestDocument variables?: V } export type RawRequestOptions = { query: string requestHeaders?: GraphQLClientRequestHeaders signal?: RequestInit['signal'] } & (V extends Record ? { variables?: V } : keyof RemoveIndex extends never ? { variables?: V } : { variables: V }) export type RequestOptions = { document: RequestDocument | TypedDocumentNode requestHeaders?: GraphQLClientRequestHeaders signal?: RequestInit['signal'] } & (V extends Record ? { variables?: V } : keyof RemoveIndex extends never ? { variables?: V } : { variables: V }) export interface BatchRequestsOptions { documents: BatchRequestDocument[] requestHeaders?: GraphQLClientRequestHeaders signal?: RequestInit['signal'] } export type RequestExtendedOptions = { url: string } & RequestOptions export type RawRequestExtendedOptions = { url: string } & RawRequestOptions export interface BatchRequestsExtendedOptions extends BatchRequestsOptions { url: string } export type ResponseMiddleware = (response: GraphQLClientResponse | Error) => void // prettier-ignore export type RequestMiddleware = (request: RequestExtendedInit) => RequestExtendedInit | Promise type RequestExtendedInit = RequestInit & { url: string operationName?: string variables?: V } export type GraphQLClientRequestHeaders = Headers | string[][] | Record // prettier-ignore export type VariablesAndRequestHeadersArgs = V extends Record // do we have explicitly no variables allowed? ? [variables?: V, requestHeaders?: GraphQLClientRequestHeaders] : keyof RemoveIndex extends never // do we get an empty variables object? ? [variables?: V, requestHeaders?: GraphQLClientRequestHeaders] : [variables: V, requestHeaders?: GraphQLClientRequestHeaders]