From 2c7a098e8f423bdb7543f97d562284c4e10674b8 Mon Sep 17 00:00:00 2001 From: Carson Full Date: Sat, 18 Sep 2021 17:58:50 -0500 Subject: [PATCH] Update Loader to use loader class types instead name strings This is a requirement from Nest 8 change where classes are registered by class instance instead of class name. https://github.com/nestjs/nest/pull/6141 https://github.com/nestjs/nest/issues/5591 --- .../data-loader/data-loader.interceptor.ts | 50 +++++++++++-------- src/core/data-loader/loader.decorator.ts | 19 ++----- 2 files changed, 34 insertions(+), 35 deletions(-) diff --git a/src/core/data-loader/data-loader.interceptor.ts b/src/core/data-loader/data-loader.interceptor.ts index 0e19de2603..4f04f3de98 100644 --- a/src/core/data-loader/data-loader.interceptor.ts +++ b/src/core/data-loader/data-loader.interceptor.ts @@ -3,13 +3,14 @@ import { ExecutionContext, Injectable, NestInterceptor, + Type, } from '@nestjs/common'; import { ContextIdFactory, ModuleRef } from '@nestjs/core'; import { GqlContextType, GqlExecutionContext } from '@nestjs/graphql'; import { Observable } from 'rxjs'; import { ServerException } from '../../common'; import { NEST_LOADER_CONTEXT_KEY } from './constants'; -import { NestDataLoader } from './loader.decorator'; +import { DataLoader, NestDataLoader } from './loader.decorator'; @Injectable() export class DataLoaderInterceptor implements NestInterceptor { @@ -25,26 +26,35 @@ export class DataLoaderInterceptor implements NestInterceptor { if (ctx[NEST_LOADER_CONTEXT_KEY] === undefined) { ctx[NEST_LOADER_CONTEXT_KEY] = { contextId: ContextIdFactory.create(), - getLoader: (type: string): Promise> => { - if (ctx[type] === undefined) { - ctx[type] = (async () => { - try { - return ( - await this.moduleRef.resolve>( - type, - ctx[NEST_LOADER_CONTEXT_KEY].contextId, - { strict: false } - ) - ).generateDataLoader(ctx); - } catch (e) { - throw new ServerException( - `The loader ${type} is not provided`, - e - ); - } - })(); + loaders: new Map< + Type>, + DataLoader + >(), + getLoader: ( + type: Type> + ): Promise> => { + if (!ctx[NEST_LOADER_CONTEXT_KEY].loaders.has(type)) { + ctx[NEST_LOADER_CONTEXT_KEY].loaders.set( + type, + (async () => { + try { + return ( + await this.moduleRef.resolve>( + type, + ctx[NEST_LOADER_CONTEXT_KEY].contextId, + { strict: false } + ) + ).generateDataLoader(ctx); + } catch (e) { + throw new ServerException( + `The loader ${type.name} is not provided`, + e + ); + } + })() + ); } - return ctx[type]; + return ctx[NEST_LOADER_CONTEXT_KEY].loaders.get(type); }, }; } diff --git a/src/core/data-loader/loader.decorator.ts b/src/core/data-loader/loader.decorator.ts index 5024d57279..226351f34a 100644 --- a/src/core/data-loader/loader.decorator.ts +++ b/src/core/data-loader/loader.decorator.ts @@ -1,4 +1,4 @@ -import { createParamDecorator, ExecutionContext } from '@nestjs/common'; +import { createParamDecorator, ExecutionContext, Type } from '@nestjs/common'; import { APP_INTERCEPTOR } from '@nestjs/core'; import { GqlExecutionContext, @@ -6,12 +6,7 @@ import { } from '@nestjs/graphql'; // eslint-disable-next-line no-restricted-imports -- the one spot we do want to import it import * as DataLoaderLib from 'dataloader'; -import { - AbstractClassType, - GqlContextType, - ID, - ServerException, -} from '../../common'; +import { GqlContextType, ID, ServerException } from '../../common'; import { NEST_LOADER_CONTEXT_KEY } from './constants'; import { DataLoaderInterceptor } from './data-loader.interceptor'; @@ -59,13 +54,7 @@ export interface NestDataLoader { * The decorator to be used within your graphql method. */ export const Loader = createParamDecorator( - (data: AbstractClassType, context: ExecutionContext) => { - let name = data?.name; - if (!name) { - throw new ServerException(`Invalid name provider to @Loader ('${name}')`); - } - name += 'Loader'; - + (type: Type>, context: ExecutionContext) => { if (context.getType() !== 'graphql') { throw new ServerException( '@Loader should only be used within the GraphQL context' @@ -79,6 +68,6 @@ export const Loader = createParamDecorator( ); } - return ctx[NEST_LOADER_CONTEXT_KEY].getLoader(name); + return ctx[NEST_LOADER_CONTEXT_KEY].getLoader(type); } );