diff --git a/README.md b/README.md index 0964a73e..78f4e173 100644 --- a/README.md +++ b/README.md @@ -115,17 +115,18 @@ export declare type IMiddlewareResolver< info: GraphQLResolveInfo, ) => Promise -export interface IMiddlewareWithFragment< +export interface IMiddlewareWithOptions< TSource = any, TContext = any, TArgs = any > { - fragment: string + fragment?: IMiddlewareFragment + fragments?: IMiddlewareFragment[] resolve?: IMiddlewareResolver } export type IMiddlewareFunction = - | IMiddlewareWithFragment + | IMiddlewareWithOptions | IMiddlewareResolver interface IMiddlewareTypeMap { @@ -210,8 +211,14 @@ const middlewareWithFragments = { return resolve(foo) }, }, - Mutation: (resolve, parent, args, ctx, info) => { - return resolve(parent, customArgs) + Mutation: { + fragments: [ + `fragment NodeID on Node { id }`, + `fragment NodeSecret on Node { secret }`, + ], + resolve: (resolve, parent, args, ctx, info) => { + return resolve(parent, customArgs) + }, }, } diff --git a/src/applicator.ts b/src/applicator.ts index d4813988..1f8d921f 100644 --- a/src/applicator.ts +++ b/src/applicator.ts @@ -5,13 +5,14 @@ import { GraphQLSchema, defaultFieldResolver, } from 'graphql' -import { IResolverOptions, IResolvers } from 'graphql-tools' import { IMiddlewareFunction, IMiddlewareResolver, IMiddlewareFieldMap, IApplyOptions, IMiddleware, + IResolvers, + IResolverOptions, } from './types' import { isMiddlewareFunction, diff --git a/src/fragments.ts b/src/fragments.ts index 7efc0bfe..61cde5e5 100644 --- a/src/fragments.ts +++ b/src/fragments.ts @@ -1,5 +1,4 @@ -import { FragmentReplacement } from './types' -import { IResolvers } from 'graphql-tools/dist/Interfaces' +import { FragmentReplacement, IResolvers } from './types' export function extractFragmentReplacements( resolvers: IResolvers, @@ -16,6 +15,14 @@ export function extractFragmentReplacements( fragment: fieldResolver.fragment, }) } + if (typeof fieldResolver === 'object' && fieldResolver.fragments) { + for (const fragment in fieldResolver.fragments) { + fragmentReplacements.push({ + field: fieldName, + fragment, + }) + } + } } } diff --git a/src/types.ts b/src/types.ts index 0132d934..ffc6ba2b 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,6 +1,14 @@ -import { GraphQLResolveInfo, GraphQLSchema } from 'graphql' +import { + GraphQLResolveInfo, + GraphQLSchema, + GraphQLTypeResolver, + GraphQLIsTypeOfFn, +} from 'graphql' +import { MergeInfo } from 'graphql-tools' -// Middleware +// Middleware Tree + +export declare type IMiddlewareFragment = string export declare type IMiddlewareResolver< TSource = any, @@ -14,17 +22,18 @@ export declare type IMiddlewareResolver< info: GraphQLResolveInfo, ) => Promise -export interface IMiddlewareWithFragment< +export interface IMiddlewareWithOptions< TSource = any, TContext = any, TArgs = any > { - fragment: string + fragment?: IMiddlewareFragment + fragments?: IMiddlewareFragment[] resolve?: IMiddlewareResolver } export type IMiddlewareFunction = - | IMiddlewareWithFragment + | IMiddlewareWithOptions | IMiddlewareResolver export interface IMiddlewareTypeMap< @@ -64,6 +73,8 @@ export declare type IMiddleware = | IMiddlewareFunction | IMiddlewareTypeMap +// Middleware + export declare type IApplyOptions = { onlyDeclaredResolvers: boolean } @@ -73,7 +84,34 @@ export declare type GraphQLSchemaWithFragmentReplacements = GraphQLSchema & { fragmentReplacements?: FragmentReplacement[] } +// Fragments (inspired by graphql-tools) + export interface FragmentReplacement { field: string fragment: string } + +export interface IResolvers { + [key: string]: IResolverObject +} + +export interface IResolverObject { + [key: string]: + | IFieldResolver + | IResolverOptions +} + +export interface IResolverOptions { + fragment?: string + resolve?: IFieldResolver + subscribe?: IFieldResolver + __resolveType?: GraphQLTypeResolver + __isTypeOf?: GraphQLIsTypeOfFn +} + +export type IFieldResolver = ( + source: TSource, + args: { [argument: string]: any }, + context: TContext, + info: GraphQLResolveInfo & { mergeInfo: MergeInfo }, +) => any diff --git a/src/utils.ts b/src/utils.ts index 450f3ce2..543fab4c 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,7 +1,7 @@ import { GraphQLObjectType, GraphQLInterfaceType } from 'graphql' import { IMiddlewareResolver, - IMiddlewareWithFragment, + IMiddlewareWithOptions, IMiddlewareFunction, IMiddlewareGenerator, } from './types' @@ -20,7 +20,7 @@ export function isMiddlewareResolver( export function isMiddlewareWithFragment( obj: any, -): obj is IMiddlewareWithFragment { +): obj is IMiddlewareWithOptions { return ( typeof obj.fragment === 'string' && (obj.resolve === undefined || isMiddlewareResolver(obj.resolve))