Skip to content

Commit

Permalink
fetchBaseQuery: expose extraOptions to prepareHeaders
Browse files Browse the repository at this point in the history
  • Loading branch information
phryneas authored and markerikson committed Oct 14, 2024
1 parent 7b50a61 commit 3e77381
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 6 deletions.
13 changes: 7 additions & 6 deletions packages/toolkit/src/query/fetchBaseQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,14 +105,14 @@ function stripUndefined(obj: any) {
return copy
}

export type FetchBaseQueryArgs = {
export type FetchBaseQueryArgs<ExtraOptions = {}> = {
baseUrl?: string
prepareHeaders?: (
headers: Headers,
api: Pick<
BaseQueryApi,
'getState' | 'extra' | 'endpoint' | 'type' | 'forced'
> & { arg: string | FetchArgs },
> & { arg: string | FetchArgs; extraOptions: ExtraOptions },
) => MaybePromise<Headers | void>
fetchFn?: (
input: RequestInfo,
Expand Down Expand Up @@ -188,7 +188,7 @@ export type FetchBaseQueryMeta = { request: Request; response?: Response }
* @param {number} timeout
* A number in milliseconds that represents the maximum time a request can take before timing out.
*/
export function fetchBaseQuery({
export function fetchBaseQuery<ExtraOptions>({
baseUrl,
prepareHeaders = (x) => x,
fetchFn = defaultFetchFn,
Expand All @@ -200,19 +200,19 @@ export function fetchBaseQuery({
responseHandler: globalResponseHandler,
validateStatus: globalValidateStatus,
...baseFetchOptions
}: FetchBaseQueryArgs = {}): BaseQueryFn<
}: FetchBaseQueryArgs<ExtraOptions> = {}): BaseQueryFn<
string | FetchArgs,
unknown,
FetchBaseQueryError,
{},
ExtraOptions,
FetchBaseQueryMeta
> {
if (typeof fetch === 'undefined' && fetchFn === defaultFetchFn) {
console.warn(
'Warning: `fetch` is not available. Please supply a custom `fetchFn` property to use `fetchBaseQuery` on SSR environments.',
)
}
return async (arg, api) => {
return async (arg, api, extraOptions) => {
const { getState, extra, endpoint, forced, type } = api
let meta: FetchBaseQueryMeta | undefined
let {
Expand Down Expand Up @@ -248,6 +248,7 @@ export function fetchBaseQuery({
endpoint,
forced,
type,
extraOptions,
})) || headers

// Only set the content-type to json if appropriate. Will not be true for FormData, ArrayBuffer, Blob, etc.
Expand Down
47 changes: 47 additions & 0 deletions packages/toolkit/src/query/tests/fetchBaseQuery.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { createSlice } from '@reduxjs/toolkit'
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query'
import { headersToObject } from 'headers-polyfill'
import { HttpResponse, delay, http } from 'msw'
// @ts-ignore
import nodeFetch from 'node-fetch'
import queryString from 'query-string'
import { vi } from 'vitest'
Expand Down Expand Up @@ -852,6 +853,52 @@ describe('fetchBaseQuery', () => {
expect(_forced).toBe(true)
expect(_extra).toBe(fakeAuth0Client)
})

test('can be instantiated with a `ExtraOptions` generic and `extraOptions` will be available in `prepareHeaders', async () => {
const prepare = vitest.fn()
const baseQuery = fetchBaseQuery<{ foo?: string; bar?: number }>({
prepareHeaders(headers, api) {
expectTypeOf(api.extraOptions).toEqualTypeOf<{ foo?: string; bar?: number }>()
prepare.call(undefined, arguments)
},
})
baseQuery('', commonBaseQueryApi, { foo: 'baz', bar: 5 })
expect(prepare).toHaveBeenCalledWith(
expect.anything(),
expect.objectContaining({ extraOptions: { foo: 'baz', bar: 5 } })
)

// ensure types
createApi({
baseQuery,
endpoints(build) {
return {
testQuery: build.query({
query: () => ({ url: '/echo', headers: {} }),
extraOptions: {
foo: 'asd',
bar: 1,
// @ts-expect-error
baz: 5,
},
}),
testMutation: build.mutation({
query: () => ({
url: '/echo',
method: 'POST',
credentials: 'omit',
}),
extraOptions: {
foo: 'qwe',
bar: 15,
// @ts-expect-error
baz: 5,
},
}),
}
},
})
})
})

test('can pass `headers` into `fetchBaseQuery`', async () => {
Expand Down

0 comments on commit 3e77381

Please sign in to comment.