arrowjs/ArrowjsCore

View on GitHub
libs/global_function.js

Summary

Maintainability
F
1 wk
Test Coverage
'use strict';

const _ = require('lodash'),
    glob = require('glob'),
    fs = require('fs'),
    fsEx = require('fs-extra'),
    path = require('path'),
    logger = require('./logger'),
    nunjucks = require('nunjucks');


/**
 * Create Environment to handles templates
 * @param {array} views - List of loaders
 * @returns {object}
 */
exports.createNewEnv = function (views, viewEngineConfig, application) {
    let self = this;
    let env = new nunjucks.Environment(new nunjucks.FileSystemLoader(views), viewEngineConfig);
    let viewSetting = application.getConfig();
    env = self.getAllFunction(env, viewSetting, application);
    env = self.getAllCustomFilter(env, viewSetting, application);
    env = self.getAllVariable(env, viewSetting, application);
    env = self.getAllExtensions(env, viewSetting, application);

    return env;
};

/**
 * Add function to Environment
 * @param {object} env - Environment to add custom filter
 * @returns {object}
 */

exports.getAllVariable = function (env, viewSetting, app) {
    if (!viewSetting.variableFile) return env;
    let userVariable;
    try {
        userVariable = require(path.normalize(__base + viewSetting.variableFile));
    } catch (err) {
        /* istanbul ignore next */
        logger.warn('Cant find file :' + path.normalize(__base + viewSetting.variableFile))
    }
    let baseVariable = require(path.resolve(__dirname, '..', 'templateExtends/variable.js'));

    /* istanbul ignore next */
    Object.keys(baseVariable).map(function (name) {
        if (typeof baseVariable[name] !== "function") {
            env.addGlobal(name, baseVariable[name]);
        }
    });
    /* istanbul ignore else */
    if (typeof userVariable === 'object' && !_.isEmpty(userVariable)) {
        Object.keys(userVariable).map(function (name) {
            if (typeof userVariable[name] !== "function") {
                env.addGlobal(name, userVariable[name]);
            }
        })
    }
    return env
};


/**
 * Add function to Environment
 * @param {object} env - Environment to add custom filter
 * @returns {object}
 */

exports.getAllExtensions = function (env, viewSetting, app) {
    var self = this;
    let basePath = path.resolve(__dirname, '..', 'templateExtends/extensions');
    let baseFunctionLinks = self.getGlobbedFiles(path.normalize(basePath + "/*.js"));

    /* istanbul ignore next */
    baseFunctionLinks.map(function (link) {
        let viewExtension = require(link);
        let extensionName = path.basename(link, ".js");
        env.addExtension(extensionName, new viewExtension());

    });
    return env
};
/**
 * Add function to Environment
 * @param {object} env - Environment to add custom filter
 * @returns {object}
 */

exports.getAllFunction = function (env, viewSetting, app) {
    let self = this;
    let basePath = path.resolve(__dirname, '..', 'templateExtends/function');
    let baseFunctionLinks = self.getGlobbedFiles(path.normalize(basePath + "/*.js"));
    baseFunctionLinks.map(function (link) {
        let viewFunction = require(link);
        /* istanbul ignore else */
        if (typeof viewFunction === 'object' && !_.isEmpty(viewFunction)) {
            let name = path.basename(link, ".js");
            let func = require(link);
            /* istanbul ignore else */
            if (typeof func === 'object' && !_.isEmpty(func)) {
                func.name = func.name || name;
                /* istanbul ignore else */
                if (func.handler) {
                    func.async = func.async || false;
                    func.handler = func.handler.bind(app);

                    /* istanbul ignore if */
                    if (func.async) {
                        env.addGlobal(func.name, function () {
                            var argsAsArray = Array.prototype.slice.call(arguments);
                            return func.handler.bind.apply(func.handler, [null].concat(argsAsArray))
                        })
                    } else {
                        env.addGlobal(func.name, func.handler);
                    }
                }
            }
        }
    });
    if (!viewSetting.functionFolder) return env;
    let functionLinks = self.getGlobbedFiles(path.normalize(__base + viewSetting.functionFolder + "/*.js"));
    functionLinks.map(function (link) {
        let viewFunction = require(link);
        /* istanbul ignore else */
        if (typeof viewFunction === 'object' && !_.isEmpty(viewFunction)) {
            let name = path.basename(link, ".js");
            let func = require(link);
            /* istanbul ignore else */
            if (typeof func === 'object' && !_.isEmpty(func)) {
                func.name = func.name || name;
                /* istanbul ignore else */
                if (func.handler) {
                    func.async = func.async || false;
                    func.handler = func.handler.bind(app);
                    if (func.async) {
                        env.addGlobal(func.name, function () {
                            var argsAsArray = Array.prototype.slice.call(arguments);
                            return func.handler.bind.apply(func.handler, [null].concat(argsAsArray))
                        })
                    } else {
                        env.addGlobal(func.name, func.handler);
                    }
                }
            }
        }
    });
    return env
};

