diff --git a/src/index.ts b/src/index.ts index 7a213ee34..015542956 100644 --- a/src/index.ts +++ b/src/index.ts @@ -134,15 +134,14 @@ const createHttpMethodFetcher = async (params: RequestVerbParams) => { const { url, query, variables, operationName, fetch, fetchOptions, middleware } = params - const headers = { ...params.headers } + const headers = new Headers(params.headers as HeadersInit) let queryParams = `` let body = undefined if (method === `POST`) { body = createRequestBody(query, variables, operationName, fetchOptions.jsonSerializer) - if (typeof body === `string`) { - // @ts-expect-error todo - headers[`Content-Type`] = `application/json` + if (typeof body === `string` && !headers.has(`Content-Type`)) { + headers.set(`Content-Type`, `application/json`) } } else { // @ts-expect-error todo needs ADT for TS to understand the different states diff --git a/src/types.ts b/src/types.ts index b4aec590a..b4b7775a2 100644 --- a/src/types.ts +++ b/src/types.ts @@ -154,6 +154,8 @@ type RequestExtendedInit = RequestInit & { variables?: V } +// TODO: Replace this type with the built-in `HeadersInit` type. +// See: https://github.com/jasonkuhrt/graphql-request/issues/608 export type GraphQLClientRequestHeaders = Headers | string[][] | Record // prettier-ignore diff --git a/tests/headers.test.ts b/tests/headers.test.ts index a1754d82b..445068d3d 100644 --- a/tests/headers.test.ts +++ b/tests/headers.test.ts @@ -107,6 +107,24 @@ describe(`using class`, () => { expect(mock.requests[0]?.headers[`x-foo`]).toEqual(`new`) }) }) + + describe(`allows content-type header to be overwritten`, () => { + test(`with request method`, async () => { + const headers = new Headers({ 'content-type': `text/plain` }) + const client = new GraphQLClient(ctx.url, { headers }) + const mock = ctx.res() + await client.request(`{ me { id } }`) + expect(mock.requests[0]?.headers[`content-type`]).toEqual(`text/plain`) + }) + + test(`with rawRequest method`, async () => { + const headers = new Headers({ 'content-type': `text/plain` }) + const client = new GraphQLClient(ctx.url, { headers }) + const mock = ctx.res() + await client.rawRequest(`{ me { id } }`) + expect(mock.requests[0]?.headers[`content-type`]).toEqual(`text/plain`) + }) + }) }) })