diff --git a/packages/loaders/url/src/index.ts b/packages/loaders/url/src/index.ts index f2411f107d7..e86c1fb44d2 100644 --- a/packages/loaders/url/src/index.ts +++ b/packages/loaders/url/src/index.ts @@ -21,7 +21,7 @@ import { fetch as crossFetch } from 'cross-fetch'; import { introspectSchema, wrapSchema } from '@graphql-tools/wrap'; import { ClientOptions, createClient } from 'graphql-ws'; import WebSocket from 'isomorphic-ws'; -import syncFetch from 'sync-fetch'; +import syncFetchImported from 'sync-fetch'; import isPromise from 'is-promise'; import { extractFiles, isExtractableFile } from 'extract-files'; import FormData from 'form-data'; @@ -33,6 +33,15 @@ import _ from 'lodash'; import { ValueOrPromise } from 'value-or-promise'; import { isLiveQueryOperationDefinitionNode } from '@n1ru4l/graphql-live-query'; +const syncFetch: SyncFetchFn = (input: RequestInfo, init?: RequestInit): SyncResponse => { + if (typeof input === 'string') { + delete init?.signal; + } else { + delete (input as any).signal; + } + return syncFetchImported(input, init); +}; + export type AsyncFetchFn = typeof import('cross-fetch').fetch; export type SyncFetchFn = (input: RequestInfo, init?: RequestInit) => SyncResponse; export type SyncResponse = Omit & { @@ -41,10 +50,8 @@ export type SyncResponse = Omit & { }; export type FetchFn = AsyncFetchFn | SyncFetchFn; -// TODO: Should the types here be changed to T extends Record ? -export type AsyncImportFn = (moduleName: string) => PromiseLike; -// TODO: Should the types here be changed to T extends Record ? -export type SyncImportFn = (moduleName: string) => T; +export type AsyncImportFn = (moduleName: string) => PromiseLike; +export type SyncImportFn = (moduleName: string) => any; const asyncImport: AsyncImportFn = (moduleName: string) => import(moduleName); const syncImport: SyncImportFn = (moduleName: string) => require(moduleName); @@ -472,10 +479,10 @@ export class UrlLoader implements Loader { fetch: AsyncFetchFn, options?: Omit ): AsyncExecutor { - return async ({ document, variables, extensions }) => { + return async ({ document, variables, extensions, operationName }) => { const controller = new AbortController(); const query = print(document); - const finalUrl = this.prepareGETUrl({ baseUrl: endpoint, query, variables }); + const finalUrl = this.prepareGETUrl({ baseUrl: endpoint, query, variables, operationName, extensions }); return observableToAsyncIterable({ subscribe: observer => { const headers = Object.assign({}, options?.headers || {}, extensions?.headers || {}); @@ -530,17 +537,21 @@ export class UrlLoader implements Loader { if (customFetch) { if (typeof customFetch === 'string') { const [moduleName, fetchFnName] = customFetch.split('#'); - const moduleResult = importFn(moduleName); - if (isPromise(moduleResult)) { - return moduleResult.then(module => (fetchFnName ? (module as Record)[fetchFnName] : module)); - } else { - return fetchFnName ? (module as Record)[fetchFnName] : moduleResult; - } + return new ValueOrPromise(() => importFn(moduleName)) + .then(module => (fetchFnName ? (module as Record)[fetchFnName] : module)) + .resolve(); } else { return customFetch as any; } } - return importFn === asyncImport ? (typeof fetch === 'undefined' ? crossFetch : fetch) : syncFetch; + if (importFn === asyncImport) { + if (typeof fetch === 'undefined') { + return crossFetch as any; + } + return fetch as any; + } else { + return syncFetch; + } } private getDefaultMethodFromOptions(method: LoadFromUrlOptions['method'], defaultMethod: 'GET' | 'POST') { @@ -560,12 +571,9 @@ export class UrlLoader implements Loader { ): typeof WebSocket | PromiseLike { if (typeof options?.webSocketImpl === 'string') { const [moduleName, webSocketImplName] = options.webSocketImpl.split('#'); - const importedModule = importFn(moduleName); - if (isPromise(importedModule)) { - return importedModule.then(webSocketImplName ? importedModule[webSocketImplName] : importedModule); - } else { - return webSocketImplName ? (importedModule as Record)[webSocketImplName] : importedModule; - } + return new ValueOrPromise(() => importFn(moduleName)) + .then(importedModule => (webSocketImplName ? importedModule[webSocketImplName] : importedModule)) + .resolve(); } else { const websocketImpl = options?.webSocketImpl || WebSocket; return websocketImpl;