@graphql-tools/url-loader 7.12.2-alpha-f0df17df.0 → 7.12.2

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.
@@ -1,4 +1,4 @@
1
- import { fetch } from 'cross-undici-fetch';
1
+ import { fetch } from '@whatwg-node/fetch';
2
2
  export const defaultAsyncFetch = async (input, init) => {
3
3
  return fetch(input, init);
4
4
  };
package/esm/index.js CHANGED
@@ -13,7 +13,7 @@ import { defaultSyncFetch } from './defaultSyncFetch.js';
13
13
  import { handleMultipartMixedResponse } from './handleMultipartMixedResponse.js';
14
14
  import { handleEventStreamResponse } from './event-stream/handleEventStreamResponse.js';
15
15
  import { addCancelToResponseStream } from './addCancelToResponseStream.js';
16
- import { AbortController, FormData, File } from 'cross-undici-fetch';
16
+ import { AbortController, FormData, File } from '@whatwg-node/fetch';
17
17
  import { isBlob, isGraphQLUpload, isPromiseLike, LEGACY_WS } from './utils.js';
18
18
  const asyncImport = (moduleName) => import(moduleName);
19
19
  const syncImport = (moduleName) => require(moduleName);
package/package.json CHANGED
@@ -1,18 +1,18 @@
1
1
  {
2
2
  "name": "@graphql-tools/url-loader",
3
- "version": "7.12.2-alpha-f0df17df.0",
3
+ "version": "7.12.2",
4
4
  "description": "A set of utils for faster development of GraphQL tools",
5
5
  "sideEffects": false,
6
6
  "peerDependencies": {
7
7
  "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0"
8
8
  },
9
9
  "dependencies": {
10
- "@graphql-tools/delegate": "9.0.0-alpha-f0df17df.0",
10
+ "@graphql-tools/delegate": "8.8.0",
11
11
  "@graphql-tools/utils": "8.8.0",
12
- "@graphql-tools/wrap": "9.0.0-alpha-f0df17df.0",
12
+ "@graphql-tools/wrap": "8.5.0",
13
13
  "@n1ru4l/graphql-live-query": "^0.9.0",
14
14
  "@types/ws": "^8.0.0",
15
- "cross-undici-fetch": "^0.4.11",
15
+ "@whatwg-node/fetch": "^0.0.2",
16
16
  "dset": "^3.1.2",
17
17
  "extract-files": "^11.0.0",
18
18
  "graphql-ws": "^5.4.1",
@@ -1,3 +1,3 @@
1
- import { fetch } from 'cross-undici-fetch';
1
+ import { fetch } from '@whatwg-node/fetch';
2
2
  export declare type AsyncFetchFn = typeof fetch;
3
3
  export declare const defaultAsyncFetch: AsyncFetchFn;
@@ -1,12 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.addCancelToResponseStream = void 0;
4
- const utils_1 = require("@graphql-tools/utils");
5
- function addCancelToResponseStream(resultStream, controller) {
6
- return (0, utils_1.withCancel)(resultStream, () => {
7
- if (!controller.signal.aborted) {
8
- controller.abort();
9
- }
10
- });
11
- }
12
- exports.addCancelToResponseStream = addCancelToResponseStream;
@@ -1,8 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.defaultAsyncFetch = void 0;
4
- const cross_undici_fetch_1 = require("cross-undici-fetch");
5
- const defaultAsyncFetch = async (input, init) => {
6
- return (0, cross_undici_fetch_1.fetch)(input, init);
7
- };
8
- exports.defaultAsyncFetch = defaultAsyncFetch;
@@ -1,15 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.defaultSyncFetch = void 0;
4
- const tslib_1 = require("tslib");
5
- const sync_fetch_1 = tslib_1.__importDefault(require("sync-fetch"));
6
- const defaultSyncFetch = (input, init) => {
7
- if (typeof input === 'string') {
8
- init === null || init === void 0 ? true : delete init.signal;
9
- }
10
- else {
11
- delete input.signal;
12
- }
13
- return (0, sync_fetch_1.default)(input, init);
14
- };
15
- exports.defaultSyncFetch = defaultSyncFetch;
@@ -1,18 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.handleEventStreamResponse = void 0;
4
- const utils_1 = require("@graphql-tools/utils");
5
- const handleReadable_js_1 = require("./handleReadable.js");
6
- const handleReadableStream_js_1 = require("./handleReadableStream.js");
7
- async function handleEventStreamResponse(response) {
8
- // node-fetch returns body as a promise so we need to resolve it
9
- const body = await response.body;
10
- if (body) {
11
- if ((0, utils_1.isAsyncIterable)(body)) {
12
- return (0, handleReadable_js_1.handleReadable)(body);
13
- }
14
- return (0, handleReadableStream_js_1.handleReadableStream)(body);
15
- }
16
- throw new Error('Response body is expected to be a readable stream but got; ' + (0, utils_1.inspect)(body));
17
- }
18
- exports.handleEventStreamResponse = handleEventStreamResponse;
@@ -1,31 +0,0 @@
1
- "use strict";
2
- /* eslint-disable no-labels */
3
- Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.handleReadable = void 0;
5
- let decodeUint8Array;
6
- if (globalThis.Buffer) {
7
- decodeUint8Array = uint8Array => globalThis.Buffer.from(uint8Array).toString('utf-8');
8
- }
9
- else {
10
- const textDecoder = new TextDecoder();
11
- decodeUint8Array = uint8Array => textDecoder.decode(uint8Array);
12
- }
13
- async function* handleReadable(readable) {
14
- outer: for await (const chunk of readable) {
15
- const chunkStr = typeof chunk === 'string' ? chunk : decodeUint8Array(chunk);
16
- for (const part of chunkStr.split('\n\n')) {
17
- if (part) {
18
- const eventStr = part.split('event: ')[1];
19
- const dataStr = part.split('data: ')[1];
20
- if (eventStr === 'complete') {
21
- break outer;
22
- }
23
- if (dataStr) {
24
- const data = JSON.parse(dataStr);
25
- yield data.payload || data;
26
- }
27
- }
28
- }
29
- }
30
- }
31
- exports.handleReadable = handleReadable;
@@ -1,131 +0,0 @@
1
- "use strict";
2
- // Based on https://github.com/Azure/fetch-event-source/blob/main/src/parse.ts
3
- Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.handleReadableStream = void 0;
5
- async function* handleReadableStream(stream) {
6
- const decoder = new TextDecoder();
7
- const reader = stream.getReader();
8
- let buffer;
9
- let position = 0; // current read position
10
- let fieldLength = -1; // length of the `field` portion of the line
11
- let discardTrailingNewline = false;
12
- try {
13
- let result;
14
- let message = {
15
- data: '',
16
- event: '',
17
- id: '',
18
- retry: undefined,
19
- };
20
- while (!(result = await reader.read()).done) {
21
- const arr = result.value;
22
- if (buffer === undefined) {
23
- buffer = arr;
24
- position = 0;
25
- fieldLength = -1;
26
- }
27
- else {
28
- // we're still parsing the old line. Append the new bytes into buffer:
29
- buffer = concat(buffer, arr);
30
- }
31
- const bufLength = buffer.length;
32
- let lineStart = 0; // index where the current line starts
33
- while (position < bufLength) {
34
- if (discardTrailingNewline) {
35
- if (buffer[position] === 10 /* ControlChars.NewLine */) {
36
- lineStart = ++position; // skip to next char
37
- }
38
- discardTrailingNewline = false;
39
- }
40
- // start looking forward till the end of line:
41
- let lineEnd = -1; // index of the \r or \n char
42
- for (; position < bufLength && lineEnd === -1; ++position) {
43
- switch (buffer[position]) {
44
- case 58 /* ControlChars.Colon */: {
45
- if (fieldLength === -1) {
46
- // first colon in line
47
- fieldLength = position - lineStart;
48
- }
49
- break;
50
- }
51
- case 13 /* ControlChars.CarriageReturn */: {
52
- discardTrailingNewline = true;
53
- break;
54
- }
55
- case 10 /* ControlChars.NewLine */: {
56
- lineEnd = position;
57
- break;
58
- }
59
- }
60
- }
61
- if (lineEnd === -1) {
62
- // We reached the end of the buffer but the line hasn't ended.
63
- // Wait for the next arr and then continue parsing:
64
- break;
65
- }
66
- // we've reached the line end, send it out:
67
- const line = buffer.subarray(lineStart, lineEnd);
68
- if (line.length === 0) {
69
- // empty line denotes end of message. Trigger the callback and start a new message:
70
- if (message.event || message.data) {
71
- // NOT a server ping (":\n\n")
72
- yield JSON.parse(message.data);
73
- message = {
74
- data: '',
75
- event: '',
76
- id: '',
77
- retry: undefined,
78
- };
79
- }
80
- }
81
- else if (fieldLength > 0) {
82
- // exclude comments and lines with no values
83
- // line is of format "<field>:<value>" or "<field>: <value>"
84
- // https://html.spec.whatwg.org/multipage/server-sent-events.html#event-stream-interpretation
85
- const field = decoder.decode(line.subarray(0, fieldLength));
86
- const valueOffset = fieldLength + (line[fieldLength + 1] === 32 /* ControlChars.Space */ ? 2 : 1);
87
- const value = decoder.decode(line.subarray(valueOffset));
88
- switch (field) {
89
- case 'data':
90
- // if this message already has data, append the new value to the old.
91
- // otherwise, just set to the new value:
92
- message.data = message.data ? message.data + '\n' + value : value; // otherwise,
93
- break;
94
- case 'event':
95
- message.event = value;
96
- break;
97
- case 'id':
98
- message.id = value;
99
- break;
100
- case 'retry': {
101
- const retry = parseInt(value, 10);
102
- message.retry = retry;
103
- break;
104
- }
105
- }
106
- }
107
- lineStart = position; // we're now on the next line
108
- fieldLength = -1;
109
- }
110
- if (lineStart === bufLength) {
111
- buffer = undefined; // we've finished reading it
112
- }
113
- else if (lineStart !== 0) {
114
- // Create a new view into buffer beginning at lineStart so we don't
115
- // need to copy over the previous lines when we get the new arr:
116
- buffer = buffer.subarray(lineStart);
117
- position -= lineStart;
118
- }
119
- }
120
- }
121
- finally {
122
- reader.releaseLock();
123
- }
124
- }
125
- exports.handleReadableStream = handleReadableStream;
126
- function concat(a, b) {
127
- const res = new Uint8Array(a.length + b.length);
128
- res.set(a);
129
- res.set(b, a.length);
130
- return res;
131
- }
@@ -1,52 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.handleMultipartMixedResponse = void 0;
4
- const node_1 = require("meros/node");
5
- const browser_1 = require("meros/browser");
6
- const utils_1 = require("@graphql-tools/utils");
7
- const merge_1 = require("dset/merge");
8
- function isIncomingMessage(body) {
9
- return body != null && typeof body === 'object' && 'pipe' in body;
10
- }
11
- async function handleMultipartMixedResponse(response) {
12
- const body = await response.body;
13
- const contentType = response.headers.get('content-type') || '';
14
- let asyncIterator;
15
- if (isIncomingMessage(body)) {
16
- // Meros/node expects headers as an object map with the content-type prop
17
- body.headers = {
18
- 'content-type': contentType,
19
- };
20
- // And it expects `IncomingMessage` and `node-fetch` returns `body` as `Promise<PassThrough>`
21
- asyncIterator = (await (0, node_1.meros)(body));
22
- }
23
- else {
24
- // Nothing is needed for regular `Response`.
25
- asyncIterator = (await (0, browser_1.meros)(response));
26
- }
27
- const executionResult = {};
28
- return (0, utils_1.mapAsyncIterator)(asyncIterator, (part) => {
29
- if (part.json) {
30
- const chunk = part.body;
31
- if (chunk.path) {
32
- if (chunk.data) {
33
- const path = ['data'];
34
- (0, merge_1.dset)(executionResult, path.concat(chunk.path), chunk.data);
35
- }
36
- if (chunk.errors) {
37
- executionResult.errors = (executionResult.errors || []).concat(chunk.errors);
38
- }
39
- }
40
- else {
41
- if (chunk.data) {
42
- executionResult.data = chunk.data;
43
- }
44
- if (chunk.errors) {
45
- executionResult.errors = chunk.errors;
46
- }
47
- }
48
- return executionResult;
49
- }
50
- });
51
- }
52
- exports.handleMultipartMixedResponse = handleMultipartMixedResponse;
package/cjs/index.js DELETED
@@ -1,612 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.UrlLoader = exports.SubscriptionProtocol = void 0;
4
- const tslib_1 = require("tslib");
5
- /* eslint-disable no-case-declarations */
6
- /// <reference lib="dom" />
7
- const graphql_1 = require("graphql");
8
- const utils_1 = require("@graphql-tools/utils");
9
- const wrap_1 = require("@graphql-tools/wrap");
10
- const graphql_ws_1 = require("graphql-ws");
11
- const isomorphic_ws_1 = tslib_1.__importDefault(require("isomorphic-ws"));
12
- const extract_files_1 = require("extract-files");
13
- const value_or_promise_1 = require("value-or-promise");
14
- const graphql_live_query_1 = require("@n1ru4l/graphql-live-query");
15
- const defaultAsyncFetch_js_1 = require("./defaultAsyncFetch.js");
16
- const defaultSyncFetch_js_1 = require("./defaultSyncFetch.js");
17
- const handleMultipartMixedResponse_js_1 = require("./handleMultipartMixedResponse.js");
18
- const handleEventStreamResponse_js_1 = require("./event-stream/handleEventStreamResponse.js");
19
- const addCancelToResponseStream_js_1 = require("./addCancelToResponseStream.js");
20
- const cross_undici_fetch_1 = require("cross-undici-fetch");
21
- const utils_js_1 = require("./utils.js");
22
- const asyncImport = (moduleName) => Promise.resolve().then(() => tslib_1.__importStar(require(moduleName)));
23
- const syncImport = (moduleName) => require(moduleName);
24
- var SubscriptionProtocol;
25
- (function (SubscriptionProtocol) {
26
- SubscriptionProtocol["WS"] = "WS";
27
- /**
28
- * Use legacy web socket protocol `graphql-ws` instead of the more current standard `graphql-transport-ws`
29
- */
30
- SubscriptionProtocol["LEGACY_WS"] = "LEGACY_WS";
31
- /**
32
- * Use SSE for subscription instead of WebSocket
33
- */
34
- SubscriptionProtocol["SSE"] = "SSE";
35
- /**
36
- * Use `graphql-sse` for subscriptions
37
- */
38
- SubscriptionProtocol["GRAPHQL_SSE"] = "GRAPHQL_SSE";
39
- })(SubscriptionProtocol = exports.SubscriptionProtocol || (exports.SubscriptionProtocol = {}));
40
- function isCompatibleUri(uri) {
41
- try {
42
- // eslint-disable-next-line no-new
43
- new URL(uri);
44
- return true;
45
- }
46
- catch (_a) {
47
- return false;
48
- }
49
- }
50
- /**
51
- * This loader loads a schema from a URL. The loaded schema is a fully-executable,
52
- * remote schema since it's created using [@graphql-tools/wrap](/docs/remote-schemas).
53
- *
54
- * ```
55
- * const schema = await loadSchema('http://localhost:3000/graphql', {
56
- * loaders: [
57
- * new UrlLoader(),
58
- * ]
59
- * });
60
- * ```
61
- */
62
- class UrlLoader {
63
- createFormDataFromVariables({ query, variables, operationName, extensions, }) {
64
- const vars = Object.assign({}, variables);
65
- const { clone, files } = (0, extract_files_1.extractFiles)(vars, 'variables', ((v) => (0, extract_files_1.isExtractableFile)(v) ||
66
- (v === null || v === void 0 ? void 0 : v.promise) ||
67
- (0, utils_1.isAsyncIterable)(v) ||
68
- (v === null || v === void 0 ? void 0 : v.then) ||
69
- typeof (v === null || v === void 0 ? void 0 : v.arrayBuffer) === 'function'));
70
- const map = {};
71
- const uploads = [];
72
- let currIndex = 0;
73
- for (const [file, curr] of files) {
74
- map[currIndex] = curr;
75
- uploads[currIndex] = file;
76
- currIndex++;
77
- }
78
- const form = new cross_undici_fetch_1.FormData();
79
- form.append('operations', JSON.stringify({
80
- query,
81
- variables: clone,
82
- operationName,
83
- extensions,
84
- }));
85
- form.append('map', JSON.stringify(map));
86
- function handleUpload(upload, i) {
87
- const indexStr = i.toString();
88
- if (upload != null) {
89
- const filename = upload.filename || upload.name || upload.path || `blob-${indexStr}`;
90
- if ((0, utils_js_1.isPromiseLike)(upload)) {
91
- return upload.then((resolvedUpload) => handleUpload(resolvedUpload, i));
92
- // If Blob
93
- }
94
- else if ((0, utils_js_1.isBlob)(upload)) {
95
- return upload.arrayBuffer().then((arrayBuffer) => {
96
- form.append(indexStr, new cross_undici_fetch_1.File([arrayBuffer], filename, { type: upload.type }), filename);
97
- });
98
- }
99
- else if ((0, utils_js_1.isGraphQLUpload)(upload)) {
100
- const stream = upload.createReadStream();
101
- const chunks = [];
102
- return Promise.resolve().then(async () => {
103
- for await (const chunk of stream) {
104
- if (chunk) {
105
- chunks.push(...chunk);
106
- }
107
- }
108
- const blobPart = new Uint8Array(chunks);
109
- form.append(indexStr, new cross_undici_fetch_1.File([blobPart], filename, { type: upload.mimetype }), filename);
110
- });
111
- }
112
- else {
113
- form.append(indexStr, new cross_undici_fetch_1.File([upload], filename), filename);
114
- }
115
- }
116
- }
117
- return value_or_promise_1.ValueOrPromise.all(uploads.map((upload, i) => new value_or_promise_1.ValueOrPromise(() => handleUpload(upload, i))))
118
- .then(() => form)
119
- .resolve();
120
- }
121
- prepareGETUrl({ baseUrl, query, variables, operationName, extensions, }) {
122
- const HTTP_URL = switchProtocols(baseUrl, {
123
- wss: 'https',
124
- ws: 'http',
125
- });
126
- const dummyHostname = 'https://dummyhostname.com';
127
- const validUrl = HTTP_URL.startsWith('http')
128
- ? HTTP_URL
129
- : HTTP_URL.startsWith('/')
130
- ? `${dummyHostname}${HTTP_URL}`
131
- : `${dummyHostname}/${HTTP_URL}`;
132
- const urlObj = new URL(validUrl);
133
- urlObj.searchParams.set('query', query);
134
- if (variables && Object.keys(variables).length > 0) {
135
- urlObj.searchParams.set('variables', JSON.stringify(variables));
136
- }
137
- if (operationName) {
138
- urlObj.searchParams.set('operationName', operationName);
139
- }
140
- if (extensions) {
141
- urlObj.searchParams.set('extensions', JSON.stringify(extensions));
142
- }
143
- const finalUrl = urlObj.toString().replace(dummyHostname, '');
144
- return finalUrl;
145
- }
146
- buildHTTPExecutor(initialEndpoint, fetch, options) {
147
- const defaultMethod = this.getDefaultMethodFromOptions(options === null || options === void 0 ? void 0 : options.method, 'POST');
148
- const HTTP_URL = switchProtocols(initialEndpoint, {
149
- wss: 'https',
150
- ws: 'http',
151
- });
152
- const executor = (request) => {
153
- var _a, _b;
154
- const controller = new cross_undici_fetch_1.AbortController();
155
- let method = defaultMethod;
156
- const operationAst = (0, utils_1.getOperationASTFromRequest)(request);
157
- const operationType = operationAst.operation;
158
- if ((options === null || options === void 0 ? void 0 : options.useGETForQueries) && operationType === 'query') {
159
- method = 'GET';
160
- }
161
- let accept = 'application/json, multipart/mixed';
162
- if (operationType === 'subscription' || (0, graphql_live_query_1.isLiveQueryOperationDefinitionNode)(operationAst)) {
163
- method = 'GET';
164
- accept = 'text/event-stream';
165
- }
166
- const endpoint = ((_a = request.extensions) === null || _a === void 0 ? void 0 : _a.endpoint) || HTTP_URL;
167
- const headers = Object.assign({
168
- accept,
169
- }, options === null || options === void 0 ? void 0 : options.headers, ((_b = request.extensions) === null || _b === void 0 ? void 0 : _b.headers) || {});
170
- const query = (0, graphql_1.print)(request.document);
171
- const requestBody = {
172
- query,
173
- variables: request.variables,
174
- operationName: request.operationName,
175
- extensions: request.extensions,
176
- };
177
- let timeoutId;
178
- if (options === null || options === void 0 ? void 0 : options.timeout) {
179
- timeoutId = setTimeout(() => {
180
- if (!controller.signal.aborted) {
181
- controller.abort();
182
- }
183
- }, options.timeout);
184
- }
185
- const credentials = (options === null || options === void 0 ? void 0 : options.credentials) !== 'disable' ? (options === null || options === void 0 ? void 0 : options.credentials) || 'same-origin' : null;
186
- return new value_or_promise_1.ValueOrPromise(() => {
187
- switch (method) {
188
- case 'GET':
189
- const finalUrl = this.prepareGETUrl({
190
- baseUrl: endpoint,
191
- ...requestBody,
192
- });
193
- return fetch(finalUrl, {
194
- method: 'GET',
195
- ...(credentials != null ? { credentials } : {}),
196
- headers,
197
- signal: controller.signal,
198
- });
199
- case 'POST':
200
- if (options === null || options === void 0 ? void 0 : options.multipart) {
201
- return new value_or_promise_1.ValueOrPromise(() => this.createFormDataFromVariables(requestBody))
202
- .then(form => fetch(endpoint, {
203
- method: 'POST',
204
- ...(credentials != null ? { credentials } : {}),
205
- body: form,
206
- headers,
207
- signal: controller.signal,
208
- }))
209
- .resolve();
210
- }
211
- else {
212
- return fetch(endpoint, {
213
- method: 'POST',
214
- ...(credentials != null ? { credentials } : {}),
215
- body: JSON.stringify(requestBody),
216
- headers: {
217
- 'content-type': 'application/json',
218
- ...headers,
219
- },
220
- signal: controller.signal,
221
- });
222
- }
223
- }
224
- })
225
- .then((fetchResult) => {
226
- if (timeoutId != null) {
227
- clearTimeout(timeoutId);
228
- }
229
- // Retry should respect HTTP Errors
230
- if ((options === null || options === void 0 ? void 0 : options.retry) != null && !fetchResult.status.toString().startsWith('2')) {
231
- throw new Error(fetchResult.statusText || `HTTP Error: ${fetchResult.status}`);
232
- }
233
- const contentType = fetchResult.headers.get('content-type');
234
- if (contentType === null || contentType === void 0 ? void 0 : contentType.includes('text/event-stream')) {
235
- return (0, handleEventStreamResponse_js_1.handleEventStreamResponse)(fetchResult).then(resultStream => (0, addCancelToResponseStream_js_1.addCancelToResponseStream)(resultStream, controller));
236
- }
237
- else if (contentType === null || contentType === void 0 ? void 0 : contentType.includes('multipart/mixed')) {
238
- return (0, handleMultipartMixedResponse_js_1.handleMultipartMixedResponse)(fetchResult).then(resultStream => (0, addCancelToResponseStream_js_1.addCancelToResponseStream)(resultStream, controller));
239
- }
240
- return fetchResult.text();
241
- })
242
- .then(result => {
243
- if (typeof result === 'string') {
244
- if (result) {
245
- return JSON.parse(result);
246
- }
247
- }
248
- else {
249
- return result;
250
- }
251
- })
252
- .resolve();
253
- };
254
- if ((options === null || options === void 0 ? void 0 : options.retry) != null) {
255
- return function retryExecutor(request) {
256
- let result;
257
- let error;
258
- let attempt = 0;
259
- function retryAttempt() {
260
- attempt++;
261
- if (attempt > options.retry) {
262
- if (result != null) {
263
- return result;
264
- }
265
- if (error != null) {
266
- throw error;
267
- }
268
- throw new Error('No result');
269
- }
270
- return new value_or_promise_1.ValueOrPromise(() => executor(request))
271
- .then(res => {
272
- var _a;
273
- result = res;
274
- if ((_a = result === null || result === void 0 ? void 0 : result.errors) === null || _a === void 0 ? void 0 : _a.length) {
275
- return retryAttempt();
276
- }
277
- return result;
278
- })
279
- .catch((e) => {
280
- error = e;
281
- return retryAttempt();
282
- })
283
- .resolve();
284
- }
285
- return retryAttempt();
286
- };
287
- }
288
- return executor;
289
- }
290
- buildWSExecutor(subscriptionsEndpoint, webSocketImpl, connectionParams) {
291
- const WS_URL = switchProtocols(subscriptionsEndpoint, {
292
- https: 'wss',
293
- http: 'ws',
294
- });
295
- const subscriptionClient = (0, graphql_ws_1.createClient)({
296
- url: WS_URL,
297
- webSocketImpl,
298
- connectionParams,
299
- lazy: true,
300
- });
301
- return ({ document, variables, operationName, extensions }) => {
302
- const query = (0, graphql_1.print)(document);
303
- return (0, utils_1.observableToAsyncIterable)({
304
- subscribe: observer => {
305
- const unsubscribe = subscriptionClient.subscribe({
306
- query,
307
- variables: variables,
308
- operationName,
309
- extensions,
310
- }, observer);
311
- return {
312
- unsubscribe,
313
- };
314
- },
315
- });
316
- };
317
- }
318
- buildWSLegacyExecutor(subscriptionsEndpoint, WebSocketImpl, options) {
319
- const WS_URL = switchProtocols(subscriptionsEndpoint, {
320
- https: 'wss',
321
- http: 'ws',
322
- });
323
- const observerById = new Map();
324
- let websocket = null;
325
- const ensureWebsocket = () => {
326
- websocket = new WebSocketImpl(WS_URL, 'graphql-ws', {
327
- followRedirects: true,
328
- headers: options === null || options === void 0 ? void 0 : options.headers,
329
- rejectUnauthorized: false,
330
- skipUTF8Validation: true,
331
- });
332
- websocket.onopen = () => {
333
- let payload = {};
334
- switch (typeof (options === null || options === void 0 ? void 0 : options.connectionParams)) {
335
- case 'function':
336
- payload = options === null || options === void 0 ? void 0 : options.connectionParams();
337
- break;
338
- case 'object':
339
- payload = options === null || options === void 0 ? void 0 : options.connectionParams;
340
- break;
341
- }
342
- websocket.send(JSON.stringify({
343
- type: utils_js_1.LEGACY_WS.CONNECTION_INIT,
344
- payload,
345
- }));
346
- };
347
- };
348
- const cleanupWebsocket = () => {
349
- if (websocket != null && observerById.size === 0) {
350
- websocket.send(JSON.stringify({
351
- type: utils_js_1.LEGACY_WS.CONNECTION_TERMINATE,
352
- }));
353
- websocket.terminate();
354
- websocket = null;
355
- }
356
- };
357
- return function legacyExecutor(request) {
358
- const id = Date.now().toString();
359
- return (0, utils_1.observableToAsyncIterable)({
360
- subscribe(observer) {
361
- ensureWebsocket();
362
- if (websocket == null) {
363
- throw new Error(`WebSocket connection is not found!`);
364
- }
365
- websocket.onmessage = event => {
366
- const data = JSON.parse(event.data.toString('utf-8'));
367
- switch (data.type) {
368
- case utils_js_1.LEGACY_WS.CONNECTION_ACK: {
369
- if (websocket == null) {
370
- throw new Error(`WebSocket connection is not found!`);
371
- }
372
- websocket.send(JSON.stringify({
373
- type: utils_js_1.LEGACY_WS.START,
374
- id,
375
- payload: {
376
- query: (0, graphql_1.print)(request.document),
377
- variables: request.variables,
378
- operationName: request.operationName,
379
- },
380
- }));
381
- break;
382
- }
383
- case utils_js_1.LEGACY_WS.CONNECTION_ERROR: {
384
- observer.error(data.payload);
385
- break;
386
- }
387
- case utils_js_1.LEGACY_WS.CONNECTION_KEEP_ALIVE: {
388
- break;
389
- }
390
- case utils_js_1.LEGACY_WS.DATA: {
391
- observer.next(data.payload);
392
- break;
393
- }
394
- case utils_js_1.LEGACY_WS.COMPLETE: {
395
- if (websocket == null) {
396
- throw new Error(`WebSocket connection is not found!`);
397
- }
398
- websocket.send(JSON.stringify({
399
- type: utils_js_1.LEGACY_WS.CONNECTION_TERMINATE,
400
- }));
401
- observer.complete();
402
- cleanupWebsocket();
403
- break;
404
- }
405
- }
406
- };
407
- return {
408
- unsubscribe: () => {
409
- websocket === null || websocket === void 0 ? void 0 : websocket.send(JSON.stringify({
410
- type: utils_js_1.LEGACY_WS.STOP,
411
- id,
412
- }));
413
- cleanupWebsocket();
414
- },
415
- };
416
- },
417
- });
418
- };
419
- }
420
- getFetch(customFetch, importFn) {
421
- if (customFetch) {
422
- if (typeof customFetch === 'string') {
423
- const [moduleName, fetchFnName] = customFetch.split('#');
424
- return new value_or_promise_1.ValueOrPromise(() => importFn(moduleName))
425
- .then(module => (fetchFnName ? module[fetchFnName] : module))
426
- .resolve();
427
- }
428
- else if (typeof customFetch === 'function') {
429
- return customFetch;
430
- }
431
- }
432
- if (importFn === asyncImport) {
433
- return defaultAsyncFetch_js_1.defaultAsyncFetch;
434
- }
435
- else {
436
- return defaultSyncFetch_js_1.defaultSyncFetch;
437
- }
438
- }
439
- getDefaultMethodFromOptions(method, defaultMethod) {
440
- if (method) {
441
- defaultMethod = method;
442
- }
443
- return defaultMethod;
444
- }
445
- getWebSocketImpl(importFn, options) {
446
- if (typeof (options === null || options === void 0 ? void 0 : options.webSocketImpl) === 'string') {
447
- const [moduleName, webSocketImplName] = options.webSocketImpl.split('#');
448
- return new value_or_promise_1.ValueOrPromise(() => importFn(moduleName))
449
- .then(importedModule => (webSocketImplName ? importedModule[webSocketImplName] : importedModule))
450
- .resolve();
451
- }
452
- else {
453
- const websocketImpl = (options === null || options === void 0 ? void 0 : options.webSocketImpl) || isomorphic_ws_1.default;
454
- return websocketImpl;
455
- }
456
- }
457
- buildSubscriptionExecutor(subscriptionsEndpoint, fetch, importFn, options) {
458
- if ((options === null || options === void 0 ? void 0 : options.subscriptionsProtocol) === SubscriptionProtocol.SSE) {
459
- return this.buildHTTPExecutor(subscriptionsEndpoint, fetch, options);
460
- }
461
- else if ((options === null || options === void 0 ? void 0 : options.subscriptionsProtocol) === SubscriptionProtocol.GRAPHQL_SSE) {
462
- if (!(options === null || options === void 0 ? void 0 : options.subscriptionsEndpoint)) {
463
- // when no custom subscriptions endpoint is specified,
464
- // graphql-sse is recommended to be used on `/graphql/stream`
465
- subscriptionsEndpoint += '/stream';
466
- }
467
- return this.buildHTTPExecutor(subscriptionsEndpoint, fetch, options);
468
- }
469
- else {
470
- const webSocketImpl$ = new value_or_promise_1.ValueOrPromise(() => this.getWebSocketImpl(importFn, options));
471
- const executor$ = webSocketImpl$.then(webSocketImpl => {
472
- if ((options === null || options === void 0 ? void 0 : options.subscriptionsProtocol) === SubscriptionProtocol.LEGACY_WS) {
473
- return this.buildWSLegacyExecutor(subscriptionsEndpoint, webSocketImpl, options);
474
- }
475
- else {
476
- return this.buildWSExecutor(subscriptionsEndpoint, webSocketImpl, options === null || options === void 0 ? void 0 : options.connectionParams);
477
- }
478
- });
479
- return request => executor$.then(executor => executor(request)).resolve();
480
- }
481
- }
482
- getExecutor(endpoint, importFn, options) {
483
- const fetch$ = new value_or_promise_1.ValueOrPromise(() => this.getFetch(options === null || options === void 0 ? void 0 : options.customFetch, importFn));
484
- const httpExecutor$ = fetch$.then(fetch => {
485
- return this.buildHTTPExecutor(endpoint, fetch, options);
486
- });
487
- if ((options === null || options === void 0 ? void 0 : options.subscriptionsEndpoint) != null || (options === null || options === void 0 ? void 0 : options.subscriptionsProtocol) !== SubscriptionProtocol.SSE) {
488
- const subscriptionExecutor$ = fetch$.then(fetch => {
489
- const subscriptionsEndpoint = (options === null || options === void 0 ? void 0 : options.subscriptionsEndpoint) || endpoint;
490
- return this.buildSubscriptionExecutor(subscriptionsEndpoint, fetch, importFn, options);
491
- });
492
- // eslint-disable-next-line no-inner-declarations
493
- function getExecutorByRequest(request) {
494
- const operationAst = (0, utils_1.getOperationASTFromRequest)(request);
495
- if (operationAst.operation === 'subscription' ||
496
- (0, graphql_live_query_1.isLiveQueryOperationDefinitionNode)(operationAst, request.variables)) {
497
- return subscriptionExecutor$;
498
- }
499
- else {
500
- return httpExecutor$;
501
- }
502
- }
503
- return request => getExecutorByRequest(request)
504
- .then(executor => executor(request))
505
- .resolve();
506
- }
507
- else {
508
- return request => httpExecutor$.then(executor => executor(request)).resolve();
509
- }
510
- }
511
- getExecutorAsync(endpoint, options) {
512
- return this.getExecutor(endpoint, asyncImport, options);
513
- }
514
- getExecutorSync(endpoint, options) {
515
- return this.getExecutor(endpoint, syncImport, options);
516
- }
517
- handleSDL(pointer, fetch, options) {
518
- const defaultMethod = this.getDefaultMethodFromOptions(options === null || options === void 0 ? void 0 : options.method, 'GET');
519
- return new value_or_promise_1.ValueOrPromise(() => fetch(pointer, {
520
- method: defaultMethod,
521
- headers: options.headers,
522
- }))
523
- .then(response => response.text())
524
- .then(schemaString => (0, utils_1.parseGraphQLSDL)(pointer, schemaString, options))
525
- .resolve();
526
- }
527
- async load(pointer, options) {
528
- if (!isCompatibleUri(pointer)) {
529
- return [];
530
- }
531
- let source = {
532
- location: pointer,
533
- };
534
- let executor;
535
- if ((options === null || options === void 0 ? void 0 : options.handleAsSDL) || pointer.endsWith('.graphql') || pointer.endsWith('.graphqls')) {
536
- const fetch = await this.getFetch(options === null || options === void 0 ? void 0 : options.customFetch, asyncImport);
537
- source = await this.handleSDL(pointer, fetch, options);
538
- if (!source.schema && !source.document && !source.rawSDL) {
539
- throw new Error(`Invalid SDL response`);
540
- }
541
- source.schema =
542
- source.schema ||
543
- (source.document
544
- ? (0, graphql_1.buildASTSchema)(source.document, options)
545
- : source.rawSDL
546
- ? (0, graphql_1.buildSchema)(source.rawSDL, options)
547
- : undefined);
548
- }
549
- else {
550
- executor = this.getExecutorAsync(pointer, options);
551
- source.schema = await (0, wrap_1.introspectSchema)(executor, {}, options);
552
- }
553
- if (!source.schema) {
554
- throw new Error(`Invalid introspected schema`);
555
- }
556
- if (options === null || options === void 0 ? void 0 : options.endpoint) {
557
- executor = this.getExecutorAsync(options.endpoint, options);
558
- }
559
- if (executor) {
560
- source.schema = (0, wrap_1.wrapSchema)({
561
- schema: source.schema,
562
- executor,
563
- batch: options === null || options === void 0 ? void 0 : options.batch,
564
- });
565
- }
566
- return [source];
567
- }
568
- loadSync(pointer, options) {
569
- if (!isCompatibleUri(pointer)) {
570
- return [];
571
- }
572
- let source = {
573
- location: pointer,
574
- };
575
- let executor;
576
- if ((options === null || options === void 0 ? void 0 : options.handleAsSDL) || pointer.endsWith('.graphql') || pointer.endsWith('.graphqls')) {
577
- const fetch = this.getFetch(options === null || options === void 0 ? void 0 : options.customFetch, syncImport);
578
- source = this.handleSDL(pointer, fetch, options);
579
- if (!source.schema && !source.document && !source.rawSDL) {
580
- throw new Error(`Invalid SDL response`);
581
- }
582
- source.schema =
583
- source.schema ||
584
- (source.document
585
- ? (0, graphql_1.buildASTSchema)(source.document, options)
586
- : source.rawSDL
587
- ? (0, graphql_1.buildSchema)(source.rawSDL, options)
588
- : undefined);
589
- }
590
- else {
591
- executor = this.getExecutorSync(pointer, options);
592
- source.schema = (0, wrap_1.introspectSchema)(executor, {}, options);
593
- }
594
- if (!source.schema) {
595
- throw new Error(`Invalid introspected schema`);
596
- }
597
- if (options === null || options === void 0 ? void 0 : options.endpoint) {
598
- executor = this.getExecutorSync(options.endpoint, options);
599
- }
600
- if (executor) {
601
- source.schema = (0, wrap_1.wrapSchema)({
602
- schema: source.schema,
603
- executor,
604
- });
605
- }
606
- return [source];
607
- }
608
- }
609
- exports.UrlLoader = UrlLoader;
610
- function switchProtocols(pointer, protocolMap) {
611
- return Object.entries(protocolMap).reduce((prev, [source, target]) => prev.replace(`${source}://`, `${target}://`).replace(`${source}:\\`, `${target}:\\`), pointer);
612
- }
package/cjs/utils.js DELETED
@@ -1,28 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.LEGACY_WS = exports.isPromiseLike = exports.isGraphQLUpload = exports.isBlob = void 0;
4
- function isBlob(obj) {
5
- return typeof obj.arrayBuffer === 'function';
6
- }
7
- exports.isBlob = isBlob;
8
- function isGraphQLUpload(upload) {
9
- return typeof upload.createReadStream === 'function';
10
- }
11
- exports.isGraphQLUpload = isGraphQLUpload;
12
- function isPromiseLike(obj) {
13
- return typeof obj.then === 'function';
14
- }
15
- exports.isPromiseLike = isPromiseLike;
16
- var LEGACY_WS;
17
- (function (LEGACY_WS) {
18
- LEGACY_WS["CONNECTION_INIT"] = "connection_init";
19
- LEGACY_WS["CONNECTION_ACK"] = "connection_ack";
20
- LEGACY_WS["CONNECTION_ERROR"] = "connection_error";
21
- LEGACY_WS["CONNECTION_KEEP_ALIVE"] = "ka";
22
- LEGACY_WS["START"] = "start";
23
- LEGACY_WS["STOP"] = "stop";
24
- LEGACY_WS["CONNECTION_TERMINATE"] = "connection_terminate";
25
- LEGACY_WS["DATA"] = "data";
26
- LEGACY_WS["ERROR"] = "error";
27
- LEGACY_WS["COMPLETE"] = "complete";
28
- })(LEGACY_WS = exports.LEGACY_WS || (exports.LEGACY_WS = {}));