UNPKG

verdaccio

Version:

A lightweight private npm proxy registry

154 lines (114 loc) 15.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = loadPlugin; var _path = _interopRequireDefault(require("path")); var _lodash = _interopRequireDefault(require("lodash")); var _logger = require("./logger"); var _constants = require("./constants"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * 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'); } // export type PluginGeneric<R, T extends IPlugin<R> = ; /** * 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.logger.error({ content: pluginId, prefix }, 'plugin not found. try npm install @{prefix}-@{content}'); throw Error(` ${prefix}-${pluginId} plugin not found. try "npm install ${prefix}-${pluginId}"`); } if (!isValid(plugin)) { _logger.logger.error({ content: pluginId }, '@{prefix}-@{content} plugin does not have the right code structure'); throw Error(`"${pluginId}" plugin does not have the right code structure`); } /* eslint new-cap:off */ try { plugin = isES6(plugin) ? new plugin.default(mergeConfig(config, pluginConfigs[pluginId]), params) : plugin(pluginConfigs[pluginId], params); } catch (error) { plugin = null; _logger.logger.error({ error, pluginId }, 'error loading a plugin @{pluginId}: @{error}'); } /* eslint new-cap:off */ if (plugin === null || !sanityCheck(plugin)) { _logger.logger.error({ content: pluginId, prefix }, "@{prefix}-@{content} doesn't look like a valid plugin"); throw Error(`sanity check has failed, "${pluginId}" is not a valid plugin`); } _logger.logger.warn({ content: pluginId, prefix }, 'Plugin successfully loaded: @{prefix}-@{content}'); return plugin; }); } //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9saWIvcGx1Z2luLWxvYWRlci50cyJdLCJuYW1lcyI6WyJ0cnlMb2FkIiwicGF0aCIsInJlcXVpcmUiLCJlcnIiLCJjb2RlIiwiTU9EVUxFX05PVF9GT1VORCIsIm1lcmdlQ29uZmlnIiwiYXBwQ29uZmlnIiwicGx1Z2luQ29uZmlnIiwiXyIsIm1lcmdlIiwiaXNWYWxpZCIsInBsdWdpbiIsImlzRnVuY3Rpb24iLCJkZWZhdWx0IiwiaXNFUzYiLCJPYmplY3QiLCJrZXlzIiwiaW5jbHVkZXMiLCJsb2FkUGx1Z2luIiwiY29uZmlnIiwicGx1Z2luQ29uZmlncyIsInBhcmFtcyIsInNhbml0eUNoZWNrIiwicHJlZml4IiwibWFwIiwicGx1Z2luSWQiLCJsb2NhbFBsdWdpbiIsIlBhdGgiLCJyZXNvbHZlIiwiX19kaXJuYW1lIiwicGx1Z2lucyIsInBsdWdpbkRpciIsImV4dGVybmFsRmlsZVBsdWdpbiIsIm1hdGNoIiwiZGlybmFtZSIsInNlbGZfcGF0aCIsImxvZ2dlciIsImVycm9yIiwiY29udGVudCIsIkVycm9yIiwid2FybiJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOztBQUVBOztBQUNBOzs7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVNBLE9BQVQsQ0FBaUJDLElBQWpCLEVBQW9DO0FBQ2xDLE1BQUk7QUFDRixXQUFPQyxPQUFPLENBQUNELElBQUQsQ0FBZDtBQUNELEdBRkQsQ0FFRSxPQUFPRSxHQUFQLEVBQVk7QUFDWixRQUFJQSxHQUFHLENBQUNDLElBQUosS0FBYUMsMkJBQWpCLEVBQW1DO0FBQ2pDLGFBQU8sSUFBUDtBQUNEOztBQUNELFVBQU1GLEdBQU47QUFDRDtBQUNGOztBQUVELFNBQVNHLFdBQVQsQ0FBcUJDLFNBQXJCLEVBQWdDQyxZQUFoQyxFQUFzRDtBQUNwRCxTQUFPQyxnQkFBRUMsS0FBRixDQUFRSCxTQUFSLEVBQW1CQyxZQUFuQixDQUFQO0FBQ0Q7O0FBRUQsU0FBU0csT0FBVCxD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QSxPQUFPLEVBQUViLFFBQVg7QUFBcUJGLE1BQUFBO0FBQXJCLEtBREYsRUFFRSxrREFGRjs7QUFJQSxXQUFPWixNQUFQO0FBQ0QsR0FuRkksQ0FBUDtBQXFGRCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBQYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IF8gZnJvbSAnbG9kYXNoJztcbmltcG9ydCB7IENvbmZpZywgSVBsdWdpbiB9IGZyb20gJ0B2ZXJkYWNjaW8vdHlwZXMnO1xuaW1wb3J0IHsgbG9nZ2VyIH0gZnJvbSAnLi9sb2dnZXInO1xuaW1wb3J0IHsgTU9EVUxFX05PVF9GT1VORCB9IGZyb20gJy4vY29uc3RhbnRzJztcblxuLyoqXG4gKiBSZXF1aXJlcyBhIG1vZHVsZS5cbiAqIEBwYXJhbSB7Kn0gcGF0aCB0aGUgbW9kdWxlJ3MgcGF0aFxuICogQHJldHVybiB7T2JqZWN0fVxuICovXG5mdW5jdGlvbiB0cnlMb2FkKHBhdGg6IHN0cmluZyk6IGFueSB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIHJlcXVpcmUocGF0aCk7XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIGlmIChlcnIuY29kZSA9PT0gTU9EVUxFX05PVF9GT1VORCkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIHRocm93IGVycjtcbiAgfVxufVxuXG5mdW5jdGlvbiBtZXJnZUNvbmZpZyhhcHBDb25maWcsIHBsdWdpbkNvbmZpZyk6IENvbmZpZyB7XG4gIHJldHVybiBfLm1lcmdlKGFwcENvbmZpZywgcGx1Z2luQ29uZmlnKTtcbn1cblxuZnVuY3Rpb24gaXNWYWxpZChwbHVnaW4pOiBib29sZWFuIHtcbiAgcmV0dXJuIF8uaXNGdW5jdGlvbihwbHVnaW4pIHx8IF8uaXNGdW5jdGlvbihwbHVnaW4uZGVmYXVsdCk7XG59XG5cbmZ1bmN0aW9uIGlzRVM2KHBsdWdpbik6IGJvb2xlYW4ge1xuICByZXR1cm4gT2JqZWN0LmtleXMocGx1Z2luKS5pbmNsdWRlcygnZGVmYXVsdCcpO1xufVxuXG4vLyBleHBvcnQgdHlwZSBQbHVnaW5HZW5lcmljPFIsIFQgZXh0ZW5kcyBJUGx1Z2luPFI+ID0gO1xuXG4vKipcbiAqIExvYWQgYSBwbHVnaW4gZm9sbG93aW5nIHRoZSBydWxlc1xuICogLSBGaXJzdCB0cnkgdG8gbG9hZCBmcm9tIHRoZSBpbnRlcm5hbCBkaXJlY3RvcnkgcGx1Z2lucyAod2hpY2ggd2lsbCBkaXNhcHBlYXIgc29vbiBvciBsYXRlcikuXG4gKiAtIEEgc2Vjb25kIGF0dGVtcHQgZnJvbSB0aGUgZXh0ZXJuYWwgcGx1Z2luIGRpcmVjdG9yeVxuICogLSBBIHRoaXJkIGF0dGVtcHQgZnJvbSBub2RlX21vZHVsZXMsIGluIGNhc2UgdG8gaGF2ZSBtdWx0aXBsZSBtYXRjaCBhcyBmb3IgaW5zdGFuY2UgdmVyZGFjY2lvLWxkYXBcbiAqIGFuZCBzaW5vcGlhLWxkYXAuIEFsbCB2ZXJkYWNjaW8gcHJlZml4IHdpbGwgaGF2ZSBwcmVmZXJlbmNlcy5cbiAqIEBwYXJhbSB7Kn0gY29uZmlnIGEgcmVmZXJlbmNlIG9mIHRoZSBjb25maWd1cmF0aW9uIHNldHRpbmdzXG4gKiBAcGFyYW0geyp9IHBsdWdpbkNvbmZpZ3NcbiAqIEBwYXJhbSB7Kn0gcGFyYW1zIGEgc2V0IG9mIHBhcmFtcyB0byBpbml0aWFsaXplIHRoZSBwbHVnaW5cbiAqIEBwYXJhbSB7Kn0gc2FuaXR5Q2hlY2sgY2FsbGJhY2sgdGhhdCBjaGVjayB0aGUgc2hhcGUgdGhhdCBzaG91bGQgZnVsZmlsbCB0aGUgcGx1Z2luXG4gKiBAcmV0dXJuIHtBcnJheX0gbGlzdCBvZiBwbHVnaW5zXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGxvYWRQbHVnaW48VCBleHRlbmRzIElQbHVnaW48VD4+KFxuICBjb25maWc6IENvbmZpZyxcbiAgcGx1Z2luQ29uZmlnczogYW55ID0ge30sXG4gIHBhcmFtczogYW55LFxuICBzYW5pdHlDaGVjazogYW55LFxuICBwcmVmaXg6IHN0cmluZyA9ICd2ZXJkYWNjaW8nXG4pOiBhbnlbXSB7XG4gIHJldHVybiBPYmplY3Qua2V5cyhwbHVnaW5Db25maWdzKS5tYXAoXG4gICAgKHBsdWdpbklkOiBzdHJpbmcpOiBJUGx1Z2luPFQ+ID0+IHtcbiAgICAgIGxldCBwbHVnaW47XG5cbiAgICAgIGNvbnN0IGxvY2FsUGx1Z2luID0gUGF0aC5yZXNvbHZlKF9fZGlybmFtZSArICcvLi4vcGx1Z2lucycsIHBsdWdpbklkKTtcbiAgICAgIC8vIHRyeSBsb2NhbCBwbHVnaW5zIGZpcnN0XG4gICAgICBwbHVnaW4gPSB0cnlMb2FkKGxvY2FsUGx1Z2luKTtcblxuICAgICAgLy8gdHJ5IHRoZSBleHRlcm5hbCBwbHVnaW4gZGlyZWN0b3J5XG4gICAgICBpZiAocGx1Z2luID09PSBudWxsICYmIGNvbmZpZy5wbHVnaW5zKSB7XG4gICAgICAgIGNvbnN0IHBsdWdpbkRpciA9IGNvbmZpZy5wbHVnaW5zO1xuICAgICAgICBjb25zdCBleHRlcm5hbEZpbGVQbHVnaW4gPSBQYXRoLnJlc29sdmUocGx1Z2luRGlyLCBwbHVnaW5JZCk7XG4gICAgICAgIHBsdWdpbiA9IHRyeUxvYWQoZXh0ZXJuYWxGaWxlUGx1Z2luKTtcblxuICAgICAgICAvLyBucG0gcGFja2FnZVxuICAgICAgICBpZiAocGx1Z2luID09PSBudWxsICYmIHBsdWdpbklkLm1hdGNoKC9eW15cXC5cXC9dLykpIHtcbiAgICAgICAgICBwbHVnaW4gPSB0cnlMb2FkKFBhdGgucmVzb2x2ZShwbHVnaW5EaXIsIGAke3ByZWZpeH0tJHtwbHVnaW5JZH1gKSk7XG4gICAgICAgICAgLy8gY29tcGF0aWJpbGl0eSBmb3Igb2xkIHNpbm9waWEgcGx1Z2luc1xuICAgICAgICAgIGlmICghcGx1Z2luKSB7XG4gICAgICAgICAgICBwbHVnaW4gPSB0cnlMb2FkKFBhdGgucmVzb2x2ZShwbHVnaW5EaXIsIGBzaW5vcGlhLSR7cGx1Z2luSWR9YCkpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBucG0gcGFja2FnZVxuICAgICAgaWYgKHBsdWdpbiA9PT0gbnVsbCAmJiBwbHVnaW5JZC5tYXRjaCgvXlteXFwuXFwvXS8pKSB7XG4gICAgICAgIHBsdWdpbiA9IHRyeUxvYWQoYCR7cHJlZml4fS0ke3BsdWdpbklkfWApO1xuICAgICAgICAvLyBjb21wYXRpYmlsaXR5IGZvciBvbGQgc2lub3BpYSBwbHVnaW5zXG4gICAgICAgIGlmICghcGx1Z2luKSB7XG4gICAgICAgICAgcGx1Z2luID0gdHJ5TG9hZChgc2lub3BpYS0ke3BsdWdpbklkfWApO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChwbHVnaW4gPT09IG51bGwpIHtcbiAgICAgICAgcGx1Z2luID0gdHJ5TG9hZChwbHVnaW5JZCk7XG4gICAgICB9XG5cbiAgICAgIC8vIHJlbGF0aXZlIHRvIGNvbmZpZyBwYXRoXG4gICAgICBpZiAocGx1Z2luID09PSBudWxsICYmIHBsdWdpbklkLm1hdGNoKC9eXFwuXFwuPygkfFxcLykvKSkge1xuICAgICAgICBwbHVnaW4gPSB0cnlMb2FkKFBhdGgucmVzb2x2ZShQYXRoLmRpcm5hbWUoY29uZmlnLnNlbGZfcGF0aCksIHBsdWdpbklkKSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChwbHVnaW4gPT09IG51bGwpIHtcbiAgICAgICAgbG9nZ2VyLmVycm9yKFxuICAgICAgICAgIHsgY29udGVudDogcGx1Z2luSWQsIHByZWZpeCB9LFxuICAgICAgICAgICdwbHVnaW4gbm90IGZvdW5kLiB0cnkgbnBtIGluc3RhbGwgQHtwcmVmaXh9LUB7Y29udGVudH0nXG4gICAgICAgICk7XG4gICAgICAgIHRocm93IEVycm9yKGBcbiAgICAgICAgJHtwcmVmaXh9LSR7cGx1Z2luSWR9IHBsdWdpbiBub3QgZm91bmQuIHRyeSBcIm5wbSBpbnN0YWxsICR7cHJlZml4fS0ke3BsdWdpbklkfVwiYCk7XG4gICAgICB9XG5cbiAgICAgIGlmICghaXNWYWxpZChwbHVnaW4pKSB7XG4gICAgICAgIGxvZ2dlci5lcnJvcihcbiAgICAgICAgICB7IGNvbnRlbnQ6IHBsdWdpbklkIH0sXG4gICAgICAgICAgJ0B7cHJlZml4fS1Ae2NvbnRlbnR9IHBsdWdpbiBkb2VzIG5vdCBoYXZlIHRoZSByaWdodCBjb2RlIHN0cnVjdHVyZSdcbiAgICAgICAgKTtcbiAgICAgICAgdGhyb3cgRXJyb3IoYFwiJHtwbHVnaW5JZH1cIiBwbHVnaW4gZG9lcyBub3QgaGF2ZSB0aGUgcmlnaHQgY29kZSBzdHJ1Y3R1cmVgKTtcbiAgICAgIH1cblxuICAgICAgLyogZXNsaW50IG5ldy1jYXA6b2ZmICovXG4gICAgICB0cnkge1xuICAgICAgICBwbHVnaW4gPSBpc0VTNihwbHVnaW4pXG4gICAgICAgICAgPyBuZXcgcGx1Z2luLmRlZmF1bHQobWVyZ2VDb25maWcoY29uZmlnLCBwbHVnaW5Db25maWdzW3BsdWdpbklkXSksIHBhcmFtcylcbiAgICAgICAgICA6IHBsdWdpbihwbHVnaW5Db25maWdzW3BsdWdpbklkXSwgcGFyYW1zKTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIHBsdWdpbiA9IG51bGw7XG4gICAgICAgIGxvZ2dlci5lcnJvcih7IGVycm9yLCBwbHVnaW5JZCB9LCAnZXJyb3IgbG9hZGluZyBhIHBsdWdpbiBAe3BsdWdpbklkfTogQHtlcnJvcn0nKTtcbiAgICAgIH1cbiAgICAgIC8qIGVzbGludCBuZXctY2FwOm9mZiAqL1xuXG4gICAgICBpZiAocGx1Z2luID09PSBudWxsIHx8ICFzYW5pdHlDaGVjayhwbHVnaW4pKSB7XG4gICAgICAgIGxvZ2dlci5lcnJvcihcbiAgICAgICAgICB7IGNvbnRlbnQ6IHBsdWdpbklkLCBwcmVmaXggfSxcbiAgICAgICAgICBcIkB7cHJlZml4fS1Ae2NvbnRlbnR9IGRvZXNuJ3QgbG9vayBsaWtlIGEgdmFsaWQgcGx1Z2luXCJcbiAgICAgICAgKTtcbiAgICAgICAgdGhyb3cgRXJyb3IoYHNhbml0eSBjaGVjayBoYXMgZmFpbGVkLCBcIiR7cGx1Z2luSWR9XCIgaXMgbm90IGEgdmFsaWQgcGx1Z2luYCk7XG4gICAgICB9XG5cbiAgICAgIGxvZ2dlci53YXJuKFxuICAgICAgICB7IGNvbnRlbnQ6IHBsdWdpbklkLCBwcmVmaXggfSxcbiAgICAgICAgJ1BsdWdpbiBzdWNjZXNzZnVsbHkgbG9hZGVkOiBAe3ByZWZpeH0tQHtjb250ZW50fSdcbiAgICAgICk7XG4gICAgICByZXR1cm4gcGx1Z2luO1xuICAgIH1cbiAgKTtcbn1cbiJdfQ==