Skip to content

Commit 5e54e38

Browse files
committed
fix: do not overwrite user-provided Content-Type header
1 parent c838ea7 commit 5e54e38

File tree

3 files changed

+23
-4
lines changed

3 files changed

+23
-4
lines changed

src/index.ts

+3-4
Original file line numberDiff line numberDiff line change
@@ -134,15 +134,14 @@ const createHttpMethodFetcher =
134134
async <V extends Variables>(params: RequestVerbParams<V>) => {
135135
const { url, query, variables, operationName, fetch, fetchOptions, middleware } = params
136136

137-
const headers = { ...params.headers }
137+
const headers = new Headers(params.headers as HeadersInit)
138138
let queryParams = ``
139139
let body = undefined
140140

141141
if (method === `POST`) {
142142
body = createRequestBody(query, variables, operationName, fetchOptions.jsonSerializer)
143-
if (typeof body === `string`) {
144-
// @ts-expect-error todo
145-
headers[`Content-Type`] = `application/json`
143+
if (typeof body === `string` && !headers.has(`Content-Type`)) {
144+
headers.set(`Content-Type`, `application/json`)
146145
}
147146
} else {
148147
// @ts-expect-error todo needs ADT for TS to understand the different states

src/types.ts

+2
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,8 @@ type RequestExtendedInit<V extends Variables = Variables> = RequestInit & {
154154
variables?: V
155155
}
156156

157+
// TODO: Replace this type with the built-in `HeadersInit` type.
158+
// See: https://github.com/jasonkuhrt/graphql-request/issues/608
157159
export type GraphQLClientRequestHeaders = Headers | string[][] | Record<string, string>
158160

159161
// prettier-ignore

tests/headers.test.ts

+18
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,24 @@ describe(`using class`, () => {
107107
expect(mock.requests[0]?.headers[`x-foo`]).toEqual(`new`)
108108
})
109109
})
110+
111+
describe(`allows content-type header to be overwritten`, () => {
112+
test(`with request method`, async () => {
113+
const headers = new Headers({ 'content-type': `text/plain` })
114+
const client = new GraphQLClient(ctx.url, { headers })
115+
const mock = ctx.res()
116+
await client.request(`{ me { id } }`)
117+
expect(mock.requests[0]?.headers[`content-type`]).toEqual(`text/plain`)
118+
})
119+
120+
test(`with rawRequest method`, async () => {
121+
const headers = new Headers({ 'content-type': `text/plain` })
122+
const client = new GraphQLClient(ctx.url, { headers })
123+
const mock = ctx.res()
124+
await client.rawRequest(`{ me { id } }`)
125+
expect(mock.requests[0]?.headers[`content-type`]).toEqual(`text/plain`)
126+
})
127+
})
110128
})
111129
})
112130

0 commit comments

Comments
 (0)