diff --git a/src/RoutingControllers.ts b/src/RoutingControllers.ts index 7b4e3231..ccfe6a6b 100644 --- a/src/RoutingControllers.ts +++ b/src/RoutingControllers.ts @@ -172,6 +172,7 @@ export class RoutingControllers { * Creates interceptors from the given "use interceptors". */ protected prepareInterceptors(uses: InterceptorMetadata[]): Function[] { + uses.sort((interceptor1, interceptor2) => interceptor2.priority - interceptor1.priority); return uses.map(use => { if (use.interceptor.prototype && use.interceptor.prototype.intercept) { // if this is function instance of InterceptorInterface diff --git a/src/decorator/UseInterceptor.ts b/src/decorator/UseInterceptor.ts index 0e76c8fb..1dfb27bd 100644 --- a/src/decorator/UseInterceptor.ts +++ b/src/decorator/UseInterceptor.ts @@ -1,5 +1,15 @@ import { getMetadataArgsStorage } from '../index'; import { Action } from '../Action'; +import { UseInterceptorMetadataArgs } from '../metadata/args/UseInterceptorMetadataArgs'; + +/** + * Specifies a given interceptor middleware or interceptor function, to which UseInterceptorMetadataArgs can be applied, to be used for controller or controller action. + * Must be set to controller action or controller class. + */ +export function UseInterceptor( + optionsOrInterceptor: Partial | Function, + ...interceptors: Array +): Function; /** * Specifies a given interceptor middleware or interceptor function to be used for controller or controller action. @@ -7,6 +17,15 @@ import { Action } from '../Action'; */ export function UseInterceptor(...interceptors: Array): Function; +/** + * Specifies a given interceptor middleware or interceptor function, to which UseInterceptorMetadataArgs can be applied, to be used for controller or controller action. + * Must be set to controller action or controller class. + */ +export function UseInterceptor( + optionsOrInterceptor: Partial | ((action: Action, result: any) => any), + ...interceptors: Array<(action: Action, result: any) => any> +): Function; + /** * Specifies a given interceptor middleware or interceptor function to be used for controller or controller action. * Must be set to controller action or controller class. @@ -14,16 +33,25 @@ export function UseInterceptor(...interceptors: Array): Function; export function UseInterceptor(...interceptors: Array<(action: Action, result: any) => any>): Function; /** - * Specifies a given interceptor middleware or interceptor function to be used for controller or controller action. + * Specifies a given interceptor middleware or interceptor function, to which UseInterceptorMetadataArgs can be applied, to be used for controller or controller action. * Must be set to controller action or controller class. */ -export function UseInterceptor(...interceptors: Array any)>): Function { +export function UseInterceptor( + optionsOrInterceptor: Partial | Function | ((action: Action, result: any) => any), + ...interceptors: Array any)> +): Function { + const optionsIsAnInterceptor = optionsOrInterceptor instanceof Function || Array.isArray(optionsOrInterceptor); + const options: Partial = optionsIsAnInterceptor + ? {} + : (optionsOrInterceptor as Partial); return function (objectOrFunction: Object | Function, methodName?: string) { - interceptors.forEach(interceptor => { + [...(optionsIsAnInterceptor ? [optionsOrInterceptor as Function] : []), ...interceptors].forEach(interceptor => { getMetadataArgsStorage().useInterceptors.push({ + ...options, interceptor: interceptor, target: methodName ? objectOrFunction.constructor : (objectOrFunction as Function), method: methodName, + priority: options.priority ?? 0, }); }); };