import { Binding , BindingScope , Constructor , Context , createBindingFromClass , filterByKey , filterByServiceInterface , } from '@loopback/core' ; import { ExpressContext } from 'apollo-server-express/dist/ApolloServer' ; import debugFactory from 'debug' ; import { ContainerType , ResolverData } from 'type-graphql' ; import { GraphQLBindings , GraphQLTags } from './keys' ; const debug = debugFactory ( 'loopback:graphql:container' ) ; const MIDDLEWARE_CONTEXT = Symbol . for ( 'loopback.middleware.context' ) ; /**
 * Context for graphql resolver resolution
 */ export class GraphQLResolutionContext extends Context { constructor ( parent , readonly resolverClass , readonly resolverData ) { super ( parent ) ; this . bind ( GraphQLBindings . RESOLVER_DATA ) . to ( resolverData ) ; this . bind ( GraphQLBindings . RESOLVER_CLASS ) . to ( resolverClass ) ; } } /**
 * Implementation of `ContainerType` to plug into `type-graphql` as the IoC
 * container
 */ export class LoopBackContainer implements ContainerType { constructor ( readonly ctx ) { } get ( resolverClass , resolverData ) { debug ( 'Resolving a resolver %s' , resolverClass . name , resolverData ) ; const graphQLCtx = resolverData . context as ExpressContext ; const reqCtx = ( graphQLCtx ?. req as any ) ?. [ MIDDLEWARE_CONTEXT ] ; const parent = reqCtx ?? this . ctx ; const resolutionCtx = new GraphQLResolutionContext ( parent , resolverClass , resolverData ) ; if ( reqCtx == null ) { resolutionCtx . scope = BindingScope . REQUEST ; } const resolverBinding = createBindingFromClass ( resolverClass , { defaultNamespace : GraphQLBindings . RESOLVERS , } ) ; const bindings = this . ctx . findByTag ( GraphQLTags . RESOLVER ) . filter ( filterByServiceInterface ( resolverClass ) ) ; if ( bindings . length === 0 ) { debug ( 'Resolver %s not found in context %s' , resolverClass . name , this . ctx . name ) ; resolutionCtx . add ( resolverBinding ) ; return resolutionCtx . getValueOrPromise ( resolverBinding . key ) ; } let found ; if ( bindings . length === 1 ) { found = bindings [ 0 ] ; } else { found = bindings . find ( filterByKey ( resolverBinding . key ) ) ; if ( ! found ) { found = bindings [ 0 ] ; } } debug ( 'Resolver %s found in context %s' , resolverClass . name , resolutionCtx . name , found ) ; return resolutionCtx . getValueOrPromise ( found . key ) ; } }