Skip to content

Commit

Permalink
refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
jasonkuhrt committed Jan 23, 2025
1 parent dc3dca7 commit 863ae8c
Showing 1 changed file with 23 additions and 42 deletions.
65 changes: 23 additions & 42 deletions packages/graphiql-toolkit/src/create-fetcher/lib.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
// todo
// Current TS Config target does not support `Headers.entries()` method.
// However it is reported as "widely available" and so should be fine to use.
// @see https://developer.mozilla.org/en-US/docs/Web/API/Headers/entries
// Several places we currently use ts-expect-error to allow this.

import { DocumentNode, visit } from 'graphql';
import { meros } from 'meros';
import type {
Expand All @@ -24,23 +30,6 @@ const errorHasCode = (err: unknown): err is { code: string } => {
return typeof err === 'object' && err !== null && 'code' in err;
};

/**
* Merge two Headers instances into one.
*
* Returns a new Headers instance (does not mutate).
*
* Headers are merged by having a copy of the first headers argument apply its `set`
* method to assign each header from the second headers argument. This means that headers
* from the second Headers instance overwrite same-named headers in the first.
*/
const mergeHeadersWithSetStrategy = (headersA: Headers, headersB: Headers) => {
const newHeaders = new Headers(headersA);
for (const [key, value] of headersB.entries()) {
newHeaders.set(key, value);
}
return newHeaders;
};

/**
* Returns true if the name matches a subscription in the AST
*
Expand Down Expand Up @@ -74,14 +63,13 @@ export const isSubscriptionWithName = (
export const createSimpleFetcher =
(options: CreateFetcherOptions, httpFetch: typeof fetch): Fetcher =>
async (graphQLParams: FetcherParams, fetcherOpts?: FetcherOpts) => {
const headers = [
new Headers({
'content-type': 'application/json',
}),
new Headers(options.headers ?? {}),
new Headers(fetcherOpts?.headers ?? {}),
].reduce(mergeHeadersWithSetStrategy, new Headers());

const headers = new Headers([
['content-type', 'application/json'],
// @ts-expect-error: todo enable ES target that has entries on headers
...new Headers(options.headers ?? {}).entries(),
// @ts-expect-error: todo enable ES target that has entries on headers
...new Headers(fetcherOpts?.headers ?? {}).entries(),
]);
const data = await httpFetch(options.url, {
method: 'POST',
body: JSON.stringify(graphQLParams),
Expand Down Expand Up @@ -162,14 +150,14 @@ export const createMultipartFetcher = (
httpFetch: typeof fetch,
): Fetcher =>
async function* (graphQLParams: FetcherParams, fetcherOpts?: FetcherOpts) {
const headers = [
new Headers({
'content-type': 'application/json',
accept: 'application/json, multipart/mixed',
}),
new Headers(options.headers ?? {}),
new Headers(fetcherOpts?.headers ?? {}),
].reduce(mergeHeadersWithSetStrategy, new Headers());
const headers = new Headers([
['content-type', 'application/json'],
['accept', 'application/json, multipart/mixed'],
// @ts-expect-error: todo enable ES target that has entries on headers
...new Headers(options.headers ?? {}).entries(),
// @ts-expect-error: todo enable ES target that has entries on headers
...new Headers(fetcherOpts?.headers ?? {}).entries(),
]);

const response = await httpFetch(options.url, {
method: 'POST',
Expand Down Expand Up @@ -210,17 +198,10 @@ export async function getWsFetcher(
return createWebsocketsFetcherFromClient(options.wsClient);
}
if (options.subscriptionUrl) {
const fetcherOptsHeaders = new Headers(fetcherOpts?.headers ?? {});
// @ts-expect-error: Current TS Config target does not support `Headers.entries()` method.
// However it is reported as "widely available" and so should be fine to use. This could
// would be more complicated without it.
// @see https://developer.mozilla.org/en-US/docs/Web/API/Headers/entries
const fetcherOptsHeadersEntries: [string, string][] = [
...fetcherOptsHeaders.entries(),
];
// todo: If there are headers with multiple values, they will be lost. Is this a problem?
const fetcherOptsHeadersRecord = Object.fromEntries(
fetcherOptsHeadersEntries,
// @ts-expect-error: todo enable ES target that has entries on headers
new Headers(fetcherOpts?.headers ?? {}).entries(),
);
return createWebsocketsFetcherFromUrl(options.subscriptionUrl, {
...options.wsConnectionParams,
Expand Down

0 comments on commit 863ae8c

Please sign in to comment.