diff --git a/README.md b/README.md index 7539d7ae..709c3d9d 100644 --- a/README.md +++ b/README.md @@ -41,9 +41,9 @@ Minimal GraphQL client supporting Node and browsers for scripts or simple apps - [Ignore](#ignore) - [All](#all) - [FAQ](#faq) - - [Why do I have to install `graphql`?](#why-do-i-have-to-install-graphql) - - [Do I need to wrap my GraphQL documents inside the `gql` template exported by `graphql-request`?](#do-i-need-to-wrap-my-graphql-documents-inside-the-gql-template-exported-by-graphql-request) - - [What's the difference between `graphql-request`, Apollo and Relay?](#whats-the-difference-between-graphql-request-apollo-and-relay) + - [Why do I have to install `graphql`?](#why-do-i-have-to-install-graphql) + - [Do I need to wrap my GraphQL documents inside the `gql` template exported by `graphql-request`?](#do-i-need-to-wrap-my-graphql-documents-inside-the-gql-template-exported-by-graphql-request) + - [What's the difference between `graphql-request`, Apollo and Relay?](#whats-the-difference-between-graphql-request-apollo-and-relay) diff --git a/examples/typed-document-node.ts b/examples/typed-document-node.ts index 1f340059..08d9f2ef 100644 --- a/examples/typed-document-node.ts +++ b/examples/typed-document-node.ts @@ -1,4 +1,4 @@ -import { GraphQLClient,request } from '../src/index.js' +import { GraphQLClient, request } from '../src/index.js' import type { TypedDocumentNode } from '@graphql-typed-document-node/core' import { parse } from 'graphql' ;(async function () { diff --git a/package.json b/package.json index 596d99a9..62927c83 100644 --- a/package.json +++ b/package.json @@ -100,7 +100,7 @@ "prettier": "^2.8.3", "type-fest": "^3.5.3", "typescript": "^4.9.4", - "vitest": "^0.28.2", + "vitest": "^0.29.0", "ws": "^8.12.0" }, "prettier": "@prisma-labs/prettier-config" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index bbc5ffd2..992ef4bc 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -36,7 +36,7 @@ specifiers: prettier: ^2.8.3 type-fest: ^3.5.3 typescript: ^4.9.4 - vitest: ^0.28.2 + vitest: ^0.29.0 ws: ^8.12.0 dependencies: @@ -77,7 +77,7 @@ devDependencies: prettier: 2.8.3 type-fest: 3.5.3 typescript: 4.9.4 - vitest: 0.28.2_happy-dom@8.1.5 + vitest: 0.29.1_happy-dom@8.1.5 ws: 8.12.0 packages: @@ -1169,6 +1169,14 @@ packages: chai: 4.3.7 dev: true + /@vitest/expect/0.29.1: + resolution: {integrity: sha512-VFt1u34D+/L4pqjLA8VGPdHbdF8dgjX9Nq573L9KG6/7MIAL9jmbEIKpXudmxjoTwcyczOXRyDuUWBQHZafjoA==} + dependencies: + '@vitest/spy': 0.29.1 + '@vitest/utils': 0.29.1 + chai: 4.3.7 + dev: true + /@vitest/runner/0.28.2: resolution: {integrity: sha512-BJ9CtfPwWM8uc5p7Ty0OprwApyh8RIaSK7QeQPhwfDYA59AAE009OytqA3aX0yj1Qy5+k/mYFJS8RJZgsueSGA==} dependencies: @@ -1177,12 +1185,26 @@ packages: pathe: 1.1.0 dev: true + /@vitest/runner/0.29.1: + resolution: {integrity: sha512-VZ6D+kWpd/LVJjvxkt79OA29FUpyrI5L/EEwoBxH5m9KmKgs1QWNgobo/CGQtIWdifLQLvZdzYEK7Qj96w/ixQ==} + dependencies: + '@vitest/utils': 0.29.1 + p-limit: 4.0.0 + pathe: 1.1.0 + dev: true + /@vitest/spy/0.28.2: resolution: {integrity: sha512-KlLzTzi5E6tHcI12VT+brlY1Pdi7sUzLf9+YXgh80+CfLu9DqPZi38doBBAUhqEnW/emoLCMinPMMoJlNAQZXA==} dependencies: tinyspy: 1.0.2 dev: true + /@vitest/spy/0.29.1: + resolution: {integrity: sha512-sRXXK44pPzaizpiZOIQP7YMhxIs80J/b6v1yR3SItpxG952c8tdA7n0O2j4OsVkjiO/ZDrjAYFrXL3gq6hLx6Q==} + dependencies: + tinyspy: 1.0.2 + dev: true + /@vitest/utils/0.28.2: resolution: {integrity: sha512-wcVTNnVdr22IGxZHDgiXrxWYcXsNg0iX2iBuOH3tVs9eme6fXJ0wxjn0/gCpp0TofQSoUwo3tX8LNACFVseDuA==} dependencies: @@ -1193,6 +1215,16 @@ packages: pretty-format: 27.5.1 dev: true + /@vitest/utils/0.29.1: + resolution: {integrity: sha512-6npOEpmyE6zPS2wsWb7yX5oDpp6WY++cC5BX6/qaaMhGC3ZlPd8BbTz3RtGPi1PfPerPvfs4KqS/JDOIaB6J3w==} + dependencies: + cli-truncate: 3.1.0 + diff: 5.1.0 + loupe: 2.3.6 + picocolors: 1.0.0 + pretty-format: 27.5.1 + dev: true + /accepts/1.3.8: resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} engines: {node: '>= 0.6'} @@ -3951,6 +3983,11 @@ packages: engines: {node: '>=14.0.0'} dev: true + /tinypool/0.3.1: + resolution: {integrity: sha512-zLA1ZXlstbU2rlpA4CIeVaqvWq41MTWqLY3FfsAXgC8+f7Pk7zroaJQxDgxn1xNudKW6Kmj4808rPFShUlIRmQ==} + engines: {node: '>=14.0.0'} + dev: true + /tinyspy/1.0.2: resolution: {integrity: sha512-bSGlgwLBYf7PnUsQ6WOc6SJ3pGOcd+d8AA6EUnLDDM0kWEstC1JIlSZA3UNliDXhd9ABoS7hiRBDCu+XP/sf1Q==} engines: {node: '>=14.0.0'} @@ -4221,6 +4258,27 @@ packages: - terser dev: true + /vite-node/0.29.1_@types+node@18.11.18: + resolution: {integrity: sha512-Ey9bTlQOQrCxQN0oJ7sTg+GrU4nTMLg44iKTFCKf31ry60csqQz4E+Q04hdWhwE4cTgpxUC+zEB1kHbf5jNkFA==} + engines: {node: '>=v14.16.0'} + hasBin: true + dependencies: + cac: 6.7.14 + debug: 4.3.4 + mlly: 1.1.0 + pathe: 1.1.0 + picocolors: 1.0.0 + vite: 4.0.4_@types+node@18.11.18 + transitivePeerDependencies: + - '@types/node' + - less + - sass + - stylus + - sugarss + - supports-color + - terser + dev: true + /vite/4.0.4_@types+node@18.11.18: resolution: {integrity: sha512-xevPU7M8FU0i/80DMR+YhgrzR5KS2ORy1B4xcX/cXLsvnUWvfHuqMmVU6N0YiJ4JWGRJJsLCgjEzKjG9/GKoSw==} engines: {node: ^14.18.0 || >=16.0.0} @@ -4311,6 +4369,62 @@ packages: - terser dev: true + /vitest/0.29.1_happy-dom@8.1.5: + resolution: {integrity: sha512-iSy6d9VwsIn7pz5I8SjVwdTLDRGKNZCRJVzROwjt0O0cffoymKwazIZ2epyMpRGpeL5tsXAl1cjXiT7agTyVug==} + engines: {node: '>=v14.16.0'} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@vitest/browser': '*' + '@vitest/ui': '*' + happy-dom: '*' + jsdom: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@vitest/browser': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + dependencies: + '@types/chai': 4.3.4 + '@types/chai-subset': 1.3.3 + '@types/node': 18.11.18 + '@vitest/expect': 0.29.1 + '@vitest/runner': 0.29.1 + '@vitest/spy': 0.29.1 + '@vitest/utils': 0.29.1 + acorn: 8.8.2 + acorn-walk: 8.2.0 + cac: 6.7.14 + chai: 4.3.7 + debug: 4.3.4 + happy-dom: 8.1.5 + local-pkg: 0.4.3 + pathe: 1.1.0 + picocolors: 1.0.0 + source-map: 0.6.1 + std-env: 3.3.1 + strip-literal: 1.0.0 + tinybench: 2.3.1 + tinypool: 0.3.1 + tinyspy: 1.0.2 + vite: 4.0.4_@types+node@18.11.18 + vite-node: 0.29.1_@types+node@18.11.18 + why-is-node-running: 2.2.2 + transitivePeerDependencies: + - less + - sass + - stylus + - sugarss + - supports-color + - terser + dev: true + /webidl-conversions/3.0.1: resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} diff --git a/src/graphql-ws.ts b/src/graphql-ws.ts index 51966f61..7f179fb4 100644 --- a/src/graphql-ws.ts +++ b/src/graphql-ws.ts @@ -1,6 +1,6 @@ import { resolveRequestDocument } from './resolveRequestDocument.js' import type * as Dom from './types.dom.js' -import type { RequestDocument, Variables } from './types.js'; +import type { RequestDocument, Variables } from './types.js' import { ClientError } from './types.js' // import type WebSocket from 'ws' diff --git a/src/index.ts b/src/index.ts index 38877a05..e24e37cf 100644 --- a/src/index.ts +++ b/src/index.ts @@ -3,7 +3,6 @@ import { defaultJsonSerializer } from './defaultJsonSerializer.js' import { HeadersInstanceToPlainObject, uppercase } from './helpers.js' import { parseBatchRequestArgs, - parseBatchRequestsExtendedArgs, parseRawRequestArgs, parseRawRequestExtendedArgs, parseRequestArgs, @@ -33,6 +32,7 @@ import { } from './types.js' import type { TypedDocumentNode } from '@graphql-typed-document-node/core' import crossFetch, * as CrossFetch from 'cross-fetch' +import type { T, V } from 'vitest/dist/types-7cd96283.js' export { BatchRequestDocument, @@ -310,12 +310,12 @@ export class GraphQLClient { /** * Send GraphQL documents in batch to the server. */ - batchRequests( - documents: BatchRequestDocument[], - requestHeaders?: Dom.RequestInit['headers'] - ): Promise - batchRequests(options: BatchRequestsOptions): Promise - batchRequests( + // prettier-ignore + batchRequests(documents: BatchRequestDocument[], requestHeaders?: Dom.RequestInit['headers']): Promise + // prettier-ignore + batchRequests(options: BatchRequestsOptions): Promise + // prettier-ignore + batchRequests( documentsOrOptions: BatchRequestDocument[] | BatchRequestsOptions, requestHeaders?: Dom.RequestInit['headers'] ): Promise { @@ -573,22 +573,39 @@ export async function request( * await batchRequests('https://foo.bar/graphql', [{ query: gql`...` }]) * ``` */ -export async function batchRequests( - url: string, - documents: BatchRequestDocument[], - requestHeaders?: Dom.RequestInit['headers'] -): Promise -export async function batchRequests( - options: BatchRequestsExtendedOptions -): Promise -export async function batchRequests( - urlOrOptions: string | BatchRequestsExtendedOptions, - documents?: BatchRequestDocument[], - requestHeaders?: Dom.RequestInit['headers'] -): Promise { - const params = parseBatchRequestsExtendedArgs(urlOrOptions, documents, requestHeaders) +export const batchRequests: BatchRequests = async (...args: BatchRequestsArgs) => { + const params = parseBatchRequestsArgsExtended(args) const client = new GraphQLClient(params.url) - return client.batchRequests(params) + return client.batchRequests(params) +} + +interface Result { + data: Data +} + +type BatchResult = [Result, ...Result[]] + +// prettier-ignore +interface BatchRequests { + (url: string, documents: BatchRequestDocument[], requestHeaders?: Dom.RequestInit['headers']): Promise + (options: BatchRequestsExtendedOptions): Promise +} + +type BatchRequestsArgs = + | [url: string, documents: BatchRequestDocument[], requestHeaders?: Dom.RequestInit['headers']] + | [options: BatchRequestsExtendedOptions] + +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, + } + } } export default request diff --git a/src/parseArgs.ts b/src/parseArgs.ts index 74229a43..197e52f7 100644 --- a/src/parseArgs.ts +++ b/src/parseArgs.ts @@ -88,18 +88,3 @@ export const parseRawRequestExtendedArgs = ( signal: undefined, } as unknown as RawRequestExtendedOptions) } - -export const parseBatchRequestsExtendedArgs = ( - urlOrOptions: string | BatchRequestsExtendedOptions, - documents?: BatchRequestDocument[], - requestHeaders?: Dom.RequestInit['headers'] -): BatchRequestsExtendedOptions => { - return (urlOrOptions as BatchRequestsExtendedOptions).documents - ? (urlOrOptions as BatchRequestsExtendedOptions) - : { - url: urlOrOptions as string, - documents: documents as BatchRequestDocument[], - requestHeaders: requestHeaders, - signal: undefined, - } -} diff --git a/src/types.ts b/src/types.ts index 55c13b30..67776cdc 100644 --- a/src/types.ts +++ b/src/types.ts @@ -96,7 +96,7 @@ export type RequestOptions = { ? { variables?: V } : { variables: V }) -export type BatchRequestsOptions = { +export interface BatchRequestsOptions { documents: BatchRequestDocument[] requestHeaders?: Dom.RequestInit['headers'] signal?: Dom.RequestInit['signal'] @@ -110,9 +110,10 @@ export type RawRequestExtendedOptions = { url: string } & RawRequestOptions -export type BatchRequestsExtendedOptions = { +export interface BatchRequestsExtendedOptions + extends BatchRequestsOptions { url: string -} & BatchRequestsOptions +} export type RequestMiddleware = ( request: RequestExtendedInit diff --git a/tests/__snapshots__/document-node.test.ts.snap b/tests/__snapshots__/document-node.test.ts.snap index 729041d1..b86fd1b2 100644 --- a/tests/__snapshots__/document-node.test.ts.snap +++ b/tests/__snapshots__/document-node.test.ts.snap @@ -1,4 +1,4 @@ -// Vitest Snapshot v1 +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html exports[`accepts graphql DocumentNode as alternative to raw string 1`] = ` { diff --git a/tests/__snapshots__/gql.test.ts.snap b/tests/__snapshots__/gql.test.ts.snap index e20352f4..e53b96ab 100644 --- a/tests/__snapshots__/gql.test.ts.snap +++ b/tests/__snapshots__/gql.test.ts.snap @@ -1,4 +1,4 @@ -// Vitest Snapshot v1 +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html exports[`gql > passthrough allowing benefits of tooling for gql template tag 1`] = ` { diff --git a/tests/general.test.ts b/tests/general.test.ts index 7e8ae52b..bd119cab 100644 --- a/tests/general.test.ts +++ b/tests/general.test.ts @@ -1,5 +1,4 @@ import { GraphQLClient, rawRequest, request } from '../src/index.js' -import type * as Dom from '../src/types.dom.js' import type { RequestConfig } from '../src/types.js' import { setupMockServer } from './__helpers.js' import { gql } from 'graphql-tag' @@ -203,7 +202,7 @@ describe(`middleware`, () => { }) it(`batchRequests`, async () => { - const requestPromise = client.batchRequests<{ result: number }>([{ document: `x` }]) + const requestPromise = client.batchRequests([{ document: `x` }]) expect(requestMiddleware).toBeCalledTimes(1) await requestPromise expect(responseMiddleware).toBeCalledTimes(1) @@ -250,7 +249,7 @@ describe(`middleware`, () => { }) it(`batchRequests`, async () => { - const requestPromise = client.batchRequests<{ result: number }>([{ document: `x` }]) + const requestPromise = client.batchRequests([{ document: `x` }]) expect(requestMiddleware).toBeCalledTimes(1) await requestPromise }) @@ -295,7 +294,7 @@ describe(`middleware`, () => { }) it(`batchRequests`, async () => { - const requestPromise = client.batchRequests<{ result: number }>([{ document: `x` }]) + const requestPromise = client.batchRequests([{ document: `x` }]) expect(requestMiddleware).toBeCalledTimes(1) await expect(requestPromise).rejects.toThrowError() expect(responseMiddleware).toBeCalledTimes(1)