# All files / common/decorators/modules module.decorator.ts

100% Statements 28/28
91.67% Branches 11/12
100% Functions 8/8
100% Lines 26/26

    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
    701x
    1x

    1x

    1x

    1x
    119x
    14x
    31x
    30x

    1x

    14x

    1x
    14x

    14x
    13x
    13x

    13x
    13x
    46x
    46x

    13x

    13x

    13x

    13x

    13x
    13x

     import * as deprecate from 'deprecate';
    import { METADATA as metadataConstants } from '../../constants';
    import { ModuleMetadata } from '../../interfaces/modules/module-metadata.interface';
    import { InvalidModuleConfigException } from './exceptions/invalid-module-config.exception';

    const metadataKeys = [
      metadataConstants.MODULES,
      metadataConstants.IMPORTS,
      metadataConstants.EXPORTS,
      metadataConstants.COMPONENTS,
      metadataConstants.CONTROLLERS,
      metadataConstants.PROVIDERS,
    ];

    const validateKeys = (keys: string[]) => {
      const isKeyInvalid = key => metadataKeys.findIndex(k => k === key) < 0;
      const validateKey = key => {
        if (!isKeyInvalid(key)) {
          return;
        }
        throw new InvalidModuleConfigException(key);
      };
      keys.forEach(validateKey);
    };

    /**
     * Defines the module
     * - `imports` - the set of the 'imported' modules
     * - `controllers` - the list of controllers (e.g. HTTP controllers)
     * - `providers` - the list of providers that belong to this module. They can be injected between themselves.
     * - `exports` - the set of components, which should be available for modules, which imports this module
     * - `components` - @deprecated the list of components that belong to this module. They can be injected between themselves.
     * @param options {ModuleMetadata} Module metadata
     */
    export function Module(metadata: ModuleMetadata): ClassDecorator {
      const propsKeys = Object.keys(metadata);

      validateKeys(propsKeys);
      showDeprecatedWarnings(metadata);
      overrideModuleMetadata(metadata);

      return (target: object) => {
        for (const property in metadata) {
          Eif (metadata.hasOwnProperty(property)) {
            Reflect.defineMetadata(property, metadata[property], target);
          }
        }
      };
    }

    function overrideModuleMetadata(moduleMetadata: ModuleMetadata) {
      moduleMetadata.modules = moduleMetadata.imports
        ? moduleMetadata.imports
        : moduleMetadata.modules;

      moduleMetadata.components = moduleMetadata.providers
        ? moduleMetadata.providers
        : moduleMetadata.components;
    }

    function showDeprecatedWarnings(moduleMetadata: ModuleMetadata) {
      const MODULES_DEPRECATED_WARNING =
        'The "modules" key in the @Module() decorator is deprecated and will be removed within next major release. Use the "imports" key instead.';
      const COMPONENTS_DEPRECATED_WARNING =
        'The "components" key in the @Module() decorator is deprecated and will be removed within next major release. Use the "providers" key instead.';

      moduleMetadata.modules && deprecate(MODULES_DEPRECATED_WARNING);
      moduleMetadata.components && deprecate(COMPONENTS_DEPRECATED_WARNING);
    }