UNPKG

2.75 kBPlain TextView Raw
1import { GraphQLClient } from '../classes/GraphQLClient.js'
2import type { RequestDocument, Variables } from '../helpers/types.js'
3
4export type BatchRequestDocument<V extends Variables = Variables> = {
5 document: RequestDocument
6 variables?: V
7}
8
9export interface BatchRequestsOptions<V extends Variables = Variables> {
10 documents: BatchRequestDocument<V>[]
11 requestHeaders?: HeadersInit
12 signal?: RequestInit['signal']
13}
14
15export interface BatchRequestsExtendedOptions<V extends Variables = Variables> extends BatchRequestsOptions<V> {
16 url: string
17}
18
19/**
20 * Send a batch of GraphQL Document to the GraphQL server for execution.
21 *
22 * @example
23 *
24 * ```ts
25 * // You can pass a raw string
26 *
27 * await batchRequests('https://foo.bar/graphql', [
28 * {
29 * query: `
30 * {
31 * query {
32 * users
33 * }
34 * }`
35 * },
36 * {
37 * query: `
38 * {
39 * query {
40 * users
41 * }
42 * }`
43 * }])
44 *
45 * // You can also pass a GraphQL DocumentNode as query. Convenient if you
46 * // are using graphql-tag package.
47 *
48 * import gql from 'graphql-tag'
49 *
50 * await batchRequests('https://foo.bar/graphql', [{ query: gql`...` }])
51 * ```
52 */
53export const batchRequests: BatchRequests = async (...args: BatchRequestsArgs) => {
54 const params = parseBatchRequestsArgsExtended(args)
55 const client = new GraphQLClient(params.url)
56 return client.batchRequests(params)
57}
58
59type BatchRequestsArgs =
60 | [url: string, documents: BatchRequestDocument[], requestHeaders?: HeadersInit]
61 | [options: BatchRequestsExtendedOptions]
62
63export const parseBatchRequestsArgsExtended = (args: BatchRequestsArgs): BatchRequestsExtendedOptions => {
64 if (args.length === 1) {
65 return args[0]
66 } else {
67 return {
68 url: args[0],
69 documents: args[1],
70 requestHeaders: args[2],
71 signal: undefined,
72 }
73 }
74}
75
76// dprint-ignore
77interface BatchRequests {
78 <T extends BatchResult, V extends Variables = Variables>(url: string, documents: BatchRequestDocument<V>[], requestHeaders?: HeadersInit): Promise<T>
79 <T extends BatchResult, V extends Variables = Variables>(options: BatchRequestsExtendedOptions<V>): Promise<T>
80}
81
82export type BatchResult = [Result, ...Result[]]
83
84interface Result<Data extends object = object> {
85 data: Data
86}
87
88export const parseBatchRequestArgs = <V extends Variables = Variables>(
89 documentsOrOptions: BatchRequestDocument<V>[] | BatchRequestsOptions<V>,
90 requestHeaders?: HeadersInit,
91): BatchRequestsOptions<V> => {
92 // eslint-disable-next-line
93 return (documentsOrOptions as BatchRequestsOptions<V>).documents
94 ? (documentsOrOptions as BatchRequestsOptions<V>)
95 : {
96 documents: documentsOrOptions as BatchRequestDocument<V>[],
97 requestHeaders: requestHeaders,
98 signal: undefined,
99 }
100}