graphql-request
Version:
Minimal GraphQL client supporting Node and browsers for scripts or simple apps.
133 lines (112 loc) • 4.44 kB
text/typescript
import type { DocumentTypeDecoration, TypedDocumentNode } from '@graphql-typed-document-node/core'
import type { GraphQLError } from 'graphql'
import type { DocumentNode } from 'graphql'
import type { MaybeLazy, MaybePromise, RemoveIndex } from '../../lib/prelude.js'
import type { ClientError } from '../classes/ClientError.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 = object
export type BatchVariables = (Variables | undefined)[]
export interface GraphQLResponse<T = unknown> {
data?: T
errors?: GraphQLError[]
extensions?: unknown
status: number
headers: Headers
/**
* The response body text. Useful for debugging non-GraphQL responses
* (e.g., 401/403 errors that return plain JSON instead of GraphQL).
*/
body: string
[key: string]: unknown
}
export interface GraphQLRequestContext<V extends Variables = Variables> {
query: string | string[]
variables?: V
}
// eslint-disable-next-line @typescript-eslint/ban-types -- String (boxed) is intentional for TypedDocumentString compatibility
export type RequestDocument = string | String | DocumentNode
/**
* TypedDocumentString is generated by \@graphql-codegen with `documentMode: 'string'`.
* It's a boxed String with type metadata for result and variables types.
* @see https://github.com/graffle-js/graffle/issues/1467
*/
// eslint-disable-next-line @typescript-eslint/ban-types -- String (boxed) matches graphql-codegen's TypedDocumentString which extends String
export type TypedDocumentString<$Result, $Variables> = String & DocumentTypeDecoration<$Result, $Variables>
export interface GraphQLClientResponse<Data> {
status: number
headers: Headers
/**
* The response body text. Useful for debugging non-GraphQL responses
* (e.g., 401/403 errors that return plain JSON instead of GraphQL).
*/
body: string
data: Data
extensions?: unknown
errors?: GraphQLError[]
}
export type HTTPMethodInput = 'GET' | 'POST' | 'get' | 'post'
export interface RequestConfig extends Omit<RequestInit, 'headers' | 'method'>, AdditionalRequestOptions {
fetch?: Fetch
method?: HTTPMethodInput
headers?: MaybeLazy<HeadersInit>
requestMiddleware?: RequestMiddleware
responseMiddleware?: ResponseMiddleware
jsonSerializer?: JsonSerializer
excludeOperationName?: boolean
}
export type RawRequestOptions<V extends Variables = Variables> =
& {
query: string
requestHeaders?: HeadersInit
signal?: RequestInit['signal']
}
& (V extends Record<any, never> ? { variables?: V }
: keyof RemoveIndex<V> extends never ? { variables?: V }
: { variables: V })
export type RequestOptions<V extends Variables = Variables, T = unknown> =
& {
document: RequestDocument | TypedDocumentNode<T, V> | TypedDocumentString<T, V>
requestHeaders?: HeadersInit
signal?: RequestInit['signal']
}
& (V extends Record<any, never> ? { variables?: V }
: keyof RemoveIndex<V> extends never ? { variables?: V }
: { variables: V })
export type ResponseMiddleware = (
response: GraphQLClientResponse<unknown> | ClientError | Error,
request: RequestInitExtended,
) => MaybePromise<void>
export type RequestMiddleware<V extends Variables = Variables> = (
request: RequestInitExtended<V>,
) => RequestInitExtended | Promise<RequestInitExtended>
export type RequestInitExtended<V extends Variables = Variables> = RequestInit & {
url: string
operationName?: string
variables?: V
}
export type VariablesAndRequestHeadersArgs<V extends Variables> = V extends Record<any, never> // do we have explicitly no variables allowed?
? [variables?: V, requestHeaders?: HeadersInit]
: keyof RemoveIndex<V> extends never // do we get an empty variables object?
? [variables?: V, requestHeaders?: HeadersInit]
: [variables: V, requestHeaders?: HeadersInit]