@graphql-tools/executor-http
Advanced tools
Comparing version 1.2.0-alpha-753096403f92c5dbcdd17828acdd17a1aa53a51e to 1.2.0-alpha-7c456f6ecf6b55a344a74e57ce6ba15bf509d93c
# @graphql-tools/executor-http | ||
## 1.2.0-alpha-753096403f92c5dbcdd17828acdd17a1aa53a51e | ||
## 1.2.0-alpha-7c456f6ecf6b55a344a74e57ce6ba15bf509d93c | ||
### Minor Changes | ||
- [#313](https://github.com/graphql-hive/gateway/pull/313) [`7530964`](https://github.com/graphql-hive/gateway/commit/753096403f92c5dbcdd17828acdd17a1aa53a51e) Thanks [@ardatan](https://github.com/ardatan)! - Automatic Persisted Queries support for upstream requests | ||
- [#316](https://github.com/graphql-hive/gateway/pull/316) [`c1e0331`](https://github.com/graphql-hive/gateway/commit/c1e0331b897a56d4d746ba5b656bae304ffe2214) Thanks [@ardatan](https://github.com/ardatan)! - Automatic Persisted Queries support for upstream requests | ||
@@ -9,0 +9,0 @@ For HTTP Executor; |
@@ -17,6 +17,16 @@ import { ExecutionRequest, DisposableSyncExecutor, DisposableAsyncExecutor } from '@graphql-tools/utils'; | ||
interface HTTPExecutorOptions { | ||
/** | ||
* The endpoint to use when querying the upstream API | ||
* @default '/graphql' | ||
*/ | ||
endpoint?: string; | ||
/** | ||
* The WHATWG compatible fetch implementation to use | ||
* @see https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API | ||
* @default globalThis.fetch | ||
*/ | ||
fetch?: FetchFn; | ||
/** | ||
* Whether to use the GET HTTP method for queries when querying the original schema | ||
* @default false | ||
*/ | ||
@@ -29,3 +39,4 @@ useGETForQueries?: boolean; | ||
/** | ||
* HTTP method to use when querying the original schema. | ||
* HTTP method to use when querying the original schema.x | ||
* @default 'POST' | ||
*/ | ||
@@ -38,3 +49,4 @@ method?: 'GET' | 'POST'; | ||
/** | ||
* Request Credentials (default: 'same-origin') | ||
* Request Credentials | ||
* @default 'same-origin' | ||
* @see https://developer.mozilla.org/en-US/docs/Web/API/Request/credentials | ||
@@ -48,3 +60,3 @@ */ | ||
/** | ||
* WHATWG compatible File implementation | ||
* WHATWG compatible `File` implementation | ||
* @see https://developer.mozilla.org/en-US/docs/Web/API/File | ||
@@ -54,3 +66,3 @@ */ | ||
/** | ||
* WHATWG compatible FormData implementation | ||
* WHATWG compatible `FormData` implementation | ||
* @see https://developer.mozilla.org/en-US/docs/Web/API/FormData | ||
@@ -60,8 +72,14 @@ */ | ||
/** | ||
* Print function for DocumentNode | ||
* Print function for `DocumentNode` | ||
* Useful when you want to memoize the print function or use a different implementation to minify the query etc. | ||
*/ | ||
print?: (doc: DocumentNode) => string; | ||
/** | ||
* Enable Automatic Persisted Queries | ||
* @see https://www.apollographql.com/docs/apollo-server/performance/apq/ | ||
*/ | ||
apq?: boolean; | ||
/** | ||
* Enable [Explicit Resource Management](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-5-2.html#using-declarations-and-explicit-resource-management) | ||
* Enable Explicit Resource Management | ||
* @see https://www.typescriptlang.org/docs/handbook/release-notes/typescript-5-2.html#using-declarations-and-explicit-resource-management | ||
* @deprecated The executors are always disposable, and this option will be removed in the next major version, there is no need to have a flag for this. | ||
@@ -71,8 +89,2 @@ */ | ||
} | ||
type SerializedRequest = { | ||
query?: string; | ||
variables?: Record<string, any>; | ||
operationName?: string; | ||
extensions?: any; | ||
}; | ||
type HeadersConfig = Record<string, string>; | ||
@@ -90,2 +102,2 @@ declare function buildHTTPExecutor(options?: Omit<HTTPExecutorOptions, 'fetch'> & { | ||
export { type AsyncFetchFn, type AsyncImportFn, type FetchFn, type HTTPExecutorOptions, type HeadersConfig, type RegularFetchFn, type SerializedRequest, type SyncFetchFn, type SyncImportFn, type SyncResponse, buildHTTPExecutor, isLiveQueryOperationDefinitionNode }; | ||
export { type AsyncFetchFn, type AsyncImportFn, type FetchFn, type HTTPExecutorOptions, type HeadersConfig, type RegularFetchFn, type SyncFetchFn, type SyncImportFn, type SyncResponse, buildHTTPExecutor, isLiveQueryOperationDefinitionNode }; |
@@ -1,4 +0,4 @@ | ||
import { isAsyncIterable, isPromise, mapMaybePromise, memoize1, createGraphQLError, inspect, mapAsyncIterator, mergeIncrementalResult, getOperationASTFromRequest } from '@graphql-tools/utils'; | ||
import { createGraphQLError, mapMaybePromise, isAsyncIterable, isPromise, memoize1, inspect, mapAsyncIterator, mergeIncrementalResult, getOperationASTFromRequest } from '@graphql-tools/utils'; | ||
import { DisposableSymbols } from '@whatwg-node/disposablestack'; | ||
import { File, FormData, TextEncoder, crypto, TextDecoder, fetch } from '@whatwg-node/fetch'; | ||
import { TextEncoder, crypto, File, FormData, TextDecoder, fetch } from '@whatwg-node/fetch'; | ||
import { ValueOrPromise } from 'value-or-promise'; | ||
@@ -15,2 +15,60 @@ import { extractFiles, isExtractableFile } from 'extract-files'; | ||
function createAbortErrorReason() { | ||
return new Error("Executor was disposed."); | ||
} | ||
function createGraphQLErrorForAbort(reason, extensions) { | ||
return createGraphQLError("The operation was aborted. reason: " + reason, { | ||
extensions | ||
}); | ||
} | ||
function createResultForAbort(reason, extensions) { | ||
return { | ||
errors: [createGraphQLErrorForAbort(reason, extensions)] | ||
}; | ||
} | ||
function hashSHA256(str) { | ||
const textEncoder = new TextEncoder(); | ||
const utf8 = textEncoder.encode(str); | ||
return mapMaybePromise( | ||
crypto.subtle.digest("SHA-256", utf8), | ||
(hashBuffer) => { | ||
let hashHex = ""; | ||
for (const bytes of new Uint8Array(hashBuffer)) { | ||
hashHex += bytes.toString(16).padStart(2, "0"); | ||
} | ||
return hashHex; | ||
} | ||
); | ||
} | ||
function jsonStringifyBody(body) { | ||
let str = "{"; | ||
let prev = false; | ||
if (body.query) { | ||
str += `"query":"${body.query.replaceAll('"', '\\"')}"`; | ||
prev = true; | ||
} | ||
if (body.variables) { | ||
if (prev) { | ||
str += ","; | ||
} | ||
str += `"variables":${JSON.stringify(body.variables)}`; | ||
prev = true; | ||
} | ||
if (body.operationName) { | ||
if (prev) { | ||
str += ","; | ||
} | ||
str += `"operationName":"${body.operationName}"`; | ||
prev = true; | ||
} | ||
if (body.extensions) { | ||
if (prev) { | ||
str += ","; | ||
} | ||
str += `"extensions":${JSON.stringify(body.extensions)}`; | ||
} | ||
str += "}"; | ||
return str; | ||
} | ||
function collectAsyncIterableValues(asyncIterable) { | ||
@@ -37,7 +95,6 @@ const values = []; | ||
if (!body.variables) { | ||
return JSON.stringify(body); | ||
return jsonStringifyBody(body); | ||
} | ||
const vars = Object.assign({}, body.variables); | ||
const { clone, files } = extractFiles( | ||
vars, | ||
body.variables, | ||
"variables", | ||
@@ -47,3 +104,3 @@ (v) => isExtractableFile(v) || v?.promise || isAsyncIterable(v) || v?.then || typeof v?.arrayBuffer === "function" | ||
if (files.size === 0) { | ||
return JSON.stringify(body); | ||
return jsonStringifyBody(body); | ||
} | ||
@@ -61,3 +118,3 @@ const map = {}; | ||
"operations", | ||
JSON.stringify({ | ||
jsonStringifyBody({ | ||
...body, | ||
@@ -129,30 +186,2 @@ variables: clone | ||
function createAbortErrorReason() { | ||
return new Error("Executor was disposed."); | ||
} | ||
function createGraphQLErrorForAbort(reason, extensions) { | ||
return createGraphQLError("The operation was aborted. reason: " + reason, { | ||
extensions | ||
}); | ||
} | ||
function createResultForAbort(reason, extensions) { | ||
return { | ||
errors: [createGraphQLErrorForAbort(reason, extensions)] | ||
}; | ||
} | ||
function hashSHA256(str) { | ||
const textEncoder = new TextEncoder(); | ||
const utf8 = textEncoder.encode(str); | ||
return mapMaybePromise( | ||
crypto.subtle.digest("SHA-256", utf8), | ||
(hashBuffer) => { | ||
let hashHex = ""; | ||
for (const bytes of new Uint8Array(hashBuffer)) { | ||
hashHex += bytes.toString(16).padStart(2, "0"); | ||
} | ||
return hashHex; | ||
} | ||
); | ||
} | ||
const DELIM = "\n\n"; | ||
@@ -159,0 +188,0 @@ function isReadableStream(value) { |
{ | ||
"name": "@graphql-tools/executor-http", | ||
"version": "1.2.0-alpha-753096403f92c5dbcdd17828acdd17a1aa53a51e", | ||
"version": "1.2.0-alpha-7c456f6ecf6b55a344a74e57ce6ba15bf509d93c", | ||
"type": "module", | ||
@@ -5,0 +5,0 @@ "description": "A set of utils for faster development of GraphQL tools", |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
70980
1362