zest/base.resolver

View on GitHub
lib/resolver/resolution-provider.js

Summary

Maintainability
C
7 hrs
Test Coverage
'use strict';
/**
 * @fileOverview The base-resolver/resolution-provider module is used for storing, managing and creating zest
 * components and for injecting them into other components.
 * @module base-resolver/resolution-provider
 * @requires base-resolver/unloader
 * @requires base-resolver/utils
 * @requires {@link external:base-logger}
 */
var Q = require('q');
var utils = require('./utils');
var logger = require('base.logger')('RESOLVER/resolution-provider');
/**
 * Resolution provider is used to resolve modules by their names. This module takes
 * {module:base-resolver/configurations~ConfigurationManager} as input.
 * @returns {module:base-resolver/resolution-provider~ResolutionProvider} the resolver with one resolve method
 */
module.exports = function (configurations, unloader) {
    // components map is used to cache components.
    var componentsMap = {}, /**
     * This function resolves an expression and returns a promise that resolves to the corresponding component
     * @param {string} dependencyExpression - the expression to resolve
     * @return {external:q} a promise that resolves to the corresponding component
     * @memberof module:base-resolver/resolution-provider~ResolutionProvider
     */
    resolve = function (dependencyExpression) {
        logger.debug('trying to resolve:', dependencyExpression);
        return utils.resolveExpression(
            dependencyExpression, function (componentName, params, cacheKey, immediate) {
                logger.debug('\tparsing  :', componentName);
                logger.debug('\tparams   :', params);
                logger.debug('\timmediate:',immediate);
                logger.debug('\tcache key:', cacheKey);
                var componentConfig = configurations.get(componentName);
                var factoryFunction = componentConfig.factory.slice(-1)[0];
                var dependencies = componentConfig.factory.slice(
                    0, -1
                );
                if (!componentsMap[cacheKey]) {
                    componentsMap[cacheKey] = Q.all(
                        dependencies.map(
                            function (dependency) {
                                if (dependency === 'options') {
                                    return utils.resolveExpression(
                                        componentConfig.options, function (value) {
                                            if (/^\{[0-9]+\}$/.test(value)) {
                                                var index = parseInt(value.replace(/\{|\}/g, ''), 10) - 1;
                                                return params[index];
                                            }
                                            return value;
                                        }
                                    );
                                }
                                if (dependency === 'unload') {
                                    return unloader.register;
                                }
                                return resolve(dependency);
                            }
                        )
                    ).then(
                        function (args) {
                            logger.debug('resolved:', dependencyExpression);
                            return factoryFunction.apply({}, args);
                        }
                    );
                }
                // if the resolution is to be done immediately, we do so
                if(immediate) {
                    logger.debug('\tresolving immediately!');
                    return {
                        promise: componentsMap[cacheKey]
                    };
                }
                return componentsMap[cacheKey];
            }
        );
    };
    /**
     * Resolver is returned by {@link module:base-resolver/resolution-provider}
     * @namespace module:base-resolver/resolution-provider~ResolutionProvider
     */
    return {
        resolve: resolve
    };
};