Blame view
node_modules/eslint/lib/config/plugins.js
5.75 KB
f7563de62
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 |
/** * @fileoverview Plugins manager * @author Nicholas C. Zakas */ "use strict"; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ const Environments = require("./environments"), Rules = require("../rules"); const debug = require("debug")("eslint:plugins"); //------------------------------------------------------------------------------ // Private //------------------------------------------------------------------------------ let plugins = Object.create(null); const PLUGIN_NAME_PREFIX = "eslint-plugin-", NAMESPACE_REGEX = /^@.*\//i; /** * Removes the prefix `eslint-plugin-` from a plugin name. * @param {string} pluginName The name of the plugin which may have the prefix. * @returns {string} The name of the plugin without prefix. */ function removePrefix(pluginName) { return pluginName.indexOf(PLUGIN_NAME_PREFIX) === 0 ? pluginName.substring(PLUGIN_NAME_PREFIX.length) : pluginName; } /** * Gets the scope (namespace) of a plugin. * @param {string} pluginName The name of the plugin which may have the prefix. * @returns {string} The name of the plugins namepace if it has one. */ function getNamespace(pluginName) { return pluginName.match(NAMESPACE_REGEX) ? pluginName.match(NAMESPACE_REGEX)[0] : ""; } /** * Removes the namespace from a plugin name. * @param {string} pluginName The name of the plugin which may have the prefix. * @returns {string} The name of the plugin without the namespace. */ function removeNamespace(pluginName) { return pluginName.replace(NAMESPACE_REGEX, ""); } //------------------------------------------------------------------------------ // Public Interface //------------------------------------------------------------------------------ module.exports = { removePrefix, getNamespace, removeNamespace, /** * Defines a plugin with a given name rather than loading from disk. * @param {string} pluginName The name of the plugin to load. * @param {Object} plugin The plugin object. * @returns {void} */ define(pluginName, plugin) { const pluginNamespace = getNamespace(pluginName), pluginNameWithoutNamespace = removeNamespace(pluginName), pluginNameWithoutPrefix = removePrefix(pluginNameWithoutNamespace), shortName = pluginNamespace + pluginNameWithoutPrefix; // load up environments and rules plugins[shortName] = plugin; Environments.importPlugin(plugin, shortName); Rules.importPlugin(plugin, shortName); // load up environments and rules for the name that '@scope/' was omitted // 3 lines below will be removed by 4.0.0 plugins[pluginNameWithoutPrefix] = plugin; Environments.importPlugin(plugin, pluginNameWithoutPrefix); Rules.importPlugin(plugin, pluginNameWithoutPrefix); }, /** * Gets a plugin with the given name. * @param {string} pluginName The name of the plugin to retrieve. * @returns {Object} The plugin or null if not loaded. */ get(pluginName) { return plugins[pluginName] || null; }, /** * Returns all plugins that are loaded. * @returns {Object} The plugins cache. */ getAll() { return plugins; }, /** * Loads a plugin with the given name. * @param {string} pluginName The name of the plugin to load. * @returns {void} * @throws {Error} If the plugin cannot be loaded. */ load(pluginName) { const pluginNamespace = getNamespace(pluginName), pluginNameWithoutNamespace = removeNamespace(pluginName), pluginNameWithoutPrefix = removePrefix(pluginNameWithoutNamespace), shortName = pluginNamespace + pluginNameWithoutPrefix, longName = pluginNamespace + PLUGIN_NAME_PREFIX + pluginNameWithoutPrefix; let plugin = null; if (pluginName.match(/\s+/)) { const whitespaceError = new Error(`Whitespace found in plugin name '${pluginName}'`); whitespaceError.messageTemplate = "whitespace-found"; whitespaceError.messageData = { pluginName: longName }; throw whitespaceError; } if (!plugins[shortName]) { try { plugin = require(longName); } catch (pluginLoadErr) { try { // Check whether the plugin exists require.resolve(longName); } catch (missingPluginErr) { // If the plugin can't be resolved, display the missing plugin error (usually a config or install error) debug(`Failed to load plugin ${longName}.`); missingPluginErr.message = `Failed to load plugin ${pluginName}: ${missingPluginErr.message}`; missingPluginErr.messageTemplate = "plugin-missing"; missingPluginErr.messageData = { pluginName: longName }; throw missingPluginErr; } // Otherwise, the plugin exists and is throwing on module load for some reason, so print the stack trace. throw pluginLoadErr; } this.define(pluginName, plugin); } }, /** * Loads all plugins from an array. * @param {string[]} pluginNames An array of plugins names. * @returns {void} * @throws {Error} If a plugin cannot be loaded. */ loadAll(pluginNames) { pluginNames.forEach(this.load, this); }, /** * Resets plugin information. Use for tests only. * @returns {void} */ testReset() { plugins = Object.create(null); } }; |