@hyper-fetch/graphql 7.5.3 → 8.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/{.eslintrc.json → .eslintrc copy.json } +1 -1
  2. package/.eslintrc.cjs +12 -0
  3. package/__tests__/e2e/e2e.graphql-server.ts +135 -0
  4. package/__tests__/e2e/e2e.graphql.spec.ts +486 -0
  5. package/__tests__/features/adapter/adapter.browser.spec.ts +110 -20
  6. package/__tests__/features/adapter/adapter.server.spec.ts +20 -27
  7. package/__tests__/features/adapter/adapter.utils.spec.ts +36 -3
  8. package/__tests__/request-module.d.ts +12 -0
  9. package/__tests__/shared/callbacks.shared.ts +3 -1
  10. package/__tests__/shared/progress.shared.ts +2 -1
  11. package/__tests__/tsconfig.json +13 -3
  12. package/__tests__/vitest.setup.ts +10 -0
  13. package/dist/adapter/adapter.constants.d.ts +4 -0
  14. package/dist/adapter/adapter.constants.d.ts.map +1 -0
  15. package/dist/adapter/adapter.d.ts +3 -0
  16. package/dist/adapter/adapter.d.ts.map +1 -0
  17. package/dist/adapter/adapter.types.d.ts +24 -0
  18. package/dist/adapter/adapter.types.d.ts.map +1 -0
  19. package/dist/adapter/adapter.utils.d.ts +9 -0
  20. package/dist/adapter/adapter.utils.d.ts.map +1 -0
  21. package/dist/adapter/http-adapter.fetch.d.ts +3 -0
  22. package/dist/adapter/http-adapter.fetch.d.ts.map +1 -0
  23. package/dist/adapter/index.d.ts +6 -0
  24. package/dist/adapter/index.d.ts.map +1 -0
  25. package/dist/index.d.ts +2 -34
  26. package/dist/index.d.ts.map +1 -0
  27. package/dist/index.mjs +183 -0
  28. package/dist/index.mjs.map +1 -0
  29. package/package.json +10 -25
  30. package/src/adapter/adapter.constants.ts +1 -1
  31. package/src/adapter/adapter.ts +3 -8
  32. package/src/adapter/adapter.types.ts +7 -3
  33. package/src/adapter/adapter.utils.ts +8 -3
  34. package/src/adapter/http-adapter.fetch.ts +186 -0
  35. package/src/adapter/index.ts +1 -0
  36. package/tsconfig.base.json +2 -6
  37. package/tsconfig.json +2 -6
  38. package/vite.config.ts +45 -0
  39. package/__tests__/global.d.ts +0 -1
  40. package/__tests__/jest.setup.ts +0 -1
  41. package/dist/browser/index.js +0 -191
  42. package/dist/browser/index.js.map +0 -7
  43. package/dist/index.js +0 -330
  44. package/dist/index.js.map +0 -7
  45. package/jest.config.ts +0 -6
  46. package/src/adapter/http-adapter.browser.ts +0 -148
  47. package/src/adapter/http-adapter.server.ts +0 -148
