@graphql-tools/executor-http 1.1.9 → 1.1.10-alpha-e8c01415b3b19676af5ff8b818bc152e3293f9e4
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.
- package/CHANGELOG.md +480 -0
- package/dist/index.cjs +546 -0
- package/{typings → dist}/index.d.cts +28 -25
- package/{typings → dist}/index.d.ts +28 -25
- package/dist/index.js +543 -0
- package/package.json +38 -46
- package/cjs/createFormDataFromVariables.js +0 -76
- package/cjs/createTimeoutSignal.js +0 -1
- package/cjs/defaultPrintFn.js +0 -14
- package/cjs/handleEventStreamResponse.js +0 -55
- package/cjs/handleMultipartMixedResponse.js +0 -48
- package/cjs/index.js +0 -314
- package/cjs/isGraphQLUpload.js +0 -7
- package/cjs/isLiveQueryOperationDefinitionNode.js +0 -8
- package/cjs/package.json +0 -1
- package/cjs/prepareGETUrl.js +0 -26
- package/esm/createFormDataFromVariables.js +0 -72
- package/esm/createTimeoutSignal.js +0 -1
- package/esm/defaultPrintFn.js +0 -10
- package/esm/handleEventStreamResponse.js +0 -50
- package/esm/handleMultipartMixedResponse.js +0 -44
- package/esm/index.js +0 -310
- package/esm/isGraphQLUpload.js +0 -3
- package/esm/isLiveQueryOperationDefinitionNode.js +0 -5
- package/esm/prepareGETUrl.js +0 -22
- package/typings/createFormDataFromVariables.d.cts +0 -10
- package/typings/createFormDataFromVariables.d.ts +0 -10
- package/typings/createTimeoutSignal.d.cts +0 -0
- package/typings/createTimeoutSignal.d.ts +0 -0
- package/typings/defaultPrintFn.d.cts +0 -2
- package/typings/defaultPrintFn.d.ts +0 -2
- package/typings/handleEventStreamResponse.d.cts +0 -4
- package/typings/handleEventStreamResponse.d.ts +0 -4
- package/typings/handleMultipartMixedResponse.d.cts +0 -2
- package/typings/handleMultipartMixedResponse.d.ts +0 -2
- package/typings/isGraphQLUpload.d.cts +0 -9
- package/typings/isGraphQLUpload.d.ts +0 -9
- package/typings/isLiveQueryOperationDefinitionNode.d.cts +0 -2
- package/typings/isLiveQueryOperationDefinitionNode.d.ts +0 -2
- package/typings/prepareGETUrl.d.cts +0 -7
- package/typings/prepareGETUrl.d.ts +0 -7
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
import { extractFiles, isExtractableFile } from 'extract-files';
|
|
2
|
-
import { ValueOrPromise } from 'value-or-promise';
|
|
3
|
-
import { isAsyncIterable, isPromise } from '@graphql-tools/utils';
|
|
4
|
-
import { File as DefaultFile, FormData as DefaultFormData } from '@whatwg-node/fetch';
|
|
5
|
-
import { isGraphQLUpload } from './isGraphQLUpload.js';
|
|
6
|
-
export function createFormDataFromVariables({ query, variables, operationName, extensions, }, { File: FileCtor = DefaultFile, FormData: FormDataCtor = DefaultFormData, }) {
|
|
7
|
-
const vars = Object.assign({}, variables);
|
|
8
|
-
const { clone, files } = extractFiles(vars, 'variables', ((v) => isExtractableFile(v) ||
|
|
9
|
-
v?.promise ||
|
|
10
|
-
isAsyncIterable(v) ||
|
|
11
|
-
v?.then ||
|
|
12
|
-
typeof v?.arrayBuffer === 'function'));
|
|
13
|
-
if (files.size === 0) {
|
|
14
|
-
return JSON.stringify({
|
|
15
|
-
query,
|
|
16
|
-
variables,
|
|
17
|
-
operationName,
|
|
18
|
-
extensions,
|
|
19
|
-
}, null, 2);
|
|
20
|
-
}
|
|
21
|
-
const map = {};
|
|
22
|
-
const uploads = [];
|
|
23
|
-
let currIndex = 0;
|
|
24
|
-
for (const [file, curr] of files) {
|
|
25
|
-
map[currIndex] = curr;
|
|
26
|
-
uploads[currIndex] = file;
|
|
27
|
-
currIndex++;
|
|
28
|
-
}
|
|
29
|
-
const form = new FormDataCtor();
|
|
30
|
-
form.append('operations', JSON.stringify({
|
|
31
|
-
query,
|
|
32
|
-
variables: clone,
|
|
33
|
-
operationName,
|
|
34
|
-
extensions,
|
|
35
|
-
}));
|
|
36
|
-
form.append('map', JSON.stringify(map, null, 2));
|
|
37
|
-
function handleUpload(upload, i) {
|
|
38
|
-
const indexStr = i.toString();
|
|
39
|
-
if (upload != null) {
|
|
40
|
-
const filename = upload.filename || upload.name || upload.path || `blob-${indexStr}`;
|
|
41
|
-
if (isPromise(upload)) {
|
|
42
|
-
return upload.then((resolvedUpload) => handleUpload(resolvedUpload, i));
|
|
43
|
-
// If Blob
|
|
44
|
-
}
|
|
45
|
-
else if (isBlob(upload)) {
|
|
46
|
-
form.append(indexStr, upload, filename);
|
|
47
|
-
}
|
|
48
|
-
else if (isGraphQLUpload(upload)) {
|
|
49
|
-
const stream = upload.createReadStream();
|
|
50
|
-
const chunks = [];
|
|
51
|
-
return Promise.resolve().then(async () => {
|
|
52
|
-
for await (const chunk of stream) {
|
|
53
|
-
if (chunk) {
|
|
54
|
-
chunks.push(...chunk);
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
const blobPart = new Uint8Array(chunks);
|
|
58
|
-
form.append(indexStr, new FileCtor([blobPart], filename, { type: upload.mimetype }), filename);
|
|
59
|
-
});
|
|
60
|
-
}
|
|
61
|
-
else {
|
|
62
|
-
form.append(indexStr, new FileCtor([upload], filename), filename);
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
return ValueOrPromise.all(uploads.map((upload, i) => new ValueOrPromise(() => handleUpload(upload, i))))
|
|
67
|
-
.then(() => form)
|
|
68
|
-
.resolve();
|
|
69
|
-
}
|
|
70
|
-
function isBlob(obj) {
|
|
71
|
-
return typeof obj.arrayBuffer === 'function';
|
|
72
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";
|
package/esm/defaultPrintFn.js
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { print, stripIgnoredCharacters } from 'graphql';
|
|
2
|
-
const printCache = new WeakMap();
|
|
3
|
-
export function defaultPrintFn(document) {
|
|
4
|
-
let printed = printCache.get(document);
|
|
5
|
-
if (!printed) {
|
|
6
|
-
printed = stripIgnoredCharacters(print(document));
|
|
7
|
-
printCache.set(document, printed);
|
|
8
|
-
}
|
|
9
|
-
return printed;
|
|
10
|
-
}
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { inspect } from '@graphql-tools/utils';
|
|
2
|
-
import { Repeater } from '@repeaterjs/repeater';
|
|
3
|
-
import { TextDecoder } from '@whatwg-node/fetch';
|
|
4
|
-
const DELIM = '\n\n';
|
|
5
|
-
export function isReadableStream(value) {
|
|
6
|
-
return value && typeof value.getReader === 'function';
|
|
7
|
-
}
|
|
8
|
-
export function handleEventStreamResponse(response) {
|
|
9
|
-
// node-fetch returns body as a promise so we need to resolve it
|
|
10
|
-
const body = response.body;
|
|
11
|
-
if (!isReadableStream(body)) {
|
|
12
|
-
throw new Error('Response body is expected to be a readable stream but got; ' + inspect(body));
|
|
13
|
-
}
|
|
14
|
-
return new Repeater((push, stop) => {
|
|
15
|
-
const decoder = new TextDecoder();
|
|
16
|
-
const reader = body.getReader();
|
|
17
|
-
reader.closed.then(stop).catch(stop); // we dont use `finally` because we want to catch errors
|
|
18
|
-
stop.finally(() => reader.cancel());
|
|
19
|
-
let currChunk = '';
|
|
20
|
-
async function pump() {
|
|
21
|
-
const { done, value: chunk } = await reader.read();
|
|
22
|
-
if (done) {
|
|
23
|
-
return stop();
|
|
24
|
-
}
|
|
25
|
-
currChunk += typeof chunk === 'string' ? chunk : decoder.decode(chunk);
|
|
26
|
-
for (;;) {
|
|
27
|
-
const delimIndex = currChunk.indexOf(DELIM);
|
|
28
|
-
if (delimIndex === -1) {
|
|
29
|
-
// incomplete message, wait for more chunks
|
|
30
|
-
break;
|
|
31
|
-
}
|
|
32
|
-
const msg = currChunk.slice(0, delimIndex); // whole message
|
|
33
|
-
currChunk = currChunk.slice(delimIndex + DELIM.length); // remainder
|
|
34
|
-
// data
|
|
35
|
-
const dataStr = msg.split('data:')[1]?.trim();
|
|
36
|
-
if (dataStr) {
|
|
37
|
-
const data = JSON.parse(dataStr);
|
|
38
|
-
await push(data.payload || data);
|
|
39
|
-
}
|
|
40
|
-
// event
|
|
41
|
-
const event = msg.split('event:')[1]?.trim();
|
|
42
|
-
if (event === 'complete') {
|
|
43
|
-
return stop();
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
return pump();
|
|
47
|
-
}
|
|
48
|
-
return pump();
|
|
49
|
-
});
|
|
50
|
-
}
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import { meros as merosReadableStream } from 'meros/browser';
|
|
2
|
-
import { meros as merosIncomingMessage } from 'meros/node';
|
|
3
|
-
import { mapAsyncIterator, mergeIncrementalResult } from '@graphql-tools/utils';
|
|
4
|
-
function isIncomingMessage(body) {
|
|
5
|
-
return body != null && typeof body === 'object' && 'pipe' in body;
|
|
6
|
-
}
|
|
7
|
-
export async function handleMultipartMixedResponse(response) {
|
|
8
|
-
const body = response.body;
|
|
9
|
-
const contentType = response.headers.get('content-type') || '';
|
|
10
|
-
let asyncIterator;
|
|
11
|
-
if (isIncomingMessage(body)) {
|
|
12
|
-
// Meros/node expects headers as an object map with the content-type prop
|
|
13
|
-
body.headers = {
|
|
14
|
-
'content-type': contentType,
|
|
15
|
-
};
|
|
16
|
-
// And it expects `IncomingMessage` and `node-fetch` returns `body` as `Promise<PassThrough>`
|
|
17
|
-
const result = await merosIncomingMessage(body);
|
|
18
|
-
if ('next' in result) {
|
|
19
|
-
asyncIterator = result;
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
else {
|
|
23
|
-
// Nothing is needed for regular `Response`.
|
|
24
|
-
const result = await merosReadableStream(response);
|
|
25
|
-
if ('next' in result) {
|
|
26
|
-
asyncIterator = result;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
const executionResult = {};
|
|
30
|
-
if (asyncIterator == null) {
|
|
31
|
-
return executionResult;
|
|
32
|
-
}
|
|
33
|
-
const resultStream = mapAsyncIterator(asyncIterator, (part) => {
|
|
34
|
-
if (part.json) {
|
|
35
|
-
const incrementalResult = part.body;
|
|
36
|
-
mergeIncrementalResult({
|
|
37
|
-
incrementalResult,
|
|
38
|
-
executionResult,
|
|
39
|
-
});
|
|
40
|
-
return executionResult;
|
|
41
|
-
}
|
|
42
|
-
});
|
|
43
|
-
return resultStream;
|
|
44
|
-
}
|
package/esm/index.js
DELETED
|
@@ -1,310 +0,0 @@
|
|
|
1
|
-
import { ValueOrPromise } from 'value-or-promise';
|
|
2
|
-
import { createGraphQLError, getOperationASTFromRequest, } from '@graphql-tools/utils';
|
|
3
|
-
import { fetch as defaultFetch } from '@whatwg-node/fetch';
|
|
4
|
-
import { createFormDataFromVariables } from './createFormDataFromVariables.js';
|
|
5
|
-
import { defaultPrintFn } from './defaultPrintFn.js';
|
|
6
|
-
import { handleEventStreamResponse } from './handleEventStreamResponse.js';
|
|
7
|
-
import { handleMultipartMixedResponse } from './handleMultipartMixedResponse.js';
|
|
8
|
-
import { isLiveQueryOperationDefinitionNode } from './isLiveQueryOperationDefinitionNode.js';
|
|
9
|
-
import { prepareGETUrl } from './prepareGETUrl.js';
|
|
10
|
-
export function buildHTTPExecutor(options) {
|
|
11
|
-
const printFn = options?.print ?? defaultPrintFn;
|
|
12
|
-
let disposeCtrl;
|
|
13
|
-
const baseExecutor = (request) => {
|
|
14
|
-
if (disposeCtrl?.signal.aborted) {
|
|
15
|
-
return createResultForAbort(disposeCtrl.signal);
|
|
16
|
-
}
|
|
17
|
-
const fetchFn = request.extensions?.fetch ?? options?.fetch ?? defaultFetch;
|
|
18
|
-
let method = request.extensions?.method || options?.method;
|
|
19
|
-
const operationAst = getOperationASTFromRequest(request);
|
|
20
|
-
const operationType = operationAst.operation;
|
|
21
|
-
if ((options?.useGETForQueries || request.extensions?.useGETForQueries) &&
|
|
22
|
-
operationType === 'query') {
|
|
23
|
-
method = 'GET';
|
|
24
|
-
}
|
|
25
|
-
let accept = 'application/graphql-response+json, application/json, multipart/mixed';
|
|
26
|
-
if (operationType === 'subscription' || isLiveQueryOperationDefinitionNode(operationAst)) {
|
|
27
|
-
method ||= 'GET';
|
|
28
|
-
accept = 'text/event-stream';
|
|
29
|
-
}
|
|
30
|
-
else {
|
|
31
|
-
method ||= 'POST';
|
|
32
|
-
}
|
|
33
|
-
const endpoint = request.extensions?.endpoint || options?.endpoint || '/graphql';
|
|
34
|
-
const headers = { accept };
|
|
35
|
-
if (options?.headers) {
|
|
36
|
-
Object.assign(headers, typeof options?.headers === 'function' ? options.headers(request) : options?.headers);
|
|
37
|
-
}
|
|
38
|
-
if (request.extensions?.headers) {
|
|
39
|
-
const { headers: headersFromExtensions, ...restExtensions } = request.extensions;
|
|
40
|
-
Object.assign(headers, headersFromExtensions);
|
|
41
|
-
request.extensions = restExtensions;
|
|
42
|
-
}
|
|
43
|
-
const query = printFn(request.document);
|
|
44
|
-
let signal = disposeCtrl?.signal;
|
|
45
|
-
let clearTimeoutFn = () => { };
|
|
46
|
-
if (options?.timeout) {
|
|
47
|
-
const timeoutCtrl = new AbortController();
|
|
48
|
-
signal = timeoutCtrl.signal;
|
|
49
|
-
disposeCtrl?.signal.addEventListener('abort', clearTimeoutFn);
|
|
50
|
-
const timeoutId = setTimeout(() => {
|
|
51
|
-
if (!timeoutCtrl.signal.aborted) {
|
|
52
|
-
timeoutCtrl.abort('timeout');
|
|
53
|
-
}
|
|
54
|
-
disposeCtrl?.signal.removeEventListener('abort', clearTimeoutFn);
|
|
55
|
-
}, options.timeout);
|
|
56
|
-
clearTimeoutFn = () => {
|
|
57
|
-
clearTimeout(timeoutId);
|
|
58
|
-
};
|
|
59
|
-
}
|
|
60
|
-
const upstreamErrorExtensions = {
|
|
61
|
-
request: {
|
|
62
|
-
method,
|
|
63
|
-
},
|
|
64
|
-
response: {},
|
|
65
|
-
};
|
|
66
|
-
return new ValueOrPromise(() => {
|
|
67
|
-
switch (method) {
|
|
68
|
-
case 'GET': {
|
|
69
|
-
const finalUrl = prepareGETUrl({
|
|
70
|
-
baseUrl: endpoint,
|
|
71
|
-
query,
|
|
72
|
-
variables: request.variables,
|
|
73
|
-
operationName: request.operationName,
|
|
74
|
-
extensions: request.extensions,
|
|
75
|
-
});
|
|
76
|
-
const fetchOptions = {
|
|
77
|
-
method: 'GET',
|
|
78
|
-
headers,
|
|
79
|
-
signal,
|
|
80
|
-
};
|
|
81
|
-
if (options?.credentials != null) {
|
|
82
|
-
fetchOptions.credentials = options.credentials;
|
|
83
|
-
}
|
|
84
|
-
upstreamErrorExtensions.request.url = finalUrl;
|
|
85
|
-
return fetchFn(finalUrl, fetchOptions, request.context, request.info);
|
|
86
|
-
}
|
|
87
|
-
case 'POST': {
|
|
88
|
-
const body = {
|
|
89
|
-
query,
|
|
90
|
-
variables: request.variables,
|
|
91
|
-
operationName: request.operationName,
|
|
92
|
-
extensions: request.extensions,
|
|
93
|
-
};
|
|
94
|
-
upstreamErrorExtensions.request.body = body;
|
|
95
|
-
return new ValueOrPromise(() => createFormDataFromVariables(body, {
|
|
96
|
-
File: options?.File,
|
|
97
|
-
FormData: options?.FormData,
|
|
98
|
-
}))
|
|
99
|
-
.then(body => {
|
|
100
|
-
if (typeof body === 'string' && !headers['content-type']) {
|
|
101
|
-
upstreamErrorExtensions.request.body = body;
|
|
102
|
-
headers['content-type'] = 'application/json';
|
|
103
|
-
}
|
|
104
|
-
const fetchOptions = {
|
|
105
|
-
method: 'POST',
|
|
106
|
-
body,
|
|
107
|
-
headers,
|
|
108
|
-
signal,
|
|
109
|
-
};
|
|
110
|
-
if (options?.credentials != null) {
|
|
111
|
-
fetchOptions.credentials = options.credentials;
|
|
112
|
-
}
|
|
113
|
-
return fetchFn(endpoint, fetchOptions, request.context, request.info);
|
|
114
|
-
})
|
|
115
|
-
.resolve();
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
})
|
|
119
|
-
.then((fetchResult) => {
|
|
120
|
-
upstreamErrorExtensions.response.status = fetchResult.status;
|
|
121
|
-
upstreamErrorExtensions.response.statusText = fetchResult.statusText;
|
|
122
|
-
Object.defineProperty(upstreamErrorExtensions.response, 'headers', {
|
|
123
|
-
get() {
|
|
124
|
-
return Object.fromEntries(fetchResult.headers.entries());
|
|
125
|
-
},
|
|
126
|
-
});
|
|
127
|
-
clearTimeoutFn();
|
|
128
|
-
// Retry should respect HTTP Errors
|
|
129
|
-
if (options?.retry != null && !fetchResult.status.toString().startsWith('2')) {
|
|
130
|
-
throw new Error(fetchResult.statusText || `Upstream HTTP Error: ${fetchResult.status}`);
|
|
131
|
-
}
|
|
132
|
-
const contentType = fetchResult.headers.get('content-type');
|
|
133
|
-
if (contentType?.includes('text/event-stream')) {
|
|
134
|
-
return handleEventStreamResponse(fetchResult);
|
|
135
|
-
}
|
|
136
|
-
else if (contentType?.includes('multipart/mixed')) {
|
|
137
|
-
return handleMultipartMixedResponse(fetchResult);
|
|
138
|
-
}
|
|
139
|
-
return fetchResult.text();
|
|
140
|
-
})
|
|
141
|
-
.then(result => {
|
|
142
|
-
if (typeof result === 'string') {
|
|
143
|
-
upstreamErrorExtensions.response.body = result;
|
|
144
|
-
if (result) {
|
|
145
|
-
try {
|
|
146
|
-
const parsedResult = JSON.parse(result);
|
|
147
|
-
upstreamErrorExtensions.response.body = parsedResult;
|
|
148
|
-
if (parsedResult.data == null &&
|
|
149
|
-
(parsedResult.errors == null || parsedResult.errors.length === 0)) {
|
|
150
|
-
return {
|
|
151
|
-
errors: [
|
|
152
|
-
createGraphQLError('Unexpected empty "data" and "errors" fields in result: ' + result, {
|
|
153
|
-
extensions: upstreamErrorExtensions,
|
|
154
|
-
}),
|
|
155
|
-
],
|
|
156
|
-
};
|
|
157
|
-
}
|
|
158
|
-
if (Array.isArray(parsedResult.errors)) {
|
|
159
|
-
return {
|
|
160
|
-
...parsedResult,
|
|
161
|
-
errors: parsedResult.errors.map(({ message, ...options }) => createGraphQLError(message, {
|
|
162
|
-
...options,
|
|
163
|
-
extensions: {
|
|
164
|
-
code: 'DOWNSTREAM_SERVICE_ERROR',
|
|
165
|
-
...(options.extensions || {}),
|
|
166
|
-
},
|
|
167
|
-
})),
|
|
168
|
-
};
|
|
169
|
-
}
|
|
170
|
-
return parsedResult;
|
|
171
|
-
}
|
|
172
|
-
catch (e) {
|
|
173
|
-
return {
|
|
174
|
-
errors: [
|
|
175
|
-
createGraphQLError(`Unexpected response: ${JSON.stringify(result)}`, {
|
|
176
|
-
extensions: upstreamErrorExtensions,
|
|
177
|
-
originalError: e,
|
|
178
|
-
}),
|
|
179
|
-
],
|
|
180
|
-
};
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
else {
|
|
185
|
-
return result;
|
|
186
|
-
}
|
|
187
|
-
})
|
|
188
|
-
.catch((e) => {
|
|
189
|
-
if (e.name === 'AggregateError') {
|
|
190
|
-
return {
|
|
191
|
-
errors: e.errors.map((e) => coerceFetchError(e, {
|
|
192
|
-
signal,
|
|
193
|
-
endpoint,
|
|
194
|
-
upstreamErrorExtensions,
|
|
195
|
-
})),
|
|
196
|
-
};
|
|
197
|
-
}
|
|
198
|
-
return {
|
|
199
|
-
errors: [
|
|
200
|
-
coerceFetchError(e, {
|
|
201
|
-
signal,
|
|
202
|
-
endpoint,
|
|
203
|
-
upstreamErrorExtensions,
|
|
204
|
-
}),
|
|
205
|
-
],
|
|
206
|
-
};
|
|
207
|
-
})
|
|
208
|
-
.resolve();
|
|
209
|
-
};
|
|
210
|
-
let executor = baseExecutor;
|
|
211
|
-
if (options?.retry != null) {
|
|
212
|
-
executor = function retryExecutor(request) {
|
|
213
|
-
let result;
|
|
214
|
-
let attempt = 0;
|
|
215
|
-
function retryAttempt() {
|
|
216
|
-
if (disposeCtrl?.signal.aborted) {
|
|
217
|
-
return createResultForAbort(disposeCtrl.signal);
|
|
218
|
-
}
|
|
219
|
-
attempt++;
|
|
220
|
-
if (attempt > options.retry) {
|
|
221
|
-
if (result != null) {
|
|
222
|
-
return result;
|
|
223
|
-
}
|
|
224
|
-
return {
|
|
225
|
-
errors: [createGraphQLError('No response returned from fetch')],
|
|
226
|
-
};
|
|
227
|
-
}
|
|
228
|
-
return new ValueOrPromise(() => baseExecutor(request))
|
|
229
|
-
.then(res => {
|
|
230
|
-
result = res;
|
|
231
|
-
if (result?.errors?.length) {
|
|
232
|
-
return retryAttempt();
|
|
233
|
-
}
|
|
234
|
-
return result;
|
|
235
|
-
})
|
|
236
|
-
.resolve();
|
|
237
|
-
}
|
|
238
|
-
return retryAttempt();
|
|
239
|
-
};
|
|
240
|
-
}
|
|
241
|
-
if (!options?.disposable) {
|
|
242
|
-
disposeCtrl = undefined;
|
|
243
|
-
return executor;
|
|
244
|
-
}
|
|
245
|
-
disposeCtrl = new AbortController();
|
|
246
|
-
Object.defineProperties(executor, {
|
|
247
|
-
[Symbol.dispose]: {
|
|
248
|
-
get() {
|
|
249
|
-
return function dispose() {
|
|
250
|
-
return disposeCtrl.abort(createAbortErrorReason());
|
|
251
|
-
};
|
|
252
|
-
},
|
|
253
|
-
},
|
|
254
|
-
[Symbol.asyncDispose]: {
|
|
255
|
-
get() {
|
|
256
|
-
return function asyncDispose() {
|
|
257
|
-
return disposeCtrl.abort(createAbortErrorReason());
|
|
258
|
-
};
|
|
259
|
-
},
|
|
260
|
-
},
|
|
261
|
-
});
|
|
262
|
-
return executor;
|
|
263
|
-
}
|
|
264
|
-
function coerceFetchError(e, { signal, endpoint, upstreamErrorExtensions, }) {
|
|
265
|
-
if (typeof e === 'string') {
|
|
266
|
-
return createGraphQLError(e, {
|
|
267
|
-
extensions: upstreamErrorExtensions,
|
|
268
|
-
});
|
|
269
|
-
}
|
|
270
|
-
else if (e.name === 'GraphQLError') {
|
|
271
|
-
return e;
|
|
272
|
-
}
|
|
273
|
-
else if (e.name === 'TypeError' && e.message === 'fetch failed') {
|
|
274
|
-
return createGraphQLError(`fetch failed to ${endpoint}`, {
|
|
275
|
-
extensions: upstreamErrorExtensions,
|
|
276
|
-
originalError: e,
|
|
277
|
-
});
|
|
278
|
-
}
|
|
279
|
-
else if (e.name === 'AbortError' && signal?.reason) {
|
|
280
|
-
return createGraphQLErrorForAbort(signal, {
|
|
281
|
-
extensions: upstreamErrorExtensions,
|
|
282
|
-
});
|
|
283
|
-
}
|
|
284
|
-
else if (e.message) {
|
|
285
|
-
return createGraphQLError(e.message, {
|
|
286
|
-
extensions: upstreamErrorExtensions,
|
|
287
|
-
originalError: e,
|
|
288
|
-
});
|
|
289
|
-
}
|
|
290
|
-
else {
|
|
291
|
-
return createGraphQLError('Unknown error', {
|
|
292
|
-
extensions: upstreamErrorExtensions,
|
|
293
|
-
originalError: e,
|
|
294
|
-
});
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
function createAbortErrorReason() {
|
|
298
|
-
return new Error('Executor was disposed.');
|
|
299
|
-
}
|
|
300
|
-
function createGraphQLErrorForAbort(signal, extensions) {
|
|
301
|
-
return createGraphQLError('The operation was aborted. reason: ' + signal.reason, {
|
|
302
|
-
extensions,
|
|
303
|
-
});
|
|
304
|
-
}
|
|
305
|
-
function createResultForAbort(signal, extensions) {
|
|
306
|
-
return {
|
|
307
|
-
errors: [createGraphQLErrorForAbort(signal, extensions)],
|
|
308
|
-
};
|
|
309
|
-
}
|
|
310
|
-
export { isLiveQueryOperationDefinitionNode };
|
package/esm/isGraphQLUpload.js
DELETED
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import { memoize1 } from '@graphql-tools/utils';
|
|
2
|
-
export const isLiveQueryOperationDefinitionNode = memoize1(function isLiveQueryOperationDefinitionNode(node) {
|
|
3
|
-
return (node.operation === 'query' &&
|
|
4
|
-
node.directives?.some(directive => directive.name.value === 'live'));
|
|
5
|
-
});
|
package/esm/prepareGETUrl.js
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { stripIgnoredCharacters } from 'graphql';
|
|
2
|
-
export function prepareGETUrl({ baseUrl = '', query, variables, operationName, extensions, }) {
|
|
3
|
-
const dummyHostname = 'https://dummyhostname.com';
|
|
4
|
-
const validUrl = baseUrl.startsWith('http')
|
|
5
|
-
? baseUrl
|
|
6
|
-
: baseUrl?.startsWith('/')
|
|
7
|
-
? `${dummyHostname}${baseUrl}`
|
|
8
|
-
: `${dummyHostname}/${baseUrl}`;
|
|
9
|
-
const urlObj = new URL(validUrl);
|
|
10
|
-
urlObj.searchParams.set('query', stripIgnoredCharacters(query));
|
|
11
|
-
if (variables && Object.keys(variables).length > 0) {
|
|
12
|
-
urlObj.searchParams.set('variables', JSON.stringify(variables));
|
|
13
|
-
}
|
|
14
|
-
if (operationName) {
|
|
15
|
-
urlObj.searchParams.set('operationName', operationName);
|
|
16
|
-
}
|
|
17
|
-
if (extensions) {
|
|
18
|
-
urlObj.searchParams.set('extensions', JSON.stringify(extensions));
|
|
19
|
-
}
|
|
20
|
-
const finalUrl = urlObj.toString().replace(dummyHostname, '');
|
|
21
|
-
return finalUrl;
|
|
22
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { FormData as DefaultFormData } from '@whatwg-node/fetch';
|
|
2
|
-
export declare function createFormDataFromVariables<TVariables>({ query, variables, operationName, extensions, }: {
|
|
3
|
-
query: string;
|
|
4
|
-
variables: TVariables;
|
|
5
|
-
operationName?: string;
|
|
6
|
-
extensions?: any;
|
|
7
|
-
}, { File: FileCtor, FormData: FormDataCtor, }: {
|
|
8
|
-
File?: typeof File;
|
|
9
|
-
FormData?: typeof DefaultFormData;
|
|
10
|
-
}): string | FormData | Promise<FormData>;
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { FormData as DefaultFormData } from '@whatwg-node/fetch';
|
|
2
|
-
export declare function createFormDataFromVariables<TVariables>({ query, variables, operationName, extensions, }: {
|
|
3
|
-
query: string;
|
|
4
|
-
variables: TVariables;
|
|
5
|
-
operationName?: string;
|
|
6
|
-
extensions?: any;
|
|
7
|
-
}, { File: FileCtor, FormData: FormDataCtor, }: {
|
|
8
|
-
File?: typeof File;
|
|
9
|
-
FormData?: typeof DefaultFormData;
|
|
10
|
-
}): string | FormData | Promise<FormData>;
|
|
File without changes
|
|
File without changes
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import { ExecutionResult } from '@graphql-tools/utils';
|
|
2
|
-
import { Repeater } from '@repeaterjs/repeater';
|
|
3
|
-
export declare function isReadableStream(value: any): value is ReadableStream;
|
|
4
|
-
export declare function handleEventStreamResponse(response: Response): Repeater<ExecutionResult<any, any>, any, unknown>;
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import { ExecutionResult } from '@graphql-tools/utils';
|
|
2
|
-
import { Repeater } from '@repeaterjs/repeater';
|
|
3
|
-
export declare function isReadableStream(value: any): value is ReadableStream;
|
|
4
|
-
export declare function handleEventStreamResponse(response: Response): Repeater<ExecutionResult<any, any>, any, unknown>;
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
/// <reference types="node" />
|
|
2
|
-
import type { Readable } from 'stream';
|
|
3
|
-
interface GraphQLUpload {
|
|
4
|
-
filename: string;
|
|
5
|
-
mimetype: string;
|
|
6
|
-
createReadStream: () => Readable;
|
|
7
|
-
}
|
|
8
|
-
export declare function isGraphQLUpload(upload: any): upload is GraphQLUpload;
|
|
9
|
-
export {};
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
/// <reference types="node" />
|
|
2
|
-
import type { Readable } from 'stream';
|
|
3
|
-
interface GraphQLUpload {
|
|
4
|
-
filename: string;
|
|
5
|
-
mimetype: string;
|
|
6
|
-
createReadStream: () => Readable;
|
|
7
|
-
}
|
|
8
|
-
export declare function isGraphQLUpload(upload: any): upload is GraphQLUpload;
|
|
9
|
-
export {};
|