All files / core/injector instance-loader.ts

100% Statements 36/36
100% Branches 0/0
100% Functions 22/22
100% Lines 36/36
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 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 911x     1x   1x     1x 4x 4x   4x     4x   4x 4x       4x 4x 4x 4x         4x 4x 4x 4x 4x   4x 4x           4x 2x               4x 2x 2x           4x 2x         4x 2x 2x           4x 1x               4x 1x 1x          
import { Logger } from '@nestjs/common';
import { Controller } from '@nestjs/common/interfaces/controllers/controller.interface';
import { Injectable } from '@nestjs/common/interfaces/injectable.interface';
import { MODULE_INIT_MESSAGE } from '../helpers/messages';
import { NestContainer } from './container';
import { Injector } from './injector';
import { Module } from './module';
 
export class InstanceLoader {
  private readonly injector = new Injector();
  private readonly logger = new Logger(InstanceLoader.name, true);
 
  constructor(private readonly container: NestContainer) {}
 
  public async createInstancesOfDependencies() {
    const modules = this.container.getModules();
 
    this.createPrototypes(modules);
    await this.createInstances(modules);
  }
 
  private createPrototypes(modules: Map<string, Module>) {
    modules.forEach(module => {
      this.createPrototypesOfComponents(module);
      this.createPrototypesOfInjectables(module);
      this.createPrototypesOfRoutes(module);
    });
  }
 
  private async createInstances(modules: Map<string, Module>) {
    await Promise.all(
      [...modules.values()].map(async module => {
        await this.createInstancesOfComponents(module);
        await this.createInstancesOfInjectables(module);
        await this.createInstancesOfRoutes(module);
 
        const { name } = module.metatype;
        this.logger.log(MODULE_INIT_MESSAGE`${name}`);
      }),
    );
  }
 
  private createPrototypesOfComponents(module: Module) {
    module.components.forEach(wrapper => {
      this.injector.loadPrototypeOfInstance<Injectable>(
        wrapper,
        module.components,
      );
    });
  }
 
  private async createInstancesOfComponents(module: Module) {
    await Promise.all(
      [...module.components.values()].map(async wrapper =>
        this.injector.loadInstanceOfComponent(wrapper, module),
      ),
    );
  }
 
  private createPrototypesOfRoutes(module: Module) {
    module.routes.forEach(wrapper => {
      this.injector.loadPrototypeOfInstance<Controller>(wrapper, module.routes);
    });
  }
 
  private async createInstancesOfRoutes(module: Module) {
    await Promise.all(
      [...module.routes.values()].map(async wrapper =>
        this.injector.loadInstanceOfRoute(wrapper, module),
      ),
    );
  }
 
  private createPrototypesOfInjectables(module: Module) {
    module.injectables.forEach(wrapper => {
      this.injector.loadPrototypeOfInstance<Controller>(
        wrapper,
        module.injectables,
      );
    });
  }
 
  private async createInstancesOfInjectables(module: Module) {
    await Promise.all(
      [...module.injectables.values()].map(async wrapper =>
        this.injector.loadInstanceOfInjectable(wrapper, module),
      ),
    );
  }
}