UNPKG

global-module-loader

Version:
166 lines (129 loc) 4.83 kB
const includeAll = require('include-all') /** * buildDictionary * * Go through each object, include the code, and determine its identity. * Tolerates non-existent files/directories by ignoring them. @param {Object} options { dirname :: the path to the source directory identity :: If disabled, (explicitly set to false) don't inject an identity into the module also don't try to use the bundled `identity` property in the module to determine the keyname in the result object default: true optional :: if enabled, fail silently and return {} when source directory does not exist or cannot be read (otherwise, exit w/ an error) default: false depth :: the level of recursion where modules will be included defaults to infinity? (not sure) filter :: only include modules whose FILENAME matches this regex default `undefined` pathFilter :: only include modules whose FULL RELATIVE PATH matches this regex (relative from the entry point directory) default `undefined` replaceExpr :: in identity: use this regex to remove substrings like 'Controller' or 'Service' and replace them with the value of `replaceVal` replaceVal :: see above default value: '' dontLoad :: if `dontLoad` is set to true, don't run the module w/ V8 or load it into memory-- instead, return a tree representing the directory structure (all extant file leaves are included as keys, with their value = `true`) useGlobalIdForKeyName :: if `useGlobalIdForKeyName` is set to true, don't lowercase the identity to get the keyname-- just use the globalId. } @param {Function} cb */ module.exports = buildDictionary function buildDictionary (options, cb) { // Defaults options.replaceVal = options.replaceVal || '' // Deliberately exclude source control directories if (!options.excludeDirs) { options.excludeDirs = /^\.(git|svn)$/ } var files = includeAll(options) // Start building the module dictionary var dictionary = {} // Iterate through each module in the set for (let filename in files) { let module = files[filename] // Keyname is how the module will be identified in the returned module tree var keyName = filename // If a module is found but marked as `undefined`, // don't actually include it (since it's probably unusable) if (typeof module === 'undefined') { return } // Unless the `identity` option is explicitly disabled, // (or `dontLoad` is set) if (!options.dontLoad && options.identity !== false) { // If no `identity` property is specified in module, infer it from the filename if (!module.identity) { if (options.replaceExpr) { module.identity = filename.replace(options.replaceExpr, options.replaceVal) } else module.identity = filename } // globalId is the name of the variable for this module // that will be exposed globally in Sails unless configured otherwise // Generate `globalId` using the original value of module.identity if (!module.globalId) { module.globalId = module.identity } // `identity` is the all-lowercase version module.identity = module.identity.toLowerCase() // Use the identity for the key name keyName = options.useGlobalIdForKeyName ? module.globalId : module.identity } // Save the module's contents in our dictionary object // (this will actually just be `true` if the `dontLoad` option is set) dictionary[keyName] = module } // Always return at least an empty object dictionary = dictionary || {} return cb(null, dictionary) } /** * Build a dictionary of named modules * (responds with an error if the container cannot be loaded) * * @param {Object} options * @param {Function} cb */ module.exports.required = (options, cb) => { return buildDictionary(options, cb) } /** * Build a dictionary of named modules * (fails silently-- returns {} if the container cannot be loaded) * * @param {Object} options * @param {Function} cb */ module.exports.optional = (options, cb) => { options.optional = true return buildDictionary(options, cb) } /** * Build a dictionary indicating whether the matched modules exist * (fails silently-- returns {} if the container cannot be loaded) * * @param {Object} options * @param {Function} cb */ module.exports.exists = (options, cb) => { options.optional = true options.dontLoad = false return buildDictionary(options, cb) } /** * Build a single module object by extending {} with the contents of each module * (fail silently-- returns {} if the container cannot be loaded) * * @param {Object} options * @param {Function} cb */ module.exports.aggregate = (options, cb) => { options.aggregate = true options.optional = true return buildDictionary(options, cb) }