UNPKG

@shahen.poghosyan/awilix

Version:

Extremely powerful dependency injection container.

135 lines 4.71 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const lifetime_1 = require("./lifetime"); const resolvers_1 = require("./resolvers"); const utils_1 = require("./utils"); const camelCase = require('camel-case'); const nameFormatters = { camelCase }; /** * Given an array of glob strings, will call `require` * on them, and call their default exported function with the * container as the first parameter. * * @param {AwilixContainer} dependencies.container * The container to install loaded modules in. * * @param {Function} dependencies.listModules * The listModules function to use for listing modules. * * @param {Function} dependencies.require * The require function - it's a dependency because it makes testing easier. * * @param {String[]} globPatterns * The array of globs to use when loading modules. * * @param {Object} opts * Passed to `listModules`, e.g. `{ cwd: '...' }`. * * @param {(string, ModuleDescriptor) => string} opts.formatName * Used to format the name the module is registered with in the container. * * @return {Object} * Returns an object describing the result. */ function loadModules(dependencies, globPatterns, opts) { const container = dependencies.container; opts = optsWithDefaults(opts, container); const modules = dependencies.listModules(globPatterns, opts); const result = modules.map(m => { const items = []; const loaded = dependencies.require(m.path); // Meh, it happens. if (!loaded) { return items; } if (utils_1.isFunction(loaded)) { // for module.exports = ... items.push({ name: m.name, path: m.path, value: loaded, opts: m.opts }); return items; } if (loaded.default && utils_1.isFunction(loaded.default)) { // ES6 default export items.push({ name: m.name, path: m.path, value: loaded.default, opts: m.opts }); } // loop through non-default exports, but require the RESOLVER property set for // it to be a valid service module export. for (const key of Object.keys(loaded)) { if (key === 'default') { // default case handled separately due to its different name (file name) continue; } if (utils_1.isFunction(loaded[key]) && resolvers_1.RESOLVER in loaded[key]) { items.push({ name: key, path: m.path, value: loaded[key], opts: m.opts }); } } return items; }); result .reduce((acc, cur) => acc.concat(cur), []) .filter(x => x) .forEach(registerDescriptor.bind(null, container, opts)); return { loadedModules: modules }; } exports.loadModules = loadModules; /** * Returns a new options object with defaults applied. */ function optsWithDefaults(opts, container) { return Object.assign({ // Does a somewhat-deep merge on the registration options. resolverOptions: Object.assign({ lifetime: lifetime_1.Lifetime.TRANSIENT }, (opts && opts.resolverOptions)) }, opts); } /** * Given a module descriptor, reads it and registers it's value with the container. * * @param {AwilixContainer} container * @param {LoadModulesOptions} opts * @param {ModuleDescriptor} moduleDescriptor */ function registerDescriptor(container, opts, moduleDescriptor) { const inlineConfig = moduleDescriptor.value[resolvers_1.RESOLVER]; let name = inlineConfig && inlineConfig.name; if (!name) { name = moduleDescriptor.name; let formatter = opts.formatName; if (formatter) { if (typeof formatter === 'string') { formatter = nameFormatters[formatter]; } if (formatter) { name = formatter(name, moduleDescriptor); } } } let moduleDescriptorOpts = moduleDescriptor.opts; if (typeof moduleDescriptorOpts === 'string') { moduleDescriptorOpts = { lifetime: moduleDescriptorOpts }; } const regOpts = Object.assign({}, opts.resolverOptions, moduleDescriptorOpts, inlineConfig); const reg = regOpts.register ? regOpts.register : utils_1.isClass(moduleDescriptor.value) ? resolvers_1.asClass : resolvers_1.asFunction; container.register(name, reg(moduleDescriptor.value, regOpts)); } //# sourceMappingURL=load-modules.js.map