Skip to content

Commit

Permalink
fix(url-loader): handle operationName correctly
Browse files Browse the repository at this point in the history
  • Loading branch information
ardatan committed Jul 12, 2021
1 parent ae55af7 commit d718efa
Showing 1 changed file with 28 additions and 20 deletions.
48 changes: 28 additions & 20 deletions packages/loaders/url/src/index.ts
Expand Up @@ -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';
Expand All @@ -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<Response, 'json' | 'text'> & {
Expand All @@ -41,10 +50,8 @@ export type SyncResponse = Omit<Response, 'json' | 'text'> & {
};
export type FetchFn = AsyncFetchFn | SyncFetchFn;

// TODO: Should the types here be changed to T extends Record<string, any> ?
export type AsyncImportFn<T = unknown> = (moduleName: string) => PromiseLike<T>;
// TODO: Should the types here be changed to T extends Record<string, any> ?
export type SyncImportFn<T = unknown> = (moduleName: string) => T;
export type AsyncImportFn = (moduleName: string) => PromiseLike<any>;
export type SyncImportFn = (moduleName: string) => any;

const asyncImport: AsyncImportFn = (moduleName: string) => import(moduleName);
const syncImport: SyncImportFn = (moduleName: string) => require(moduleName);
Expand Down Expand Up @@ -472,10 +479,10 @@ export class UrlLoader implements Loader<LoadFromUrlOptions> {
fetch: AsyncFetchFn,
options?: Omit<LoadFromUrlOptions, 'subscriptionEndpoint'>
): AsyncExecutor<any, ExecutionExtensions> {
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 || {});
Expand Down Expand Up @@ -530,17 +537,21 @@ export class UrlLoader implements Loader<LoadFromUrlOptions> {
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<string, any>)[fetchFnName] : module));
} else {
return fetchFnName ? (module as Record<string, any>)[fetchFnName] : moduleResult;
}
return new ValueOrPromise(() => importFn(moduleName))
.then(module => (fetchFnName ? (module as Record<string, any>)[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') {
Expand All @@ -560,12 +571,9 @@ export class UrlLoader implements Loader<LoadFromUrlOptions> {
): typeof WebSocket | PromiseLike<typeof WebSocket> {
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<string, any>)[webSocketImplName] : importedModule;
}
return new ValueOrPromise(() => importFn(moduleName))
.then(importedModule => (webSocketImplName ? importedModule[webSocketImplName] : importedModule))
.resolve();
} else {
const websocketImpl = options?.webSocketImpl || WebSocket;
return websocketImpl;
Expand Down

0 comments on commit d718efa

Please sign in to comment.