UNPKG

3.43 kBPlain TextView Raw
1import type { TypedDocumentNode } from '@graphql-typed-document-node/core'
2import { GraphQLClient } from '../classes/GraphQLClient.js'
3import type { RequestDocument, RequestOptions, Variables, VariablesAndRequestHeadersArgs } from '../helpers/types.js'
4
5/**
6 * Send a GraphQL Document to the GraphQL server for execution.
7 *
8 * @example
9 *
10 * ```ts
11 * // You can pass a raw string
12 *
13 * await request('https://foo.bar/graphql', `
14 * {
15 * query {
16 * users
17 * }
18 * }
19 * `)
20 *
21 * // You can also pass a GraphQL DocumentNode. Convenient if you
22 * // are using graphql-tag package.
23 *
24 * import gql from 'graphql-tag'
25 *
26 * await request('https://foo.bar/graphql', gql`...`)
27 *
28 * // If you don't actually care about using DocumentNode but just
29 * // want the tooling support for gql template tag like IDE syntax
30 * // coloring and prettier autoformat then note you can use the
31 * // passthrough gql tag shipped with graphql-request to save a bit
32 * // of performance and not have to install another dep into your project.
33 *
34 * import { gql } from 'graphql-request'
35 *
36 * await request('https://foo.bar/graphql', gql`...`)
37 * ```
38 */
39// REMARKS: In order to have autocomplete for options work make it the first overload. If not
40// then autocomplete will instead show the various methods for a string, which is not what we want.
41
42// dprint-ignore
43export async function request<T, V extends Variables = Variables>(options: RequestExtendedOptions<V, T>): Promise<T>
44// dprint-ignore
45export async function request<T, V extends Variables = Variables>(url: string, document: RequestDocument | TypedDocumentNode<T, V>, ...variablesAndRequestHeaders: VariablesAndRequestHeadersArgs<V>): Promise<T>
46// dprint-ignore
47// eslint-disable-next-line
48export async function request<T, V extends Variables = Variables>(urlOrOptions: string | RequestExtendedOptions<V, T>, document?: RequestDocument | TypedDocumentNode<T, V>, ...variablesAndRequestHeaders: VariablesAndRequestHeadersArgs<V>): Promise<T> {
49 const requestOptions = parseRequestExtendedArgs<V>(urlOrOptions, document, ...variablesAndRequestHeaders)
50 const client = new GraphQLClient(requestOptions.url)
51 return client.request<T, V>({
52 ...requestOptions,
53 })
54}
55
56export const parseRequestArgs = <V extends Variables = Variables>(
57 documentOrOptions: RequestDocument | RequestOptions<V>,
58 variables?: V,
59 requestHeaders?: HeadersInit,
60): RequestOptions<V> => {
61 return (documentOrOptions as RequestOptions<V>).document
62 ? (documentOrOptions as RequestOptions<V>)
63 : ({
64 document: documentOrOptions as RequestDocument,
65 variables: variables,
66 requestHeaders: requestHeaders,
67 signal: undefined,
68 } as unknown as RequestOptions<V>)
69}
70
71export type RequestExtendedOptions<V extends Variables = Variables, T = unknown> = {
72 url: string
73} & RequestOptions<V, T>
74
75export const parseRequestExtendedArgs = <V extends Variables = Variables>(
76 urlOrOptions: string | RequestExtendedOptions<V>,
77 document?: RequestDocument,
78 ...variablesAndRequestHeaders: VariablesAndRequestHeadersArgs<V>
79): RequestExtendedOptions<V> => {
80 const [variables, requestHeaders] = variablesAndRequestHeaders
81 return typeof urlOrOptions === `string`
82 ? ({
83 url: urlOrOptions,
84 document: document as RequestDocument,
85 variables,
86 requestHeaders,
87 signal: undefined,
88 } as unknown as RequestExtendedOptions<V>)
89 : urlOrOptions
90}