UNPKG

@toss/nestjs-aop

Version:

<!-- PROJECT LOGO --> <br /> <div align="center"> <a href="https://github.com/toss/nestjs-aop"> <img src="https://toss.tech/wp-content/uploads/2022/11/tech-article-nest-js-02.png" alt="Logo" height="200"> </a>

51 lines (47 loc) 1.8 kB
import { applyDecorators } from '@nestjs/common'; import { AopMetadata } from './core/types'; import { AddMetadata } from './utils'; /** * @param metadataKey equal to 1st argument of Aspect Decorator * @param metadata The value corresponding to the metadata of WrapParams. It can be obtained from LazyDecorator's warp method and used. */ export const createDecorator = ( metadataKey: symbol | string, metadata?: unknown, ): MethodDecorator => { const aopSymbol = Symbol('AOP_DECORATOR'); return applyDecorators( // 1. Add metadata to the method (target: object, propertyKey: string | symbol, descriptor: PropertyDescriptor) => { return AddMetadata<symbol | string, AopMetadata>(metadataKey, { originalFn: descriptor.value, metadata, aopSymbol, })(target, propertyKey, descriptor); }, // 2. Wrap the method before the lazy decorator is executed (_: object, propertyKey: string | symbol, descriptor: PropertyDescriptor) => { const originalFn = descriptor.value; descriptor.value = function (this: any, ...args: unknown[]) { const wrappedFn = this[aopSymbol]?.[propertyKey]; if (wrappedFn) { // If there is a wrapper stored in the method, use it return wrappedFn.apply(this, args); } // if there is no wrapper that comes out of method, call originalFn return originalFn.apply(this, args); }; /** * There are codes that using `function.name`. * Therefore the codes below are necessary. * * ex) @nestjs/swagger */ Object.defineProperty(descriptor.value, 'name', { value: propertyKey.toString(), writable: false, }); Object.setPrototypeOf(descriptor.value, originalFn); }, ); };