/**
 * Add custom filter to Environment
 * @param {object} env - Environment to add custom filter
 * @returns {object}
 */
exports.getAllCustomFilter = function (env, viewSetting, app) {
    let self = this;

    let basePath = path.resolve(__dirname, '..', 'templateExtends/filter');
    let baseFilterLinks = self.getGlobbedFiles(path.normalize(basePath + "/*.js"));

    baseFilterLinks.map(function (link) {
        let name = path.basename(link, ".js")
        let filter = require(link);
        /* istanbul ignore else */
        if (typeof filter === 'object' && !_.isEmpty(filter)) {
            filter.name = filter.name || name;

            /* istanbul ignore else */
            if (filter.handler) {
                filter.handler = filter.handler.bind(app);
                filter.async = filter.async || false;
                if (filter.async) {
                    env.addFilter(filter.name, filter.handler, true)
                } else {
                    env.addFilter(filter.name, filter.handler)
                }
            }
        }
    });
    if (!viewSetting.filterFolder) return env;
    let filterLinks = self.getGlobbedFiles(path.normalize(__base + viewSetting.filterFolder + "/*.js"));
    filterLinks.map(function (link) {
        let name = path.basename(link, ".js");
        let filter = require(link);
        /* istanbul ignore else */
        if (typeof filter === 'object' && !_.isEmpty(filter)) {
            filter.name = filter.name || name;

            /* istanbul ignore else */
            if (filter.handler) {
                filter.handler = filter.handler.bind(app);
                filter.async = filter.async || false;
                if (filter.async) {
                    env.addFilter(filter.name, filter.handler, true)
                } else {
                    env.addFilter(filter.name, filter.handler)
                }
            }
        }
    });
    return env
};


///**
// * Send mail with provided options
// * @param {object} mailOptions
// * @returns {Promise}
// */
//exports.sendMail = function (mailOptions) {
//    return new Promise(function (fulfill, reject) {
//        __mailSender.sendMail(mailOptions, function (err, info) {
//
//            if (err) {
//                reject(err);
//            } else {
//                fulfill(info);
//            }
//        });
//    });
//};

/**
 * Get files by glob patterns
 */
module.exports.getGlobbedFiles = function (globPatterns, removeRoot) {
    // For context switching
    let _this = this;

    // URL paths regex
    let urlRegex = new RegExp('^(?:[a-z]+:)?\/\/', 'i');

    // The output array
    let output = [];

    // If glob pattern is array so we use each pattern in a recursive way, otherwise we use glob

    /* istanbul ignore if */
    if (_.isArray(globPatterns)) {
        globPatterns.forEach(function (globPattern) {
            output = _.union(output, _this.getGlobbedFiles(globPattern, removeRoot));
        });

        /* istanbul ignore else */
    } else if (_.isString(globPatterns)) {

        /* istanbul ignore if */
        if (urlRegex.test(globPatterns)) {
            output.push(globPatterns);
        } else {
            var files = glob.sync(globPatterns,{nosort : true});
            if(files.length > 0) {
                files = files.sort(function (a,b) {
                    if(a && path.basename(a, path.extname(a)) === "main"){
                        return 1
                    } else if (b && path.basename(b, path.extname(b)) === "main") {
                        return -1
                    } else {
                        return 0
                    }
                });
            }
            /* istanbul ignore if */
            if (removeRoot) {
                files = files.map(function (file) {
                    return file.replace(removeRoot, '');
                })
            }
            output = _.union(output, files);
        }
    }
    return output;
};

/**
 * Scan folder config and read all configuration file. If configuration file does not exists then copy default
 * configuration file from Arrowjs module to folder config
 */

