# All files / decorators/gapi-module gapi-module.decorator.ts

8.2% Statements 5/61
0% Branches 0/40
0% Functions 0/11
8.47% Lines 5/59

Press n or j to go to the next uncovered block, b, p or k for the previous block.

    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
    91
    92
    93
    94
    95
    96
    97
    98

    6x
    6x

    6x

    6x

    6x

     import { GapiModuleArguments } from './gapi-module.decorator.interface';
    import { GapiModuleSymbol } from './gapi-module.symbol';
    import { ApplyServicesHook } from '../../utils/services/apply/apply.service';
    import 'reflect-metadata';
    import Container from '../../utils/container/index';
    import { ServiceMetadata } from '../../utils/container';
    import { ModuleContainerService } from '../../utils/services/module/module.service';

    const moduleContainerService = Container.get(ModuleContainerService);

    function getInjectables(module) {
        const injectables = [];
        module.deps.forEach(i => {
            if (i.constructor === Function) {
                injectables.push(Container.get(i));
            } else {
                injectables.push(i);
            }
        });
        return injectables;
    }

    function importModules(modules, original, status) {
        modules.forEach((module) => {
            if (!module) {
                throw new Error(`Incorrect importing '${status}' inside ${original.name}`);
            }
            if (module.constructor === Object) {
                if (module.provide && module.useClass) {
                    const original = module.useClass;
                    const f: any = () => new original(...getInjectables(module));
                    Container.set(module.provide, new f.constructor());
                } else if (module.provide && module.useFactory) {
                    if (module.useFactory.constructor === Function) {
                        if (module.deps && module.deps.length) {
                            const originalFactory = module.useFactory;
                            module.useFactory = () => originalFactory(...getInjectables(module));
                        }
                        moduleContainerService.createModule(original.name, null).registerDependencyHandler(module);
                        Container.set(module.provide, module.useFactory());
                    } else {
                        throw new Error(`Wrong Factory function ${module.provide ? JSON.stringify(module.provide) : ''} inside module: ${original.name}`);
                    }
                } else if (module.provide && module.useValue) {
                    Container.set(module.provide, module.useValue);
                } else {
                    throw new Error(`Wrong Injectable '${status}' ${module.provide ? JSON.stringify(module.provide) : ''} inside module: ${original.name}`);
                }
            } else {
                let name = module.name;
                if (name === 'f') {
                    name = module.constructor.name;
                }
                Object.defineProperty(module, 'name', { value: name, writable: true });
                Container.get(module);
            }

        });
    }

    export function GapiModule<T, K extends keyof T>(module: GapiModuleArguments) {
        return (target) => {
            const original = target;
            function construct(constructor, args) {
                const c: any = function () {
                    if (module.types) {
                        importModules(module.types, original, 'types');
                    }
                    if (module.services) {
                        importModules(module.services, original, 'services');
                    }
                    if (module.imports) {
                        importModules(module.imports, original, 'imports');
                    }
                    if (module.controllers) {
                        importModules(module.controllers, original, 'controllers');
                    }
                    this.injectables = module;
                    moduleContainerService.createModule(original.name, this.injectables);
                    return new constructor();
                };

                c.prototype = constructor.prototype;
                Object.defineProperty(c, 'name', { value: constructor.name, writable: true });
                return Container.get(c);

            }
            const f: any = function (...args) {
                console.log('Loaded Module: ' + original.name);
                return construct(original, args);
            };
            f.prototype = original.prototype;
            if (original.forRoot) {
                f.forRoot = original.forRoot;
            }
            return f;
        };
    }