Skip to content

Commit

Permalink
feat: add opts object to loaders
Browse files Browse the repository at this point in the history
  • Loading branch information
Davide-Gheri committed Feb 18, 2021
1 parent 5ad6dfe commit 2a94abf
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 22 deletions.
72 changes: 53 additions & 19 deletions lib/services/loaders-explorer.service.ts
Original file line number Diff line number Diff line change
@@ -1,35 +1,47 @@
import { Inject, Injectable } from '@nestjs/common';
import { BaseExplorerService } from '@nestjs/graphql/dist/services';
import { head, identity } from 'lodash';
import { Loader, MercuriusLoaders } from 'mercurius';
import { FastifyReply } from 'fastify';
import { createContextId, REQUEST } from '@nestjs/core';
import { ModulesContainer } from '@nestjs/core/injector/modules-container';
import { MetadataScanner } from '@nestjs/core/metadata-scanner';
import { head, identity } from 'lodash';
import { ExternalContextCreator } from '@nestjs/core/helpers/external-context-creator';
import { REQUEST_CONTEXT_ID } from '@nestjs/core/router/request/request-constants';
import { Injector } from '@nestjs/core/injector/injector';
import { InternalCoreModule } from '@nestjs/core/injector/internal-core-module';
import {
ContextId,
InstanceWrapper,
} from '@nestjs/core/injector/instance-wrapper';
import { Module } from '@nestjs/core/injector/module';
import { Inject, Injectable } from '@nestjs/common';
import { isUndefined } from '@nestjs/common/utils/shared.utils';
import { extractMetadata } from '../utils/extract-metadata.util';
import { createContextId, REQUEST } from '@nestjs/core';
import { FieldMiddleware, TypeMetadataStorage } from '@nestjs/graphql';
import { BaseExplorerService } from '@nestjs/graphql/dist/services';
import { ObjectTypeMetadata } from '@nestjs/graphql/dist/schema-builder/metadata/object-type.metadata';
import {
PARAM_ARGS_METADATA,
GRAPHQL_MODULE_OPTIONS,
FIELD_RESOLVER_MIDDLEWARE_METADATA,
} from '@nestjs/graphql/dist/graphql.constants';
import { MercuriusGqlParamsFactory } from '../factories/params.factory';
import { MercuriusModuleOptions } from '../interfaces';
import {
LoaderQuery,
MercuriusModuleOptions,
LoaderCtx,
LoaderMiddleware,
} from '../interfaces';
import { MercuriusParamType } from '../mercurius-param-type.enum';
import { REQUEST_CONTEXT_ID } from '@nestjs/core/router/request/request-constants';
import { Injector } from '@nestjs/core/injector/injector';
import { InternalCoreModule } from '@nestjs/core/injector/internal-core-module';
import { extractMetadata } from '../utils/extract-metadata.util';
import { decorateLoaderResolverWithMiddleware } from '../utils/decorate-loader-resolver.util';

interface LoaderMetadata {
type: string;
methodName: string;
name: string;
callback: Function;
callback: Loader;
opts?: {
cache: boolean;
};
}

@Injectable()
Expand All @@ -47,7 +59,7 @@ export class LoadersExplorerService extends BaseExplorerService {
super();
}

explore() {
explore(): MercuriusLoaders {
const modules = this.getModules(
this.modulesContainer,
this.gqlOptions.include || [],
Expand All @@ -63,9 +75,10 @@ export class LoadersExplorerService extends BaseExplorerService {
}
acc[loader.type][loader.name] = {
loader: loader.callback,
opts: loader.opts,
};
return acc;
}, {});
}, {} as MercuriusLoaders);
}

filterLoaders(wrapper: InstanceWrapper, moduleRef: Module): LoaderMetadata[] {
Expand All @@ -81,17 +94,28 @@ export class LoadersExplorerService extends BaseExplorerService {
return true;
};

const loaders = this.metadataScanner.scanFromPrototype(
const loaders: Omit<
LoaderMetadata,
'callback' | 'opts'
>[] = this.metadataScanner.scanFromPrototype(
instance,
prototype,
(name) => {
return extractMetadata(instance, prototype, name, predicate);
},
);

const isRequestScoped = !wrapper.isDependencyTreeStatic();
return loaders
.filter((loader) => !!loader)
.map((loader) => {
const objectTypeMetadata = this.getObjectTypeMetadataByName(
loader.type,
);
const fieldOptions = objectTypeMetadata?.properties.find(
(p) => p.schemaName === loader.name,
)?.options as { opts?: { cache: boolean } };

const createContext = (transform?: Function) =>
this.createContextCallback(
instance,
Expand All @@ -104,6 +128,7 @@ export class LoadersExplorerService extends BaseExplorerService {
);
return {
...loader,
opts: fieldOptions?.opts,
callback: createContext(),
};
});
Expand Down Expand Up @@ -220,19 +245,20 @@ export class LoadersExplorerService extends BaseExplorerService {
}

private registerFieldMiddlewareIfExists<
TSource extends object = any,
TContext = {},
TSource extends LoaderQuery[] = any,
TContext extends LoaderCtx = LoaderCtx,
TArgs = { [argName: string]: any },
TOutput = any
>(resolverFn: Function, instance: object, methodKey: string) {
>(resolverFn: Loader, instance: object, methodKey: string) {
const fieldMiddleware = Reflect.getMetadata(
FIELD_RESOLVER_MIDDLEWARE_METADATA,
instance[methodKey],
);

const middlewareFunctions = (
this.gqlOptions?.buildSchemaOptions?.fieldMiddleware || []
).concat(fieldMiddleware || []);
const middlewareFunctions = ((this.gqlOptions?.buildSchemaOptions
?.fieldMiddleware || []) as FieldMiddleware<TArgs, TContext>[]).concat(
fieldMiddleware || [],
);

if (middlewareFunctions?.length === 0) {
return resolverFn;
Expand All @@ -246,4 +272,12 @@ export class LoadersExplorerService extends BaseExplorerService {
middlewareFunctions,
);
}

private getObjectTypeMetadataByName(
name: string,
): ObjectTypeMetadata | undefined {
return TypeMetadataStorage.getObjectTypesMetadata().find(
(m) => m.name === name,
);
}
}
6 changes: 3 additions & 3 deletions lib/utils/decorate-loader-resolver.util.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { LoaderMiddleware } from '../interfaces/loader-middleware.interface';
import { LoaderQuery, LoaderMiddleware, LoaderCtx } from '../interfaces';

export function decorateLoaderResolverWithMiddleware<
TSource extends object = any,
TContext = {},
TSource extends LoaderQuery[] = any,
TContext extends LoaderCtx = LoaderCtx,
TOutput = any
>(
originalResolveFnFactory: (...args: [TSource, TContext]) => Function,
Expand Down

0 comments on commit 2a94abf

Please sign in to comment.