# 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);
          }),
        );
      }
    }