{"size": 5563, "ext": "js", "max_stars_repo_path": "framework/di.js", "max_stars_repo_name": "hcarine/node-mvc", "max_stars_repo_stars_event_min_datetime": "2015-01-06T09:19:26.000Z", "max_stars_repo_stars_event_max_datetime": "2015-02-16T07:03:36.000Z", "max_issues_repo_path": "framework/di.js", "max_issues_repo_name": "hcarine/node-mvc", "max_issues_repo_issues_event_min_datetime": "2018-05-03T13:27:16.000Z", "max_issues_repo_issues_event_max_datetime": "2018-05-03T13:27:16.000Z", "max_forks_repo_path": "framework/di.js", "max_forks_repo_name": "hcarine/node-mvc", "max_forks_repo_forks_event_min_datetime": "2015-02-23T09:23:03.000Z", "max_forks_repo_forks_event_max_datetime": "2020-01-31T10:28:19.000Z"}
{"max_stars_count": 10, "max_issues_count": 1, "max_forks_count": 6, "avg_line_length": 26.2405660377, "max_line_length": 124, "alphanum_fraction": 0.537300018}
"use strict";
/* global Type: true, error: true, path: true, util: true, fs: true, INVALID_ALIAS_VALUE: true */
var Type = require('static-type-js');
var core = require('./core');
var path = require('path');
var util = require('util');
var fs = require('fs');
var error;
/**
 * @license Mit Licence 2014
 * @since 0.0.1
 * @author Igor Ivanovic
 * @name DI
 *
 * @constructor
 * @description
 * DI is main object for handling dependency injection
 */
var DI = Type.create({
    filePaths: Type.OBJECT,
    aliases: Type.OBJECT
}, {
    _construct: function DI_construct() {
        this.aliases = {};
        this.setAlias('framework', __dirname + '/');
        try {
            this.filePaths = JSON.parse(fs.readFileSync(this.normalizePath('@{framework}/files.json'), {encoding: 'utf8'}));
        } catch (e) {
            throw "Cannot load @{framework}/files.json path";
        }

    },
    /**
     * @since 0.0.1
     * @author Igor Ivanovic
     * @method DI#hasAlias
     *
     * @description
     * Has an alias
     */
    hasAlias: function DI_hasAlias(key) {
        return this.aliases.hasOwnProperty(key);
    },
    /**
     * @since 0.0.1
     * @author Igor Ivanovic
     * @method DI#getAlias
     *
     * @description
     * Get an alias
     */
    getAlias: function DI_getAlias(key) {
        if (this.aliases.hasOwnProperty(key)) {
            return this.normalizePath(this.aliases[key]);
        } else {
            error = this.load('error');
            throw new error.Exception('DI.getAlias: "' + key + '" is not valid');
        }
    },
    /**
     * @since 0.0.1
     * @author Igor Ivanovic
     * @method DI#setAlias
     *
     * @description
     * Set an path alias
     */
    setAlias: function DI_setAlias(key, value) {
        this.aliases[key] = this.normalizePath(value);
    },
    /**
     * @since 0.0.1
     * @author Igor Ivanovic
     * @method DI#normalizePath
     *
     * @description
     * Normalize path
     */
    normalizePath: function DI_normalizePath(value) {
        if (Type.isString(value)) {
            Object.keys(this.aliases).forEach(function (key) {
                value = value.replace('@{' + key + '}', this.aliases[key]);
            }.bind(this));
            return path.normalize(value);
        } else {
            throw new error.DataError({value: value}, 'DI.normalizePath: value is not string');
        }
    },
    /**
     * @since 0.0.1
     * @author Igor Ivanovic
     * @method DI#readFileSync
     *
     * @description
     * Read file sync
     */
    readFileSync: function DI_readFileSync(name) {
        try {
            return fs.readFileSync(this.normalizePath(name), {encoding: 'utf8'});
        } catch (e) {
            error = this.load('error');
            throw new error.Exception('DI.readFileSync', e);
        }
    },
    /**
     * @since 0.0.1
     * @author Igor Ivanovic
     * @method DI#exists
     *
     * @description
     * Check if file exists
     */
    exists: function DI_exists(file) {
        if (!Type.isString(file)) {
            error = this.load('error');
            throw new error.DataError({file: file}, 'DI.exists:  file or fileType must bi string');
        }
        return fs.existsSync(file);
    },
    /**
     * @since 0.0.1
     * @author Igor Ivanovic
     * @method DI#refereshNodeModuleCache
     *
     * @description
     * Reset file cache
     */
    refereshNodeModuleCache: function DI_refereshNodeModuleCache(file) {
        var path = this.getFilePath(file),
            key = require.resolve(path + '.js');
        // because all modules in node are cached while executing tests we want to delete cached version
        delete require.cache[key];

        return path;
    },
    /**
     * @since 0.0.1
     * @author Igor Ivanovic
     * @method DI#mockLoad
     *
     * @description
     * Mock load for testing purposes
     */
    mock: function DI_mock(file, mocks) {
        // save original
        var load =  DI.prototype.load, path;
        // mock load

        DI.prototype.load = function (name) {
            return mocks[name];
        };
        try {
            // load module or exec if its function
            if (Type.isString(file)) {
                // do require
                return require(this.refereshNodeModuleCache(file));

            } else if (Type.isFunction(file)) {
                return file();
            }
        } catch (e) {
            return e;
        } finally {
            // restore load
            DI.prototype.load = load;
        }
    },
    /**
     * @since 0.0.1
     * @author Igor Ivanovic
     * @method DI#dirname
     *
     * @description
     * Get dir of file
     */
    dirname: function DI_dirname(name) {
        return path.dirname(name);
    },
    /**
     * @since 0.0.1
     * @author Igor Ivanovic
     * @method DI#getPath
     *
     * @description
     * Get module path so we can load it
     */
    getFilePath: function DI_getFilePath(moduleName) {
        if (moduleName in this.filePaths) {
            moduleName = this.filePaths[moduleName];
        }
        return this.normalizePath(moduleName);
    },
    /**
     * @since 0.0.1
     * @author Igor Ivanovic
     * @method DI#load
     *
     * @description
     * Load an package
     */
    load: function DI_load(name) {
        try {
            return require(this.getFilePath(name));
        } catch (e) {
            error = this.load('error');
            throw new error.Exception('DI.load', e);
        }
    }
});


module.exports = new DI;