UNPKG

verdaccio

Version:

A lightweight private npm proxy registry

144 lines (106 loc) 4.15 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = loadPlugin; var _path = _interopRequireDefault(require("path")); var _lodash = _interopRequireDefault(require("lodash")); var _logger = _interopRequireDefault(require("./logger")); var _constants = require("./constants"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * @prettier * */ /** * Requires a module. * @param {*} path the module's path * @return {Object} */ function tryLoad(path) { try { return require(path); } catch (err) { if (err.code === _constants.MODULE_NOT_FOUND) { return null; } throw err; } } function mergeConfig(appConfig, pluginConfig) { return _lodash.default.merge(appConfig, pluginConfig); } function isValid(plugin) { return _lodash.default.isFunction(plugin) || _lodash.default.isFunction(plugin.default); } function isES6(plugin) { return Object.keys(plugin).includes('default'); } /** * Load a plugin following the rules * - First try to load from the internal directory plugins (which will disappear soon or later). * - A second attempt from the external plugin directory * - A third attempt from node_modules, in case to have multiple match as for instance verdaccio-ldap * and sinopia-ldap. All verdaccio prefix will have preferences. * @param {*} config a reference of the configuration settings * @param {*} pluginConfigs * @param {*} params a set of params to initialize the plugin * @param {*} sanityCheck callback that check the shape that should fulfill the plugin * @return {Array} list of plugins */ function loadPlugin(config, pluginConfigs = {}, params, sanityCheck, prefix = 'verdaccio') { return Object.keys(pluginConfigs).map(pluginId => { let plugin; const localPlugin = _path.default.resolve(__dirname + '/../plugins', pluginId); // try local plugins first plugin = tryLoad(localPlugin); // try the external plugin directory if (plugin === null && config.plugins) { const pluginDir = config.plugins; const externalFilePlugin = _path.default.resolve(pluginDir, pluginId); plugin = tryLoad(externalFilePlugin); // npm package if (plugin === null && pluginId.match(/^[^\.\/]/)) { plugin = tryLoad(_path.default.resolve(pluginDir, `${prefix}-${pluginId}`)); // compatibility for old sinopia plugins if (!plugin) { plugin = tryLoad(_path.default.resolve(pluginDir, `sinopia-${pluginId}`)); } } } // npm package if (plugin === null && pluginId.match(/^[^\.\/]/)) { plugin = tryLoad(`${prefix}-${pluginId}`); // compatibility for old sinopia plugins if (!plugin) { plugin = tryLoad(`sinopia-${pluginId}`); } } if (plugin === null) { plugin = tryLoad(pluginId); } // relative to config path if (plugin === null && pluginId.match(/^\.\.?($|\/)/)) { plugin = tryLoad(_path.default.resolve(_path.default.dirname(config.self_path), pluginId)); } if (plugin === null) { _logger.default.logger.error({ content: pluginId }, 'plugin not found. try npm install verdaccio-@{content}'); throw Error(` ${prefix}-${pluginId} plugin not found. try "npm install ${prefix}-${pluginId}"`); } if (!isValid(plugin)) { _logger.default.logger.error({ content: pluginId }, "@{content} doesn't look like a valid plugin"); throw Error(`"${pluginId}" is not a valid plugin`); } /* eslint new-cap:off */ plugin = isES6(plugin) ? new plugin.default(mergeConfig(config, pluginConfigs[pluginId]), params) : plugin(pluginConfigs[pluginId], params); /* eslint new-cap:off */ if (plugin === null || !sanityCheck(plugin)) { _logger.default.logger.error({ content: pluginId }, "@{content} doesn't look like a valid plugin"); throw Error(`"${pluginId}" is not a valid plugin`); } _logger.default.logger.warn({ content: `${prefix}-${pluginId}` }, 'Plugin successfully loaded: @{content}'); return plugin; }); }