All files / core/interceptors interceptors-consumer.ts

94.44% Statements 17/18
100% Branches 6/6
85.71% Functions 6/7
100% Lines 16/16
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57    1x 1x 1x 1x   1x               12x 10x   2x 2x                 2x 4x     2x               3x               3x   3x 3x          
import { NestInterceptor } from '@nestjs/common';
import { Controller } from '@nestjs/common/interfaces';
import { isEmpty } from '@nestjs/common/utils/shared.utils';
import { defer, from as fromPromise, Observable } from 'rxjs';
import { switchMap } from 'rxjs/operators';
import { ExecutionContextHost } from '../helpers/execution-context.host';
 
export class InterceptorsConsumer {
  public async intercept(
    interceptors: NestInterceptor[],
    args: any[],
    instance: Controller,
    callback: (...args) => any,
    next: () => Promise<any>,
  ): Promise<any> {
    if (isEmpty(interceptors)) {
      return next();
    }
    const context = this.createContext(args, instance, callback);
    const start$ = defer(() => this.transformDeffered(next));
    /***
      const nextFn =  (i: number) => async () => {
      if (i <= interceptors.length) {
        return start$;
      }
      return await interceptors[i].intercept(context, nextFn(i + 1) as any);
    };
    */
    const result$ = await interceptors.reduce(
      async (stream$, interceptor) => interceptor.intercept(context, await stream$),
      Promise.resolve(start$),
    );
    return result$.toPromise();
  }
 
  public createContext(
    args: any[],
    instance: Controller,
    callback: (...args) => any,
  ): ExecutionContextHost {
    return new ExecutionContextHost(
      args,
      instance.constructor as any,
      callback,
    );
  }
 
  public transformDeffered(next: () => Promise<any>): Observable<any> {
    return fromPromise(next()).pipe(
      switchMap(res => {
        const isDeffered = res instanceof Promise || res instanceof Observable;
        return isDeffered ? res : Promise.resolve(res);
      }),
    );
  }
}