From e718a138eb39136ba65f70705da97bc650df935f Mon Sep 17 00:00:00 2001 From: Michael Raith Date: Sat, 30 Dec 2017 11:48:46 +0100 Subject: [PATCH] refactor: move everything from index.js into a new file library.js --- .eslintrc | 2 +- source/index.js | 589 ++-------------------------------------------- source/library.js | 565 ++++++++++++++++++++++++++++++++++++++++++++ source/utils.js | 16 +- 4 files changed, 587 insertions(+), 585 deletions(-) create mode 100644 source/library.js diff --git a/.eslintrc b/.eslintrc index e388ee4..16c571d 100644 --- a/.eslintrc +++ b/.eslintrc @@ -43,7 +43,7 @@ "no-unused-vars": 2, "strict": [ 2, - "function" + "safe" ], "no-invalid-this": 2, "keyword-spacing": [ diff --git a/source/index.js b/source/index.js index 38db4ae..76aa9ac 100644 --- a/source/index.js +++ b/source/index.js @@ -6,13 +6,9 @@ * @namespace Index */ -var path = require('path'); -var fs = require('fs'); -var Utils = require('./utils'); +'use strict'; -// Define all dependencies outside the container function to keep them -var factories = {}; -var modules = {}; +var lib = require('./library.js'); /** * simple dependency injection. No nesting, just pure simplicity @@ -27,572 +23,25 @@ var modules = {}; * var container = require('@bruce17/dependable').container(); */ exports.container = function () { - 'use strict'; - - var container = {}; - - // Define some regex - var regex = { - fileEnding: /\.\w+$/, - dashes: /\-(\w)/g, - scriptFiles: /\.(js|coffee)$/, - strFunc: /function.*\(([\s\S]*?)\)/, - strFuncES6: /\(([\s\S]*?)\)\s*\=>/ - }; - - // Define a list of factory names which should be blacklisted e.g. in method "find" - var factoryBlacklist = [ - '_container' - ]; - - - /** - * Register a dependency in the di-container. - * - * @param {string|object} name Register a dependency by its name (+ function) or a hash-set at once. - * @param {function} func If a name is given, register this function. - * - * @returns {Array|function} - * - * @function register - * @memberOf Index.Container - * - * @example - * // Register some simple dependencies - * container.register('occupation', 'tax attorney'); - * container.register('transport', { - * type: 'station wagon', - * material: 'wood-paneled' - * }); - * container.register({ - * 'foo': 'bar', - * 'obj': { - * 'str': 'test', - * 'num': 123 - * } - * }); - * - * // Register a dependency that has other dependencies - * container.register('song', function (occupation, transport, legalStatus) { - * var song = {}; - * - * song.chorus = function chorus() { - * return [ - * 'I\'m a ' + occupation, - * 'On a ' + transport.material + ' ' + transport.type + ' I ride', - * 'And I\'m ' + legalStatus.message - * ].join('\n'); - * }; - * - * return song; - * }); - */ - var register = function (name, func) { - if (Utils.isObject(name)) { - var hash = name; - var results = []; - - var key; - - for (key in hash) { - if (hash.hasOwnProperty(key)) { - results.push(registerOne(key, hash[key])); - } - } - - return results; - } else { - return registerOne(name, func); - } - }; - - /** - * Register a library dependency in the di-container. - * - * Difference between "register" and "registerLibrary": This method registers library methods which export a bunch - * of methods via the module pattern. This methods wraps the actual library into another function to avoid the - * library to be executed directly and to avoid dependency injection of function arguments. - * - * @param {string|object} name Register a library dependency by its name (+ function) or a hash-set at once. - * @param {function} func If a name is given, register this function. - * - * @returns {Array|function} - * - * @function registerLibrary - * @memberOf Index.Container - * - * @example - * // Register some library methods - * var lodash = require('lodash'); - * var promise = require('promise'); - * var express = require('express'); - * - * container.registerLibrary('lodash', lodash); - * container.registerLibrary({ - * 'promise': promise, - * 'express': express - * }); - */ - var registerLibrary = function (name, func) { - if (Utils.isObject(name)) { - var hash = name; - var results = []; - - var key; - - for (key in hash) { - if (hash.hasOwnProperty(key)) { - results.push(registerOne(key, (function (library) { - return function () { - return library; - }; - })(hash[key]))); - } - } - - return results; - } else { - return registerOne(name, function () { - return func; - }); - } - }; - - /** - * Register a new dependency. - * - * @param {string} name - * @param {function} func - * - * @returns {function} - * - * @function registerOne - * @memberOf Index.Container - * @protected - */ - var registerOne = function (name, func) { - factories[name] = toFactory(func); - return factories[name]; - }; - - /** - * Return a list of all factories. - * - * @returns {object} - * - * @function list - * @memberOf Index.Container - */ - var list = function () { - return factories; - }; - - /** - * Return a list all matching factories. - * - * @param {string} searchPattern An matching factory name including optional asterisk characters as placeholders. - * - * @function find - * @memberOf Index.Container - * - * @example - * // Find a dependency by its full name - * var result = container.find('lodash'); - * console.log('lodash', result.lodash); - * - * // Find more dependencies - * var controllers = container.find('*Controller'); - * console.log('controllers', controllers); // e.g. "IndexController", "AuthController", etc. - */ - var find = function (searchPattern) { - var result = {}; - var key; - - // Prepare a regex to select a specific set of the permissions. - var preparedRegex = new RegExp( - Utils.isString(searchPattern) && searchPattern.length > 0 ? - '^' + Utils.escapeRegex(searchPattern).replace('\\*', '.*') + '$' : - '', - 'i' - ); - - if (preparedRegex.source !== '' && preparedRegex.source !== '(?:)') { - for (key in factories) { - if (factories.hasOwnProperty(key) && !Utils.inArray(factoryBlacklist, key) && preparedRegex.test(key)) { - result[key] = get(key); - } - } - } - - return result; - }; - - /** - * Load a directory of files or a file into the di-container. - * The filename will be the identifier. - * - * @param {string} fileOrDir A file path or a path. - * @param {Array} subDirs Also load content from subdirectories depending on "fileOrDir" as base path. - * @param {object} options Pass optional options to this method. - * - * @returns {Array|function} A list of register files or just one register file function. - * - * @function load - * @memberOf Index.Container - * - * @example - * // Load all dependencies in a directory - * container.load(__dirname + '/services'); - * // e.g. loads "Image.js", "Excel.js", "Export.js" - * - * // Load all dependencies in a directory and subdirectories - * container.load(__dirname + '/models', ['user', 'role']); - * // e.g. loads "user/Foo.js", "user/Bar.js", "role/NoAccess.js", "role/Admin.js" - * - * // Load all dependencies in a directory and prepend a prefix - * container.load(__dirname + '/models', {prefix: 'Model'}); - * // e.g. loads "Foo.js" into "ModelFoo" or "Bar.js" into "ModelBar" - * - * // Load all dependencies in a directory, subdirectories and prepend a prefix - * container.load(__dirname + '/models', ['user', 'role'], {prefix: 'Model'}); - * // e.g. loads "user/Foo.js" into "ModelFoo" or "role/Admin.js" into "ModelAdmin" - * - * // You can also use "postfix" to append a optional string to every loaded dependency. - */ - var load = function (fileOrDir, subDirs, options) { - // Maybe the user only passed two arguments an "path" + "options". Adjust the arguments in that case. - if (options === undefined) { - if (Utils.isObject(subDirs)) { - options = subDirs; - } - } - - // Load a directory - if (fs.statSync(fileOrDir).isDirectory()) { - var results = loadDir(fileOrDir, options); - - // Load a subdirectory - if (Utils.isArray(subDirs)) { - var i, iLen; - var subDir; - - // Iterate over each sub directory ... - for (i = 0, iLen = subDirs.length; i < iLen; i++) { - subDir = path.join(fileOrDir, subDirs[i]); - - // ... and load it via "loadDir" - if (fs.statSync(subDir).isDirectory()) { - results.concat( - loadDir(subDir, options) - ); - } - } - } - - return results; - } - - // Load a file - return loadFile(fileOrDir, options); - }; - - /** - * Load a file into the di-container. - * - * @param {string} file - * @param {object} options Pass optional options to this method. - * - * @returns {function} - * - * @function loadFile - * @memberOf Index.Container - * @protected - */ - var loadFile = function (file, options) { - options = (Utils.isObject(options) ? options : {}); - - var module = file.replace(regex.fileEnding, ''); - - // Remove dashes from files and camelcase results - var name = path.basename(module).replace(regex.dashes, function (match, letter) { - return letter.toUpperCase(); - }); - - // Add a prefix to the dependency's name - if ('prefix' in options && Utils.isString(options.prefix)) { - name = options.prefix + name; - } - // Add a postfix to the dependency's name - if ('postfix' in options && Utils.isString(options.postfix)) { - name = name + options.postfix; - } - - return register(name, require(module)); - }; - - /** - * Load files in a directory to the di-container. - * - * @param {string} dir - * @param {object} options Pass optional options to this method. - * - * @returns {Array} - * - * @function loadDir - * @memberOf Index.Container - * @protected - */ - var loadDir = function (dir, options) { - var fileNames = fs.readdirSync(dir); - var files = fileNames.map(function(file) { - return path.join(dir, file); - }); - - var results = []; - var file; - var stats; - - for (var i = 0, iMax = files.length; i < iMax; i++) { - file = files[i]; - - if (!file.match(regex.scriptFiles)) { - continue; - } - - stats = fs.statSync(file); - if (stats.isFile()) { - results.push(loadFile(file, options)); - } - //TODO: erm ... useless!? - //else { - // results.push(void 0); - //} - } - - return results; - }; - - /** - * Convert a function into the proper internal di factory format. - * - * @param {function} func - * - * @returns {object} - * - * @function toFactory - * @memberOf Index.Container - * @protected - */ - var toFactory = function (func) { - if (typeof func === 'function') { - return { - func: func, - required: argList(func) - }; - } else { - return { - func: function () { - return func; - }, - required: [] - }; - } - }; - - /** - * Return a functions argument list for di dependency injection. - * - * @param {function} func - * - * @returns {Array} - * - * @function argList - * @memberOf Index.Container - * @protected - */ - var argList = function (func) { - // Normal ES5 function check - var match = func.toString().match(regex.strFunc); - - if (!match) { - // ES6 fat arrow function check - match = func.toString().match(regex.strFuncES6); - - if (!match) { - throw new Error('Could not parse function arguments: ' + func.toString()); - } - } - - return match[1].split(',') - .filter(notEmpty) - .map(function (str) { - return str.trim(); - }); - }; - - /** - * Check if a argument is not empty. - * - * @param {*} arg - * - * @returns {boolean} - * - * @function notEmpty - * @memberOf Index.Container - * @protected - */ - var notEmpty = function (arg) { - return arg; - }; - - /** - * Gives you a single dependency. - * - * @param {string} name - * @param {object} overrides - * @param {Array} visited - * - * @TODO: add visitation / detect require loops - * - * @function get - * @memberOf Index.Container - * - * @example - * // Get a dependency from the di-container - * var _ = container.get('lodash'); - * var IndexController = container.get('IndexController'); - */ - var get = function (name, overrides, visited) { - if (visited === undefined) { - visited = []; - } - - // eslint-disable-next-line eqeqeq - var isOverridden = (overrides != null); - - // Check for circular dependencies - if (haveVisited(visited, name)) { - throw new Error('Circular dependency with "' + name + '"'); - } - visited = visited.concat(name); - - var factory = factories[name]; - if (!factory) { - var module = modules[name]; - - if (module) { - register(name, require(module)); - factory = factories[name]; - } else { - throw new Error('Dependency "' + name + '" was not registered'); - } - } - - // Use the one you already created - if (factory.instance && !isOverridden) { - return factory.instance; - } - - // Apply args to the right - var dependencies = factory.required.map(function (name) { - if (overrides && overrides[name]) { - return overrides[name]; - } else { - return get(name, overrides, visited); - } - }); - - // Prepare the factory instance - var instance = factory.func.apply(factory, dependencies); - - if (!isOverridden) { - factory.instance = instance; - } - - return instance; - }; - - /** - * - * @param {Array} visited - * @param {string} name - * - * @returns {Number} - * - * @function haveVisited - * @memberOf Index.Container - * @protected - */ - var haveVisited = function (visited, name) { - return visited.filter(function (n) { - return n === name; - }).length; - }; - - /** - * Resolve a dependency and overwrite it. - * - * @param {object} overrides - * @param {function} func - * - * @function resolve - * @memberOf Index.Container - * - * @example - * container.resolve(function (lodash) { - * console.log('lodash', lodash); - * }); - */ - var resolve = function (overrides, func) { - if (!func) { - func = overrides; - overrides = null; - } - - register('__temp', func); - return get('__temp', overrides, []); - }; - - /** - * Register this di-container itself into the container. - * - * @function registerContainer - * @memberOf Index.Container - * @protected - */ - var registerContainer = function () { - // Let people access the container if they know what they're doing - container.register('_container', container); - }; - - /** - * Clear all dependencies - * - * @function clearAll - * @memberOf Index.Container - * @protected - */ - var clearAll = function () { - factories = {}; - modules = {}; - - registerContainer(); - }; - // Prepare the public functions to be passed to the outer world - container = { - get: get, - resolve: resolve, - register: register, - registerLibrary: registerLibrary, - load: load, - list: list, - find: find, - clearAll: clearAll - }; - + var container = { + get: lib.get, + resolve: lib.resolve, + register: lib.register, + registerLibrary: lib.registerLibrary, + load: lib.load, + list: lib.list, + find: lib.find, + clearAll: function () { + lib.clearAll(); + + lib.registerContainer(container); + }, + }; + + var factories = lib.list(); if (!('_container' in factories)) { - registerContainer(); + lib.registerContainer(container); } return container; diff --git a/source/library.js b/source/library.js new file mode 100644 index 0000000..7429682 --- /dev/null +++ b/source/library.js @@ -0,0 +1,565 @@ +/** + * @author Michael Raith + * @email mraith@gmail.com + * @date 30.12.2017 11:08 + * + * @namespace Library + */ + +'use strict'; + +var path = require('path'); +var fs = require('fs'); +var Utils = require('./utils'); + +// Define all dependencies outside the container function to keep them +var factories = {}; +var modules = {}; + +// Define some regex +var regex = { + fileEnding: /\.\w+$/, + dashes: /\-(\w)/g, + scriptFiles: /\.(js|coffee)$/, + strFunc: /function.*\(([\s\S]*?)\)/, + strFuncES6: /\(([\s\S]*?)\)\s*\=>/ +}; + +// Define a list of factory names which should be blacklisted e.g. in method "find" +var factoryBlacklist = [ + '_container' +]; + + +var exports = module.exports = {}; + + + +/** + * Check if a argument is not empty. + * + * @param {*} arg + * + * @returns {boolean} + * + * @function notEmpty + * @memberOf Library + * @property + */ +var notEmpty = function notEmpty(arg) { + return arg; +}; + +/** + * Return a functions argument list for di dependency injection. + * + * @param {function} func + * + * @returns {Array} + * + * @function argList + * @memberOf Library + * @protected + */ +var argList = function argList(func) { + // Normal ES5 function check + var match = func.toString().match(regex.strFunc); + + if (!match) { + // ES6 fat arrow function check + match = func.toString().match(regex.strFuncES6); + + if (!match) { + throw new Error('Could not parse function arguments: ' + func.toString()); + } + } + + return match[1].split(',') + .filter(notEmpty) + .map(function (str) { + return str.trim(); + }); +}; + +/** + * + * @param {Array} visited + * @param {string} name + * + * @returns {Number} + * + * @function haveVisited + * @memberOf Library + * @protected + */ +var haveVisited = function haveVisited(visited, name) { + return visited.filter(function (n) { + return n === name; + }).length; +}; + +/** + * Convert a function into the proper internal di factory format. + * + * @param {function} func + * + * @returns {object} + * + * @function toFactory + * @memberOf Library + * @protected + */ +var toFactory = function toFactory(func) { + if (typeof func === 'function') { + return { + func: func, + required: argList(func) + }; + } else { + return { + func: function () { + return func; + }, + required: [] + }; + } +}; + +/** + * Register a new dependency. + * + * @param {string} name + * @param {function} func + * + * @returns {function} + * + * @function registerOne + * @memberOf Library + * @protected + */ +var registerOne = function registerOne(name, func) { + factories[name] = toFactory(func); + + return factories[name]; +}; + +/** + * Register a dependency in the di-container. + * + * @param {string|object} name Register a dependency by its name (+ function) or a hash-set at once. + * @param {function} func If a name is given, register this function. + * + * @returns {Array|function} + * + * @function register + * @memberOf Library + * + * @example + * // Register some simple dependencies + * container.register('occupation', 'tax attorney'); + * container.register('transport', { + * type: 'station wagon', + * material: 'wood-paneled' + * }); +* container.register({ + * 'foo': 'bar', + * 'obj': { + * 'str': 'test', + * 'num': 123 + * } + * }); + * + * // Register a dependency that has other dependencies + * container.register('song', function (occupation, transport, legalStatus) { + * var song = {}; + * + * song.chorus = function chorus() { + * return [ + * 'I\'m a ' + occupation, + * 'On a ' + transport.material + ' ' + transport.type + ' I ride', + * 'And I\'m ' + legalStatus.message + * ].join('\n'); + * }; + * + * return song; + * }); + */ +exports.register = function register(name, func) { + if (Utils.isObject(name)) { + var hash = name; + var results = []; + + var key; + + for (key in hash) { + if (hash.hasOwnProperty(key)) { + results.push(registerOne(key, hash[key])); + } + } + + return results; + } else { + return registerOne(name, func); + } +}; + +/** + * Register a library dependency in the di-container. + * + * Difference between "register" and "registerLibrary": This method registers library methods which export a bunch + * of methods via the module pattern. This methods wraps the actual library into another function to avoid the + * library to be executed directly and to avoid dependency injection of function arguments. + * + * @param {string|object} name Register a library dependency by its name (+ function) or a hash-set at once. + * @param {function} func If a name is given, register this function. + * + * @returns {Array|function} + * + * @function registerLibrary + * @memberOf Library + * + * @example + * // Register some library methods + * var lodash = require('lodash'); + * var promise = require('promise'); + * var express = require('express'); + * + * container.registerLibrary('lodash', lodash); + * container.registerLibrary({ + * 'promise': promise, + * 'express': express + * }); + */ +exports.registerLibrary = function registerLibrary(name, func) { + if (Utils.isObject(name)) { + var hash = name; + var results = []; + + var key; + + for (key in hash) { + if (hash.hasOwnProperty(key)) { + results.push(registerOne(key, (function (library) { + return function () { + return library; + }; + })(hash[key]))); + } + } + + return results; + } else { + return registerOne(name, function () { + return func; + }); + } +}; + +/** + * Return a list of all factories. + * + * @returns {object} + * + * @function list + * @memberOf Library + */ +exports.list = function list() { + return factories; +}; + +/** + * Load a file into the di-container. + * + * @param {string} file + * @param {object} options Pass optional options to this method. + * + * @returns {function} + * + * @function loadFile + * @memberOf Library + * @protected + */ +var loadFile = function loadFile(file, options) { + options = (Utils.isObject(options) ? options : {}); + + var module = file.replace(regex.fileEnding, ''); + + // Remove dashes from files and camelcase results + var name = path.basename(module).replace(regex.dashes, function (match, letter) { + return letter.toUpperCase(); + }); + + // Add a prefix to the dependency's name + if ('prefix' in options && Utils.isString(options.prefix)) { + name = options.prefix + name; + } + // Add a postfix to the dependency's name + if ('postfix' in options && Utils.isString(options.postfix)) { + name = name + options.postfix; + } + + return exports.register(name, require(module)); +}; + +/** + * Load files in a directory to the di-container. + * + * @param {string} dir + * @param {object} options Pass optional options to this method. + * + * @returns {Array} + * + * @function loadDir + * @memberOf Library + * @protected + */ +var loadDir = function loadDir(dir, options) { + var fileNames = fs.readdirSync(dir); + var files = fileNames.map(function(file) { + return path.join(dir, file); + }); + + var results = []; + var file; + var stats; + + for (var i = 0, iMax = files.length; i < iMax; i++) { + file = files[i]; + + if (!file.match(regex.scriptFiles)) { + continue; + } + + stats = fs.statSync(file); + if (stats.isFile()) { + results.push(loadFile(file, options)); + } + } + + return results; +}; + +/** + * Load a directory of files or a file into the di-container. + * The filename will be the identifier. + * + * @param {string} fileOrDir A file path or a path. + * @param {Array} subDirs Also load content from subdirectories depending on "fileOrDir" as base path. + * @param {object} options Pass optional options to this method. + * + * @returns {Array|function} A list of register files or just one register file function. + * + * @function load + * @memberOf Library + * + * @example + * // Load all dependencies in a directory + * container.load(__dirname + '/services'); + * // e.g. loads "Image.js", "Excel.js", "Export.js" + * + * // Load all dependencies in a directory and subdirectories + * container.load(__dirname + '/models', ['user', 'role']); + * // e.g. loads "user/Foo.js", "user/Bar.js", "role/NoAccess.js", "role/Admin.js" + * + * // Load all dependencies in a directory and prepend a prefix + * container.load(__dirname + '/models', {prefix: 'Model'}); + * // e.g. loads "Foo.js" into "ModelFoo" or "Bar.js" into "ModelBar" + * + * // Load all dependencies in a directory, subdirectories and prepend a prefix + * container.load(__dirname + '/models', ['user', 'role'], {prefix: 'Model'}); + * // e.g. loads "user/Foo.js" into "ModelFoo" or "role/Admin.js" into "ModelAdmin" + * + * // You can also use "postfix" to append a optional string to every loaded dependency. + */ +exports.load = function load(fileOrDir, subDirs, options) { + // Maybe the user only passed two arguments an "path" + "options". Adjust the arguments in that case. + if (options === undefined) { + if (Utils.isObject(subDirs)) { + options = subDirs; + } + } + + // Load a directory + if (fs.statSync(fileOrDir).isDirectory()) { + var results = loadDir(fileOrDir, options); + + // Load a subdirectory + if (Utils.isArray(subDirs)) { + var i, iLen; + var subDir; + + // Iterate over each sub directory ... + for (i = 0, iLen = subDirs.length; i < iLen; i++) { + subDir = path.join(fileOrDir, subDirs[i]); + + // ... and load it via "loadDir" + if (fs.statSync(subDir).isDirectory()) { + results.concat( + loadDir(subDir, options) + ); + } + } + } + + return results; + } + + // Load a file + return loadFile(fileOrDir, options); +}; + +/** + * Gives you a single dependency. + * + * @param {string} name + * @param {object} overrides + * @param {Array} visited + * + * @TODO: add visitation / detect require loops + * + * @function get + * @memberOf Library + * + * @example + * // Get a dependency from the di-container + * var _ = container.get('lodash'); + * var IndexController = container.get('IndexController'); + */ +exports.get = function get(name, overrides, visited) { + if (visited === undefined) { + visited = []; + } + + // eslint-disable-next-line eqeqeq + var isOverridden = (overrides != null); + + // Check for circular dependencies + if (haveVisited(visited, name)) { + throw new Error('Circular dependency with "' + name + '"'); + } + visited = visited.concat(name); + + var factory = factories[name]; + if (!factory) { + var module = modules[name]; + + if (module) { + exports.register(name, require(module)); + factory = factories[name]; + } else { + throw new Error('Dependency "' + name + '" was not registered'); + } + } + + // Use the one you already created + if (factory.instance && !isOverridden) { + return factory.instance; + } + + // Apply args to the right + var dependencies = factory.required.map(function (name) { + if (overrides && overrides[name]) { + return overrides[name]; + } else { + return exports.get(name, overrides, visited); + } + }); + + // Prepare the factory instance + var instance = factory.func.apply(factory, dependencies); + + if (!isOverridden) { + factory.instance = instance; + } + + return instance; +}; + +/** + * Return a list all matching factories. + * + * @param {string} searchPattern An matching factory name including optional asterisk characters as placeholders. + * + * @function find + * @memberOf Library + * + * @example + * // Find a dependency by its full name + * var result = container.find('lodash'); + * console.log('lodash', result.lodash); + * + * // Find more dependencies + * var controllers = container.find('*Controller'); + * console.log('controllers', controllers); // e.g. "IndexController", "AuthController", etc. + */ +exports.find = function find(searchPattern) { + var result = {}; + var key; + + // Prepare a regex to select a specific set of the permissions. + var preparedRegex = new RegExp( + Utils.isString(searchPattern) && searchPattern.length > 0 ? + '^' + Utils.escapeRegex(searchPattern).replace('\\*', '.*') + '$' : + '', + 'i' + ); + + if (preparedRegex.source !== '' && preparedRegex.source !== '(?:)') { + for (key in factories) { + if (factories.hasOwnProperty(key) && !Utils.inArray(factoryBlacklist, key) && preparedRegex.test(key)) { + result[key] = exports.get(key); + } + } + } + + return result; +}; + +/** + * Resolve a dependency and overwrite it. + * + * @param {object} overrides + * @param {function} func + * + * @function resolve + * @memberOf Library + * + * @example + * container.resolve(function (lodash) { + * console.log('lodash', lodash); + * }); + */ +exports.resolve = function resolve(overrides, func) { + if (!func) { + func = overrides; + overrides = null; + } + + exports.register('__temp', func); + + return exports.get('__temp', overrides, []); +}; + +/** + * Register this di-container itself into the container. + * + * @param {object} container The container itself. + * + * @function registerContainer + * @memberOf Library + */ +exports.registerContainer = function registerContainer(container) { + // Let people access the container if they know what they're doing + exports.register('_container', container); +}; + +/** + * Clear all dependencies + * + * @function clearAll + * @memberOf Library + */ +exports.clearAll = function clearAll() { + factories = {}; + modules = {}; +}; diff --git a/source/utils.js b/source/utils.js index bd0c31e..e0a0d5c 100644 --- a/source/utils.js +++ b/source/utils.js @@ -6,6 +6,8 @@ * @namespace Utils */ +'use strict'; + var regex = { escape: /[.*+?^${}()|[\]\/\\]/g }; @@ -25,8 +27,6 @@ var regexInst = { * @memberOf Utils */ exports.isArray = function isObject(ary) { - 'use strict'; - return (ary === Object(ary)) && (ary instanceof Array); }; @@ -41,8 +41,6 @@ exports.isArray = function isObject(ary) { * @memberOf Utils */ exports.isObject = function isObject(obj) { - 'use strict'; - return (obj === Object(obj)) && !(obj instanceof Array); }; @@ -57,8 +55,6 @@ exports.isObject = function isObject(obj) { * @memberOf Utils */ exports.isString = function isString(str) { - 'use strict'; - return ( (str === String(str)) || (this.isObject(str) && str.valueOf() === String(str.valueOf())) @@ -76,8 +72,6 @@ exports.isString = function isString(str) { * @memberOf Utils */ exports.isUndefined = function isUndefined(value) { - 'use strict'; - return value === undefined; }; @@ -93,8 +87,6 @@ exports.isUndefined = function isUndefined(value) { * @memberOf Utils */ exports.inArray = function inArray(haystack, needle) { - 'use strict'; - var result = false; if (this.isArray(haystack)) { @@ -123,8 +115,6 @@ exports.inArray = function inArray(haystack, needle) { * @memberOf Utils */ exports.simpleCompare = function simpleCompare(a, b) { - 'use strict'; - var result = false; if (this.isObject(a) && this.isObject(b)) { @@ -149,8 +139,6 @@ exports.simpleCompare = function simpleCompare(a, b) { * @memberOf Utils */ exports.escapeRegex = function escapeRegex(string) { - 'use strict'; - var escapeString = (this.isString(string) ? string : ''); return (escapeString && regexInst.escape.test(escapeString)) ?