Created
September 7, 2022 14:14
-
-
Save josephdpurcell/fc04cfd428a6ee9d7ffb64685e4fe3a6 to your computer and use it in GitHub Desktop.
Revisions
-
josephdpurcell created this gist
Sep 7, 2022 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,25 @@ import { ArgumentMetadata, createParamDecorator, ExecutionContext } from '@nestjs/common'; import { METADATA__PARAM_TYPE } from '../constants'; // METADATA__PARAM_TYPE = 'myType' import { paramTypeEnhancer } from './param-type.enhancer'; export const MyDecorator = createParamDecorator( async (data: unknown, ctx: ExecutionContext): Promise<any> => { const metatype = Reflect.getOwnMetadata(METADATA__PARAM_TYPE, ctx.getHandler()); // We build the argument metadata that @nestjs/class-validator is expecting. // Specifically, we specify the type as "custom" -- this is a special value // coming from NestJS and all custom decorators are "custom". The data is // left undefined (only a @Query or @Param type would have data). Last, the // metatype is the reference to the type. const argument: ArgumentMetadata = { type: 'custom', data: undefined, metatype: metatype, }; // Do processing here. You can even return a promise. // Often you want access to the request which can be done like this: const request = ctx.switchToHttp().getRequest(); }, [paramTypeEnhancer], ); This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,22 @@ import { ParamDecoratorEnhancer } from '@nestjs/common'; import { METADATA__PARAM_TYPE } from '../constants'; // METADATA__PARAM_TYPE = 'myType' /** * This enhancer grabs the Typescript type of the parameter and shoves it into * the metadata. We do this because the CustomParamFactory does not have access * to the type of param. */ export const paramTypeEnhancer: ParamDecoratorEnhancer = ( target: Record<string, unknown>, propertyKey: string, parameterIndex: number, ): void => { // Typescript adds the "design:paramtypes" metadata with an array of class // types where the keys are the method argument index and the value is the // class type. const paramTypes = Reflect.getOwnMetadata('design:paramtypes', target, propertyKey); // We can use the parameterIndex to retrieve the specific type we want. const metatype = paramTypes[parameterIndex]; // Now, we assign the parameter type to the metadata at a key we know. Reflect.defineMetadata(METADATA__PARAM_TYPE, metatype, target[propertyKey]); };