import { GraphQLArgumentConfig, GraphQLFieldConfig, GraphQLInputType, GraphQLOutputType, GraphQLResolveInfo, GraphQLFieldConfigArgumentMap, } from 'graphql'; import * as graphql from './graphql'; import { InputTypeComposer } from './InputTypeComposer'; import { SchemaComposer } from './SchemaComposer'; import { ComposeArgumentConfig, ComposeArgumentType, ComposeArgumentConfigAsObject, ComposeFieldConfigArgumentMap, ComposeOutputType, ObjectTypeComposer, ArgsMap, } from './ObjectTypeComposer'; import { ProjectionType } from './utils/projection'; import { Extensions } from './utils/definitions'; export type ResolveParams = { source: TSource; args: TArgs; context: TContext; info: GraphQLResolveInfo; projection: Partial; [opt: string]: any; }; export type ResolverKinds = 'query' | 'mutation' | 'subscription'; export type ResolverFilterArgFn = ( query: any, value: any, resolveParams: ResolveParams ) => any; export type ResolverFilterArgConfig = { name: string; type: ComposeArgumentType; description?: string; query?: ResolverFilterArgFn; filterTypeNameFallback?: string; defaultValue?: any; }; export type ResolverSortArgFn = ( resolveParams: ResolveParams ) => any; export type ResolverSortArgConfig = { name: string; sortTypeNameFallback?: string; value: | { [key: string]: any } | ResolverSortArgFn | string | number | boolean | any[]; deprecationReason?: string | null; description?: string | null; }; export type ResolverOpts = { type?: ComposeOutputType; resolve?: ResolverRpCb; args?: ComposeFieldConfigArgumentMap; name?: string; displayName?: string; kind?: ResolverKinds; description?: string; parent?: Resolver; extensions?: Extensions; }; export type ResolverWrapCb< TNewSource, TPrevSource, TContext, TNewArgs = ArgsMap, TPrevArgs = ArgsMap > = ( newResolver: Resolver, prevResolver: Resolver ) => Resolver; export type ResolverRpCb = ( resolveParams: ResolveParams ) => Promise | any; export type ResolverNextRpCb = ( next: ResolverRpCb ) => ResolverRpCb; export type ResolverWrapArgsCb = ( prevArgs: GraphQLFieldConfigArgumentMap ) => ComposeFieldConfigArgumentMap; export type ResolverWrapTypeCb = ( prevType: GraphQLOutputType ) => ComposeOutputType; export type ResolveDebugOpts = { showHidden?: boolean; depth?: number; colors?: boolean; }; export type ResolverMiddleware = ( resolve: (source: TSource, args: TArgs, context: TContext, info: GraphQLResolveInfo) => any, source: TSource, args: TArgs, context: TContext, info: GraphQLResolveInfo ) => any; /** * The most interesting class in `graphql-compose`. The main goal of `Resolver` is to keep available resolve methods for Type and use them for building relation with other types. */ export class Resolver { public schemaComposer: SchemaComposer; public type: ComposeOutputType; public args: ComposeFieldConfigArgumentMap; public resolve: ( resolveParams: Partial> ) => Promise | any; public name: string; public displayName: string | void; public kind: ResolverKinds | void; public description: string | void; public parent: Resolver | void; public extensions?: Extensions; constructor( opts: ResolverOpts, schemaComposer: SchemaComposer ); /** * ----------------------------------------------- * Output type methods * ----------------------------------------------- */ public getType(): GraphQLOutputType; public getTypeComposer(): ObjectTypeComposer; public setType( gqType: ComposeOutputType ): Resolver; /** * ----------------------------------------------- * Args methods * ----------------------------------------------- */ public hasArg(argName: string): boolean; public getArg(argName: string): ComposeArgumentConfigAsObject; public getArgConfig(argName: string): GraphQLArgumentConfig; public getArgType(argName: string): GraphQLInputType; public getArgTC(argName: string): InputTypeComposer; public getArgs(): ComposeFieldConfigArgumentMap; public getArgNames(): string[]; public setArgs( args: ComposeFieldConfigArgumentMap ): Resolver; public setArg(argName: string, argConfig: ComposeArgumentConfig): this; public extendArg(argName: string, partialArgConfig: Partial): this; public addArgs(newArgs: ComposeFieldConfigArgumentMap): this; public removeArg(argNameOrArray: string | string[]): this; public removeOtherArgs(argNameOrArray: string | string[]): this; public reorderArgs(names: string[]): this; public cloneArg(argName: string, newTypeName: string): this; public isRequired(argName: string): boolean; public makeRequired(argNameOrArray: string | string[]): this; public makeOptional(argNameOrArray: string | string[]): this; public addFilterArg( opts: ResolverFilterArgConfig ): Resolver; public addSortArg( opts: ResolverSortArgConfig ): Resolver; /** * ----------------------------------------------- * Resolve methods * ----------------------------------------------- */ public getResolve(): ResolverRpCb; public setResolve( resolve: ResolverRpCb ): Resolver; /** * ----------------------------------------------- * Wrap methods * ----------------------------------------------- */ /** * You may construct a new resolver with wrapped logic: * * @example * const log = []; * * const mw1 = async (resolve, source, args, context, info) => { * log.push('m1.before'); * const res = await resolve(source, args, context, info); * log.push('m1.after'); * return res; * }; * * const mw2 = async (resolve, source, args, context, info) => { * log.push('m2.before'); * const res = await resolve(source, args, context, info); * log.push('m2.after'); * return res; * }; * * const newResolver = Resolver.withMiddlewares([mw1, mw2]); * await newResolver.resolve({}); * * expect(log).toEqual([ * 'm1.before', * 'm2.before', * 'call resolve', * 'm2.after', * 'm1.after' * ]); */ public withMiddlewares( middlewares: Array> ): Resolver; public wrap( cb?: ResolverWrapCb, newResolverOpts?: ResolverOpts ): Resolver; public wrapResolve( cb: ResolverNextRpCb, wrapperName?: string ): Resolver; public wrapArgs( cb: ResolverWrapArgsCb, wrapperName?: string ): Resolver; public wrapCloneArg( argName: string, newTypeName: string ): Resolver; public wrapType( cb: ResolverWrapTypeCb, wrapperName?: string ): Resolver; /** * ----------------------------------------------- * Misc methods * ----------------------------------------------- */ public getFieldConfig(opts?: { projection?: ProjectionType; }): GraphQLFieldConfig; public getKind(): ResolverKinds | void; public setKind(kind: string): this; public getDescription(): string | null; public setDescription(description: string | void): this; public get(path: string | string[]): any; public clone( opts?: ResolverOpts ): Resolver; /** * ----------------------------------------------- * Debug methods * ----------------------------------------------- */ public getNestedName(): string; public toString(colors?: boolean): string; public setDisplayName(name: string): this; public toDebugStructure(colors?: boolean): object; public debugExecTime(): Resolver; public debugParams( filterPaths: (string | string[]) | null, opts?: ResolveDebugOpts ): Resolver; public debugPayload( filterPaths: (string | string[]) | null, opts?: ResolveDebugOpts ): Resolver; public debug( filterDotPaths?: { params?: string | string[]; payload?: string | string[]; }, opts?: ResolveDebugOpts ): Resolver; }