Skip to content

Commit

Permalink
new adapter
Browse files Browse the repository at this point in the history
  • Loading branch information
prc5 committed Feb 8, 2025
1 parent 5d17bda commit 8b00993
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 71 deletions.
64 changes: 38 additions & 26 deletions packages/adapter-graphql/src/adapter/adapter.browser.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,32 @@
import { getAdapterBindings, getResponseHeaders, parseResponse, getErrorMessage } from "@hyper-fetch/core";

import { gqlExtra, GraphQLAdapterType, defaultTimeout, getRequestValues } from "adapter";

export const adapter: GraphQLAdapterType = async (request, requestId) => {
const {
makeRequest,
config,
import { getResponseHeaders, parseResponse, getErrorMessage, Adapter, QueryParamsType } from "@hyper-fetch/core";

import {
gqlExtra,
GraphQLAdapterType,
defaultTimeout,
getRequestValues,
GraphqlMethod,
GraphQlExtraType,
GraphQlEndpointType,
} from "adapter";

export const adapter: GraphQLAdapterType = new Adapter<
Partial<XMLHttpRequest>,
GraphqlMethod,
number,
GraphQlExtraType,
QueryParamsType | string,
GraphQlEndpointType
>({
name: "graphql",
defaultMethod: GraphqlMethod.POST,
defaultExtra: gqlExtra,
systemErrorStatus: 0,
systemErrorExtra: gqlExtra,
}).setFetcher(
async ({
request,
adapterOptions,
headers,
onError,
onResponseEnd,
Expand All @@ -18,25 +39,17 @@ export const adapter: GraphQLAdapterType = async (request, requestId) => {
onBeforeRequest,
onRequestStart,
onSuccess,
} = await getAdapterBindings<GraphQLAdapterType>({
request,
requestId,
systemErrorStatus: 0,
systemErrorExtra: gqlExtra,
internalErrorFormatter: (error) => [error],
});

const { fullUrl, payload } = getRequestValues(request);
}) => {
const { fullUrl, payload } = getRequestValues(request);

return makeRequest((resolve) => {
const xhr = new XMLHttpRequest();
xhr.timeout = defaultTimeout;

const onAbort = () => xhr.abort();

// Inject xhr options
if (config) {
Object.entries(config).forEach(([name, value]) => {
if (adapterOptions) {
Object.entries(adapterOptions).forEach(([name, value]) => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
xhr[name] = value;
Expand All @@ -50,7 +63,7 @@ export const adapter: GraphQLAdapterType = async (request, requestId) => {
Object.entries(headers).forEach(([name, value]) => xhr.setRequestHeader(name, value as string));

// Listen to abort signal
const unmountListener = createAbortListener({ status: 0, extra: gqlExtra, onAbort, resolve });
const unmountListener = createAbortListener({ status: 0, extra: gqlExtra, onAbort });

// Request handlers
xhr.upload.onprogress = onRequestProgress;
Expand All @@ -68,7 +81,7 @@ export const adapter: GraphQLAdapterType = async (request, requestId) => {
unmountListener();
};

xhr.ontimeout = () => onTimeoutError({ status: 0, extra: gqlExtra, resolve });
xhr.ontimeout = () => onTimeoutError({ status: 0, extra: gqlExtra });

// Data handler
xhr.onreadystatechange = (e: Event) => {
Expand All @@ -87,14 +100,13 @@ export const adapter: GraphQLAdapterType = async (request, requestId) => {
if (failure) {
const error = errors || [getErrorMessage()];
// delay to finish after onabort/ontimeout
onError({ error, status, extra: { headers: responseHeaders, extensions }, resolve });
onError({ error, status, extra: { headers: responseHeaders, extensions } });
} else {
onSuccess({
data,
error: errors,
status,
extra: { headers: responseHeaders, extensions },
resolve,
});
}
}
Expand All @@ -105,5 +117,5 @@ export const adapter: GraphQLAdapterType = async (request, requestId) => {
onRequestStart();

xhr.send(payload);
});
};
},
);
100 changes: 55 additions & 45 deletions packages/adapter-graphql/src/adapter/adapter.server.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,34 @@
import { getAdapterBindings, parseErrorResponse, parseResponse } from "@hyper-fetch/core";
import { Adapter, parseErrorResponse, parseResponse, QueryParamsType } from "@hyper-fetch/core";
import http, { OutgoingHttpHeaders } from "http";
import https from "https";

import { gqlExtra, defaultTimeout, GraphQLAdapterType, getRequestValues } from "adapter";

export const adapter: GraphQLAdapterType = async (request, requestId) => {
const {
makeRequest,
config,
import {
gqlExtra,
defaultTimeout,
GraphQLAdapterType,
getRequestValues,
GraphQlExtraType,
GraphqlMethod,
GraphQlEndpointType,
} from "adapter";

export const adapter: GraphQLAdapterType = new Adapter<
Partial<XMLHttpRequest>,
GraphqlMethod,
number,
GraphQlExtraType,
QueryParamsType | string,
GraphQlEndpointType
>({
name: "graphql",
defaultMethod: GraphqlMethod.POST,
defaultExtra: gqlExtra,
systemErrorStatus: 0,
systemErrorExtra: gqlExtra,
}).setFetcher(
async ({
request,
adapterOptions,
headers,
onError,
onResponseEnd,
Expand All @@ -19,44 +40,35 @@ export const adapter: GraphQLAdapterType = async (request, requestId) => {
onBeforeRequest,
onRequestStart,
onSuccess,
} = await getAdapterBindings<GraphQLAdapterType>({
request,
requestId,
systemErrorStatus: 0,
systemErrorExtra: gqlExtra,
internalErrorFormatter: (error) => [error],
});

const { fullUrl, payload } = getRequestValues(request);

const httpClient = request.client.url.includes("https://") ? https : http;
const options = {
method: request.method,
headers: headers as OutgoingHttpHeaders,
timeout: defaultTimeout,
signal: undefined as AbortSignal | undefined,
} satisfies https.RequestOptions;

Object.entries(config || {}).forEach(([name, value]) => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
options[name] = value;
});

// if (request.payload) {
// options.headers["Content-Length"] = Buffer.byteLength(JSON.stringify(payload));
// }

onBeforeRequest();

return makeRequest((resolve) => {
}) => {
const { fullUrl, payload } = getRequestValues(request);

const httpClient = request.client.url.includes("https://") ? https : http;
const options = {
method: request.method,
headers: headers as OutgoingHttpHeaders,
timeout: defaultTimeout,
signal: undefined as AbortSignal | undefined,
} satisfies https.RequestOptions;

Object.entries(adapterOptions || {}).forEach(([name, value]) => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
options[name] = value;
});

// if (request.payload) {
// options.headers["Content-Length"] = Buffer.byteLength(JSON.stringify(payload));
// }

onBeforeRequest();

const unmountListener = createAbortListener({
status: 0,
extra: gqlExtra,
onAbort: ({ signal }) => {
options.signal = signal;
},
resolve,
});

const httpRequest = httpClient.request(fullUrl, options, (response) => {
Expand Down Expand Up @@ -89,7 +101,6 @@ export const adapter: GraphQLAdapterType = async (request, requestId) => {
error: errors,
status: statusCode,
extra: { headers: response.headers as Record<string, string>, extensions: extensions ?? {} },
resolve,
});
} else {
// delay to finish after onabort/ontimeout
Expand All @@ -102,7 +113,6 @@ export const adapter: GraphQLAdapterType = async (request, requestId) => {
error,
status: statusCode,
extra: { headers: response.headers as Record<string, string>, extensions: extensions ?? {} },
resolve,
});
}

Expand All @@ -111,11 +121,11 @@ export const adapter: GraphQLAdapterType = async (request, requestId) => {
});
});

httpRequest.on("timeout", () => onTimeoutError({ status: 0, extra: gqlExtra, resolve }));
httpRequest.on("error", (error) => onError({ error, status: 0, extra: gqlExtra, resolve }));
httpRequest.on("timeout", () => onTimeoutError({ status: 0, extra: gqlExtra }));
httpRequest.on("error", (error) => onError({ error, status: 0, extra: gqlExtra }));
if (payload) {
httpRequest.write(payload);
}
httpRequest.end();
});
};
},
);

0 comments on commit 8b00993

Please sign in to comment.