module.exports.getRawConfig = function getRawConfig() {
    let conf = {};

    //get config.js
    try {
        // check file accessibility 
        fs.accessSync(__base + 'config/config.js');
        // assign config object to conf
        _.assign(conf, require(__base + 'config/config'));
    } catch (err) {

        /* istanbul ignore else */
        if (err.code === 'ENOENT') {
            fsEx.copySync(path.resolve(__dirname, '..', 'config/config.js'), __base + 'config/config.js');
            _.assign(conf, require(__base + 'config/config'));
        } else {
            throw err
        }
    }

    //get websocket.js
    try {
        fs.accessSync(__base + 'config/websocket.js');
        _.assign(conf, require(__base + 'config/websocket'));
    } catch (err) {

        /* istanbul ignore else */
        if (err.code === 'ENOENT') {
            fsEx.copySync(path.resolve(__dirname, '..', 'config/websocket.js'), __base + 'config/websocket.js');
            _.assign(conf, require(__base + 'config/websocket'));
        } else {

            throw err
        }
    }

    //get error.js
    try {
        fs.accessSync(__base + 'config/error.js');
        _.assign(conf, require(__base + 'config/error'));
    } catch (err) {

        /* istanbul ignore else */
        if (err.code === 'ENOENT') {
            fsEx.copySync(path.resolve(__dirname, '..', 'config/error.js'), __base + 'config/error.js');
            _.assign(conf, require(__base + 'config/error'));
        } else {
            throw err
        }
    }

    //get redis.js
    try {
        fs.accessSync(__base + 'config/redis.js');
        _.assign(conf, require(__base + 'config/redis'));
    } catch (err) {
        /* istanbul ignore else */
        if (err.code === 'ENOENT') {
            fsEx.copySync(path.resolve(__dirname, '..', 'config/redis.js'), __base + 'config/redis.js');
            _.assign(conf, require(__base + 'config/redis'));
        } else {
            throw err
        }
    }

    //get view.js
    try {
        fs.accessSync(__base + 'config/view.js');
        _.assign(conf, require(__base + 'config/view'));
    } catch (err) {
        /* istanbul ignore else */
        if (err.code === 'ENOENT') {
            fsEx.copySync(path.resolve(__dirname, '..', 'config/view.js'), __base + 'config/view.js');
            _.assign(conf, require(__base + 'config/view'));
        } else {
            throw err
        }
    }

    //get session.js
    try {
        fs.accessSync(__base + 'config/session.js');
    } catch (err) {
        /* istanbul ignore else */
        if (err.code === 'ENOENT') {
            fsEx.copySync(path.resolve(__dirname, '..', 'config/session.js'), __base + 'config/session.js');
        } else {
            throw err
        }
    }

    //get express.js
    try {
        fs.accessSync(__base + 'config/express.js');
    } catch (err) {
        /* istanbul ignore else */
        if (err.code === 'ENOENT') {
            fsEx.copySync(path.resolve(__dirname, '..', 'config/express.js'), __base + 'config/express.js');
        } else {
            throw err
        }
    }

    //get passport.js
    try {
        fs.accessSync(__base + 'config/passport.js');
    } catch (err) {
        /* istanbul ignore else */
        if (err.code === 'ENOENT') {
            fsEx.copySync(path.resolve(__dirname, '..', 'config/passport.js'), __base + 'config/passport.js');
        } else {
            throw err
        }
    }

    //get database.js
    try {
        fs.accessSync(__base + 'config/database.js');
        _.assign(conf, require(__base + 'config/database'));
    } catch (err) {
        /* istanbul ignore else */
        if (err.code === 'ENOENT') {
            fsEx.copySync(path.resolve(__dirname, '..', 'config/database.js'), __base + 'config/database.js');
            _.assign(conf, require(__base + 'config/database'));
        } else {
            throw err
        }
    }

    //setup strategy
    createDirectory('config/strategies');
    try {
        fs.accessSync(__base + 'config/strategies/local.js');
    } catch (err) {
        /* istanbul ignore else */
        if (err.code === 'ENOENT') {
            fsEx.copySync(path.resolve(__dirname, '..', 'config/strategies/local.js'), __base + 'config/strategies/local.js');
        } else {
            throw err
        }
    }

    //get default config

    try {
        fs.accessSync(__base + 'config/env/default.js');
        _.assign(conf, require(__base + 'config/env/default.js'));
    } catch (err) {
        /* istanbul ignore else */
        if (err.code === 'ENOENT') {
            fsEx.copySync(path.resolve(__dirname, '..', 'config/env/default.js'), __base + 'config/env/default.js');
            conf = _.merge(conf, require(__base + 'config/env/default.js'));
        } else {
            throw err
        }
    }


    //get ENV config
    /* istanbul ignore next */
    let env = process.env.NODE_ENV || "development";
    try {
        fs.accessSync(__base + 'config/env/' + env + ".js");
        _.assign(conf, require(__base + 'config/env/' + env));
    } catch (err) {

        /* istanbul ignore else */
        if (err.code === 'ENOENT') {
            fsEx.copySync(path.resolve(__dirname, '..', 'config/env/development.js'), __base + 'config/env/' + env + '.js');
            conf = _.merge(conf, require(__base + 'config/env/' + env));
        } else {
            throw err
        }
    }
    return conf
};
/**
 * Read file config/structure.js and return structure object
 */
module.exports.getStructure = function getStructure() {
    let structure = {};
    try {        
        fs.accessSync(__base + 'config/structure.js');
        /* istanbul ignore next */
        // assign all content in config/structure.js to structure 
        _.assign(structure, require(__base + 'config/structure'));
    } catch (err) {
        /* istanbul ignore else */
        if (err.code === 'ENOENT') {
            fsEx.copySync(path.resolve(__dirname, '..', 'config/structure.js'), __base + 'config/structure.js');
            _.assign(structure, require(__base + 'config/structure'));
        } else {
            throw err
        }

    }
    return structure;
};

/**
 * Create directory
 * @param {string} path
 * return {void}
 */

function createDirectory(path) {
    fs.mkdir(__base + path, function (err) {
        //if (err == null) console.log('Create directory ' + path);
    });
};

exports.createDirectory = createDirectory