All files / core/injector module-token-factory.ts

100% Statements 19/19
87.5% Branches 7/8
100% Functions 7/7
100% Lines 18/18
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  1x   1x 1x   1x           16x 16x 16x         16x               18x       17x       3x 3x 3x   3x     3x     3x       19x 19x      
import { DynamicModule } from '@nestjs/common';
import { SHARED_MODULE_METADATA } from '@nestjs/common/constants';
import { Type } from '@nestjs/common/interfaces/type.interface';
import * as hash from 'object-hash';
import stringify from 'fast-safe-stringify';
 
export class ModuleTokenFactory {
  public create(
    metatype: Type<any>,
    scope: Type<any>[],
    dynamicModuleMetadata?: Partial<DynamicModule> | undefined,
  ): string {
    const reflectedScope = this.reflectScope(metatype);
    const isSingleScoped = reflectedScope === true;
    const opaqueToken = {
      module: this.getModuleName(metatype),
      dynamic: this.getDynamicMetadataToken(dynamicModuleMetadata),
      scope: isSingleScoped ? this.getScopeStack(scope) : reflectedScope,
    };
    return hash(opaqueToken);
  }
 
  public getDynamicMetadataToken(
    dynamicModuleMetadata: Partial<DynamicModule> | undefined,
  ): string {
    // Uses safeStringify instead of JSON.stringify
    // to support circular dynamic modules
    return dynamicModuleMetadata ? stringify(dynamicModuleMetadata) : '';
  }
 
  public getModuleName(metatype: Type<any>): string {
    return metatype.name;
  }
 
  public getScopeStack(scope: Type<any>[]): string[] {
    const reversedScope = scope.reverse();
    const firstGlobalIndex = reversedScope.findIndex(
      s => this.reflectScope(s) === 'global',
    );
    scope.reverse();
 
    const stack =
      firstGlobalIndex >= 0
        ? scope.slice(scope.length - firstGlobalIndex - 1)
        : scope;
    return stack.map(module => module.name);
  }
 
  private reflectScope(metatype: Type<any>) {
    const scope = Reflect.getMetadata(SHARED_MODULE_METADATA, metatype);
    return scope ? scope : 'global';
  }
}