@@ -1,148 +0,0 @@
1
- import {
2
- getResponseHeaders,
3
- parseResponse,
4
- getErrorMessage,
5
- Adapter,
6
- QueryParamsType,
7
- stringifyKey,
8
- } from "@hyper-fetch/core";
9
-
10
- import {
11
- gqlExtra,
12
- GraphqlAdapterType,
13
- defaultTimeout,
14
- getRequestValues,
15
- GraphqlMethod,
16
- GraphQlExtraType,
17
- GraphQlEndpointType,
18
- gqlEndpointMapper,
19
- gqlEndpointNameMapper,
20
- } from "adapter";
21
-
22
- export const getGqlAdapter = (): GraphqlAdapterType =>
23
- new Adapter<
24
- Partial<XMLHttpRequest>,
25
- GraphqlMethod,
26
- number,
27
- GraphQlExtraType,
28
- QueryParamsType | string,
29
- undefined,
30
- GraphQlEndpointType
31
- >({
32
- name: "graphql-browser",
33
- defaultMethod: GraphqlMethod.POST,
34
- defaultExtra: gqlExtra,
35
- systemErrorStatus: 0,
36
- systemErrorExtra: gqlExtra,
37
- })
38
- .onInitialize(({ client }) => {
39
- client.setCacheKeyMapper((request) => {
40
- return `${request.method}_${gqlEndpointNameMapper(request.endpoint)}-${stringifyKey(request.params)}-${stringifyKey(request.queryParams)}`;
41
- });
42
- client.setQueryKeyMapper((request) => {
43
- return `${request.method}_${gqlEndpointNameMapper(request.endpoint)}-${stringifyKey(request.params)}-${stringifyKey(request.queryParams)}`;
44
- });
45
- client.setAbortKeyMapper((request) => {
46
- return `${request.method}_${gqlEndpointNameMapper(request.endpoint)}-${request.cancelable}`;
47
- });
48
- })
49
- .setInternalErrorMapping((error) => [error])
50
- .setDevtoolsEndpointGetter(gqlEndpointNameMapper)
51
- .setEndpointMapper(gqlEndpointMapper)
52
- .setFetcher(
53
- async ({
54
- request,
55
- adapterOptions,
56
- headers,
57
- onError,
58
- onResponseEnd,
59
- onTimeoutError,
60
- onRequestEnd,
61
- createAbortListener,
62
- onResponseProgress,
63
- onRequestProgress,
64
- onResponseStart,
65
- onBeforeRequest,
66
- onRequestStart,
67
- onSuccess,
68
- }) => {
69
- const { fullUrl, payload } = getRequestValues(request);
70
-
71
- const xhr = new XMLHttpRequest();
72
- xhr.timeout = defaultTimeout;
73
-
74
- const onAbort = () => xhr.abort();
75
-
76
- // Inject xhr options
77
- if (adapterOptions) {
78
- Object.entries(adapterOptions).forEach(([name, value]) => {
79
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
80
- // @ts-ignore
81
- xhr[name] = value;
82
- });
83
- }
84
-
85
- // Open connection
86
- xhr.open(request.method, fullUrl, true);
87
-
88
- // Set Headers
89
- Object.entries(headers).forEach(([name, value]) => xhr.setRequestHeader(name, value as string));
90
-
91
- // Listen to abort signal
92
- const unmountListener = createAbortListener({ status: 0, extra: gqlExtra, onAbort });
93
-
94
- // Request handlers
95
- xhr.upload.onprogress = onRequestProgress;
96
-
97
- // Response handlers
98
- xhr.onloadstart = (): void => {
99
- onRequestEnd();
100
- onResponseStart();
101
- };
102
-
103
- xhr.onprogress = onResponseProgress;
104
-
105
- xhr.onloadend = () => {
106
- onResponseEnd();
107
- unmountListener();
108
- };
109
-
110
- /* istanbul ignore next */
111
- xhr.ontimeout = () => onTimeoutError({ status: 0, extra: gqlExtra });
112
-
113
- // Data handler
114
- xhr.onreadystatechange = (e: Event) => {
115
- const event = e as unknown as ProgressEvent<XMLHttpRequest>;
116
- const finishedState = 4;
117
-
118
- if (event.target && event.target.readyState === finishedState) {
119
- const { status } = event.target;
120
- const response = parseResponse(event.target.response);
121
- const data = response.data ?? null;
122
- const errors = response?.errors || null;
123
- const extensions = response?.extensions || {};
124
- const failure = response?.errors || status > 399 || status === 0;
125
- const responseHeaders = getResponseHeaders(xhr.getAllResponseHeaders());
126
-
127
- if (failure) {
128
- const error = errors || [getErrorMessage()];
129
- // delay to finish after onabort/ontimeout
130
- onError({ error, status, extra: { headers: responseHeaders, extensions } });
131
- } else {
132
- onSuccess({
133
- data,
134
- error: errors,
135
- status,
136
- extra: { headers: responseHeaders, extensions },
137
- });
138
- }
139
- }
140
- };
141
-
142
- // Start request
143
- onBeforeRequest();
144
- onRequestStart();
145
-
146
- xhr.send(payload);
147
- },
148
- );
@@ -1,148 +0,0 @@
1
- import { Adapter, getErrorMessage, parseErrorResponse, parseResponse, QueryParamsType } from "@hyper-fetch/core";
2
- import http, { OutgoingHttpHeaders } from "http";
3
- import https from "https";
4
-
5
- import {
6
- gqlExtra,
7
- defaultTimeout,
8
- GraphqlAdapterType,
9
- getRequestValues,
10
- GraphQlExtraType,
11
- GraphqlMethod,
12
- GraphQlEndpointType,
13
- gqlEndpointMapper,
14
- gqlEndpointNameMapper,
15
- } from "adapter";
16
-
17
- export const getGqlAdapter = (): GraphqlAdapterType =>
18
- new Adapter<
19
- Partial<XMLHttpRequest>,
20
- GraphqlMethod,
21
- number,
22
- GraphQlExtraType,
23
- QueryParamsType | string,
24
- undefined,
25
- GraphQlEndpointType
26
- >({
27
- name: "graphql-server",
28
- defaultMethod: GraphqlMethod.POST,
29
- defaultExtra: gqlExtra,
30
- systemErrorStatus: 0,
31
- systemErrorExtra: gqlExtra,
32
- })
33
- .onInitialize(({ client }) => {
34
- client.setCacheKeyMapper((request) => {
35
- return `${request.method}_${gqlEndpointNameMapper(request.endpoint)}-${JSON.stringify(request.params)}-${JSON.stringify(request.queryParams)}`;
36
- });
37
- client.setQueryKeyMapper((request) => {
38
- return `${request.method}_${gqlEndpointNameMapper(request.endpoint)}-${JSON.stringify(request.params)}-${JSON.stringify(request.queryParams)}`;
39
- });
40
- client.setAbortKeyMapper((request) => {
41
- return `${request.method}_${gqlEndpointNameMapper(request.endpoint)}-${request.cancelable}`;
42
- });
43
- })
44
- .setInternalErrorMapping((error) => [error])
45
- .setDevtoolsEndpointGetter(gqlEndpointNameMapper)
46
- .setEndpointMapper(gqlEndpointMapper)
47
- .setFetcher(
48
- async ({
49
- request,
50
- adapterOptions,
51
- headers,
52
- onError,
53
- onResponseEnd,
54
- onTimeoutError,
55
- onRequestEnd,
56
- createAbortListener,
57
- getAbortController,
58
- onResponseProgress,
59
- onResponseStart,
60
- onBeforeRequest,
61
- onRequestStart,
62
- onSuccess,
63
- }) => {
64
- const { fullUrl, payload } = getRequestValues(request);
65
-
66
- const httpClient = request.client.url.includes("https://") ? https : http;
67
- const options = {
68
- method: request.method,
69
- headers: headers as OutgoingHttpHeaders,
70
- timeout: defaultTimeout,
71
- signal: getAbortController()?.signal,
72
- } satisfies https.RequestOptions;
73
-
74
- Object.entries(adapterOptions || {}).forEach(([name, value]) => {
75
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
76
- // @ts-ignore
77
- options[name] = value;
78
- });
79
-
80
- onBeforeRequest();
81
-
82
- const unmountListener = createAbortListener({
83
- status: 0,
84
- extra: gqlExtra,
85
- });
86
-
87
- const httpRequest = httpClient.request(fullUrl, options, (response) => {
88
- response.setEncoding("utf8");
89
-
90
- let chunks = "";
91
- const totalDownloadBytes = Number(response.headers["content-length"]);
92
- let downloadedBytes = 0;
93
-
94
- onRequestStart();
95
-
96
- response.on("data", (chunk) => {
97
- /* istanbul ignore next */
98
- if (!chunks) {
99
- onRequestEnd();
100
- onResponseStart();
101
- }
102
- downloadedBytes += chunk.length;
103
- chunks += chunk;
104
- onResponseProgress({ total: totalDownloadBytes, loaded: downloadedBytes });
105
- });
106
-
107
- response.on("end", () => {
108
- /* istanbul ignore next */
109
- const { statusCode = 0 } = response;
110
- const success = String(statusCode).startsWith("2") || String(statusCode).startsWith("3");
111
-
112
- if (success) {
113
- const { data, errors, extensions } = parseResponse(chunks);
114
- onSuccess({
115
- data: data ?? null,
116
- error: errors,
117
- status: statusCode,
118
- extra: { headers: response.headers as Record<string, string>, extensions: extensions ?? {} },
119
- });
120
- } else {
121
- // delay to finish after onabort/ontimeout
122
- const result = parseErrorResponse(chunks);
123
- /* istanbul ignore next */
124
- const error = "errors" in result ? result.errors : null;
125
- /* istanbul ignore next */
126
- const extensions = "extensions" in result ? result.extensions : {};
127
-
128
- onError({
129
- error: error ?? [getErrorMessage()],
130
- status: statusCode,
131
- extra: { headers: response.headers as Record<string, string>, extensions },
132
- });
133
- }
134
-
135
- unmountListener();
136
- onResponseEnd();
137
- });
138
- });
139
-
140
- /* istanbul ignore next */
141
- httpRequest.on("timeout", () => onTimeoutError({ status: 0, extra: gqlExtra }));
142
- httpRequest.on("error", (error) => onError({ error, status: 0, extra: gqlExtra }));
143
- if (payload) {
144
- httpRequest.write(payload);
145
- }
146
- httpRequest.end();
147
- },
148
- );