/* eslint-disable @typescript-eslint/no-explicit-any */ import { Response } from 'supertest' import { GraphQLError, GraphQLErrorExtensions } from 'graphql' import supertest, { Variables } from 'supertest-graphql' import { expect } from 'vitest' type GetGQL = (gql: typeof String.raw) => string export type RequestOptions = { type: 'query' | 'mutate' variables?: TVariables gql: GetGQL } export type RequestResponse = { data: TData errors: readonly (GraphQLError & { extensions: TExtensions })[] response: Response } type ExpectNoErrors = { expectNoErrors: () => Promise> } export const request = (getHttpServer: () => unknown) => < TData = any, TVariables extends Variables = Variables, TExtensions extends GraphQLErrorExtensions = GraphQLErrorExtensions, >( options: RequestOptions, ): PromiseLike> & ExpectNoErrors => { const supertestRequest = supertest(getHttpServer()) const method = supertestRequest[options.type].bind(supertestRequest) const gql = options.gql(String.raw) const resultPromise = method(gql, options.variables).then((result) => ({ errors: result.errors! as any, data: result.data!, response: result.response, })) return { then: resultPromise.then.bind(resultPromise), expectNoErrors: () => resultPromise.then((result) => { expect(result.errors, `Expected no GraphQL errors but found: ${result.errors}`).toBeUndefined() return result }), } }