@graphql-tools/executor-http
Advanced tools
Comparing version 1.1.10-alpha-23d63c2f792bd1d2c43df878a0eabc967e6a5b37 to 1.1.10-alpha-2e0cf13f04929774e79ef18a7d2ea9515d3e0f00
# @graphql-tools/executor-http | ||
## 1.1.10-alpha-23d63c2f792bd1d2c43df878a0eabc967e6a5b37 | ||
## 1.1.10-alpha-2e0cf13f04929774e79ef18a7d2ea9515d3e0f00 | ||
@@ -11,8 +11,2 @@ ### Patch Changes | ||
- [#180](https://github.com/graphql-hive/gateway/pull/180) [`ad751f5`](https://github.com/graphql-hive/gateway/commit/ad751f582d666319969a93908c275a311e180023) Thanks [@ardatan](https://github.com/ardatan)! - dependencies updates: | ||
- Added dependency [`@whatwg-node/disposablestack@^0.0.5` ↗︎](https://www.npmjs.com/package/@whatwg-node/disposablestack/v/0.0.5) (to `dependencies`) | ||
- [#180](https://github.com/graphql-hive/gateway/pull/180) [`875cbc6`](https://github.com/graphql-hive/gateway/commit/875cbc620ba05d4e04cd368bf3e530a59352bf5f) Thanks [@ardatan](https://github.com/ardatan)! - Use new explicit resource management internally | ||
- [#98](https://github.com/graphql-hive/gateway/pull/98) [`697308d`](https://github.com/graphql-hive/gateway/commit/697308df3b2dd96f28dc65a5f5361a911077e022) Thanks [@ardatan](https://github.com/ardatan)! - Bun support by using native Bun API whenever possible | ||
@@ -19,0 +13,0 @@ |
@@ -1,2 +0,2 @@ | ||
import { ExecutionRequest, DisposableSyncExecutor, DisposableAsyncExecutor } from '@graphql-tools/utils'; | ||
import { ExecutionRequest, DisposableSyncExecutor, SyncExecutor, DisposableAsyncExecutor, AsyncExecutor } from '@graphql-tools/utils'; | ||
import { OperationDefinitionNode, GraphQLResolveInfo, DocumentNode } from 'graphql'; | ||
@@ -59,3 +59,4 @@ | ||
/** | ||
* @deprecated Not used anymore | ||
* Enable [Explicit Resource Management](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-5-2.html#using-declarations-and-explicit-resource-management) | ||
* @default false | ||
*/ | ||
@@ -65,13 +66,43 @@ disposable?: boolean; | ||
type HeadersConfig = Record<string, string>; | ||
declare function buildHTTPExecutor(options?: Omit<HTTPExecutorOptions, 'fetch'> & { | ||
declare function buildHTTPExecutor(options?: Omit<HTTPExecutorOptions, 'fetch' | 'disposable'> & { | ||
fetch: SyncFetchFn; | ||
disposable: true; | ||
}): DisposableSyncExecutor<any, HTTPExecutorOptions>; | ||
declare function buildHTTPExecutor(options?: Omit<HTTPExecutorOptions, 'fetch' | 'disposable'> & { | ||
fetch: SyncFetchFn; | ||
disposable: false; | ||
}): SyncExecutor<any, HTTPExecutorOptions>; | ||
declare function buildHTTPExecutor(options?: Omit<HTTPExecutorOptions, 'fetch'> & { | ||
fetch: SyncFetchFn; | ||
}): SyncExecutor<any, HTTPExecutorOptions>; | ||
declare function buildHTTPExecutor(options?: Omit<HTTPExecutorOptions, 'fetch' | 'disposable'> & { | ||
fetch: AsyncFetchFn; | ||
disposable: true; | ||
}): DisposableAsyncExecutor<any, HTTPExecutorOptions>; | ||
declare function buildHTTPExecutor(options?: Omit<HTTPExecutorOptions, 'fetch' | 'disposable'> & { | ||
fetch: AsyncFetchFn; | ||
disposable: false; | ||
}): AsyncExecutor<any, HTTPExecutorOptions>; | ||
declare function buildHTTPExecutor(options?: Omit<HTTPExecutorOptions, 'fetch'> & { | ||
fetch: AsyncFetchFn; | ||
}): AsyncExecutor<any, HTTPExecutorOptions>; | ||
declare function buildHTTPExecutor(options?: Omit<HTTPExecutorOptions, 'fetch' | 'disposable'> & { | ||
fetch: RegularFetchFn; | ||
disposable: true; | ||
}): DisposableAsyncExecutor<any, HTTPExecutorOptions>; | ||
declare function buildHTTPExecutor(options?: Omit<HTTPExecutorOptions, 'fetch'>): DisposableAsyncExecutor<any, HTTPExecutorOptions>; | ||
declare function buildHTTPExecutor(options?: Omit<HTTPExecutorOptions, 'fetch' | 'disposable'> & { | ||
fetch: RegularFetchFn; | ||
disposable: false; | ||
}): AsyncExecutor<any, HTTPExecutorOptions>; | ||
declare function buildHTTPExecutor(options?: Omit<HTTPExecutorOptions, 'fetch'> & { | ||
fetch: RegularFetchFn; | ||
}): AsyncExecutor<any, HTTPExecutorOptions>; | ||
declare function buildHTTPExecutor(options?: Omit<HTTPExecutorOptions, 'fetch' | 'disposable'> & { | ||
disposable: true; | ||
}): DisposableAsyncExecutor<any, HTTPExecutorOptions>; | ||
declare function buildHTTPExecutor(options?: Omit<HTTPExecutorOptions, 'fetch' | 'disposable'> & { | ||
disposable: false; | ||
}): AsyncExecutor<any, HTTPExecutorOptions>; | ||
declare function buildHTTPExecutor(options?: Omit<HTTPExecutorOptions, 'fetch'>): AsyncExecutor<any, HTTPExecutorOptions>; | ||
export { type AsyncFetchFn, type AsyncImportFn, type FetchFn, type HTTPExecutorOptions, type HeadersConfig, type RegularFetchFn, type SyncFetchFn, type SyncImportFn, type SyncResponse, buildHTTPExecutor, isLiveQueryOperationDefinitionNode }; |
@@ -1,3 +0,2 @@ | ||
import { isAsyncIterable, isPromise, fakePromise, createGraphQLError, inspect, mapAsyncIterator, mergeIncrementalResult, memoize1, getOperationASTFromRequest } from '@graphql-tools/utils'; | ||
import { DisposableSymbols } from '@whatwg-node/disposablestack'; | ||
import { isAsyncIterable, isPromise, fakePromise, inspect, mapAsyncIterator, mergeIncrementalResult, memoize1, getOperationASTFromRequest, mapMaybePromise, createGraphQLError } from '@graphql-tools/utils'; | ||
import { File, FormData, TextDecoder, fetch } from '@whatwg-node/fetch'; | ||
@@ -92,7 +91,14 @@ import { ValueOrPromise } from 'value-or-promise'; | ||
} | ||
return ValueOrPromise.all( | ||
uploads.map( | ||
(upload, i) => new ValueOrPromise(() => handleUpload(upload, i)) | ||
) | ||
).then(() => form).resolve(); | ||
const jobs = []; | ||
for (const i in uploads) { | ||
const upload = uploads[i]; | ||
const job = handleUpload(upload, Number(i)); | ||
if (isPromise(job)) { | ||
jobs.push(job); | ||
} | ||
} | ||
if (jobs.length > 0) { | ||
return Promise.all(jobs).then(() => form); | ||
} | ||
return form; | ||
} | ||
@@ -113,19 +119,2 @@ function isBlob(obj) { | ||
function createAbortErrorReason() { | ||
return new Error("Executor was disposed."); | ||
} | ||
function createGraphQLErrorForAbort(signal, extensions) { | ||
return createGraphQLError( | ||
"The operation was aborted. reason: " + signal.reason, | ||
{ | ||
extensions | ||
} | ||
); | ||
} | ||
function createResultForAbort(signal, extensions) { | ||
return { | ||
errors: [createGraphQLErrorForAbort(signal, extensions)] | ||
}; | ||
} | ||
const DELIM = "\n\n"; | ||
@@ -135,3 +124,3 @@ function isReadableStream(value) { | ||
} | ||
function handleEventStreamResponse(signal, response) { | ||
function handleEventStreamResponse(response) { | ||
const body = response.body; | ||
@@ -152,6 +141,2 @@ if (!isReadableStream(body)) { | ||
async function pump() { | ||
if (signal.aborted) { | ||
await push(createResultForAbort(signal)); | ||
return stop(); | ||
} | ||
if (!body?.locked) { | ||
@@ -258,5 +243,5 @@ return stop(); | ||
const printFn = options?.print ?? defaultPrintFn; | ||
const disposeCtrl = new AbortController(); | ||
let disposeCtrl; | ||
const baseExecutor = (request) => { | ||
if (disposeCtrl.signal.aborted) { | ||
if (disposeCtrl?.signal.aborted) { | ||
return createResultForAbort(disposeCtrl.signal); | ||
@@ -292,5 +277,18 @@ } | ||
const query = printFn(request.document); | ||
let signal = disposeCtrl.signal; | ||
let signal = disposeCtrl?.signal; | ||
let clearTimeoutFn = () => { | ||
}; | ||
if (options?.timeout) { | ||
signal = AbortSignal.any([signal, AbortSignal.timeout(options.timeout)]); | ||
const timeoutCtrl = new AbortController(); | ||
signal = timeoutCtrl.signal; | ||
disposeCtrl?.signal.addEventListener("abort", clearTimeoutFn); | ||
const timeoutId = setTimeout(() => { | ||
if (!timeoutCtrl.signal.aborted) { | ||
timeoutCtrl.abort("timeout"); | ||
} | ||
disposeCtrl?.signal.removeEventListener("abort", clearTimeoutFn); | ||
}, options.timeout); | ||
clearTimeoutFn = () => { | ||
clearTimeout(timeoutId); | ||
}; | ||
} | ||
@@ -332,28 +330,29 @@ const upstreamErrorExtensions = { | ||
upstreamErrorExtensions.request.body = body; | ||
return new ValueOrPromise( | ||
() => createFormDataFromVariables(body, { | ||
return mapMaybePromise( | ||
createFormDataFromVariables(body, { | ||
File: options?.File, | ||
FormData: options?.FormData | ||
}) | ||
).then((body2) => { | ||
if (typeof body2 === "string" && !headers["content-type"]) { | ||
upstreamErrorExtensions.request.body = body2; | ||
headers["content-type"] = "application/json"; | ||
}), | ||
(body2) => { | ||
if (typeof body2 === "string" && !headers["content-type"]) { | ||
upstreamErrorExtensions.request.body = body2; | ||
headers["content-type"] = "application/json"; | ||
} | ||
const fetchOptions = { | ||
method: "POST", | ||
body: body2, | ||
headers, | ||
signal | ||
}; | ||
if (options?.credentials != null) { | ||
fetchOptions.credentials = options.credentials; | ||
} | ||
return fetchFn( | ||
endpoint, | ||
fetchOptions, | ||
request.context, | ||
request.info | ||
); | ||
} | ||
const fetchOptions = { | ||
method: "POST", | ||
body: body2, | ||
headers, | ||
signal | ||
}; | ||
if (options?.credentials != null) { | ||
fetchOptions.credentials = options.credentials; | ||
} | ||
return fetchFn( | ||
endpoint, | ||
fetchOptions, | ||
request.context, | ||
request.info | ||
); | ||
}).resolve(); | ||
); | ||
} | ||
@@ -369,2 +368,3 @@ } | ||
}); | ||
clearTimeoutFn(); | ||
if (options?.retry != null && !fetchResult.status.toString().startsWith("2")) { | ||
@@ -377,3 +377,3 @@ throw new Error( | ||
if (contentType?.includes("text/event-stream")) { | ||
return handleEventStreamResponse(signal, fetchResult); | ||
return handleEventStreamResponse(fetchResult); | ||
} else if (contentType?.includes("multipart/mixed")) { | ||
@@ -478,3 +478,3 @@ return handleMultipartMixedResponse(fetchResult); | ||
} | ||
return new ValueOrPromise(() => baseExecutor(request)).then((res) => { | ||
return mapMaybePromise(baseExecutor(request), (res) => { | ||
result = res; | ||
@@ -485,3 +485,3 @@ if (result?.errors?.length) { | ||
return result; | ||
}).resolve(); | ||
}); | ||
} | ||
@@ -491,4 +491,9 @@ return retryAttempt(); | ||
} | ||
if (!options?.disposable) { | ||
disposeCtrl = void 0; | ||
return executor; | ||
} | ||
disposeCtrl = new AbortController(); | ||
Object.defineProperties(executor, { | ||
[DisposableSymbols.dispose]: { | ||
[Symbol.dispose]: { | ||
get() { | ||
@@ -500,3 +505,3 @@ return function dispose() { | ||
}, | ||
[DisposableSymbols.asyncDispose]: { | ||
[Symbol.asyncDispose]: { | ||
get() { | ||
@@ -527,3 +532,3 @@ return function asyncDispose() { | ||
}); | ||
} else if (e.name === "AbortError" && signal.reason) { | ||
} else if (e.name === "AbortError" && signal?.reason) { | ||
return createGraphQLErrorForAbort(signal, { | ||
@@ -544,3 +549,19 @@ extensions: upstreamErrorExtensions | ||
} | ||
function createAbortErrorReason() { | ||
return new Error("Executor was disposed."); | ||
} | ||
function createGraphQLErrorForAbort(signal, extensions) { | ||
return createGraphQLError( | ||
"The operation was aborted. reason: " + signal.reason, | ||
{ | ||
extensions | ||
} | ||
); | ||
} | ||
function createResultForAbort(signal, extensions) { | ||
return { | ||
errors: [createGraphQLErrorForAbort(signal, extensions)] | ||
}; | ||
} | ||
export { buildHTTPExecutor, isLiveQueryOperationDefinitionNode }; |
{ | ||
"name": "@graphql-tools/executor-http", | ||
"version": "1.1.10-alpha-23d63c2f792bd1d2c43df878a0eabc967e6a5b37", | ||
"version": "1.1.10-alpha-2e0cf13f04929774e79ef18a7d2ea9515d3e0f00", | ||
"type": "module", | ||
@@ -44,3 +44,2 @@ "description": "A set of utils for faster development of GraphQL tools", | ||
"@repeaterjs/repeater": "^3.0.4", | ||
"@whatwg-node/disposablestack": "^0.0.5", | ||
"@whatwg-node/fetch": "^0.10.0", | ||
@@ -47,0 +46,0 @@ "extract-files": "^11.0.0", |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
62823
8
1191
- Removed@whatwg-node/disposablestack@^0.0.5