@graphql-mesh/fusion-runtime
Version:
Runtime for GraphQL Mesh Fusion Supergraph
228 lines (221 loc) • 12.3 kB
TypeScript
import * as _graphql_tools_utils from '@graphql-tools/utils';
import { ExecutionRequest, MaybePromise, Executor, Maybe, TypeSource, IResolvers, DisposableExecutor } from '@graphql-tools/utils';
import { Transport, TransportEntry, TransportContext } from '@graphql-mesh/transport-common';
export { TransportEntry, TransportGetSubgraphExecutor, TransportGetSubgraphExecutorOptions } from '@graphql-mesh/transport-common';
import { Logger, OnDelegateHook } from '@graphql-mesh/types';
import { Subschema, DelegationPlanBuilder, MergedTypeResolver, SubschemaConfig } from '@graphql-tools/delegate';
import * as graphql from 'graphql';
import { GraphQLSchema, ExecutionResult, GraphQLError, FragmentDefinitionNode, SelectionNode, SelectionSetNode, DocumentNode } from 'graphql';
import { GraphQLResolveInfo, GraphQLOutputType } from 'graphql/type';
import { DisposableSymbols } from '@whatwg-node/disposablestack';
type Transports = {
[key: string]: MaybePromise<Transport | {
default: Transport;
}>;
} | ((kind: string) => MaybePromise<Transport | {
default: Transport;
}>);
declare const subgraphNameByExecutionRequest: WeakMap<ExecutionRequest<any, any, any, Record<string, any>, any>, string>;
/**
* This function creates a executor factory that uses the transport packages,
* and wraps them with the hooks
*/
declare function getOnSubgraphExecute({ onSubgraphExecuteHooks, transportContext, transportEntryMap, getSubgraphSchema, transportExecutorStack, transports, getDisposeReason, }: {
onSubgraphExecuteHooks: OnSubgraphExecuteHook[];
transports?: Transports;
transportContext?: TransportContext;
transportEntryMap: Record<string, TransportEntry>;
getSubgraphSchema(subgraphName: string): GraphQLSchema;
transportExecutorStack: AsyncDisposableStack;
getDisposeReason?: () => GraphQLError | undefined;
}): (subgraphName: string, executionRequest: ExecutionRequest) => MaybePromise<_graphql_tools_utils.MaybeAsyncIterable<_graphql_tools_utils.ExecutionResult<any, any>>>;
interface WrapExecuteWithHooksOptions {
executor: Executor;
onSubgraphExecuteHooks: OnSubgraphExecuteHook[];
subgraphName: string;
transportEntryMap?: Record<string, TransportEntry>;
getSubgraphSchema: (subgraphName: string) => GraphQLSchema;
transportContext?: TransportContext;
}
declare module 'graphql' {
interface GraphQLResolveInfo {
executionRequest?: ExecutionRequest;
}
}
/**
* This function wraps the executor created by the transport package
* with `onSubgraphExecuteHooks` to hook into the execution phase of subgraphs
*/
declare function wrapExecutorWithHooks({ executor: baseExecutor, onSubgraphExecuteHooks, subgraphName, transportEntryMap, getSubgraphSchema, transportContext, }: WrapExecuteWithHooksOptions): Executor;
interface UnifiedGraphPlugin<TContext> {
onSubgraphExecute?: OnSubgraphExecuteHook<TContext>;
onDelegationPlan?: OnDelegationPlanHook<TContext>;
onDelegationStageExecute?: OnDelegationStageExecuteHook<TContext>;
}
type OnSubgraphExecuteHook<TContext = any> = (payload: OnSubgraphExecutePayload<TContext>) => MaybePromise<Maybe<OnSubgraphExecuteDoneHook | void>>;
interface OnSubgraphExecutePayload<TContext> {
subgraph: GraphQLSchema;
subgraphName: string;
transportEntry?: TransportEntry;
executionRequest: ExecutionRequest<any, TContext>;
setExecutionRequest(executionRequest: ExecutionRequest): void;
executor: Executor;
setExecutor(executor: Executor): void;
requestId?: string;
logger?: Logger;
}
interface OnSubgraphExecuteDonePayload {
result: AsyncIterable<ExecutionResult> | ExecutionResult;
setResult(result: AsyncIterable<ExecutionResult> | ExecutionResult): void;
}
type OnSubgraphExecuteDoneHook = (payload: OnSubgraphExecuteDonePayload) => MaybePromise<Maybe<OnSubgraphExecuteDoneResult | void>>;
type OnSubgraphExecuteDoneResultOnNext = (payload: OnSubgraphExecuteDoneOnNextPayload) => MaybePromise<void>;
interface OnSubgraphExecuteDoneOnNextPayload {
result: ExecutionResult;
setResult(result: ExecutionResult): void;
}
type OnSubgraphExecuteDoneResultOnEnd = () => MaybePromise<void>;
type OnSubgraphExecuteDoneResult = {
onNext?: OnSubgraphExecuteDoneResultOnNext;
onEnd?: OnSubgraphExecuteDoneResultOnEnd;
};
type OnDelegationPlanHook<TContext> = (payload: OnDelegationPlanHookPayload<TContext>) => Maybe<OnDelegationPlanDoneHook | void>;
interface OnDelegationPlanHookPayload<TContext> {
supergraph: GraphQLSchema;
subgraph: string;
sourceSubschema: Subschema<any, any, any, TContext>;
typeName: string;
variables: Record<string, any>;
fragments: Record<string, FragmentDefinitionNode>;
fieldNodes: SelectionNode[];
context: TContext;
requestId?: string;
logger?: Logger;
info?: GraphQLResolveInfo;
delegationPlanBuilder: DelegationPlanBuilder;
setDelegationPlanBuilder(delegationPlanBuilder: DelegationPlanBuilder): void;
}
type OnDelegationPlanDoneHook = (payload: OnDelegationPlanDonePayload) => Maybe<void>;
interface OnDelegationPlanDonePayload {
delegationPlan: ReturnType<DelegationPlanBuilder>;
setDelegationPlan: (delegationPlan: ReturnType<DelegationPlanBuilder>) => void;
}
type OnDelegationStageExecuteHook<TContext> = (payload: OnDelegationStageExecutePayload<TContext>) => Maybe<OnDelegationStageExecuteDoneHook>;
interface OnDelegationStageExecutePayload<TContext> {
object: any;
context: TContext;
info: GraphQLResolveInfo;
subgraph: string;
subschema: Subschema<any, any, any, TContext>;
selectionSet: SelectionSetNode;
key?: any;
type: GraphQLOutputType;
resolver: MergedTypeResolver<TContext>;
setResolver: (resolver: MergedTypeResolver<TContext>) => void;
typeName: string;
requestId?: string;
logger?: Logger;
}
type OnDelegationStageExecuteDoneHook = (payload: OnDelegationStageExecuteDonePayload) => void;
interface OnDelegationStageExecuteDonePayload {
result: any;
setResult: (result: any) => void;
}
declare function compareSchemas(a: DocumentNode | string | GraphQLSchema, b: DocumentNode | string | GraphQLSchema): boolean;
declare function compareSubgraphNames(name1: string, name2: string): boolean;
declare function wrapMergedTypeResolver<TContext extends Record<string, any>>(originalResolver: MergedTypeResolver<TContext>, typeName: string, onDelegationStageExecuteHooks: OnDelegationStageExecuteHook<TContext>[], baseLogger?: Logger): MergedTypeResolver<TContext>;
declare function millisecondsToStr(milliseconds: number): string;
type TransportEntryAdditions = {
[subgraph: '*' | string]: Partial<TransportEntry>;
};
declare function ensureSchema(source: GraphQLSchema | DocumentNode | string): GraphQLSchema;
type UnifiedGraphHandler = (opts: UnifiedGraphHandlerOpts) => UnifiedGraphHandlerResult;
interface UnifiedGraphHandlerOpts {
unifiedGraph: GraphQLSchema;
additionalTypeDefs?: TypeSource;
additionalResolvers?: IResolvers<unknown, any> | IResolvers<unknown, any>[];
onSubgraphExecute: ReturnType<typeof getOnSubgraphExecute>;
onDelegationStageExecuteHooks?: OnDelegationStageExecuteHook<any>[];
transportEntryAdditions?: TransportEntryAdditions;
/**
* Whether to batch the subgraph executions.
* @default true
*/
batch?: boolean;
logger?: Logger;
}
interface UnifiedGraphHandlerResult {
unifiedGraph: GraphQLSchema;
transportEntryMap: Record<string, TransportEntry>;
subschemas: SubschemaConfig[];
additionalResolvers: IResolvers[];
}
interface UnifiedGraphManagerOptions<TContext> {
getUnifiedGraph(ctx: TransportContext): MaybePromise<GraphQLSchema | string | DocumentNode>;
handleUnifiedGraph?: UnifiedGraphHandler;
transports?: Transports;
transportEntryAdditions?: TransportEntryAdditions;
/** Schema polling interval in milliseconds. */
pollingInterval?: number;
additionalTypeDefs?: TypeSource;
additionalResolvers?: IResolvers<unknown, TContext> | IResolvers<unknown, TContext>[];
transportContext?: TransportContext;
onSubgraphExecuteHooks?: OnSubgraphExecuteHook<TContext>[];
onDelegateHooks?: OnDelegateHook<unknown>[];
onDelegationPlanHooks?: OnDelegationPlanHook<TContext>[];
onDelegationStageExecuteHooks?: OnDelegationStageExecuteHook<TContext>[];
/**
* Whether to batch the subgraph executions.
* @default true
*/
batch?: boolean;
}
declare class UnifiedGraphManager<TContext> implements AsyncDisposable {
private opts;
private batch;
private handleUnifiedGraph;
private unifiedGraph?;
private lastLoadedUnifiedGraph?;
private onSubgraphExecuteHooks;
private onDelegationPlanHooks;
private onDelegationStageExecuteHooks;
private inContextSDK;
private initialUnifiedGraph$?;
private polling$?;
private _transportEntryMap?;
private _transportExecutorStack?;
private lastLoadTime?;
constructor(opts: UnifiedGraphManagerOptions<TContext>);
private cleanup;
private ensureUnifiedGraph;
private disposeReason;
private handleLoadedUnifiedGraph;
private getAndSetUnifiedGraph;
getUnifiedGraph(): MaybePromise<GraphQLSchema>;
getContext<T extends {} = {}>(base?: T): MaybePromise<T>;
getTransportEntryMap(): MaybePromise<Record<string, TransportEntry<Record<string, any>>>>;
invalidateUnifiedGraph(): MaybePromise<GraphQLSchema>;
[DisposableSymbols.asyncDispose](): PromiseLike<void>;
}
declare const restoreExtraDirectives: (schema: GraphQLSchema) => GraphQLSchema;
declare function getStitchingDirectivesTransformerForSubschema(): (subschemaConfig: SubschemaConfig) => SubschemaConfig;
declare function handleResolveToDirectives(typeDefsOpt: TypeSource, additionalTypeDefs: TypeSource, additionalResolvers: IResolvers[]): graphql.DocumentNode;
declare const handleFederationSupergraph: UnifiedGraphHandler;
interface HandleFederationSubschemaOpts {
subschemaConfig: SubschemaConfig & {
endpoint?: string;
};
realSubgraphNameMap?: Map<string, string>;
schemaDirectives?: Record<string, any>;
transportEntryMap: Record<string, TransportEntry>;
additionalTypeDefs: TypeSource[];
stitchingDirectivesTransformer: (subschemaConfig: SubschemaConfig) => SubschemaConfig;
onSubgraphExecute: ReturnType<typeof getOnSubgraphExecute>;
}
declare function handleFederationSubschema({ subschemaConfig, realSubgraphNameMap, schemaDirectives, transportEntryMap, additionalTypeDefs, stitchingDirectivesTransformer, onSubgraphExecute, }: HandleFederationSubschemaOpts): SubschemaConfig<any, any, any, Record<string, any>> & {
endpoint?: string;
};
type SdkRequester = (document: DocumentNode, variables?: any, operationContext?: any) => any;
declare function getExecutorForUnifiedGraph<TContext>(opts: UnifiedGraphManagerOptions<TContext>): DisposableExecutor<TContext>;
declare function getSdkRequesterForUnifiedGraph(opts: UnifiedGraphManagerOptions<any>): SdkRequester;
export { type HandleFederationSubschemaOpts, type OnDelegationPlanDoneHook, type OnDelegationPlanDonePayload, type OnDelegationPlanHook, type OnDelegationPlanHookPayload, type OnDelegationStageExecuteDoneHook, type OnDelegationStageExecuteDonePayload, type OnDelegationStageExecuteHook, type OnDelegationStageExecutePayload, type OnSubgraphExecuteDoneHook, type OnSubgraphExecuteDoneOnNextPayload, type OnSubgraphExecuteDonePayload, type OnSubgraphExecuteDoneResult, type OnSubgraphExecuteDoneResultOnEnd, type OnSubgraphExecuteDoneResultOnNext, type OnSubgraphExecuteHook, type OnSubgraphExecutePayload, type TransportEntryAdditions, type Transports, type UnifiedGraphHandler, type UnifiedGraphHandlerOpts, type UnifiedGraphHandlerResult, UnifiedGraphManager, type UnifiedGraphManagerOptions, type UnifiedGraphPlugin, type WrapExecuteWithHooksOptions, compareSchemas, compareSubgraphNames, ensureSchema, getExecutorForUnifiedGraph, getOnSubgraphExecute, getSdkRequesterForUnifiedGraph, getStitchingDirectivesTransformerForSubschema, handleFederationSubschema, handleFederationSupergraph, handleResolveToDirectives, millisecondsToStr, restoreExtraDirectives, subgraphNameByExecutionRequest, wrapExecutorWithHooks, wrapMergedTypeResolver };