diff --git a/examples/community-graphql-code-generator.ts b/examples/community-graphql-code-generator.ts index b3769c7f..77a59c39 100644 --- a/examples/community-graphql-code-generator.ts +++ b/examples/community-graphql-code-generator.ts @@ -12,7 +12,7 @@ * @see https://www.the-guild.dev/graphql/codegen/docs/guides/react-vue. */ -import request, { gql } from '../src/index.js' +import request, { gql } from '../src/entrypoints/main.js' // @ts-expect-error todo make this actually work import { graphql } from './gql/gql' diff --git a/examples/configuration-fetch-custom-function.ts b/examples/configuration-fetch-custom-function.ts index 1e385fbb..fffaa545 100644 --- a/examples/configuration-fetch-custom-function.ts +++ b/examples/configuration-fetch-custom-function.ts @@ -1,4 +1,4 @@ -import { gql, GraphQLClient } from '../src/index.js' +import { gql, GraphQLClient } from '../src/entrypoints/main.js' import fetchCookie from 'fetch-cookie' const endpoint = `https://api.graph.cool/simple/v1/cixos23120m0n0173veiiwrjr` diff --git a/examples/configuration-fetch-options.ts b/examples/configuration-fetch-options.ts index 1330e0b8..e412eec7 100644 --- a/examples/configuration-fetch-options.ts +++ b/examples/configuration-fetch-options.ts @@ -1,4 +1,4 @@ -import { gql, GraphQLClient } from '../src/index.js' +import { gql, GraphQLClient } from '../src/entrypoints/main.js' const endpoint = `https://api.graph.cool/simple/v1/cixos23120m0n0173veiiwrjr` diff --git a/examples/configuration-incremental-endpoint.ts b/examples/configuration-incremental-endpoint.ts index 1830b8e7..bb60c113 100644 --- a/examples/configuration-incremental-endpoint.ts +++ b/examples/configuration-incremental-endpoint.ts @@ -2,7 +2,7 @@ * If you want to change the endpoint after the GraphQLClient has been initialized, you can use the `setEndpoint()` function. */ -import { GraphQLClient } from '../src/index.js' +import { GraphQLClient } from '../src/entrypoints/main.js' const client = new GraphQLClient(`https://api.graph.cool/simple/v1/cixos23120m0n0173veiiwrjr`) diff --git a/examples/configuration-incremental-request-headers.ts b/examples/configuration-incremental-request-headers.ts index 0a423850..1ef60bd5 100644 --- a/examples/configuration-incremental-request-headers.ts +++ b/examples/configuration-incremental-request-headers.ts @@ -2,7 +2,7 @@ * If you want to set headers after the GraphQLClient has been initialized, you can use the `setHeader()` or `setHeaders()` functions. */ -import { GraphQLClient } from '../src/index.js' +import { GraphQLClient } from '../src/entrypoints/main.js' const client = new GraphQLClient(`https://api.graph.cool/simple/v1/cixos23120m0n0173veiiwrjr`) diff --git a/examples/configuration-request-json-serializer.ts b/examples/configuration-request-json-serializer.ts index 7a3f4a91..f699b013 100644 --- a/examples/configuration-request-json-serializer.ts +++ b/examples/configuration-request-json-serializer.ts @@ -3,7 +3,7 @@ * An original use case for this feature is `BigInt` support: */ -import { gql, GraphQLClient } from '../src/index.js' +import { gql, GraphQLClient } from '../src/entrypoints/main.js' import JSONbig from 'json-bigint' const jsonSerializer = JSONbig({ useNativeBigInt: true }) diff --git a/examples/graphql-batching-requests.ts b/examples/graphql-batching-requests.ts index 06bbdc54..1a5a6685 100644 --- a/examples/graphql-batching-requests.ts +++ b/examples/graphql-batching-requests.ts @@ -2,7 +2,7 @@ * It is possible with `graphql-request` to use batching via the `batchRequests()` function. * @see https://github.com/graphql/graphql-over-http/blob/main/rfcs/Batching.md */ -import { batchRequests, gql } from '../src/index.js' +import { batchRequests, gql } from '../src/entrypoints/main.js' const endpoint = `https://api.spacex.land/graphql/` diff --git a/examples/graphql-document-variables.ts b/examples/graphql-document-variables.ts index 64c16337..45dfa327 100644 --- a/examples/graphql-document-variables.ts +++ b/examples/graphql-document-variables.ts @@ -1,4 +1,4 @@ -import { gql, request } from '../src/index.js' +import { gql, request } from '../src/entrypoints/main.js' const endpoint = `https://api.graph.cool/simple/v1/cixos23120m0n0173veiiwrjr` diff --git a/examples/graphql-mutations.ts b/examples/graphql-mutations.ts index fe7c5216..405bd1be 100644 --- a/examples/graphql-mutations.ts +++ b/examples/graphql-mutations.ts @@ -1,4 +1,4 @@ -import { gql, GraphQLClient } from '../src/index.js' +import { gql, GraphQLClient } from '../src/entrypoints/main.js' const endpoint = `https://api.graph.cool/simple/v1/cixos23120m0n0173veiiwrjr` diff --git a/examples/other-error-handling.ts b/examples/other-error-handling.ts index 52bbf9b3..4a2a4617 100644 --- a/examples/other-error-handling.ts +++ b/examples/other-error-handling.ts @@ -1,4 +1,4 @@ -import { gql, request } from '../src/index.js' +import { gql, request } from '../src/entrypoints/main.js' const endpoint = `https://api.graph.cool/simple/v1/cixos23120m0n0173veiiwrjr` diff --git a/examples/other-middleware.ts b/examples/other-middleware.ts index 54876358..4cfbcbad 100644 --- a/examples/other-middleware.ts +++ b/examples/other-middleware.ts @@ -2,8 +2,8 @@ * It's possible to use a middleware to pre-process any request or handle raw response. */ -import { GraphQLClient } from '../src/index.js' -import type { RequestMiddleware, ResponseMiddleware } from '../src/types.js' +import { GraphQLClient } from '../src/entrypoints/main.js' +import type { RequestMiddleware, ResponseMiddleware } from '../src/helpers/types.js' const endpoint = `https://api.spacex.land/graphql/` diff --git a/examples/request-authentication-via-http-header.ts b/examples/request-authentication-via-http-header.ts index 921af886..ab26ba00 100644 --- a/examples/request-authentication-via-http-header.ts +++ b/examples/request-authentication-via-http-header.ts @@ -1,4 +1,4 @@ -import { gql, GraphQLClient } from '../src/index.js' +import { gql, GraphQLClient } from '../src/entrypoints/main.js' const endpoint = `https://api.graph.cool/simple/v1/cixos23120m0n0173veiiwrjr` diff --git a/examples/request-cancellation.ts b/examples/request-cancellation.ts index b9581b4c..337ecac8 100644 --- a/examples/request-cancellation.ts +++ b/examples/request-cancellation.ts @@ -2,7 +2,7 @@ * It is possible to cancel a request using an `AbortController` signal. */ -import { gql, GraphQLClient } from '../src/index.js' +import { gql, GraphQLClient } from '../src/entrypoints/main.js' const endpoint = `https://api.graph.cool/simple/v1/cixos23120m0n0173veiiwrjr` diff --git a/examples/request-handle-raw-response.ts b/examples/request-handle-raw-response.ts index cb184412..4b680bd5 100644 --- a/examples/request-handle-raw-response.ts +++ b/examples/request-handle-raw-response.ts @@ -3,7 +3,7 @@ * If you need to access the `extensions` key you can use the `rawRequest` method: */ -import { gql, rawRequest } from '../src/index.js' +import { gql, rawRequest } from '../src/entrypoints/main.js' const endpoint = `https://api.graph.cool/simple/v1/cixos23120m0n0173veiiwrjr` diff --git a/examples/request-headers-dynamic-per-request.ts b/examples/request-headers-dynamic-per-request.ts index e31562a4..ebede986 100644 --- a/examples/request-headers-dynamic-per-request.ts +++ b/examples/request-headers-dynamic-per-request.ts @@ -3,7 +3,7 @@ * To do that, pass a function that returns the headers to the `headers` property when creating a new `GraphQLClient`. */ -import { gql, GraphQLClient } from '../src/index.js' +import { gql, GraphQLClient } from '../src/entrypoints/main.js' const client = new GraphQLClient(`https://some-api`, { headers: () => ({ 'X-Sent-At-Time': Date.now().toString() }), diff --git a/examples/request-headers-static-per-request.ts b/examples/request-headers-static-per-request.ts index 63dcf765..5e13dc41 100644 --- a/examples/request-headers-static-per-request.ts +++ b/examples/request-headers-static-per-request.ts @@ -2,7 +2,7 @@ * It is possible to pass custom headers for each request. `request()` and `rawRequest()` accept a header object as the third parameter */ -import { gql, GraphQLClient } from '../src/index.js' +import { gql, GraphQLClient } from '../src/entrypoints/main.js' const endpoint = `https://api.graph.cool/simple/v1/cixos23120m0n0173veiiwrjr` diff --git a/examples/request-method-get.ts b/examples/request-method-get.ts index 33a0062c..06860554 100644 --- a/examples/request-method-get.ts +++ b/examples/request-method-get.ts @@ -1,7 +1,7 @@ /** * Queries can be sent as an HTTP GET request: */ -import { gql, GraphQLClient } from '../src/index.js' +import { gql, GraphQLClient } from '../src/entrypoints/main.js' const endpoint = `https://api.graph.cool/simple/v1/cixos23120m0n0173veiiwrjr` diff --git a/examples/typescript-typed-document-node.ts b/examples/typescript-typed-document-node.ts index c165930a..a3833121 100644 --- a/examples/typescript-typed-document-node.ts +++ b/examples/typescript-typed-document-node.ts @@ -1,4 +1,4 @@ -import { gql, GraphQLClient, request } from '../src/index.js' +import { gql, GraphQLClient, request } from '../src/entrypoints/main.js' import type { TypedDocumentNode } from '@graphql-typed-document-node/core' import { parse } from 'graphql' diff --git a/package.json b/package.json index bfba2d45..a359066e 100644 --- a/package.json +++ b/package.json @@ -5,8 +5,8 @@ "exports": { ".": { "import": { - "types": "./build/index.d.ts", - "default": "./build/index.js" + "types": "./build/entrypoints/main.d.ts", + "default": "./build/entrypoints/main.js" } } }, diff --git a/src/index.ts b/src/classes/GraphQLClient.ts similarity index 64% rename from src/index.ts rename to src/classes/GraphQLClient.ts index 01bfedf4..00d8db2d 100644 --- a/src/index.ts +++ b/src/classes/GraphQLClient.ts @@ -1,188 +1,35 @@ -import { ACCEPT_HEADER, CONTENT_TYPE_GQL, CONTENT_TYPE_HEADER, CONTENT_TYPE_JSON } from './constants.js' -import { defaultJsonSerializer } from './defaultJsonSerializer.js' -import { HeadersInstanceToPlainObject, uppercase } from './helpers.js' -import { - parseBatchRequestArgs, - parseRawRequestArgs, - parseRawRequestExtendedArgs, - parseRequestArgs, - parseRequestExtendedArgs, -} from './parseArgs.js' -import { resolveRequestDocument } from './resolveRequestDocument.js' +import type { BatchRequestDocument, BatchRequestsOptions, BatchResult } from '../functions/batchRequests.js' +import { parseBatchRequestArgs } from '../functions/batchRequests.js' +import { parseRawRequestArgs } from '../functions/rawRequest.js' +import { parseRequestArgs } from '../functions/request.js' +import { defaultJsonSerializer } from '../helpers/defaultJsonSerializer.js' +import { resolveRequestDocument } from '../helpers/resolveRequestDocument.js' import type { - BatchRequestDocument, + Fetch, FetchOptions, - GraphQLClientResponse, - GraphQLResponse, HTTPMethodInput, JsonSerializer, - MaybeLazy, - RequestConfig, + RequestDocument, RequestMiddleware, - ResponseMiddleware, + RequestOptions, VariablesAndRequestHeadersArgs, -} from './types.js' +} from '../helpers/types.js' import { - BatchRequestsExtendedOptions, - BatchRequestsOptions, ClientError, - RawRequestExtendedOptions, - RawRequestOptions, - RequestDocument, - RequestExtendedOptions, - RequestOptions, - Variables, -} from './types.js' + type GraphQLClientResponse, + type RawRequestOptions, + type RequestConfig, + type Variables, +} from '../helpers/types.js' +import { cleanQuery, isGraphQLContentType } from '../lib/graphql.js' +import { ACCEPT_HEADER, CONTENT_TYPE_GQL, CONTENT_TYPE_HEADER, CONTENT_TYPE_JSON } from '../lib/http.js' +import { callOrIdentity, HeadersInstanceToPlainObject, uppercase } from '../lib/prelude.js' import type { TypedDocumentNode } from '@graphql-typed-document-node/core' -/** - * Convert the given headers configuration into a plain object. - */ -const resolveHeaders = (headers?: HeadersInit): Record => { - let oHeaders: Record = {} - if (headers) { - if (headers instanceof Headers) { - oHeaders = HeadersInstanceToPlainObject(headers) - } else if (Array.isArray(headers)) { - headers.forEach(([name, value]) => { - if (name && value !== undefined) { - oHeaders[name] = value - } - }) - } else { - oHeaders = headers - } - } - - return oHeaders -} - -/** - * Clean a GraphQL document to send it via a GET query - */ -const cleanQuery = (str: string): string => str.replace(/([\s,]|#[^\n\r]+)+/g, ` `).trim() - -type BuildRequestConfigParamsBatch = { - query: string[] - variables: V[] | undefined - operationName: undefined - jsonSerializer: JsonSerializer -} - -type BuildRequestConfigParamsSingle = { - query: string - variables: V | undefined - operationName: string | undefined - jsonSerializer: JsonSerializer -} - -type BuildRequestConfigParams = BuildRequestConfigParamsSingle | BuildRequestConfigParamsBatch - -/** - * Create query string for GraphQL request - */ -const buildRequestConfig = (params: BuildRequestConfigParams): string => { - if (!Array.isArray(params.query)) { - const params_ = params as BuildRequestConfigParamsSingle - const search: string[] = [`query=${encodeURIComponent(cleanQuery(params_.query))}`] - - if (params.variables) { - search.push(`variables=${encodeURIComponent(params_.jsonSerializer.stringify(params_.variables))}`) - } - - if (params_.operationName) { - search.push(`operationName=${encodeURIComponent(params_.operationName)}`) - } - - return search.join(`&`) - } - - if (typeof params.variables !== `undefined` && !Array.isArray(params.variables)) { - throw new Error(`Cannot create query with given variable type, array expected`) - } - - // Batch support - const params_ = params as BuildRequestConfigParamsBatch - const payload = params.query.reduce<{ query: string; variables: string | undefined }[]>( - (acc, currentQuery, index) => { - acc.push({ - query: cleanQuery(currentQuery), - variables: params_.variables ? params_.jsonSerializer.stringify(params_.variables[index]) : undefined, - }) - return acc - }, - [], - ) - - return `query=${encodeURIComponent(params_.jsonSerializer.stringify(payload))}` -} - -type Fetch = (url: string, config: RequestInit) => Promise - -interface RequestVerbParams { - url: string - query: string | string[] - fetch: Fetch - fetchOptions: FetchOptions - variables?: V - headers?: HeadersInit - operationName?: string - middleware?: RequestMiddleware -} - -const createHttpMethodFetcher = - (method: 'GET' | 'POST') => - async (params: RequestVerbParams) => { - const { url, query, variables, operationName, fetch, fetchOptions, middleware } = params - - const headers = new Headers(params.headers) - let queryParams = `` - let body = undefined - - if (!headers.has(ACCEPT_HEADER)) { - headers.set(ACCEPT_HEADER, [CONTENT_TYPE_GQL, CONTENT_TYPE_JSON].join(`, `)) - } - - if (method === `POST`) { - body = createRequestBody(query, variables, operationName, fetchOptions.jsonSerializer) - if (typeof body === `string` && !headers.has(CONTENT_TYPE_HEADER)) { - headers.set(CONTENT_TYPE_HEADER, CONTENT_TYPE_JSON) - } - } else { - // @ts-expect-error todo needs ADT for TS to understand the different states - queryParams = buildRequestConfig({ - query, - variables, - operationName, - jsonSerializer: fetchOptions.jsonSerializer ?? defaultJsonSerializer, - }) - } - - const init: RequestInit = { - method, - headers, - body, - ...fetchOptions, - } - - let urlResolved = url - let initResolved = init - if (middleware) { - const result = await Promise.resolve(middleware({ ...init, url, operationName, variables })) - const { url: urlNew, ...initNew } = result - urlResolved = urlNew - initResolved = initNew - } - if (queryParams) { - urlResolved = `${urlResolved}?${queryParams}` - } - return await fetch(urlResolved, initResolved) - } - /** * GraphQL Client. */ -class GraphQLClient { +export class GraphQLClient { constructor( private url: string, public readonly requestConfig: RequestConfig = {}, @@ -379,6 +226,39 @@ class GraphQLClient { } } +// prettier-ignore +interface RawRequestMethod { + (query: string, variables?: V, requestHeaders?: HeadersInit): Promise> + (options: RawRequestOptions): Promise> +} + +// prettier-ignore +type RawRequestMethodArgs = + | [query: string, variables?: V, requestHeaders?: HeadersInit] + | [RawRequestOptions] + +/** + * Convert the given headers configuration into a plain object. + */ +const resolveHeaders = (headers?: HeadersInit): Record => { + let oHeaders: Record = {} + if (headers) { + if (headers instanceof Headers) { + oHeaders = HeadersInstanceToPlainObject(headers) + } else if (Array.isArray(headers)) { + headers.forEach(([name, value]) => { + if (name && value !== undefined) { + oHeaders[name] = value + } + }) + } else { + oHeaders = headers + } + } + + return oHeaders +} + const makeRequest = async (params: { url: string query: string | string[] @@ -434,160 +314,72 @@ const makeRequest = async (params: } } -// prettier-ignore -interface RawRequestMethod { - (query: string, variables?: V, requestHeaders?: HeadersInit): Promise> - (options: RawRequestOptions): Promise> -} - -// prettier-ignore -type RawRequestMethodArgs = - | [query: string, variables?: V, requestHeaders?: HeadersInit] - | [RawRequestOptions] - -// prettier-ignore -interface RawRequest { - (url: string, query: string, ...variablesAndRequestHeaders: VariablesAndRequestHeadersArgs): Promise> - (options: RawRequestExtendedOptions): Promise> -} - -// prettier-ignore -type RawRequestArgs = - | [options: RawRequestExtendedOptions, query?: string, ...variablesAndRequestHeaders: VariablesAndRequestHeadersArgs] - | [url: string, query?: string, ...variablesAndRequestHeaders: VariablesAndRequestHeadersArgs] - -/** - * Send a GraphQL Query to the GraphQL server for execution. - */ -const rawRequest: RawRequest = async ( - ...args: RawRequestArgs -): Promise> => { - const [urlOrOptions, query, ...variablesAndRequestHeaders] = args - const requestOptions = parseRawRequestExtendedArgs(urlOrOptions, query, ...variablesAndRequestHeaders) - const client = new GraphQLClient(requestOptions.url) - return client.rawRequest({ - ...requestOptions, - }) -} +const getResult = async ( + response: Response, + jsonSerializer: JsonSerializer, +): Promise< + | { data: object; errors: undefined }[] + | { data: object; errors: undefined } + | { data: undefined; errors: object } + | { data: undefined; errors: object[] } +> => { + const contentType = response.headers.get(CONTENT_TYPE_HEADER) -/** - * Send a GraphQL Document to the GraphQL server for execution. - * - * @example - * - * ```ts - * // You can pass a raw string - * - * await request('https://foo.bar/graphql', ` - * { - * query { - * users - * } - * } - * `) - * - * // You can also pass a GraphQL DocumentNode. Convenient if you - * // are using graphql-tag package. - * - * import gql from 'graphql-tag' - * - * await request('https://foo.bar/graphql', gql`...`) - * - * // If you don't actually care about using DocumentNode but just - * // want the tooling support for gql template tag like IDE syntax - * // coloring and prettier autoformat then note you can use the - * // passthrough gql tag shipped with graphql-request to save a bit - * // of performance and not have to install another dep into your project. - * - * import { gql } from 'graphql-request' - * - * await request('https://foo.bar/graphql', gql`...`) - * ``` - */ -// REMARKS: In order to have autocomplete for options work make it the first overload. If not -// then autocomplete will instead show the various methods for a string, which is not what we want. -// prettier-ignore -async function request(options: RequestExtendedOptions): Promise -// prettier-ignore -async function request(url: string, document: RequestDocument | TypedDocumentNode, ...variablesAndRequestHeaders: VariablesAndRequestHeadersArgs): Promise -// prettier-ignore -// eslint-disable-next-line -async function request(urlOrOptions: string | RequestExtendedOptions, document?: RequestDocument | TypedDocumentNode, ...variablesAndRequestHeaders: VariablesAndRequestHeadersArgs): Promise { - const requestOptions = parseRequestExtendedArgs(urlOrOptions, document, ...variablesAndRequestHeaders) - const client = new GraphQLClient(requestOptions.url) - return client.request({ - ...requestOptions, - }) + if (contentType && isGraphQLContentType(contentType)) { + return jsonSerializer.parse(await response.text()) as any + } else { + return response.text() as any + } } -/** - * Send a batch of GraphQL Document to the GraphQL server for execution. - * - * @example - * - * ```ts - * // You can pass a raw string - * - * await batchRequests('https://foo.bar/graphql', [ - * { - * query: ` - * { - * query { - * users - * } - * }` - * }, - * { - * query: ` - * { - * query { - * users - * } - * }` - * }]) - * - * // You can also pass a GraphQL DocumentNode as query. Convenient if you - * // are using graphql-tag package. - * - * import gql from 'graphql-tag' - * - * await batchRequests('https://foo.bar/graphql', [{ query: gql`...` }]) - * ``` - */ -const batchRequests: BatchRequests = async (...args: BatchRequestsArgs) => { - const params = parseBatchRequestsArgsExtended(args) - const client = new GraphQLClient(params.url) - return client.batchRequests(params) -} +const createHttpMethodFetcher = + (method: 'GET' | 'POST') => + async (params: RequestVerbParams) => { + const { url, query, variables, operationName, fetch, fetchOptions, middleware } = params -interface Result { - data: Data -} + const headers = new Headers(params.headers) + let queryParams = `` + let body = undefined -type BatchResult = [Result, ...Result[]] + if (!headers.has(ACCEPT_HEADER)) { + headers.set(ACCEPT_HEADER, [CONTENT_TYPE_GQL, CONTENT_TYPE_JSON].join(`, `)) + } -// prettier-ignore -interface BatchRequests { - (url: string, documents: BatchRequestDocument[], requestHeaders?: HeadersInit): Promise - (options: BatchRequestsExtendedOptions): Promise -} + if (method === `POST`) { + body = createRequestBody(query, variables, operationName, fetchOptions.jsonSerializer) + if (typeof body === `string` && !headers.has(CONTENT_TYPE_HEADER)) { + headers.set(CONTENT_TYPE_HEADER, CONTENT_TYPE_JSON) + } + } else { + // @ts-expect-error todo needs ADT for TS to understand the different states + queryParams = buildRequestConfig({ + query, + variables, + operationName, + jsonSerializer: fetchOptions.jsonSerializer ?? defaultJsonSerializer, + }) + } -type BatchRequestsArgs = - | [url: string, documents: BatchRequestDocument[], requestHeaders?: HeadersInit] - | [options: BatchRequestsExtendedOptions] + const init: RequestInit = { + method, + headers, + body, + ...fetchOptions, + } -const parseBatchRequestsArgsExtended = (args: BatchRequestsArgs): BatchRequestsExtendedOptions => { - if (args.length === 1) { - return args[0] - } else { - return { - url: args[0], - documents: args[1], - requestHeaders: args[2], - signal: undefined, + let urlResolved = url + let initResolved = init + if (middleware) { + const result = await Promise.resolve(middleware({ ...init, url, operationName, variables })) + const { url: urlNew, ...initNew } = result + urlResolved = urlNew + initResolved = initNew } + if (queryParams) { + urlResolved = `${urlResolved}?${queryParams}` + } + return await fetch(urlResolved, initResolved) } -} const createRequestBody = ( query: string | string[], @@ -616,74 +408,68 @@ const createRequestBody = ( return jsonSerializer_.stringify(payload) } -const getResult = async ( - response: Response, - jsonSerializer: JsonSerializer, -): Promise< - | { data: object; errors: undefined }[] - | { data: object; errors: undefined } - | { data: undefined; errors: object } - | { data: undefined; errors: object[] } -> => { - const contentType = response.headers.get(CONTENT_TYPE_HEADER) +/** + * Create query string for GraphQL request + */ +const buildRequestConfig = (params: BuildRequestConfigParams): string => { + if (!Array.isArray(params.query)) { + const params_ = params as BuildRequestConfigParamsSingle + const search: string[] = [`query=${encodeURIComponent(cleanQuery(params_.query))}`] - if (contentType && isJsonContentType(contentType)) { - return jsonSerializer.parse(await response.text()) as any - } else { - return response.text() as any + if (params.variables) { + search.push(`variables=${encodeURIComponent(params_.jsonSerializer.stringify(params_.variables))}`) + } + + if (params_.operationName) { + search.push(`operationName=${encodeURIComponent(params_.operationName)}`) + } + + return search.join(`&`) } -} -const isJsonContentType = (contentType: string) => { - const contentTypeLower = contentType.toLowerCase() + if (typeof params.variables !== `undefined` && !Array.isArray(params.variables)) { + throw new Error(`Cannot create query with given variable type, array expected`) + } - return contentTypeLower.includes(CONTENT_TYPE_GQL) || contentTypeLower.includes(CONTENT_TYPE_JSON) + // Batch support + const params_ = params as BuildRequestConfigParamsBatch + const payload = params.query.reduce<{ query: string; variables: string | undefined }[]>( + (acc, currentQuery, index) => { + acc.push({ + query: cleanQuery(currentQuery), + variables: params_.variables ? params_.jsonSerializer.stringify(params_.variables[index]) : undefined, + }) + return acc + }, + [], + ) + + return `query=${encodeURIComponent(params_.jsonSerializer.stringify(payload))}` } -const callOrIdentity = (value: MaybeLazy) => { - return typeof value === `function` ? (value as () => T)() : value +interface RequestVerbParams { + url: string + query: string | string[] + fetch: Fetch + fetchOptions: FetchOptions + variables?: V + headers?: HeadersInit + operationName?: string + middleware?: RequestMiddleware } -/** - * Convenience passthrough template tag to get the benefits of tooling for the gql template tag. This does not actually parse the input into a GraphQL DocumentNode like graphql-tag package does. It just returns the string with any variables given interpolated. Can save you a bit of performance and having to install another package. - * - * @example - * ``` - * import { gql } from 'graphql-request' - * - * await request('https://foo.bar/graphql', gql`...`) - * ``` - * - * @remarks - * - * Several tools in the Node GraphQL ecosystem are hardcoded to specially treat any template tag named "gql". For example see this prettier issue: https://github.com/prettier/prettier/issues/4360. Using this template tag has no runtime effect beyond variable interpolation. - */ -export const gql = (chunks: TemplateStringsArray, ...variables: unknown[]): string => { - return chunks.reduce( - (acc, chunk, index) => `${acc}${chunk}${index in variables ? String(variables[index]) : ``}`, - ``, - ) +type BuildRequestConfigParams = BuildRequestConfigParamsSingle | BuildRequestConfigParamsBatch + +type BuildRequestConfigParamsBatch = { + query: string[] + variables: V[] | undefined + operationName: undefined + jsonSerializer: JsonSerializer } -export { GraphQLWebSocketClient } from './graphql-ws.js' -export { resolveRequestDocument } from './resolveRequestDocument.js' -export { - BatchRequestDocument, - batchRequests, - BatchRequestsExtendedOptions, - BatchRequestsOptions, - ClientError, - GraphQLClient, - GraphQLResponse, - rawRequest, - RawRequestExtendedOptions, - RawRequestOptions, - request, - RequestDocument, - RequestExtendedOptions, - RequestMiddleware, - RequestOptions, - ResponseMiddleware, - Variables, +type BuildRequestConfigParamsSingle = { + query: string + variables: V | undefined + operationName: string | undefined + jsonSerializer: JsonSerializer } -export default request diff --git a/src/entrypoints/main.ts b/src/entrypoints/main.ts new file mode 100644 index 00000000..87ce8dff --- /dev/null +++ b/src/entrypoints/main.ts @@ -0,0 +1,37 @@ +import { + type BatchRequestDocument, + type BatchRequestsExtendedOptions, + type BatchRequestsOptions, +} from '../functions/batchRequests.js' +import { RequestExtendedOptions } from '../functions/request.js' +import { request } from '../functions/request.js' +import type { GraphQLResponse, RequestMiddleware, ResponseMiddleware } from '../helpers/types.js' +import { + ClientError, + RawRequestOptions, + RequestDocument, + RequestOptions, + Variables, +} from '../helpers/types.js' +export { GraphQLClient } from '../classes/GraphQLClient.js' +export { batchRequests } from '../functions/batchRequests.js' +export { gql } from '../functions/gql.js' +export { rawRequest } from '../functions/rawRequest.js' +export { resolveRequestDocument } from '../helpers/resolveRequestDocument.js' +export { GraphQLWebSocketClient } from '../lib/graphql-ws.js' +export { + BatchRequestDocument, + BatchRequestsExtendedOptions, + BatchRequestsOptions, + ClientError, + GraphQLResponse, + RawRequestOptions, + request, + RequestDocument, + RequestExtendedOptions, + RequestMiddleware, + RequestOptions, + ResponseMiddleware, + Variables, +} +export default request diff --git a/src/functions/batchRequests.ts b/src/functions/batchRequests.ts new file mode 100644 index 00000000..dfa099f8 --- /dev/null +++ b/src/functions/batchRequests.ts @@ -0,0 +1,100 @@ +import { GraphQLClient } from '../classes/GraphQLClient.js' +import type { RequestDocument, Variables } from '../helpers/types.js' + +export type BatchRequestDocument = { + document: RequestDocument + variables?: V +} + +export interface BatchRequestsOptions { + documents: BatchRequestDocument[] + requestHeaders?: HeadersInit + signal?: RequestInit['signal'] +} + +export interface BatchRequestsExtendedOptions + extends BatchRequestsOptions { + url: string +} + +/** + * Send a batch of GraphQL Document to the GraphQL server for execution. + * + * @example + * + * ```ts + * // You can pass a raw string + * + * await batchRequests('https://foo.bar/graphql', [ + * { + * query: ` + * { + * query { + * users + * } + * }` + * }, + * { + * query: ` + * { + * query { + * users + * } + * }` + * }]) + * + * // You can also pass a GraphQL DocumentNode as query. Convenient if you + * // are using graphql-tag package. + * + * import gql from 'graphql-tag' + * + * await batchRequests('https://foo.bar/graphql', [{ query: gql`...` }]) + * ``` + */ +export const batchRequests: BatchRequests = async (...args: BatchRequestsArgs) => { + const params = parseBatchRequestsArgsExtended(args) + const client = new GraphQLClient(params.url) + return client.batchRequests(params) +} + +type BatchRequestsArgs = + | [url: string, documents: BatchRequestDocument[], requestHeaders?: HeadersInit] + | [options: BatchRequestsExtendedOptions] + +export const parseBatchRequestsArgsExtended = (args: BatchRequestsArgs): BatchRequestsExtendedOptions => { + if (args.length === 1) { + return args[0] + } else { + return { + url: args[0], + documents: args[1], + requestHeaders: args[2], + signal: undefined, + } + } +} + +// prettier-ignore +interface BatchRequests { + (url: string, documents: BatchRequestDocument[], requestHeaders?: HeadersInit): Promise + (options: BatchRequestsExtendedOptions): Promise +} + +export type BatchResult = [Result, ...Result[]] + +interface Result { + data: Data +} + +export const parseBatchRequestArgs = ( + documentsOrOptions: BatchRequestDocument[] | BatchRequestsOptions, + requestHeaders?: HeadersInit, +): BatchRequestsOptions => { + return (documentsOrOptions as BatchRequestsOptions).documents + ? (documentsOrOptions as BatchRequestsOptions) + : { + documents: documentsOrOptions as BatchRequestDocument[], + requestHeaders: requestHeaders, + signal: undefined, + } +} diff --git a/src/functions/gql.ts b/src/functions/gql.ts new file mode 100644 index 00000000..e8dbe5df --- /dev/null +++ b/src/functions/gql.ts @@ -0,0 +1,20 @@ +/** + * Convenience passthrough template tag to get the benefits of tooling for the gql template tag. This does not actually parse the input into a GraphQL DocumentNode like graphql-tag package does. It just returns the string with any variables given interpolated. Can save you a bit of performance and having to install another package. + * + * @example + * ``` + * import { gql } from 'graphql-request' + * + * await request('https://foo.bar/graphql', gql`...`) + * ``` + * + * @remarks + * + * Several tools in the Node GraphQL ecosystem are hardcoded to specially treat any template tag named "gql". For example see this prettier issue: https://github.com/prettier/prettier/issues/4360. Using this template tag has no runtime effect beyond variable interpolation. + */ +export const gql = (chunks: TemplateStringsArray, ...variables: unknown[]): string => { + return chunks.reduce( + (acc, chunk, index) => `${acc}${chunk}${index in variables ? String(variables[index]) : ``}`, + ``, + ) +} diff --git a/src/functions/rawRequest.ts b/src/functions/rawRequest.ts new file mode 100644 index 00000000..1684475e --- /dev/null +++ b/src/functions/rawRequest.ts @@ -0,0 +1,68 @@ +import { GraphQLClient } from '../classes/GraphQLClient.js' +import type { + GraphQLClientResponse, + RawRequestOptions, + Variables, + VariablesAndRequestHeadersArgs, +} from '../helpers/types.js' + +/** + * Send a GraphQL Query to the GraphQL server for execution. + */ +export const rawRequest: RawRequest = async ( + ...args: RawRequestArgs +): Promise> => { + const [urlOrOptions, query, ...variablesAndRequestHeaders] = args + const requestOptions = parseRawRequestExtendedArgs(urlOrOptions, query, ...variablesAndRequestHeaders) + const client = new GraphQLClient(requestOptions.url) + return client.rawRequest({ + ...requestOptions, + }) +} + +// prettier-ignore +interface RawRequest { + (url: string, query: string, ...variablesAndRequestHeaders: VariablesAndRequestHeadersArgs): Promise> + (options: RawRequestExtendedOptions): Promise> +} + +// prettier-ignore +type RawRequestArgs = + | [options: RawRequestExtendedOptions, query?: string, ...variablesAndRequestHeaders: VariablesAndRequestHeadersArgs] + | [url: string, query?: string, ...variablesAndRequestHeaders: VariablesAndRequestHeadersArgs] + +export const parseRawRequestExtendedArgs = ( + urlOrOptions: string | RawRequestExtendedOptions, + query?: string, + ...variablesAndRequestHeaders: VariablesAndRequestHeadersArgs +): RawRequestExtendedOptions => { + const [variables, requestHeaders] = variablesAndRequestHeaders + return typeof urlOrOptions === `string` + ? ({ + url: urlOrOptions, + query: query as string, + variables, + requestHeaders, + signal: undefined, + } as unknown as RawRequestExtendedOptions) + : urlOrOptions +} + +export type RawRequestExtendedOptions = { + url: string +} & RawRequestOptions + +export const parseRawRequestArgs = ( + queryOrOptions: string | RawRequestOptions, + variables?: V, + requestHeaders?: HeadersInit, +): RawRequestOptions => { + return (queryOrOptions as RawRequestOptions).query + ? (queryOrOptions as RawRequestOptions) + : ({ + query: queryOrOptions as string, + variables: variables, + requestHeaders: requestHeaders, + signal: undefined, + } as unknown as RawRequestOptions) +} diff --git a/src/functions/request.ts b/src/functions/request.ts new file mode 100644 index 00000000..d166f261 --- /dev/null +++ b/src/functions/request.ts @@ -0,0 +1,95 @@ +import { GraphQLClient } from '../classes/GraphQLClient.js' +import type { + RequestDocument, + RequestOptions, + Variables, + VariablesAndRequestHeadersArgs, +} from '../helpers/types.js' +import type { TypedDocumentNode } from '@graphql-typed-document-node/core' + +/** + * Send a GraphQL Document to the GraphQL server for execution. + * + * @example + * + * ```ts + * // You can pass a raw string + * + * await request('https://foo.bar/graphql', ` + * { + * query { + * users + * } + * } + * `) + * + * // You can also pass a GraphQL DocumentNode. Convenient if you + * // are using graphql-tag package. + * + * import gql from 'graphql-tag' + * + * await request('https://foo.bar/graphql', gql`...`) + * + * // If you don't actually care about using DocumentNode but just + * // want the tooling support for gql template tag like IDE syntax + * // coloring and prettier autoformat then note you can use the + * // passthrough gql tag shipped with graphql-request to save a bit + * // of performance and not have to install another dep into your project. + * + * import { gql } from 'graphql-request' + * + * await request('https://foo.bar/graphql', gql`...`) + * ``` + */ +// REMARKS: In order to have autocomplete for options work make it the first overload. If not +// then autocomplete will instead show the various methods for a string, which is not what we want. + +// prettier-ignore +export async function request(options: RequestExtendedOptions): Promise +// prettier-ignore +export async function request(url: string, document: RequestDocument | TypedDocumentNode, ...variablesAndRequestHeaders: VariablesAndRequestHeadersArgs): Promise +// prettier-ignore +// eslint-disable-next-line +export async function request(urlOrOptions: string | RequestExtendedOptions, document?: RequestDocument | TypedDocumentNode, ...variablesAndRequestHeaders: VariablesAndRequestHeadersArgs): Promise { + const requestOptions = parseRequestExtendedArgs(urlOrOptions, document, ...variablesAndRequestHeaders) + const client = new GraphQLClient(requestOptions.url) + return client.request({ + ...requestOptions, + }) +} + +export const parseRequestArgs = ( + documentOrOptions: RequestDocument | RequestOptions, + variables?: V, + requestHeaders?: HeadersInit, +): RequestOptions => { + return (documentOrOptions as RequestOptions).document + ? (documentOrOptions as RequestOptions) + : ({ + document: documentOrOptions as RequestDocument, + variables: variables, + requestHeaders: requestHeaders, + signal: undefined, + } as unknown as RequestOptions) +} + +export type RequestExtendedOptions = { + url: string +} & RequestOptions + +export const parseRequestExtendedArgs = ( + urlOrOptions: string | RequestExtendedOptions, + document?: RequestDocument, + ...variablesAndRequestHeaders: VariablesAndRequestHeadersArgs +): RequestExtendedOptions => { + const [variables, requestHeaders] = variablesAndRequestHeaders + return typeof urlOrOptions === `string` + ? ({ + url: urlOrOptions, + document: document as RequestDocument, + variables, + requestHeaders, + signal: undefined, + } as unknown as RequestExtendedOptions) + : urlOrOptions +} diff --git a/src/defaultJsonSerializer.ts b/src/helpers/defaultJsonSerializer.ts similarity index 100% rename from src/defaultJsonSerializer.ts rename to src/helpers/defaultJsonSerializer.ts diff --git a/src/resolveRequestDocument.ts b/src/helpers/resolveRequestDocument.ts similarity index 100% rename from src/resolveRequestDocument.ts rename to src/helpers/resolveRequestDocument.ts diff --git a/src/types.ts b/src/helpers/types.ts similarity index 84% rename from src/types.ts rename to src/helpers/types.ts index 905da6a1..331002b1 100644 --- a/src/types.ts +++ b/src/helpers/types.ts @@ -1,4 +1,4 @@ -import type { RemoveIndex } from './helpers.js' +import type { MaybeLazy, RemoveIndex } from '../lib/prelude.js' import type { TypedDocumentNode } from '@graphql-typed-document-node/core' import type { GraphQLError } from 'graphql/error/GraphQLError.js' import type { DocumentNode } from 'graphql/language/ast.js' @@ -76,8 +76,6 @@ export class ClientError extends Error { } } -export type MaybeLazy = T | (() => T) - export type RequestDocument = string | DocumentNode export interface GraphQLClientResponse { @@ -99,11 +97,6 @@ export interface RequestConfig extends Omit, jsonSerializer?: JsonSerializer } -export type BatchRequestDocument = { - document: RequestDocument - variables?: V -} - export type RawRequestOptions = { query: string requestHeaders?: HeadersInit @@ -124,25 +117,6 @@ export type RequestOptions = { ? { variables?: V } : { variables: V }) -export interface BatchRequestsOptions { - documents: BatchRequestDocument[] - requestHeaders?: HeadersInit - 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 | ClientError | Error) => void // prettier-ignore diff --git a/src/graphql-ws.ts b/src/lib/graphql-ws.ts similarity index 97% rename from src/graphql-ws.ts rename to src/lib/graphql-ws.ts index fbb14a36..12aeac63 100644 --- a/src/graphql-ws.ts +++ b/src/lib/graphql-ws.ts @@ -1,7 +1,7 @@ /* eslint-disable */ -import { resolveRequestDocument } from './resolveRequestDocument.js' -import type { RequestDocument, Variables } from './types.js' -import { ClientError } from './types.js' +import { resolveRequestDocument } from '../helpers/resolveRequestDocument.js' +import type { RequestDocument, Variables } from '../helpers/types.js' +import { ClientError } from '../helpers/types.js' import { TypedDocumentNode } from '@graphql-typed-document-node/core' // import type WebSocket from 'ws' diff --git a/src/lib/graphql.ts b/src/lib/graphql.ts new file mode 100644 index 00000000..e2bd247e --- /dev/null +++ b/src/lib/graphql.ts @@ -0,0 +1,12 @@ +import { CONTENT_TYPE_GQL, CONTENT_TYPE_JSON } from './http.js' + +/** + * Clean a GraphQL document to send it via a GET query + */ +export const cleanQuery = (str: string): string => str.replace(/([\s,]|#[^\n\r]+)+/g, ` `).trim() + +export const isGraphQLContentType = (contentType: string) => { + const contentTypeLower = contentType.toLowerCase() + + return contentTypeLower.includes(CONTENT_TYPE_GQL) || contentTypeLower.includes(CONTENT_TYPE_JSON) +} diff --git a/src/constants.ts b/src/lib/http.ts similarity index 100% rename from src/constants.ts rename to src/lib/http.ts diff --git a/src/helpers.ts b/src/lib/prelude.ts similarity index 73% rename from src/helpers.ts rename to src/lib/prelude.ts index c573b686..21a6c426 100644 --- a/src/helpers.ts +++ b/src/lib/prelude.ts @@ -14,3 +14,9 @@ export const HeadersInstanceToPlainObject = (headers: Response['headers']): Reco }) return o } + +export const callOrIdentity = (value: MaybeLazy) => { + return typeof value === `function` ? (value as () => T)() : value +} + +export type MaybeLazy = T | (() => T) diff --git a/src/parseArgs.ts b/src/parseArgs.ts deleted file mode 100644 index 474735bc..00000000 --- a/src/parseArgs.ts +++ /dev/null @@ -1,88 +0,0 @@ -import type { - BatchRequestDocument, - BatchRequestsOptions, - RawRequestExtendedOptions, - RawRequestOptions, - RequestDocument, - RequestExtendedOptions, - RequestOptions, - Variables, - VariablesAndRequestHeadersArgs, -} from './types.js' - -export const parseRequestArgs = ( - documentOrOptions: RequestDocument | RequestOptions, - variables?: V, - requestHeaders?: HeadersInit, -): RequestOptions => { - return (documentOrOptions as RequestOptions).document - ? (documentOrOptions as RequestOptions) - : ({ - document: documentOrOptions as RequestDocument, - variables: variables, - requestHeaders: requestHeaders, - signal: undefined, - } as unknown as RequestOptions) -} - -export const parseRawRequestArgs = ( - queryOrOptions: string | RawRequestOptions, - variables?: V, - requestHeaders?: HeadersInit, -): RawRequestOptions => { - return (queryOrOptions as RawRequestOptions).query - ? (queryOrOptions as RawRequestOptions) - : ({ - query: queryOrOptions as string, - variables: variables, - requestHeaders: requestHeaders, - signal: undefined, - } as unknown as RawRequestOptions) -} - -export const parseBatchRequestArgs = ( - documentsOrOptions: BatchRequestDocument[] | BatchRequestsOptions, - requestHeaders?: HeadersInit, -): BatchRequestsOptions => { - return (documentsOrOptions as BatchRequestsOptions).documents - ? (documentsOrOptions as BatchRequestsOptions) - : { - documents: documentsOrOptions as BatchRequestDocument[], - requestHeaders: requestHeaders, - signal: undefined, - } -} - -export const parseRequestExtendedArgs = ( - urlOrOptions: string | RequestExtendedOptions, - document?: RequestDocument, - ...variablesAndRequestHeaders: VariablesAndRequestHeadersArgs -): RequestExtendedOptions => { - const [variables, requestHeaders] = variablesAndRequestHeaders - return (urlOrOptions as RequestExtendedOptions).document - ? (urlOrOptions as RequestExtendedOptions) - : ({ - url: urlOrOptions as string, - document: document as RequestDocument, - variables, - requestHeaders, - signal: undefined, - } as unknown as RequestExtendedOptions) -} - -export const parseRawRequestExtendedArgs = ( - urlOrOptions: string | RawRequestExtendedOptions, - query?: string, - ...variablesAndRequestHeaders: VariablesAndRequestHeadersArgs -): RawRequestExtendedOptions => { - const [variables, requestHeaders] = variablesAndRequestHeaders - return (urlOrOptions as RawRequestExtendedOptions).query - ? (urlOrOptions as RawRequestExtendedOptions) - : ({ - url: urlOrOptions as string, - query: query as string, - variables, - requestHeaders, - signal: undefined, - } as unknown as RawRequestExtendedOptions) -} diff --git a/tests/batching.test.ts b/tests/batching.test.ts index e45d0a63..5f25c759 100644 --- a/tests/batching.test.ts +++ b/tests/batching.test.ts @@ -1,4 +1,4 @@ -import { batchRequests } from '../src/index.js' +import { batchRequests } from '../src/entrypoints/main.js' import type { MockSpecBatch } from './__helpers.js' import { setupMockServer } from './__helpers.js' import { expect, test } from 'vitest' diff --git a/tests/custom-fetch.test.ts b/tests/custom-fetch.test.ts index c8460548..36343d84 100644 --- a/tests/custom-fetch.test.ts +++ b/tests/custom-fetch.test.ts @@ -1,4 +1,4 @@ -import { GraphQLClient } from '../src/index.js' +import { GraphQLClient } from '../src/entrypoints/main.js' import { setupMockServer } from './__helpers.js' import { expect, test } from 'vitest' diff --git a/tests/document-node.test.ts b/tests/document-node.test.ts index 314c1548..a2a98033 100644 --- a/tests/document-node.test.ts +++ b/tests/document-node.test.ts @@ -1,4 +1,4 @@ -import { request } from '../src/index.js' +import { request } from '../src/entrypoints/main.js' import { setupMockServer } from './__helpers.js' import { gql } from 'graphql-tag' import { expect, it } from 'vitest' diff --git a/tests/endpoint.test.ts b/tests/endpoint.test.ts index e679aafa..f4830904 100644 --- a/tests/endpoint.test.ts +++ b/tests/endpoint.test.ts @@ -1,4 +1,4 @@ -import { GraphQLClient } from '../src/index.js' +import { GraphQLClient } from '../src/entrypoints/main.js' import { setupMockServer } from './__helpers.js' import { describe, expect, test } from 'vitest' diff --git a/tests/errorPolicy.test.ts b/tests/errorPolicy.test.ts index 1702cbae..db1f1395 100644 --- a/tests/errorPolicy.test.ts +++ b/tests/errorPolicy.test.ts @@ -1,4 +1,4 @@ -import { GraphQLClient } from '../src/index.js' +import { GraphQLClient } from '../src/entrypoints/main.js' import { setupMockServer } from './__helpers.js' import { expect, test } from 'vitest' diff --git a/tests/exports.ts b/tests/exports.ts index 1b375a0d..f1fdc589 100644 --- a/tests/exports.ts +++ b/tests/exports.ts @@ -1,2 +1,2 @@ /* eslint-disable */ -import { RequestMiddleware, ResponseMiddleware } from '../src/index.js' +import { RequestMiddleware, ResponseMiddleware } from '../src/entrypoints/main.js' diff --git a/tests/fetch.test.ts b/tests/fetch.test.ts index 8d117954..48bb2b5a 100644 --- a/tests/fetch.test.ts +++ b/tests/fetch.test.ts @@ -1,4 +1,4 @@ -import { gql, GraphQLClient } from '../src/index.js' +import { gql, GraphQLClient } from '../src/entrypoints/main.js' import { expect, test, vitest } from 'vitest' test(`custom fetch configuration is passed through`, async () => { diff --git a/tests/general.test.ts b/tests/general.test.ts index 1229309f..5bfc88f8 100644 --- a/tests/general.test.ts +++ b/tests/general.test.ts @@ -1,4 +1,4 @@ -import { GraphQLClient, rawRequest, request } from '../src/index.js' +import { GraphQLClient, rawRequest, request } from '../src/entrypoints/main.js' import { setupMockServer } from './__helpers.js' import { gql } from 'graphql-tag' import type { Mock } from 'vitest' diff --git a/tests/gql.test.ts b/tests/gql.test.ts index 193a57be..a40f220c 100644 --- a/tests/gql.test.ts +++ b/tests/gql.test.ts @@ -1,4 +1,4 @@ -import { request } from '../src/index.js' +import { request } from '../src/entrypoints/main.js' import { setupMockServer } from './__helpers.js' import { gql } from 'graphql-tag' import { describe, expect, it } from 'vitest' diff --git a/tests/headers.test.ts b/tests/headers.test.ts index 473af88a..006a279a 100644 --- a/tests/headers.test.ts +++ b/tests/headers.test.ts @@ -1,4 +1,4 @@ -import { GraphQLClient, request } from '../src/index.js' +import { GraphQLClient, request } from '../src/entrypoints/main.js' import { setupMockServer } from './__helpers.js' import { describe, expect, test } from 'vitest' diff --git a/tests/json-serializer.test.ts b/tests/json-serializer.test.ts index cde39ea2..569aaeca 100644 --- a/tests/json-serializer.test.ts +++ b/tests/json-serializer.test.ts @@ -1,5 +1,5 @@ -import { GraphQLClient } from '../src/index.js' -import type { Fetch, Variables } from '../src/types.js' +import { GraphQLClient } from '../src/entrypoints/main.js' +import type { Fetch, Variables } from '../src/helpers/types.js' import { setupMockServer } from './__helpers.js' import { beforeEach, describe, expect, test, vitest } from 'vitest' diff --git a/tests/signal.test.ts b/tests/signal.test.ts index 739f4108..c1673e5b 100644 --- a/tests/signal.test.ts +++ b/tests/signal.test.ts @@ -1,4 +1,4 @@ -import { batchRequests, GraphQLClient, rawRequest, request } from '../src/index.js' +import { batchRequests, GraphQLClient, rawRequest, request } from '../src/entrypoints/main.js' import { setupMockServer, sleep } from './__helpers.js' import { expect, it } from 'vitest' diff --git a/tests/typed-document-node.test.ts b/tests/typed-document-node.test.ts index 242df04d..9b09d69c 100644 --- a/tests/typed-document-node.test.ts +++ b/tests/typed-document-node.test.ts @@ -1,4 +1,4 @@ -import request, { gql } from '../src/index.js' +import request, { gql } from '../src/entrypoints/main.js' import { setupMockServer } from './__helpers.js' import type { TypedDocumentNode } from '@graphql-typed-document-node/core' import { parse } from 'graphql'