verdaccio
Version:
A lightweight private npm proxy registry
154 lines (114 loc) • 15.5 kB
JavaScript
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==
;