From: Thomas Lamprecht Date: Mon, 6 Dec 2021 13:06:04 +0000 (+0100) Subject: commit build of 8.4.0 X-Git-Url: https://git.proxmox.com/?p=pve-eslint.git;a=commitdiff_plain;h=66999ef37c0a72eb5980062241db5a9af8082f4e commit build of 8.4.0 Signed-off-by: Thomas Lamprecht --- diff --git a/src/lib/eslint.js b/src/lib/eslint.js index c85210d..d42c4e1 100644 --- a/src/lib/eslint.js +++ b/src/lib/eslint.js @@ -1464,7 +1464,7 @@ var store = __webpack_require__(33); (module.exports = function (key, value) { return store[key] || (store[key] = value !== undefined ? value : {}); })('versions', []).push({ - version: '3.19.2', + version: '3.19.3', mode: IS_PURE ? 'pure' : 'global', copyright: '© 2021 Denis Pushkarev (zloirock.ru)' }); @@ -4452,10 +4452,10 @@ var returnThis = function () { return this; }; -module.exports = function (IteratorConstructor, NAME, next) { +module.exports = function (IteratorConstructor, NAME, next, ENUMERABLE_NEXT) { var TO_STRING_TAG = NAME + ' Iterator'; IteratorConstructor.prototype = create(IteratorPrototype, { - next: createPropertyDescriptor(1, next) + next: createPropertyDescriptor(+!ENUMERABLE_NEXT, next) }); setToStringTag(IteratorConstructor, TO_STRING_TAG, false, true); Iterators[TO_STRING_TAG] = returnThis; @@ -9474,7 +9474,7 @@ var V8_VERSION = __webpack_require__(24); var SPECIES = wellKnownSymbol('species'); var PROMISE = 'Promise'; -var getInternalState = InternalStateModule.get; +var getInternalState = InternalStateModule.getterFor(PROMISE); var setInternalState = InternalStateModule.set; var getInternalPromiseState = InternalStateModule.getterFor(PROMISE); var NativePromisePrototype = NativePromise && NativePromise.prototype; @@ -16925,7 +16925,7 @@ var URLSearchParamsIterator = createIteratorConstructor(function Iterator(params } return step; -}); +}, true); var URLSearchParamsState = function (init) { this.entries = []; @@ -18032,6 +18032,14 @@ const path = __webpack_require__(429), timing = __webpack_require__(857), ruleReplacements = __webpack_require__(858); +const { + getRuleFromConfig +} = __webpack_require__(859); + +const { + FlatConfigArray +} = __webpack_require__(860); + const debug = __webpack_require__(496)("eslint:linter"); const MAX_AUTOFIX_PASSES = 10; @@ -18048,7 +18056,9 @@ const DEFAULT_ERROR_LOC = { column: 1 } }; -const parserSymbol = Symbol.for("eslint.RuleTester.parser"); //------------------------------------------------------------------------------ +const parserSymbol = Symbol.for("eslint.RuleTester.parser"); + +const globals = __webpack_require__(877); //------------------------------------------------------------------------------ // Typedefs //------------------------------------------------------------------------------ @@ -18066,6 +18076,8 @@ const parserSymbol = Symbol.for("eslint.RuleTester.parser"); //----------------- /** @typedef {import("../shared/types").ParserOptions} ParserOptions */ +/** @typedef {import("../shared/types").LanguageOptions} LanguageOptions */ + /** @typedef {import("../shared/types").Processor} Processor */ /** @typedef {import("../shared/types").Rule} Rule */ @@ -18137,6 +18149,39 @@ const parserSymbol = Symbol.for("eslint.RuleTester.parser"); //----------------- // Helpers //------------------------------------------------------------------------------ +/** + * Determines if a given object is Espree. + * @param {Object} parser The parser to check. + * @returns {boolean} True if the parser is Espree or false if not. + */ + + +function isEspree(parser) { + return !!(parser === espree || parser[parserSymbol] === espree); +} +/** + * Retrieves globals for the given ecmaVersion. + * @param {number} ecmaVersion The version to retrieve globals for. + * @returns {Object} The globals for the given ecmaVersion. + */ + + +function getGlobalsForEcmaVersion(ecmaVersion) { + switch (ecmaVersion) { + case 3: + return globals.es3; + + case 5: + return globals.es5; + + default: + if (ecmaVersion < 2015) { + return globals["es".concat(ecmaVersion + 2009)]; + } + + return globals["es".concat(ecmaVersion)]; + } +} /** * Ensures that variables representing built-in properties of the Global Object, * and any globals declared by special block comments, are present in the global @@ -18147,6 +18192,7 @@ const parserSymbol = Symbol.for("eslint.RuleTester.parser"); //----------------- * @returns {void} */ + function addDeclaredGlobals(globalScope, configGlobals, _ref) { let { exportedVariables, @@ -18288,7 +18334,7 @@ function createDisableDirectives(options) { for (const ruleId of directiveRules) { // push to directives, if the rule is defined(including null, e.g. /*eslint enable*/) - if (ruleId === null || ruleMapper(ruleId) !== null) { + if (ruleId === null || !!ruleMapper(ruleId)) { result.directives.push({ parentComment, type, @@ -18442,7 +18488,7 @@ function getDirectiveComments(filename, ast, ruleMapper, warnInlineConfig) { const rule = ruleMapper(name); const ruleValue = parseResult.config[name]; - if (rule === null) { + if (!rule) { problems.push(createLintingProblem({ ruleId: name, loc: comment.loc @@ -18490,7 +18536,7 @@ function getDirectiveComments(filename, ast, ruleMapper, warnInlineConfig) { function normalizeEcmaVersion(parser, ecmaVersion) { - if ((parser[parserSymbol] || parser) === espree) { + if (isEspree(parser)) { if (ecmaVersion === "latest") { return espree.latestEcmaVersion; } @@ -18503,6 +18549,40 @@ function normalizeEcmaVersion(parser, ecmaVersion) { return ecmaVersion >= 2015 ? ecmaVersion - 2009 : ecmaVersion; } +/** + * Normalize ECMAScript version from the initial config into languageOptions (year) + * format. + * @param {any} [ecmaVersion] ECMAScript version from the initial config + * @returns {number} normalized ECMAScript version + */ + + +function normalizeEcmaVersionForLanguageOptions(ecmaVersion) { + switch (ecmaVersion) { + case 3: + return 3; + // void 0 = no ecmaVersion specified so use the default + + case 5: + case void 0: + return 5; + + default: + if (typeof ecmaVersion === "number") { + return ecmaVersion >= 2015 ? ecmaVersion : ecmaVersion + 2009; + } + + } + /* + * We default to the latest supported ecmaVersion for everything else. + * Remember, this is for languageOptions.ecmaVersion, which sets the version + * that is used for a number of processes inside of ESLint. It's normally + * safe to assume people want the latest unless otherwise specified. + */ + + + return espree.latestEcmaVersion + 2009; +} const eslintEnvPattern = /\/\*\s*eslint-env\s(.+?)(?:\*\/|$)/gsu; /** @@ -18552,7 +18632,9 @@ function normalizeFilename(filename) { function normalizeVerifyOptions(providedOptions, config) { - const disableInlineConfig = config.noInlineConfig === true; + const linterOptions = config.linterOptions || config; // .noInlineConfig for eslintrc, .linterOptions.noInlineConfig for flat + + const disableInlineConfig = linterOptions.noInlineConfig === true; const ignoreInlineConfig = providedOptions.allowInlineConfig === false; const configNameOfNoInlineConfig = config.configNameOfNoInlineConfig ? " (".concat(config.configNameOfNoInlineConfig, ")") : ""; let reportUnusedDisableDirectives = providedOptions.reportUnusedDisableDirectives; @@ -18562,7 +18644,7 @@ function normalizeVerifyOptions(providedOptions, config) { } if (typeof reportUnusedDisableDirectives !== "string") { - reportUnusedDisableDirectives = config.reportUnusedDisableDirectives ? "warn" : "off"; + reportUnusedDisableDirectives = linterOptions.reportUnusedDisableDirectives ? "warn" : "off"; } return { @@ -18600,6 +18682,34 @@ function resolveParserOptions(parser, providedOptions, enabledEnvironments) { mergedParserOptions.ecmaVersion = normalizeEcmaVersion(parser, mergedParserOptions.ecmaVersion); return mergedParserOptions; } +/** + * Converts parserOptions to languageOptions for backwards compatibility with eslintrc. + * @param {ConfigData} config Config object. + * @param {Object} config.globals Global variable definitions. + * @param {Parser} config.parser The parser to use. + * @param {ParserOptions} config.parserOptions The parserOptions to use. + * @returns {LanguageOptions} The languageOptions equivalent. + */ + + +function createLanguageOptions(_ref2) { + let { + globals: configuredGlobals, + parser, + parserOptions + } = _ref2; + const { + ecmaVersion, + sourceType + } = parserOptions; + return { + globals: configuredGlobals, + ecmaVersion: normalizeEcmaVersionForLanguageOptions(ecmaVersion), + sourceType, + parser, + parserOptions + }; +} /** * Combines the provided globals object with the globals from environments * @param {Record} providedGlobals The 'globals' key in a config @@ -18647,21 +18757,22 @@ function getRuleOptions(ruleConfig) { /** * Analyze scope of the given AST. * @param {ASTNode} ast The `Program` node to analyze. - * @param {ParserOptions} parserOptions The parser options. + * @param {LanguageOptions} languageOptions The parser options. * @param {Record} visitorKeys The visitor keys. * @returns {ScopeManager} The analysis result. */ -function analyzeScope(ast, parserOptions, visitorKeys) { +function analyzeScope(ast, languageOptions, visitorKeys) { + const parserOptions = languageOptions.parserOptions; const ecmaFeatures = parserOptions.ecmaFeatures || {}; - const ecmaVersion = parserOptions.ecmaVersion || DEFAULT_ECMA_VERSION; + const ecmaVersion = languageOptions.ecmaVersion || DEFAULT_ECMA_VERSION; return eslintScope.analyze(ast, { ignoreEval: true, nodejsScope: ecmaFeatures.globalReturn, impliedStrict: ecmaFeatures.impliedStrict, ecmaVersion: typeof ecmaVersion === "number" ? ecmaVersion : 6, - sourceType: parserOptions.sourceType || "script", + sourceType: languageOptions.sourceType || "script", childVisitorKeys: visitorKeys || evk.KEYS, fallback: Traverser.getKeys }); @@ -18671,8 +18782,7 @@ function analyzeScope(ast, parserOptions, visitorKeys) { * optimization of functions, so it's best to keep the try-catch as isolated * as possible * @param {string} text The text to parse. - * @param {Parser} parser The parser to parse. - * @param {ParserOptions} providedParserOptions Options to pass to the parser + * @param {LanguageOptions} languageOptions Options to pass to the parser * @param {string} filePath The path to the file being parsed. * @returns {{success: false, error: Problem}|{success: true, sourceCode: SourceCode}} * An object containing the AST and parser services if parsing was successful, or the error if parsing failed @@ -18680,9 +18790,17 @@ function analyzeScope(ast, parserOptions, visitorKeys) { */ -function parse(text, parser, providedParserOptions, filePath) { +function parse(text, languageOptions, filePath) { const textToParse = stripUnicodeBOM(text).replace(astUtils.shebangPattern, (match, captured) => "//".concat(captured)); - const parserOptions = Object.assign({}, providedParserOptions, { + const { + ecmaVersion, + sourceType, + parser + } = languageOptions; + const parserOptions = Object.assign({ + ecmaVersion, + sourceType + }, languageOptions.parserOptions, { loc: true, range: true, raw: true, @@ -18706,7 +18824,7 @@ function parse(text, parser, providedParserOptions, filePath) { const ast = parseResult.ast; const parserServices = parseResult.services || {}; const visitorKeys = parseResult.visitorKeys || evk.KEYS; - const scopeManager = parseResult.scopeManager || analyzeScope(ast, parserOptions, visitorKeys); + const scopeManager = parseResult.scopeManager || analyzeScope(ast, languageOptions, visitorKeys); return { success: true, @@ -18771,15 +18889,17 @@ function getScope(scopeManager, currentNode) { * Marks a variable as used in the current scope * @param {ScopeManager} scopeManager The scope manager for this AST. The scope may be mutated by this function. * @param {ASTNode} currentNode The node currently being traversed - * @param {Object} parserOptions The options used to parse this text + * @param {LanguageOptions} languageOptions The options used to parse this text * @param {string} name The name of the variable that should be marked as used. * @returns {boolean} True if the variable was found and marked as used, false if not. */ -function markVariableAsUsed(scopeManager, currentNode, parserOptions, name) { - const hasGlobalReturn = parserOptions.ecmaFeatures && parserOptions.ecmaFeatures.globalReturn; - const specialScope = hasGlobalReturn || parserOptions.sourceType === "module"; +function markVariableAsUsed(scopeManager, currentNode, languageOptions, name) { + const parserOptions = languageOptions.parserOptions; + const sourceType = languageOptions.sourceType; + const hasGlobalReturn = parserOptions.ecmaFeatures && parserOptions.ecmaFeatures.globalReturn || sourceType === "commonjs"; + const specialScope = hasGlobalReturn || sourceType === "module"; const currentScope = getScope(scopeManager, currentNode); // Special Node.js scope means we need to start one level deeper const initialScope = currentScope.type === "global" && specialScope ? currentScope.childScopes[0] : currentScope; @@ -18864,8 +18984,8 @@ const BASE_TRAVERSAL_CONTEXT = Object.freeze(Object.keys(DEPRECATED_SOURCECODE_P * @param {SourceCode} sourceCode A SourceCode object for the given text * @param {Object} configuredRules The rules configuration * @param {function(string): Rule} ruleMapper A mapper function from rule names to rules - * @param {Object} parserOptions The options that were passed to the parser - * @param {string} parserName The name of the parser in the config + * @param {string | undefined} parserName The name of the parser in the config + * @param {LanguageOptions} languageOptions The options for parsing the code. * @param {Object} settings The settings that were enabled in the config * @param {string} filename The reported filename of the code * @param {boolean} disableFixes If true, it doesn't make `fix` properties. @@ -18874,7 +18994,7 @@ const BASE_TRAVERSAL_CONTEXT = Object.freeze(Object.keys(DEPRECATED_SOURCECODE_P * @returns {Problem[]} An array of reported problems */ -function runRules(sourceCode, configuredRules, ruleMapper, parserOptions, parserName, settings, filename, disableFixes, cwd, physicalFilename) { +function runRules(sourceCode, configuredRules, ruleMapper, parserName, languageOptions, settings, filename, disableFixes, cwd, physicalFilename) { const emitter = createEmitter(); const nodeQueue = []; let currentNode = sourceCode.ast; @@ -18910,9 +19030,11 @@ function runRules(sourceCode, configuredRules, ruleMapper, parserOptions, parser getPhysicalFilename: () => physicalFilename || filename, getScope: () => getScope(sourceCode.scopeManager, currentNode), getSourceCode: () => sourceCode, - markVariableAsUsed: name => markVariableAsUsed(sourceCode.scopeManager, currentNode, parserOptions, name), - parserOptions, + markVariableAsUsed: name => markVariableAsUsed(sourceCode.scopeManager, currentNode, languageOptions, name), + parserOptions: { ...languageOptions.parserOptions + }, parserPath: parserName, + languageOptions, parserServices: sourceCode.parserServices, settings })); @@ -18926,7 +19048,7 @@ function runRules(sourceCode, configuredRules, ruleMapper, parserOptions, parser const rule = ruleMapper(ruleId); - if (rule === null) { + if (!rule) { lintingProblems.push(createLintingProblem({ ruleId })); @@ -19094,29 +19216,50 @@ function normalizeCwd(cwd) { */ -const internalSlotsMap = new WeakMap(); //------------------------------------------------------------------------------ +const internalSlotsMap = new WeakMap(); +/** + * Throws an error when the given linter is in flat config mode. + * @param {Linter} linter The linter to check. + * @returns {void} + * @throws {Error} If the linter is in flat config mode. + */ + +function assertEslintrcConfig(linter) { + const { + configType + } = internalSlotsMap.get(linter); + + if (configType === "flat") { + throw new Error("This method cannot be used with flat config. Add your entries directly into the config array."); + } +} //------------------------------------------------------------------------------ // Public Interface //------------------------------------------------------------------------------ /** * Object that is responsible for verifying JavaScript text - * @name eslint + * @name Linter */ + class Linter { /** * Initialize the Linter. * @param {Object} [config] the config object * @param {string} [config.cwd] path to a directory that should be considered as the current working directory, can be undefined. + * @param {"flat"|"eslintrc"} [config.configType="eslintrc"] the type of config used. */ constructor() { let { - cwd + cwd, + configType } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; internalSlotsMap.set(this, { cwd: normalizeCwd(cwd), lastConfigArray: null, lastSourceCode: null, + configType, + // TODO: Remove after flat config conversion parserMap: new Map([["espree", espree]]), ruleMap: new Rules() }); @@ -19188,9 +19331,14 @@ class Linter { const parserOptions = resolveParserOptions(parser, config.parserOptions || {}, enabledEnvs); const configuredGlobals = resolveGlobals(config.globals || {}, enabledEnvs); const settings = config.settings || {}; + const languageOptions = createLanguageOptions({ + globals: config.globals, + parser, + parserOptions + }); if (!slots.lastSourceCode) { - const parseResult = parse(text, parser, parserOptions, options.filename); + const parseResult = parse(text, languageOptions, options.filename); if (!parseResult.success) { return [parseResult.error]; @@ -19208,7 +19356,7 @@ class Linter { ast: slots.lastSourceCode.ast, parserServices: slots.lastSourceCode.parserServices, visitorKeys: slots.lastSourceCode.visitorKeys, - scopeManager: analyzeScope(slots.lastSourceCode.ast, parserOptions) + scopeManager: analyzeScope(slots.lastSourceCode.ast, languageOptions) }); } } @@ -19230,7 +19378,7 @@ class Linter { let lintingProblems; try { - lintingProblems = runRules(sourceCode, configuredRules, ruleId => getRule(slots, ruleId), parserOptions, parserName, settings, options.filename, options.disableFixes, slots.cwd, providedOptions.physicalFilename); + lintingProblems = runRules(sourceCode, configuredRules, ruleId => getRule(slots, ruleId), parserName, languageOptions, settings, options.filename, options.disableFixes, slots.cwd, providedOptions.physicalFilename); } catch (err) { err.message += "\nOccurred while linting ".concat(options.filename); debug("An error occurred while traversing"); @@ -19275,13 +19423,41 @@ class Linter { verify(textOrSourceCode, config, filenameOrOptions) { debug("Verify"); + const { + configType + } = internalSlotsMap.get(this); const options = typeof filenameOrOptions === "string" ? { filename: filenameOrOptions - } : filenameOrOptions || {}; // CLIEngine passes a `ConfigArray` object. + } : filenameOrOptions || {}; + + if (config) { + if (configType === "flat") { + /* + * Because of how Webpack packages up the files, we can't + * compare directly to `FlatConfigArray` using `instanceof` + * because it's not the same `FlatConfigArray` as in the tests. + * So, we work around it by assuming an array is, in fact, a + * `FlatConfigArray` if it has a `getConfig()` method. + */ + let configArray = config; + + if (!Array.isArray(config) || typeof config.getConfig !== "function") { + configArray = new FlatConfigArray(config); + configArray.normalizeSync(); + } + + return this._verifyWithFlatConfigArray(textOrSourceCode, configArray, options, true); + } - if (config && typeof config.extractConfig === "function") { - return this._verifyWithConfigArray(textOrSourceCode, config, options); + if (typeof config.extractConfig === "function") { + return this._verifyWithConfigArray(textOrSourceCode, config, options); + } } + /* + * If we get to here, it means `config` is just an object rather + * than a config array so we can go right into linting. + */ + /* * `Linter` doesn't support `overrides` property in configuration. * So we cannot apply multiple processors. @@ -19294,6 +19470,180 @@ class Linter { return this._verifyWithoutProcessors(textOrSourceCode, config, options); } + /** + * Verify with a processor. + * @param {string|SourceCode} textOrSourceCode The source code. + * @param {FlatConfig} config The config array. + * @param {VerifyOptions&ProcessorOptions} options The options. + * @param {FlatConfigArray} [configForRecursive] The `ConfigArray` object to apply multiple processors recursively. + * @returns {LintMessage[]} The found problems. + */ + + + _verifyWithFlatConfigArrayAndProcessor(textOrSourceCode, config, options, configForRecursive) { + const filename = options.filename || ""; + const filenameToExpose = normalizeFilename(filename); + const physicalFilename = options.physicalFilename || filenameToExpose; + const text = ensureText(textOrSourceCode); + + const preprocess = options.preprocess || (rawText => [rawText]); + + const postprocess = options.postprocess || (messagesList => messagesList.flat()); + + const filterCodeBlock = options.filterCodeBlock || (blockFilename => blockFilename.endsWith(".js")); + + const originalExtname = path.extname(filename); + const messageLists = preprocess(text, filenameToExpose).map((block, i) => { + debug("A code block was found: %o", block.filename || "(unnamed)"); // Keep the legacy behavior. + + if (typeof block === "string") { + return this._verifyWithFlatConfigArrayAndWithoutProcessors(block, config, options); + } + + const blockText = block.text; + const blockName = path.join(filename, "".concat(i, "_").concat(block.filename)); // Skip this block if filtered. + + if (!filterCodeBlock(blockName, blockText)) { + debug("This code block was skipped."); + return []; + } // Resolve configuration again if the file content or extension was changed. + + + if (configForRecursive && (text !== blockText || path.extname(blockName) !== originalExtname)) { + debug("Resolving configuration again because the file content or extension was changed."); + return this._verifyWithFlatConfigArray(blockText, configForRecursive, { ...options, + filename: blockName, + physicalFilename + }); + } // Does lint. + + + return this._verifyWithFlatConfigArrayAndWithoutProcessors(blockText, config, { ...options, + filename: blockName, + physicalFilename + }); + }); + return postprocess(messageLists, filenameToExpose); + } + /** + * Same as linter.verify, except without support for processors. + * @param {string|SourceCode} textOrSourceCode The text to parse or a SourceCode object. + * @param {FlatConfig} providedConfig An ESLintConfig instance to configure everything. + * @param {VerifyOptions} [providedOptions] The optional filename of the file being checked. + * @throws {Error} If during rule execution. + * @returns {LintMessage[]} The results as an array of messages or an empty array if no messages. + */ + + + _verifyWithFlatConfigArrayAndWithoutProcessors(textOrSourceCode, providedConfig, providedOptions) { + const slots = internalSlotsMap.get(this); + const config = providedConfig || {}; + const options = normalizeVerifyOptions(providedOptions, config); + let text; // evaluate arguments + + if (typeof textOrSourceCode === "string") { + slots.lastSourceCode = null; + text = textOrSourceCode; + } else { + slots.lastSourceCode = textOrSourceCode; + text = textOrSourceCode.text; + } + + const languageOptions = config.languageOptions; + languageOptions.ecmaVersion = normalizeEcmaVersionForLanguageOptions(languageOptions.ecmaVersion); // add configured globals and language globals + + const configuredGlobals = { ...getGlobalsForEcmaVersion(languageOptions.ecmaVersion), + ...(languageOptions.sourceType === "commonjs" ? globals.commonjs : void 0), + ...languageOptions.globals + }; // Espree expects this information to be passed in + + if (isEspree(languageOptions.parser)) { + const parserOptions = languageOptions.parserOptions; + + if (languageOptions.sourceType) { + parserOptions.sourceType = languageOptions.sourceType; + + if (parserOptions.sourceType === "module" && parserOptions.ecmaFeatures && parserOptions.ecmaFeatures.globalReturn) { + parserOptions.ecmaFeatures.globalReturn = false; + } + } + } + + const settings = config.settings || {}; + + if (!slots.lastSourceCode) { + const parseResult = parse(text, languageOptions, options.filename); + + if (!parseResult.success) { + return [parseResult.error]; + } + + slots.lastSourceCode = parseResult.sourceCode; + } else { + /* + * If the given source code object as the first argument does not have scopeManager, analyze the scope. + * This is for backward compatibility (SourceCode is frozen so it cannot rebind). + */ + if (!slots.lastSourceCode.scopeManager) { + slots.lastSourceCode = new SourceCode({ + text: slots.lastSourceCode.text, + ast: slots.lastSourceCode.ast, + parserServices: slots.lastSourceCode.parserServices, + visitorKeys: slots.lastSourceCode.visitorKeys, + scopeManager: analyzeScope(slots.lastSourceCode.ast, languageOptions) + }); + } + } + + const sourceCode = slots.lastSourceCode; + const commentDirectives = options.allowInlineConfig ? getDirectiveComments(options.filename, sourceCode.ast, ruleId => getRuleFromConfig(ruleId, config), options.warnInlineConfig) : { + configuredRules: {}, + enabledGlobals: {}, + exportedVariables: {}, + problems: [], + disableDirectives: [] + }; // augment global scope with declared global variables + + addDeclaredGlobals(sourceCode.scopeManager.scopes[0], configuredGlobals, { + exportedVariables: commentDirectives.exportedVariables, + enabledGlobals: commentDirectives.enabledGlobals + }); + const configuredRules = Object.assign({}, config.rules, commentDirectives.configuredRules); + let lintingProblems; + + try { + lintingProblems = runRules(sourceCode, configuredRules, ruleId => getRuleFromConfig(ruleId, config), void 0, languageOptions, settings, options.filename, options.disableFixes, slots.cwd, providedOptions.physicalFilename); + } catch (err) { + err.message += "\nOccurred while linting ".concat(options.filename); + debug("An error occurred while traversing"); + debug("Filename:", options.filename); + + if (err.currentNode) { + const { + line + } = err.currentNode.loc.start; + debug("Line:", line); + err.message += ":".concat(line); + } + + debug("Parser Options:", languageOptions.parserOptions); // debug("Parser Path:", parserName); + + debug("Settings:", settings); + + if (err.ruleId) { + err.message += "\nRule: \"".concat(err.ruleId, "\""); + } + + throw err; + } + + return applyDisableDirectives({ + directives: commentDirectives.disableDirectives, + disableFixes: options.disableFixes, + problems: lintingProblems.concat(commentDirectives.problems).sort((problemA, problemB) => problemA.line - problemB.line || problemA.column - problemB.column), + reportUnusedDisableDirectives: options.reportUnusedDisableDirectives + }); + } /** * Verify a given code with `ConfigArray`. * @param {string|SourceCode} textOrSourceCode The source code. @@ -19328,6 +19678,49 @@ class Linter { return this._verifyWithoutProcessors(textOrSourceCode, config, options); } + /** + * Verify a given code with a flat config. + * @param {string|SourceCode} textOrSourceCode The source code. + * @param {FlatConfigArray} configArray The config array. + * @param {VerifyOptions&ProcessorOptions} options The options. + * @param {boolean} [firstCall=false] Indicates if this is being called directly + * from verify(). (TODO: Remove once eslintrc is removed.) + * @returns {LintMessage[]} The found problems. + */ + + + _verifyWithFlatConfigArray(textOrSourceCode, configArray, options) { + let firstCall = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; + debug("With flat config: %s", options.filename); // we need a filename to match configs against + + const filename = options.filename || ""; // Store the config array in order to get plugin envs and rules later. + + internalSlotsMap.get(this).lastConfigArray = configArray; + const config = configArray.getConfig(filename); // Verify. + + if (config.processor) { + debug("Apply the processor: %o", config.processor); + const { + preprocess, + postprocess, + supportsAutofix + } = config.processor; + const disableFixes = options.disableFixes || !supportsAutofix; + return this._verifyWithFlatConfigArrayAndProcessor(textOrSourceCode, config, { ...options, + filename, + disableFixes, + postprocess, + preprocess + }, configArray); + } // check for options-based processing + + + if (firstCall && (options.preprocess || options.postprocess)) { + return this._verifyWithFlatConfigArrayAndProcessor(textOrSourceCode, config, options); + } + + return this._verifyWithFlatConfigArrayAndWithoutProcessors(textOrSourceCode, config, options); + } /** * Verify with a processor. * @param {string|SourceCode} textOrSourceCode The source code. @@ -19401,6 +19794,7 @@ class Linter { defineRule(ruleId, ruleModule) { + assertEslintrcConfig(this); internalSlotsMap.get(this).ruleMap.define(ruleId, ruleModule); } /** @@ -19411,6 +19805,7 @@ class Linter { defineRules(rulesToDefine) { + assertEslintrcConfig(this); Object.getOwnPropertyNames(rulesToDefine).forEach(ruleId => { this.defineRule(ruleId, rulesToDefine[ruleId]); }); @@ -19422,6 +19817,7 @@ class Linter { getRules() { + assertEslintrcConfig(this); const { lastConfigArray, ruleMap @@ -19443,13 +19839,14 @@ class Linter { defineParser(parserId, parserModule) { + assertEslintrcConfig(this); internalSlotsMap.get(this).parserMap.set(parserId, parserModule); } /** * Performs multiple autofix passes over the text until as many fixes as possible * have been applied. * @param {string} text The source text to apply fixes to. - * @param {ConfigData|ConfigArray} config The ESLint config object to use. + * @param {ConfigData|ConfigArray|FlatConfigArray} config The ESLint config object to use. * @param {VerifyOptions&ProcessorOptions&FixOptions} options The ESLint options object to use. * @returns {{fixed:boolean,messages:LintMessage[],output:string}} The result of the fix operation as returned from the * SourceCodeFixer. @@ -23594,7 +23991,16 @@ function normalizeOptions(options) { const sourceType = normalizeSourceType(options.sourceType); const ranges = options.range === true; const locations = options.loc === true; - const allowReserved = ecmaVersion === 3 ? "never" : false; + + if (ecmaVersion !== 3 && options.allowReserved) { + + // a value of `false` is intentionally allowed here, so a shared config can overwrite it when needed + throw new Error("`allowReserved` is only supported when ecmaVersion is 3"); + } + if (typeof options.allowReserved !== "undefined" && typeof options.allowReserved !== "boolean") { + throw new Error("`allowReserved`, when present, must be `true` or `false`"); + } + const allowReserved = ecmaVersion === 3 ? (options.allowReserved || "never") : false; const ecmaFeatures = options.ecmaFeatures || {}; const allowReturnOutsideFunction = options.sourceType === "commonjs" || Boolean(ecmaFeatures.globalReturn); @@ -23940,7 +24346,7 @@ var espree = () => Parser => { }; }; -const version$1 = "9.1.0"; +const version$1 = "9.2.0"; /** * @fileoverview Main Espree file that converts Acorn into Esprima output. @@ -34210,7 +34616,7 @@ module.exports = merge; /***/ ((module) => { "use strict"; -module.exports = JSON.parse('{"name":"eslint","version":"8.3.0","author":"Nicholas C. Zakas ","description":"An AST-based pattern checker for JavaScript.","bin":{"eslint":"./bin/eslint.js"},"main":"./lib/api.js","exports":{"./package.json":"./package.json",".":"./lib/api.js","./use-at-your-own-risk":"./lib/unsupported-api.js"},"scripts":{"test":"node Makefile.js test","test:cli":"mocha","lint":"node Makefile.js lint","fix":"node Makefile.js lint -- fix","fuzz":"node Makefile.js fuzz","generate-release":"node Makefile.js generateRelease","generate-alpharelease":"node Makefile.js generatePrerelease -- alpha","generate-betarelease":"node Makefile.js generatePrerelease -- beta","generate-rcrelease":"node Makefile.js generatePrerelease -- rc","publish-release":"node Makefile.js publishRelease","gensite":"node Makefile.js gensite","webpack":"node Makefile.js webpack","perf":"node Makefile.js perf"},"gitHooks":{"pre-commit":"lint-staged"},"lint-staged":{"*.js":"eslint --fix","*.md":"markdownlint"},"files":["LICENSE","README.md","bin","conf","lib","messages"],"repository":"eslint/eslint","funding":"https://opencollective.com/eslint","homepage":"https://eslint.org","bugs":"https://github.com/eslint/eslint/issues/","dependencies":{"@eslint/eslintrc":"^1.0.4","@humanwhocodes/config-array":"^0.6.0","ajv":"^6.10.0","chalk":"^4.0.0","cross-spawn":"^7.0.2","debug":"^4.3.2","doctrine":"^3.0.0","enquirer":"^2.3.5","escape-string-regexp":"^4.0.0","eslint-scope":"^7.1.0","eslint-utils":"^3.0.0","eslint-visitor-keys":"^3.1.0","espree":"^9.1.0","esquery":"^1.4.0","esutils":"^2.0.2","fast-deep-equal":"^3.1.3","file-entry-cache":"^6.0.1","functional-red-black-tree":"^1.0.1","glob-parent":"^6.0.1","globals":"^13.6.0","ignore":"^4.0.6","import-fresh":"^3.0.0","imurmurhash":"^0.1.4","is-glob":"^4.0.0","js-yaml":"^4.1.0","json-stable-stringify-without-jsonify":"^1.0.1","levn":"^0.4.1","lodash.merge":"^4.6.2","minimatch":"^3.0.4","natural-compare":"^1.4.0","optionator":"^0.9.1","progress":"^2.0.0","regexpp":"^3.2.0","semver":"^7.2.1","strip-ansi":"^6.0.1","strip-json-comments":"^3.1.0","text-table":"^0.2.0","v8-compile-cache":"^2.0.3"},"devDependencies":{"@babel/core":"^7.4.3","@babel/preset-env":"^7.4.3","babel-loader":"^8.0.5","chai":"^4.0.1","cheerio":"^0.22.0","common-tags":"^1.8.0","core-js":"^3.1.3","dateformat":"^4.5.1","ejs":"^3.0.2","eslint":"file:.","eslint-config-eslint":"file:packages/eslint-config-eslint","eslint-plugin-eslint-comments":"^3.2.0","eslint-plugin-eslint-plugin":"^4.0.1","eslint-plugin-internal-rules":"file:tools/internal-rules","eslint-plugin-jsdoc":"^37.0.0","eslint-plugin-node":"^11.1.0","eslint-release":"^3.2.0","eslump":"^3.0.0","esprima":"^4.0.1","fs-teardown":"^0.1.3","glob":"^7.1.6","jsdoc":"^3.5.5","karma":"^6.1.1","karma-chrome-launcher":"^3.1.0","karma-mocha":"^2.0.1","karma-mocha-reporter":"^2.2.5","karma-webpack":"^5.0.0","lint-staged":"^11.0.0","load-perf":"^0.2.0","markdownlint":"^0.23.1","markdownlint-cli":"^0.28.1","memfs":"^3.0.1","mocha":"^8.3.2","mocha-junit-reporter":"^2.0.0","node-polyfill-webpack-plugin":"^1.0.3","npm-license":"^0.3.3","nyc":"^15.0.1","proxyquire":"^2.0.1","puppeteer":"^9.1.1","recast":"^0.20.4","regenerator-runtime":"^0.13.2","shelljs":"^0.8.2","sinon":"^11.0.0","temp":"^0.9.0","webpack":"^5.23.0","webpack-cli":"^4.5.0","yorkie":"^2.0.0"},"keywords":["ast","lint","javascript","ecmascript","espree"],"license":"MIT","engines":{"node":"^12.22.0 || ^14.17.0 || >=16.0.0"}}'); +module.exports = JSON.parse('{"name":"eslint","version":"8.4.0","author":"Nicholas C. Zakas ","description":"An AST-based pattern checker for JavaScript.","bin":{"eslint":"./bin/eslint.js"},"main":"./lib/api.js","exports":{"./package.json":"./package.json",".":"./lib/api.js","./use-at-your-own-risk":"./lib/unsupported-api.js"},"scripts":{"test":"node Makefile.js test","test:cli":"mocha","lint":"node Makefile.js lint","fix":"node Makefile.js lint -- fix","fuzz":"node Makefile.js fuzz","generate-release":"node Makefile.js generateRelease","generate-alpharelease":"node Makefile.js generatePrerelease -- alpha","generate-betarelease":"node Makefile.js generatePrerelease -- beta","generate-rcrelease":"node Makefile.js generatePrerelease -- rc","publish-release":"node Makefile.js publishRelease","gensite":"node Makefile.js gensite","webpack":"node Makefile.js webpack","perf":"node Makefile.js perf"},"gitHooks":{"pre-commit":"lint-staged"},"lint-staged":{"*.js":"eslint --fix","*.md":"markdownlint"},"files":["LICENSE","README.md","bin","conf","lib","messages"],"repository":"eslint/eslint","funding":"https://opencollective.com/eslint","homepage":"https://eslint.org","bugs":"https://github.com/eslint/eslint/issues/","dependencies":{"@eslint/eslintrc":"^1.0.5","@humanwhocodes/config-array":"^0.9.2","ajv":"^6.10.0","chalk":"^4.0.0","cross-spawn":"^7.0.2","debug":"^4.3.2","doctrine":"^3.0.0","enquirer":"^2.3.5","escape-string-regexp":"^4.0.0","eslint-scope":"^7.1.0","eslint-utils":"^3.0.0","eslint-visitor-keys":"^3.1.0","espree":"^9.2.0","esquery":"^1.4.0","esutils":"^2.0.2","fast-deep-equal":"^3.1.3","file-entry-cache":"^6.0.1","functional-red-black-tree":"^1.0.1","glob-parent":"^6.0.1","globals":"^13.6.0","ignore":"^4.0.6","import-fresh":"^3.0.0","imurmurhash":"^0.1.4","is-glob":"^4.0.0","js-yaml":"^4.1.0","json-stable-stringify-without-jsonify":"^1.0.1","levn":"^0.4.1","lodash.merge":"^4.6.2","minimatch":"^3.0.4","natural-compare":"^1.4.0","optionator":"^0.9.1","progress":"^2.0.0","regexpp":"^3.2.0","semver":"^7.2.1","strip-ansi":"^6.0.1","strip-json-comments":"^3.1.0","text-table":"^0.2.0","v8-compile-cache":"^2.0.3"},"devDependencies":{"@babel/core":"^7.4.3","@babel/preset-env":"^7.4.3","babel-loader":"^8.0.5","chai":"^4.0.1","cheerio":"^0.22.0","common-tags":"^1.8.0","core-js":"^3.1.3","dateformat":"^4.5.1","ejs":"^3.0.2","eslint":"file:.","eslint-config-eslint":"file:packages/eslint-config-eslint","eslint-plugin-eslint-comments":"^3.2.0","eslint-plugin-eslint-plugin":"^4.0.1","eslint-plugin-internal-rules":"file:tools/internal-rules","eslint-plugin-jsdoc":"^37.0.0","eslint-plugin-node":"^11.1.0","eslint-release":"^3.2.0","eslump":"^3.0.0","esprima":"^4.0.1","fs-teardown":"^0.1.3","glob":"^7.1.6","jsdoc":"^3.5.5","karma":"^6.1.1","karma-chrome-launcher":"^3.1.0","karma-mocha":"^2.0.1","karma-mocha-reporter":"^2.2.5","karma-webpack":"^5.0.0","lint-staged":"^11.0.0","load-perf":"^0.2.0","markdownlint":"^0.24.0","markdownlint-cli":"^0.30.0","memfs":"^3.0.1","mocha":"^8.3.2","mocha-junit-reporter":"^2.0.0","node-polyfill-webpack-plugin":"^1.0.3","npm-license":"^0.3.3","nyc":"^15.0.1","proxyquire":"^2.0.1","puppeteer":"^9.1.1","recast":"^0.20.4","regenerator-runtime":"^0.13.2","shelljs":"^0.8.2","sinon":"^11.0.0","temp":"^0.9.0","webpack":"^5.23.0","webpack-cli":"^4.5.0","yorkie":"^2.0.0"},"keywords":["ast","lint","javascript","ecmascript","espree"],"license":"MIT","engines":{"node":"^12.22.0 || ^14.17.0 || >=16.0.0"}}'); /***/ }), /* 444 */ @@ -58453,6 +58859,8 @@ function isPropertyDescriptor(node) { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -61093,6 +61501,8 @@ const astUtils = __webpack_require__(548); //----------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -61354,6 +61764,8 @@ const astUtils = __webpack_require__(548); //----------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -61723,6 +62135,8 @@ function getArrayMethodName(node) { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -61889,6 +62303,8 @@ const astUtils = __webpack_require__(548); //----------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -62186,6 +62602,8 @@ const astUtils = __webpack_require__(548); //----------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -62482,6 +62900,8 @@ function hasBlockBody(node) { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -62639,6 +63059,8 @@ const astUtils = __webpack_require__(548); //----------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -62796,6 +63218,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "suggestion", @@ -62924,6 +63348,8 @@ const util = __webpack_require__(548); //--------------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -63100,6 +63526,8 @@ const astUtils = __webpack_require__(548); //----------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -63292,6 +63720,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { deprecated: true, @@ -63471,6 +63901,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "suggestion", @@ -63915,6 +64347,8 @@ function createRegExpForIgnorePatterns(normalizedOptions) { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -64154,6 +64588,8 @@ const astUtils = __webpack_require__(548); //----------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -64395,6 +64831,8 @@ function normalizeOptions(optionValue, ecmaVersion) { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -64691,6 +65129,8 @@ const astUtils = __webpack_require__(548); //----------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -64876,6 +65316,8 @@ const astUtils = __webpack_require__(548); //----------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -65175,6 +65617,8 @@ const { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -65346,6 +65790,8 @@ const astUtils = __webpack_require__(548); //----------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -65594,6 +66040,8 @@ function isClassConstructor(node) { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -65741,6 +66189,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "suggestion", @@ -65997,6 +66447,8 @@ function isPossibleConstructor(node) { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -66302,6 +66754,8 @@ const astUtils = __webpack_require__(548); //----------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -66773,6 +67227,8 @@ const DEFAULT_COMMENT_PATTERN = /^no default$/iu; //---------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "suggestion", @@ -66863,6 +67319,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "suggestion", @@ -66907,6 +67365,7 @@ module.exports = { * @author Chiawen Chen */ +/** @type {import('../shared/types').Rule} */ module.exports = { meta: { @@ -66972,6 +67431,8 @@ const astUtils = __webpack_require__(548); //----------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -67085,6 +67546,8 @@ const keywords = __webpack_require__(583); //----------------------------------- const validIdentifier = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/u; // `null` literal must be handled separately. const literalTypesToCheck = new Set(["string", "boolean"]); +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "suggestion", @@ -67239,6 +67702,8 @@ module.exports = ["abstract", "boolean", "break", "byte", "case", "catch", "char // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "layout", @@ -67358,6 +67823,8 @@ const astUtils = __webpack_require__(548); //----------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -67518,6 +67985,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "problem", @@ -67655,6 +68124,8 @@ const astUtils = __webpack_require__(548); //----------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -67938,6 +68409,8 @@ const optionsObject = { }, additionalProperties: false }; +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "suggestion", @@ -68142,6 +68615,8 @@ function isFunctionName(variable) { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -68302,6 +68777,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "suggestion", @@ -68407,6 +68884,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "layout", @@ -68525,6 +69004,8 @@ const astUtils = __webpack_require__(548); //----------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -68814,6 +69295,8 @@ const OVERRIDE_SCHEMA = { additionalProperties: false }] }; +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "layout", @@ -69030,6 +69513,8 @@ function isReachable(segment) { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -69205,6 +69690,8 @@ function isShadowed(scope, node) { const reference = findReference(scope, node); return reference && reference.resolved && reference.resolved.defs.length > 0; } +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -69336,6 +69823,8 @@ function isAccessorKind(node) { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -69477,6 +69966,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "suggestion", @@ -69554,6 +70045,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { deprecated: true, @@ -69712,6 +70205,8 @@ function isShorthandPropertyDefinition(node) { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -69888,6 +70383,8 @@ function isPropertyNameInDestructuring(node) { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -70018,6 +70515,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "suggestion", @@ -70178,6 +70677,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "suggestion", @@ -70424,6 +70925,8 @@ const { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -70911,6 +71414,8 @@ const ELEMENT_LIST_SCHEMA = { enum: ["first", "off"] }] }; +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "layout", @@ -73266,6 +73771,8 @@ const astUtils = __webpack_require__(548); //----------------------------------- /* istanbul ignore next: this rule has known coverage issues, but it's deprecated and shouldn't be updated in the future anyway. */ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -74320,6 +74827,8 @@ function isInitialized(node) { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -74444,6 +74953,8 @@ const QUOTE_SETTINGS = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "layout", @@ -74637,6 +75148,8 @@ function initOptions(toOptions, fromOptions) { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -75235,6 +75748,8 @@ function isCloseParenOfTemplate(token) { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -75783,6 +76298,8 @@ const astUtils = __webpack_require__(548); //----------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -75903,6 +76420,8 @@ const astUtils = __webpack_require__(548); //----------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -76035,6 +76554,8 @@ function getCommentLineNums(comments) { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -76443,6 +76964,8 @@ const astUtils = __webpack_require__(548); //----------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -76642,6 +77165,8 @@ const astUtils = __webpack_require__(548); //----------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -76832,6 +77357,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "suggestion", @@ -76913,6 +77440,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "suggestion", @@ -77117,6 +77646,8 @@ const OPTIONS_OR_INTEGER_SCHEMA = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "layout", @@ -77486,6 +78017,8 @@ function range(start, end) { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -77702,6 +78235,8 @@ function getCommentLineNumbers(comments) { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -77713,7 +78248,7 @@ module.exports = { }, schema: [OPTIONS_OR_INTEGER_SCHEMA], messages: { - exceed: "{{name}} has too many lines ({{lineCount}}). Maximum allowed is {{maxLines}}." + exceed: "{{name}} has exceeded the limit of lines allowed by {{linesExceed}}. Maximum allowed number of lines per function is {{maxLines}}." } }, @@ -77806,18 +78341,28 @@ module.exports = { } let lineCount = 0; + let comments = 0; + let blankLines = 0; for (let i = node.loc.start.line - 1; i < node.loc.end.line; ++i) { const line = lines[i]; if (skipComments) { if (commentLineNumbers.has(i + 1) && isFullLineComment(line, i + 1, commentLineNumbers.get(i + 1))) { + if (lineCount <= maxLines) { + comments++; + } + continue; } } if (skipBlankLines) { if (line.match(/^\s*$/u)) { + if (lineCount <= maxLines) { + blankLines++; + } + continue; } } @@ -77827,12 +78372,21 @@ module.exports = { if (lineCount > maxLines) { const name = upperCaseFirst(astUtils.getFunctionNameWithKind(funcNode)); + const linesExceed = lineCount - maxLines; + const loc = { + start: { + line: node.loc.start.line + maxLines + (comments + blankLines), + column: 0 + }, + end: node.loc.end + }; context.report({ node, + loc, messageId: "exceed", data: { name, - lineCount, + linesExceed, maxLines } }); @@ -77864,6 +78418,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "suggestion", @@ -77984,6 +78540,8 @@ const { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -78082,6 +78640,8 @@ const { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -78260,6 +78820,8 @@ const astUtils = __webpack_require__(548); //----------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -78448,6 +79010,8 @@ const astUtils = __webpack_require__(548); //----------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -78912,6 +79476,8 @@ const astUtils = __webpack_require__(548); //----------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -79117,6 +79683,8 @@ function calculateCapIsNewExceptions(config) { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -79325,6 +79893,8 @@ const astUtils = __webpack_require__(548); //----------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -79409,6 +79979,8 @@ const astUtils = __webpack_require__(548); //----------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -79656,6 +80228,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "layout", @@ -79879,6 +80453,8 @@ const astUtils = __webpack_require__(548); //----------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -80072,6 +80648,8 @@ function isGlobalThisReferenceOrGlobalWindow(scope, node) { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -80138,6 +80716,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "suggestion", @@ -80189,6 +80769,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "problem", @@ -80268,6 +80850,8 @@ function isLooped(node, parent) { return false; } } +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -80339,6 +80923,8 @@ const BITWISE_OPERATORS = ["^", "|", "&", "<<", ">>", ">>>", "^=", "|=", "&=", " // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "suggestion", @@ -80454,6 +81040,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { deprecated: true, @@ -80503,6 +81091,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "suggestion", @@ -80552,6 +81142,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "suggestion", @@ -80623,6 +81215,8 @@ const astUtils = __webpack_require__(548); //----------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -80701,6 +81295,8 @@ const astUtils = __webpack_require__(548); //----------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -80765,6 +81361,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "problem", @@ -80843,6 +81441,8 @@ const NODE_DESCRIPTIONS = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "problem", @@ -80985,6 +81585,8 @@ function isConditional(node) { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -81061,6 +81663,8 @@ const astUtils = __webpack_require__(548); //----------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -81182,6 +81786,8 @@ const astUtils = __webpack_require__(548); //----------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -81243,6 +81849,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "problem", @@ -81353,6 +81961,7 @@ module.exports = { case "ArrowFunctionExpression": case "FunctionExpression": case "ObjectExpression": + case "ClassExpression": return true; case "TemplateLiteral": @@ -81390,6 +81999,9 @@ module.exports = { return isLeftConstant && isRightConstant || isLeftShortCircuit || isRightShortCircuit; } + case "NewExpression": + return inBooleanPosition; + case "AssignmentExpression": if (node.operator === "=") { return isConstant(node.right, inBooleanPosition); @@ -81526,6 +82138,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "problem", @@ -81585,6 +82199,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "suggestion", @@ -81659,6 +82275,8 @@ const collector = new class { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "problem", @@ -84190,6 +84808,8 @@ exports.visitRegExpAST = visitRegExpAST; // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "problem", @@ -84232,6 +84852,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "suggestion", @@ -84275,6 +84897,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "suggestion", @@ -84327,6 +84951,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "problem", @@ -84408,6 +85034,8 @@ const astUtils = __webpack_require__(548); //----------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -84562,6 +85190,8 @@ const splitByAnd = splitByLogicalOperator.bind(null, "&&"); //------------------ // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "problem", @@ -84713,6 +85343,8 @@ class ObjectInfo { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -84790,6 +85422,8 @@ const astUtils = __webpack_require__(548); //----------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -85073,6 +85707,8 @@ function handleImportsExports(context, modules, declarationType, includeExports) } }; } +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -85136,6 +85772,8 @@ const FixTracker = __webpack_require__(662); //--------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -85692,6 +86330,8 @@ const astUtils = __webpack_require__(548); //----------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -85794,6 +86434,8 @@ const regex = /^([^\\[]|\\.|\[([^\\\]]|\\.)+\])*$/u; //------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "problem", @@ -85907,6 +86549,8 @@ function getKind(node) { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -85992,6 +86636,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "problem", @@ -86051,6 +86697,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "suggestion", @@ -86117,6 +86765,8 @@ function isMember(node, name) { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -86358,6 +87008,8 @@ const astUtils = __webpack_require__(548); //----------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -86417,6 +87069,8 @@ const globals = __webpack_require__(492); //------------------------------------ // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -86572,6 +87226,8 @@ const SIDE_EFFECT_FREE_NODE_TYPES = new Set(["Literal", "Identifier", "ThisExpre // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "suggestion", @@ -86762,6 +87418,8 @@ const precedence = astUtils.getPrecedence; //----------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "suggestion", @@ -87048,6 +87706,8 @@ const astUtils = __webpack_require__(548); //----------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -87204,6 +87864,8 @@ const { } = __webpack_require__(501); const astUtils = __webpack_require__(548); +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -88358,6 +89020,8 @@ const astUtils = __webpack_require__(548); //----------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -88514,6 +89178,8 @@ function hasBlankLinesBetween(node, token) { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -88616,6 +89282,8 @@ const astUtils = __webpack_require__(548); //----------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -88682,6 +89350,8 @@ const astUtils = __webpack_require__(548); //----------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -88758,6 +89428,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "suggestion", @@ -88992,6 +89664,8 @@ function getNonEmptyOperand(node) { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -89187,6 +89861,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "suggestion", @@ -89319,6 +89995,8 @@ const { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -89559,6 +90237,8 @@ function getWriteNode(id) { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -89639,6 +90319,8 @@ const astUtils = __webpack_require__(548); //----------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -89775,6 +90457,8 @@ function getAllowedBodyDescription(node) { return "program"; } +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -89854,6 +90538,8 @@ const undefined1 = void 0; //--------------------------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "problem", @@ -90005,6 +90691,8 @@ const astUtils = __webpack_require__(548); //----------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -90157,6 +90845,8 @@ const LINE_BREAK = astUtils.createGlobalLinebreakMatcher(); //------------------ // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "problem", @@ -90403,6 +91093,8 @@ const { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -90451,6 +91143,8 @@ const astUtils = __webpack_require__(548); //----------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -90524,6 +91218,8 @@ const astUtils = __webpack_require__(548); //----------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -90677,6 +91373,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "suggestion", @@ -90801,6 +91499,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "suggestion", @@ -91002,6 +91702,8 @@ function isSafe(loopNode, reference) { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -91069,6 +91771,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "problem", @@ -91294,6 +91998,8 @@ function normalizeIgnoreValue(x) { return x; } +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -91576,6 +92282,8 @@ const kinds = Object.keys(hasCharacterSequence); //----------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "problem", @@ -91845,6 +92553,8 @@ function getChildNode(node) { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -91988,6 +92698,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { deprecated: true, @@ -92189,6 +92901,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "layout", @@ -92299,6 +93013,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "suggestion", @@ -92363,6 +93079,8 @@ const astUtils = __webpack_require__(548); //----------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -92496,6 +93214,8 @@ const astUtils = __webpack_require__(548); //----------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -92554,6 +93274,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "layout", @@ -92706,6 +93428,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "suggestion", @@ -92798,6 +93522,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "suggestion", @@ -92898,6 +93624,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "problem", @@ -92943,6 +93671,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "suggestion", @@ -92987,6 +93717,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "suggestion", @@ -93037,6 +93769,8 @@ const callMethods = new Set(["apply", "bind", "call"]); //---------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "suggestion", @@ -93109,6 +93843,8 @@ const astUtils = __webpack_require__(548); //----------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -93160,6 +93896,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { deprecated: true, @@ -93205,6 +93943,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "problem", @@ -93258,6 +93998,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "suggestion", @@ -93319,6 +94061,8 @@ function getUnicodeEscape(character) { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -93467,6 +94211,8 @@ function getReportNodeName(node) { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -93533,6 +94279,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "suggestion", @@ -93576,6 +94324,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "suggestion", @@ -93630,6 +94380,8 @@ module.exports = { //------------------------------------------------------------------------------ const stopNodePattern = /(?:Statement|Declaration|Function(?:Expression)?|Program)$/u; +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "suggestion", @@ -93856,6 +94608,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { deprecated: true, @@ -93943,6 +94697,8 @@ function isForLoopAfterthought(node) { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -94009,6 +94765,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { deprecated: true, @@ -94058,6 +94816,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { deprecated: true, @@ -94154,6 +94914,8 @@ function isPromiseExecutor(node, scope) { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -94230,6 +94992,8 @@ const { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -94278,6 +95042,8 @@ const astUtils = __webpack_require__(548); //----------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -94346,6 +95112,8 @@ const astUtils = __webpack_require__(548); //----------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -94530,6 +95298,8 @@ function isString(node) { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -94681,6 +95451,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "suggestion", @@ -94769,6 +95541,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "suggestion", @@ -94949,6 +95723,8 @@ const arrayOfStringsOrObjectPatterns = { uniqueItems: true }] }; +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "suggestion", @@ -95546,6 +96322,8 @@ const arrayOfStringsOrObjects = { }, uniqueItems: true }; +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { deprecated: true, @@ -95725,6 +96503,8 @@ const astUtils = __webpack_require__(548); //----------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -95908,6 +96688,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "suggestion", @@ -95989,6 +96771,8 @@ const SENTINEL_TYPE = /^(?:[a-zA-Z]+?Statement|ArrowFunctionExpression|FunctionE // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "suggestion", @@ -96057,6 +96841,8 @@ const astUtils = __webpack_require__(548); //----------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -96169,6 +96955,8 @@ const astUtils = __webpack_require__(548); //----------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -96307,6 +97095,8 @@ function eachSelfAssignment(left, right, props, report) { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -96378,6 +97168,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "problem", @@ -96448,6 +97240,8 @@ const DEFAULT_OPTIONS = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "suggestion", @@ -96674,6 +97468,8 @@ function getOuterScope(scope) { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -96780,6 +97576,8 @@ const astUtils = __webpack_require__(548); //----------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -96997,6 +97795,8 @@ function safelyShadowsUndefined(variable) { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -97048,6 +97848,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "layout", @@ -97120,6 +97922,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "problem", @@ -97169,6 +97973,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { deprecated: true, @@ -97230,6 +98036,8 @@ const anyNonWhitespaceRegex = /\S/u; //----------------------------------------- // Public Interface //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "layout", @@ -97302,6 +98110,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "problem", @@ -97346,6 +98156,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "suggestion", @@ -97406,6 +98218,8 @@ function isConstructorFunction(node) { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -97676,6 +98490,8 @@ const astUtils = __webpack_require__(548); //----------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -97732,6 +98548,8 @@ const astUtils = __webpack_require__(548); //----------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -97915,6 +98733,8 @@ function hasTypeOfOperator(node) { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -97980,6 +98800,8 @@ const astUtils = __webpack_require__(548); //----------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -98054,6 +98876,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "suggestion", @@ -98132,6 +98956,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "suggestion", @@ -98411,6 +99237,8 @@ const astUtils = __webpack_require__(548); //----------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -98666,6 +99494,8 @@ function updateModifiedFlag(conditions, modifiers) { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -98893,6 +99723,8 @@ const OR_PRECEDENCE = astUtils.getPrecedence({ // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "suggestion", @@ -99133,6 +99965,8 @@ class ConsecutiveRange { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -99349,6 +100183,8 @@ function getDifference(arrA, arrB) { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -99459,6 +100295,8 @@ const SENTINEL_NODE_TYPE_CONTINUE = /^(?:Program|(?:Function|Class)(?:Declaratio // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "problem", @@ -99599,6 +100437,8 @@ function isNegation(node) { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -99697,6 +100537,8 @@ const UNSAFE_RELATIONAL_OPERATORS = new Set(["in", "instanceof"]); function isDestructuringPattern(node) { return node.type === "ObjectPattern" || node.type === "ArrayPattern"; } +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -99926,6 +100768,8 @@ function alwaysTrue() { function alwaysFalse() { return false; } +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -100119,6 +100963,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "suggestion", @@ -100235,6 +101081,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "problem", @@ -100440,6 +101288,8 @@ const astUtils = __webpack_require__(548); //----------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -101256,6 +102106,8 @@ function isEvaluatedDuringInitialization(reference) { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -101430,6 +102282,8 @@ function isNegativeLookaround(node) { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -101605,6 +102459,8 @@ function isValidThisArg(expectedThis, thisArg, sourceCode) { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -101662,6 +102518,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "suggestion", @@ -101792,6 +102650,8 @@ function hasUselessComputedKey(node) { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -101946,6 +102806,8 @@ function getRight(node) { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -102104,6 +102966,8 @@ function isRedundantSuperCall(body, ctorParams) { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -102258,6 +103122,8 @@ function parseRegExp(regExpText) { }); return charList; } +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -102435,6 +103301,8 @@ const astUtils = __webpack_require__(548); //----------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -102648,6 +103516,8 @@ function isInFinally(node) { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -103055,6 +103925,8 @@ function hasNameDisallowedForLetDeclarations(variable) { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -103213,6 +104085,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "suggestion", @@ -103277,6 +104151,8 @@ const CHAR_LIMIT = 40; //------------------------------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "suggestion", @@ -103452,6 +104328,8 @@ const astUtils = __webpack_require__(548); //----------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -103561,6 +104439,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "suggestion", @@ -103605,6 +104485,8 @@ module.exports = { const POSITION_SCHEMA = { enum: ["beside", "below", "any"] }; +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "layout", @@ -103858,6 +104740,8 @@ function areLineBreaksRequired(node, options, first, last) { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -104035,6 +104919,8 @@ const astUtils = __webpack_require__(548); //----------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -104359,6 +105245,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "layout", @@ -104466,6 +105354,8 @@ const astUtils = __webpack_require__(548); //----------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -104951,6 +105841,8 @@ function isInStatementList(node) { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -105528,6 +106420,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "suggestion", @@ -105656,6 +106550,8 @@ function isNonCommutativeOperatorWithShorthand(operator) { function canBeFixed(node) { return node.type === "Identifier" || node.type === "MemberExpression" && (node.object.type === "Identifier" || node.object.type === "ThisExpression") && (!node.computed || node.property.type === "Literal"); } +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -105829,6 +106725,8 @@ const astUtils = __webpack_require__(548); //----------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -106061,6 +106959,8 @@ const astUtils = __webpack_require__(548); //----------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -106771,6 +107671,8 @@ const StatementTypes = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "layout", @@ -107131,6 +108033,8 @@ function hasDuplicateParams(paramsList) { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -107668,6 +108572,8 @@ function findUp(node, type, shouldStop) { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -107842,6 +108748,8 @@ const PRECEDENCE_OF_ASSIGNMENT_EXPR = astUtils.getPrecedence({ // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "suggestion", @@ -108183,6 +109091,8 @@ function parenthesizeIfShould(text, shouldParenthesize) { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -108309,6 +109219,8 @@ const parser = new regexpp.RegExpParser(); //----------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "suggestion", @@ -108433,6 +109345,8 @@ function isParseInt(calleeNode) { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -108764,6 +109678,8 @@ function defineFixer(node, sourceCode) { } }; } +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -108830,6 +109746,8 @@ const astUtils = __webpack_require__(548); //----------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -108944,6 +109862,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "suggestion", @@ -109099,6 +110019,8 @@ function isStaticTemplateLiteral(node) { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -109296,6 +110218,8 @@ function isNotNormalMemberAccess(reference) { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -109390,6 +110314,8 @@ function isValidThisArg(expectedThis, thisArg, context) { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -109563,6 +110489,8 @@ function endsWithTemplateCurly(node) { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -109732,6 +110660,8 @@ const keywords = __webpack_require__(583); //----------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -110105,6 +111035,8 @@ const AVOID_ESCAPE = "avoid-escape"; //----------------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "layout", @@ -110421,6 +111353,8 @@ function isDefaultRadix(radix) { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -110726,6 +111660,8 @@ class SegmentInfo { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -110903,6 +111839,8 @@ function capitalizeFirstLetter(text) { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -110997,6 +111935,7 @@ module.exports = { * @deprecated in ESLint v5.10.0 */ +/** @type {import('../shared/types').Rule} */ module.exports = { meta: { @@ -111135,6 +112074,8 @@ const { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -111206,6 +112147,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "suggestion", @@ -111288,6 +112231,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "layout", @@ -111421,6 +112366,8 @@ const astUtils = __webpack_require__(548); //----------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -111802,6 +112749,8 @@ const astUtils = __webpack_require__(548); //----------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -112098,6 +113047,8 @@ function isLastChild(node) { const nodeList = getChildren(node.parent); return nodeList !== null && nodeList[nodeList.length - 1] === node; // before `}` or etc. } +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -112199,6 +113150,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "suggestion", @@ -112497,6 +113450,8 @@ const isValidOrders = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "suggestion", @@ -112666,6 +113621,8 @@ try { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "suggestion", @@ -112772,6 +113729,8 @@ function isFunctionBody(node) { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -112941,6 +113900,8 @@ const astUtils = __webpack_require__(548); //----------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -113089,6 +114050,8 @@ const astUtils = __webpack_require__(548); //----------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -113391,6 +114354,8 @@ const { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -113589,6 +114554,8 @@ const astUtils = __webpack_require__(548); //----------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -114060,6 +115027,8 @@ function createNeverStylePattern(markers) { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -114352,6 +115321,8 @@ function isSimpleParameterList(params) { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -114612,6 +115583,8 @@ const astUtils = __webpack_require__(548); //----------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -114745,6 +115718,8 @@ const astUtils = __webpack_require__(548); //----------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -114815,6 +115790,8 @@ const astUtils = __webpack_require__(548); //----------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -114956,6 +115933,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "layout", @@ -115046,6 +116025,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "layout", @@ -115136,6 +116117,8 @@ function isNaNIdentifier(node) { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -115268,6 +116251,8 @@ const doctrine = __webpack_require__(844); //----------------------------------- // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -118293,6 +119278,8 @@ module.exports = JSON.parse('{"name":"doctrine","description":"JSDoc parser","ho // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "problem", @@ -118380,6 +119367,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "suggestion", @@ -118554,6 +119543,8 @@ function isCalleeOfNewExpression(node) { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -118715,6 +119706,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "layout", @@ -118771,6 +119764,8 @@ module.exports = { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { type: "layout", @@ -119020,6 +120015,8 @@ function getNormalizedLiteral(node) { // Rule Definition //------------------------------------------------------------------------------ +/** @type {import('../shared/types').Rule} */ + module.exports = { meta: { @@ -119594,6834 +120591,9915 @@ module.exports = JSON.parse('{"rules":{"generator-star":["generator-star-spacing /***/ }), /* 859 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +/***/ ((module) => { "use strict"; +/** + * @fileoverview Shared functions to work with configs. + * @author Nicholas C. Zakas + */ + //----------------------------------------------------------------------------- +// Functions +//----------------------------------------------------------------------------- +/** + * Parses a ruleId into its plugin and rule parts. + * @param {string} ruleId The rule ID to parse. + * @returns {{pluginName:string,ruleName:string}} The plugin and rule + * parts of the ruleId; + */ + +function parseRuleId(ruleId) { + let pluginName, ruleName; // distinguish between core rules and plugin rules + + if (ruleId.includes("/")) { + pluginName = ruleId.slice(0, ruleId.lastIndexOf("/")); + ruleName = ruleId.slice(pluginName.length + 1); + } else { + pluginName = "@"; + ruleName = ruleId; + } + + return { + pluginName, + ruleName + }; +} +/** + * Retrieves a rule instance from a given config based on the ruleId. + * @param {string} ruleId The rule ID to look for. + * @param {FlatConfig} config The config to search. + * @returns {import("../shared/types").Rule|undefined} The rule if found + * or undefined if not. + */ + + +function getRuleFromConfig(ruleId, config) { + const { + pluginName, + ruleName + } = parseRuleId(ruleId); + const plugin = config.plugins && config.plugins[pluginName]; + let rule = plugin && plugin.rules && plugin.rules[ruleName]; // normalize function rules into objects + + if (rule && typeof rule === "function") { + rule = { + create: rule + }; + } + + return rule; +} //----------------------------------------------------------------------------- +// Exports +//----------------------------------------------------------------------------- -const { - CLIEngine -} = __webpack_require__(860); module.exports = { - CLIEngine + parseRuleId, + getRuleFromConfig }; /***/ }), /* 860 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; -/* provided dependency */ var process = __webpack_require__(494); /** - * @fileoverview Main CLI object. + * @fileoverview Flat Config Array * @author Nicholas C. Zakas */ + //----------------------------------------------------------------------------- +// Requirements +//----------------------------------------------------------------------------- -/* - * The CLI object should *not* call process.exit() directly. It should only return - * exit codes. This allows other programs to use the CLI object and still control - * when the program exits. +const { + ConfigArray, + ConfigArraySymbol +} = __webpack_require__(861); + +const { + flatConfigSchema +} = __webpack_require__(870); + +const { + RuleValidator +} = __webpack_require__(871); + +const { + defaultConfig +} = __webpack_require__(874); + +const recommendedConfig = __webpack_require__(875); + +const allConfig = __webpack_require__(876); //----------------------------------------------------------------------------- +// Helpers +//----------------------------------------------------------------------------- + + +const ruleValidator = new RuleValidator(); +/** + * Splits a plugin identifier in the form a/b/c into two parts: a/b and c. + * @param {string} identifier The identifier to parse. + * @returns {{objectName: string, pluginName: string}} The parts of the plugin + * name. */ -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ -const fs = __webpack_require__(861); +function splitPluginIdentifier(identifier) { + const parts = identifier.split("/"); + return { + objectName: parts.pop(), + pluginName: parts.join("/") + }; +} //----------------------------------------------------------------------------- +// Exports +//----------------------------------------------------------------------------- -const path = __webpack_require__(429); +/** + * Represents an array containing configuration information for ESLint. + */ -const defaultOptions = __webpack_require__(862); -const pkg = __webpack_require__(443); +class FlatConfigArray extends ConfigArray { + /** + * Creates a new instance. + * @param {*[]} configs An array of configuration information. + * @param {{basePath: string, baseConfig: FlatConfig}} options The options + * to use for the config array instance. + */ + constructor(configs) { + let { + basePath, + baseConfig = defaultConfig + } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + super(configs, { + basePath, + schema: flatConfigSchema + }); + this.unshift(...baseConfig); + } + /* eslint-disable class-methods-use-this -- Desired as instance method */ -const { - Legacy: { - ConfigOps, - naming, - CascadingConfigArrayFactory, - IgnorePattern, - getUsedExtractedConfigs, - ModuleResolver + /** + * Replaces a config with another config to allow us to put strings + * in the config array that will be replaced by objects before + * normalization. + * @param {Object} config The config to preprocess. + * @returns {Object} The preprocessed config. + */ + + + [ConfigArraySymbol.preprocessConfig](config) { + if (config === "eslint:recommended") { + return recommendedConfig; + } + + if (config === "eslint:all") { + return allConfig; + } + + return config; } -} = __webpack_require__(863); + /** + * Finalizes the config by replacing plugin references with their objects + * and validating rule option schemas. + * @param {Object} config The config to finalize. + * @returns {Object} The finalized config. + * @throws {TypeError} If the config is invalid. + */ -const { - FileEnumerator -} = __webpack_require__(877); -const { - Linter -} = __webpack_require__(881); + [ConfigArraySymbol.finalizeConfig](config) { + const { + plugins, + languageOptions, + processor + } = config; // Check parser value -const builtInRules = __webpack_require__(545); + if (languageOptions && languageOptions.parser && typeof languageOptions.parser === "string") { + const { + pluginName, + objectName: parserName + } = splitPluginIdentifier(languageOptions.parser); -const loadRules = __webpack_require__(882); + if (!plugins || !plugins[pluginName] || !plugins[pluginName].parsers || !plugins[pluginName].parsers[parserName]) { + throw new TypeError("Key \"parser\": Could not find \"".concat(parserName, "\" in plugin \"").concat(pluginName, "\".")); + } -const hash = __webpack_require__(884); + languageOptions.parser = plugins[pluginName].parsers[parserName]; + } // Check processor value -const LintResultCache = __webpack_require__(886); -const debug = __webpack_require__(496)("eslint:cli-engine"); + if (processor && typeof processor === "string") { + const { + pluginName, + objectName: processorName + } = splitPluginIdentifier(processor); -const validFixTypes = new Set(["directive", "problem", "suggestion", "layout"]); //------------------------------------------------------------------------------ -// Typedefs -//------------------------------------------------------------------------------ -// For VSCode IntelliSense + if (!plugins || !plugins[pluginName] || !plugins[pluginName].processors || !plugins[pluginName].processors[processorName]) { + throw new TypeError("Key \"processor\": Could not find \"".concat(processorName, "\" in plugin \"").concat(pluginName, "\".")); + } -/** @typedef {import("../shared/types").ConfigData} ConfigData */ + config.processor = plugins[pluginName].processors[processorName]; + } -/** @typedef {import("../shared/types").DeprecatedRuleInfo} DeprecatedRuleInfo */ + ruleValidator.validate(config); + return config; + } + /* eslint-enable class-methods-use-this -- Desired as instance method */ -/** @typedef {import("../shared/types").LintMessage} LintMessage */ -/** @typedef {import("../shared/types").ParserOptions} ParserOptions */ +} -/** @typedef {import("../shared/types").Plugin} Plugin */ +exports.FlatConfigArray = FlatConfigArray; -/** @typedef {import("../shared/types").RuleConf} RuleConf */ +/***/ }), +/* 861 */ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { -/** @typedef {import("../shared/types").Rule} Rule */ +"use strict"; -/** @typedef {ReturnType} ConfigArray */ -/** @typedef {ReturnType} ExtractedConfig */ +Object.defineProperty(exports, "__esModule", ({ + value: true +})); -/** - * The options to configure a CLI engine with. - * @typedef {Object} CLIEngineOptions - * @property {boolean} [allowInlineConfig] Enable or disable inline configuration comments. - * @property {ConfigData} [baseConfig] Base config object, extended by all configs used with this CLIEngine instance - * @property {boolean} [cache] Enable result caching. - * @property {string} [cacheLocation] The cache file to use instead of .eslintcache. - * @property {string} [configFile] The configuration file to use. - * @property {string} [cwd] The value to use for the current working directory. - * @property {string[]} [envs] An array of environments to load. - * @property {string[]|null} [extensions] An array of file extensions to check. - * @property {boolean|Function} [fix] Execute in autofix mode. If a function, should return a boolean. - * @property {string[]} [fixTypes] Array of rule types to apply fixes for. - * @property {string[]} [globals] An array of global variables to declare. - * @property {boolean} [ignore] False disables use of .eslintignore. - * @property {string} [ignorePath] The ignore file to use instead of .eslintignore. - * @property {string|string[]} [ignorePattern] One or more glob patterns to ignore. - * @property {boolean} [useEslintrc] False disables looking for .eslintrc - * @property {string} [parser] The name of the parser to use. - * @property {ParserOptions} [parserOptions] An object of parserOption settings to use. - * @property {string[]} [plugins] An array of plugins to load. - * @property {Record} [rules] An object of rules to use. - * @property {string[]} [rulePaths] An array of directories to load custom rules from. - * @property {boolean} [reportUnusedDisableDirectives] `true` adds reports for unused eslint-disable directives - * @property {boolean} [globInputPaths] Set to false to skip glob resolution of input file paths to lint (default: true). If false, each input file paths is assumed to be a non-glob path to an existing file. - * @property {string} [resolvePluginsRelativeTo] The folder where plugins should be resolved from, defaulting to the CWD - */ +function _interopDefault(ex) { + return ex && typeof ex === 'object' && 'default' in ex ? ex['default'] : ex; +} -/** - * A linting result. - * @typedef {Object} LintResult - * @property {string} filePath The path to the file that was linted. - * @property {LintMessage[]} messages All of the messages for the result. - * @property {number} errorCount Number of errors for the result. - * @property {number} warningCount Number of warnings for the result. - * @property {number} fixableErrorCount Number of fixable errors for the result. - * @property {number} fixableWarningCount Number of fixable warnings for the result. - * @property {string} [source] The source code of the file that was linted. - * @property {string} [output] The source code of the file that was linted, with as many fixes applied as possible. - */ +var path = _interopDefault(__webpack_require__(429)); -/** - * Linting results. - * @typedef {Object} LintReport - * @property {LintResult[]} results All of the result. - * @property {number} errorCount Number of errors for the result. - * @property {number} warningCount Number of warnings for the result. - * @property {number} fixableErrorCount Number of fixable errors for the result. - * @property {number} fixableWarningCount Number of fixable warnings for the result. - * @property {DeprecatedRuleInfo[]} usedDeprecatedRules The list of used deprecated rules. - */ +var minimatch = _interopDefault(__webpack_require__(862)); + +var createDebug = _interopDefault(__webpack_require__(496)); +var objectSchema = __webpack_require__(866); /** - * Private data for CLIEngine. - * @typedef {Object} CLIEngineInternalSlots - * @property {Map} additionalPluginPool The map for additional plugins. - * @property {string} cacheFilePath The path to the cache of lint results. - * @property {CascadingConfigArrayFactory} configArrayFactory The factory of configs. - * @property {(filePath: string) => boolean} defaultIgnores The default predicate function to check if a file ignored or not. - * @property {FileEnumerator} fileEnumerator The file enumerator. - * @property {ConfigArray[]} lastConfigArrays The list of config arrays that the last `executeOnFiles` or `executeOnText` used. - * @property {LintResultCache|null} lintResultCache The cache of lint results. - * @property {Linter} linter The linter instance which has loaded rules. - * @property {CLIEngineOptions} options The normalized options of this instance. + * @fileoverview ConfigSchema + * @author Nicholas C. Zakas */ //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ -/** @type {WeakMap} */ - -const internalSlotsMap = new WeakMap(); /** - * Determines if each fix type in an array is supported by ESLint and throws - * an error if not. - * @param {string[]} fixTypes An array of fix types to check. + * Assets that a given value is an array. + * @param {*} value The value to check. * @returns {void} - * @throws {Error} If an invalid fix type is found. + * @throws {TypeError} When the value is not an array. */ -function validateFixTypes(fixTypes) { - for (const fixType of fixTypes) { - if (!validFixTypes.has(fixType)) { - throw new Error("Invalid fix type \"".concat(fixType, "\" found.")); - } + +function assertIsArray(value) { + if (!Array.isArray(value)) { + throw new TypeError('Expected value to be an array.'); } } /** - * It will calculate the error and warning count for collection of messages per file - * @param {LintMessage[]} messages Collection of messages - * @returns {Object} Contains the stats - * @private + * Assets that a given value is an array containing only strings and functions. + * @param {*} value The value to check. + * @returns {void} + * @throws {TypeError} When the value is not an array of strings and functions. */ -function calculateStatsPerFile(messages) { - return messages.reduce((stat, message) => { - if (message.fatal || message.severity === 2) { - stat.errorCount++; +function assertIsArrayOfStringsAndFunctions(value, name) { + assertIsArray(value); - if (message.fatal) { - stat.fatalErrorCount++; - } + if (value.some(item => typeof item !== 'string' && typeof item !== 'function')) { + throw new TypeError('Expected array to only contain strings.'); + } +} //------------------------------------------------------------------------------ +// Exports +//------------------------------------------------------------------------------ - if (message.fix) { - stat.fixableErrorCount++; - } - } else { - stat.warningCount++; +/** + * The base schema that every ConfigArray uses. + * @type Object + */ - if (message.fix) { - stat.fixableWarningCount++; + +const baseSchema = Object.freeze({ + name: { + required: false, + + merge() { + return undefined; + }, + + validate(value) { + if (typeof value !== 'string') { + throw new TypeError('Property must be a string.'); } } - return stat; - }, { - errorCount: 0, - fatalErrorCount: 0, - warningCount: 0, - fixableErrorCount: 0, - fixableWarningCount: 0 - }); -} + }, + files: { + required: false, + + merge() { + return undefined; + }, + + validate(value) { + // first check if it's an array + assertIsArray(value); // then check each member + + value.forEach(item => { + if (Array.isArray(item)) { + assertIsArrayOfStringsAndFunctions(item); + } else if (typeof item !== 'string' && typeof item !== 'function') { + throw new TypeError('Items must be a string, a function, or an array of strings and functions.'); + } + }); + } + + }, + ignores: { + required: false, + + merge() { + return undefined; + }, + + validate: assertIsArrayOfStringsAndFunctions + } +}); /** - * It will calculate the error and warning count for collection of results from all files - * @param {LintResult[]} results Collection of messages from all the files - * @returns {Object} Contains the stats - * @private + * @fileoverview ConfigArray + * @author Nicholas C. Zakas */ +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ +const debug = createDebug('@hwc/config-array'); +const MINIMATCH_OPTIONS = { + matchBase: true +}; +const CONFIG_TYPES = new Set(['array', 'function']); +/** + * Shorthand for checking if a value is a string. + * @param {any} value The value to check. + * @returns {boolean} True if a string, false if not. + */ -function calculateStatsPerRun(results) { - return results.reduce((stat, result) => { - stat.errorCount += result.errorCount; - stat.fatalErrorCount += result.fatalErrorCount; - stat.warningCount += result.warningCount; - stat.fixableErrorCount += result.fixableErrorCount; - stat.fixableWarningCount += result.fixableWarningCount; - return stat; - }, { - errorCount: 0, - fatalErrorCount: 0, - warningCount: 0, - fixableErrorCount: 0, - fixableWarningCount: 0 - }); +function isString(value) { + return typeof value === 'string'; } /** - * Processes an source code using ESLint. - * @param {Object} config The config object. - * @param {string} config.text The source code to verify. - * @param {string} config.cwd The path to the current working directory. - * @param {string|undefined} config.filePath The path to the file of `text`. If this is undefined, it uses ``. - * @param {ConfigArray} config.config The config. - * @param {boolean} config.fix If `true` then it does fix. - * @param {boolean} config.allowInlineConfig If `true` then it uses directive comments. - * @param {boolean} config.reportUnusedDisableDirectives If `true` then it reports unused `eslint-disable` comments. - * @param {FileEnumerator} config.fileEnumerator The file enumerator to check if a path is a target or not. - * @param {Linter} config.linter The linter instance to verify. - * @returns {LintResult} The result of linting. - * @private + * Normalizes a `ConfigArray` by flattening it and executing any functions + * that are found inside. + * @param {Array} items The items in a `ConfigArray`. + * @param {Object} context The context object to pass into any function + * found. + * @param {Array} extraConfigTypes The config types to check. + * @returns {Promise} A flattened array containing only config objects. + * @throws {TypeError} When a config function returns a function. */ -function verifyText(_ref) { - let { - text, - cwd, - filePath: providedFilePath, - config, - fix, - allowInlineConfig, - reportUnusedDisableDirectives, - fileEnumerator, - linter - } = _ref; - const filePath = providedFilePath || ""; - debug("Lint ".concat(filePath)); - /* - * Verify. - * `config.extractConfig(filePath)` requires an absolute path, but `linter` - * doesn't know CWD, so it gives `linter` an absolute path always. - */ +async function normalize(items, context, extraConfigTypes) { + const allowFunctions = extraConfigTypes.includes('function'); + const allowArrays = extraConfigTypes.includes('array'); - const filePathToVerify = filePath === "" ? path.join(cwd, filePath) : filePath; - const { - fixed, - messages, - output - } = linter.verifyAndFix(text, config, { - allowInlineConfig, - filename: filePathToVerify, - fix, - reportUnusedDisableDirectives, + async function* flatTraverse(array) { + for (let item of array) { + if (typeof item === 'function') { + if (!allowFunctions) { + throw new TypeError('Unexpected function.'); + } - /** - * Check if the linter should adopt a given code block or not. - * @param {string} blockFilename The virtual filename of a code block. - * @returns {boolean} `true` if the linter should adopt the code block. - */ - filterCodeBlock(blockFilename) { - return fileEnumerator.isTargetPath(blockFilename); - } + item = item(context); - }); // Tweak and return. + if (item.then) { + item = await item; + } + } - const result = { - filePath, - messages, - ...calculateStatsPerFile(messages) - }; + if (Array.isArray(item)) { + if (!allowArrays) { + throw new TypeError('Unexpected array.'); + } - if (fixed) { - result.output = output; + yield* flatTraverse(item); + } else if (typeof item === 'function') { + throw new TypeError('A config function can only return an object or array.'); + } else { + yield item; + } + } } + /* + * Async iterables cannot be used with the spread operator, so we need to manually + * create the array to return. + */ - if (result.errorCount + result.warningCount > 0 && typeof result.output === "undefined") { - result.source = text; + + const asyncIterable = await flatTraverse(items); + const configs = []; + + for await (const config of asyncIterable) { + configs.push(config); } - return result; + return configs; } /** - * Returns result with warning by ignore settings - * @param {string} filePath File path of checked code - * @param {string} baseDir Absolute path of base directory - * @returns {LintResult} Result with single warning - * @private + * Normalizes a `ConfigArray` by flattening it and executing any functions + * that are found inside. + * @param {Array} items The items in a `ConfigArray`. + * @param {Object} context The context object to pass into any function + * found. + * @param {Array} extraConfigTypes The config types to check. + * @returns {Array} A flattened array containing only config objects. + * @throws {TypeError} When a config function returns a function. */ -function createIgnoreResult(filePath, baseDir) { - let message; - const isHidden = filePath.split(path.sep).find(segment => /^\./u.test(segment)); - const isInNodeModules = baseDir && path.relative(baseDir, filePath).startsWith("node_modules"); +function normalizeSync(items, context, extraConfigTypes) { + const allowFunctions = extraConfigTypes.includes('function'); + const allowArrays = extraConfigTypes.includes('array'); - if (isHidden) { - message = "File ignored by default. Use a negated ignore pattern (like \"--ignore-pattern '!'\") to override."; - } else if (isInNodeModules) { - message = "File ignored by default. Use \"--ignore-pattern '!node_modules/*'\" to override."; - } else { - message = "File ignored because of a matching ignore pattern. Use \"--no-ignore\" to override."; - } + function* flatTraverse(array) { + for (let item of array) { + if (typeof item === 'function') { + if (!allowFunctions) { + throw new TypeError('Unexpected function.'); + } - return { - filePath: path.resolve(filePath), - messages: [{ - fatal: false, - severity: 1, - message - }], - errorCount: 0, - warningCount: 1, - fixableErrorCount: 0, - fixableWarningCount: 0 - }; -} -/** - * Get a rule. - * @param {string} ruleId The rule ID to get. - * @param {ConfigArray[]} configArrays The config arrays that have plugin rules. - * @returns {Rule|null} The rule or null. - */ + item = item(context); + if (item.then) { + throw new TypeError('Async config functions are not supported.'); + } + } -function getRule(ruleId, configArrays) { - for (const configArray of configArrays) { - const rule = configArray.pluginRules.get(ruleId); + if (Array.isArray(item)) { + if (!allowArrays) { + throw new TypeError('Unexpected array.'); + } - if (rule) { - return rule; + yield* flatTraverse(item); + } else if (typeof item === 'function') { + throw new TypeError('A config function can only return an object or array.'); + } else { + yield item; + } } } - return builtInRules.get(ruleId) || null; + return [...flatTraverse(items)]; } /** - * Checks whether a message's rule type should be fixed. - * @param {LintMessage} message The message to check. - * @param {ConfigArray[]} lastConfigArrays The list of config arrays that the last `executeOnFiles` or `executeOnText` used. - * @param {string[]} fixTypes An array of fix types to check. - * @returns {boolean} Whether the message should be fixed. + * Determines if a given file path should be ignored based on the given + * matcher. + * @param {string|() => boolean} matcher The pattern to match. + * @param {string} filePath The absolute path of the file to check. + * @param {string} relativeFilePath The relative path of the file to check. + * @returns {boolean} True if the path should be ignored and false if not. */ -function shouldMessageBeFixed(message, lastConfigArrays, fixTypes) { - if (!message.ruleId) { - return fixTypes.has("directive"); +function shouldIgnoreFilePath(matcher, filePath, relativeFilePath) { + if (typeof matcher === 'function') { + return matcher(filePath); } - const rule = message.ruleId && getRule(message.ruleId, lastConfigArrays); - return Boolean(rule && rule.meta && fixTypes.has(rule.meta.type)); + return minimatch(relativeFilePath, matcher, MINIMATCH_OPTIONS); } /** - * Collect used deprecated rules. - * @param {ConfigArray[]} usedConfigArrays The config arrays which were used. - * @returns {IterableIterator} Used deprecated rules. + * Determines if a given file path is matched by a config. If the config + * has no `files` field, then it matches; otherwise, if a `files` field + * is present then we match the globs in `files` and exclude any globs in + * `ignores`. + * @param {string} filePath The absolute file path to check. + * @param {Object} config The config object to check. + * @returns {boolean} True if the file path is matched by the config, + * false if not. */ -function* iterateRuleDeprecationWarnings(usedConfigArrays) { - const processedRuleIds = new Set(); // Flatten used configs. +function pathMatches(filePath, basePath, config) { + // a config without `files` field always match + if (!config.files) { + return true; + } + /* + * For both files and ignores, functions are passed the absolute + * file path while strings are compared against the relative + * file path. + */ - /** @type {ExtractedConfig[]} */ - const configs = [].concat(...usedConfigArrays.map(getUsedExtractedConfigs)); // Traverse rule configs. + const relativeFilePath = path.relative(basePath, filePath); // if files isn't an array, throw an error - for (const config of configs) { - for (const [ruleId, ruleConfig] of Object.entries(config.rules)) { - // Skip if it was processed. - if (processedRuleIds.has(ruleId)) { - continue; - } + if (!Array.isArray(config.files) || config.files.length === 0) { + throw new TypeError('The files key must be a non-empty array.'); + } // match both strings and functions - processedRuleIds.add(ruleId); // Skip if it's not used. - if (!ConfigOps.getRuleSeverity(ruleConfig)) { - continue; - } + const match = pattern => { + if (isString(pattern)) { + return minimatch(relativeFilePath, pattern, MINIMATCH_OPTIONS); + } - const rule = getRule(ruleId, usedConfigArrays); // Skip if it's not deprecated. + if (typeof pattern === 'function') { + return pattern(filePath); + } - if (!(rule && rule.meta && rule.meta.deprecated)) { - continue; - } // This rule was used and deprecated. + throw new TypeError("Unexpected matcher type ".concat(pattern, ".")); + }; + const isFilePathIgnored = matcher => { + return shouldIgnoreFilePath(matcher, filePath, relativeFilePath); + }; // check for all matches to config.files - yield { - ruleId, - replacedBy: rule.meta.replacedBy || [] - }; + + let filePathMatchesPattern = config.files.some(pattern => { + if (Array.isArray(pattern)) { + return pattern.every(match); } + + return match(pattern); + }); + /* + * If the file path matches the config.files patterns, then check to see + * if there are any files to ignore. + */ + + if (filePathMatchesPattern && config.ignores) { + filePathMatchesPattern = !config.ignores.some(isFilePathIgnored); } + + return filePathMatchesPattern; } /** - * Checks if the given message is an error message. - * @param {LintMessage} message The message to check. - * @returns {boolean} Whether or not the message is an error message. - * @private + * Ensures that a ConfigArray has been normalized. + * @param {ConfigArray} configArray The ConfigArray to check. + * @returns {void} + * @throws {Error} When the `ConfigArray` is not normalized. */ -function isErrorMessage(message) { - return message.severity === 2; +function assertNormalized(configArray) { + // TODO: Throw more verbose error + if (!configArray.isNormalized()) { + throw new Error('ConfigArray must be normalized to perform this operation.'); + } } /** - * return the cacheFile to be used by eslint, based on whether the provided parameter is - * a directory or looks like a directory (ends in `path.sep`), in which case the file - * name will be the `cacheFile/.cache_hashOfCWD` - * - * if cacheFile points to a file or looks like a file then in will just use that file - * @param {string} cacheFile The name of file to be used to store the cache - * @param {string} cwd Current working directory - * @returns {string} the resolved path to the cache file + * Ensures that config types are valid. + * @param {Array} extraConfigTypes The config types to check. + * @returns {void} + * @throws {Error} When the config types array is invalid. */ -function getCacheFile(cacheFile, cwd) { - /* - * make sure the path separators are normalized for the environment/os - * keeping the trailing path separator if present - */ - const normalizedCacheFile = path.normalize(cacheFile); - const resolvedCacheFile = path.resolve(cwd, normalizedCacheFile); - const looksLikeADirectory = normalizedCacheFile.slice(-1) === path.sep; - /** - * return the name for the cache file in case the provided parameter is a directory - * @returns {string} the resolved path to the cacheFile - */ +function assertExtraConfigTypes(extraConfigTypes) { + if (extraConfigTypes.length > 2) { + throw new TypeError('configTypes must be an array with at most two items.'); + } - function getCacheFileForDirectory() { - return path.join(resolvedCacheFile, ".cache_".concat(hash(cwd))); + for (const configType of extraConfigTypes) { + if (!CONFIG_TYPES.has(configType)) { + throw new TypeError("Unexpected config type \"".concat(configType, "\" found. Expected one of: \"object\", \"array\", \"function\".")); + } } +} //------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ - let fileStats; - try { - fileStats = fs.lstatSync(resolvedCacheFile); - } catch { - fileStats = null; - } - /* - * in case the file exists we need to verify if the provided path - * is a directory or a file. If it is a directory we want to create a file - * inside that directory - */ +const ConfigArraySymbol = { + isNormalized: Symbol('isNormalized'), + configCache: Symbol('configCache'), + schema: Symbol('schema'), + finalizeConfig: Symbol('finalizeConfig'), + preprocessConfig: Symbol('preprocessConfig') +}; // used to store calculate data for faster lookup +const dataCache = new WeakMap(); +/** + * Represents an array of config objects and provides method for working with + * those config objects. + */ - if (fileStats) { - /* - * is a directory or is a file, but the original file the user provided - * looks like a directory but `path.resolve` removed the `last path.sep` - * so we need to still treat this like a directory +class ConfigArray extends Array { + /** + * Creates a new instance of ConfigArray. + * @param {Iterable|Function|Object} configs An iterable yielding config + * objects, or a config function, or a config object. + * @param {string} [options.basePath=""] The path of the config file + * @param {boolean} [options.normalized=false] Flag indicating if the + * configs have already been normalized. + * @param {Object} [options.schema] The additional schema + * definitions to use for the ConfigArray schema. + * @param {Array} [options.configTypes] List of config types supported. + */ + constructor(configs) { + let { + basePath = '', + normalized = false, + schema: customSchema, + extraConfigTypes = [] + } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + super(); + /** + * Tracks if the array has been normalized. + * @property isNormalized + * @type boolean + * @private */ - if (fileStats.isDirectory() || looksLikeADirectory) { - return getCacheFileForDirectory(); - } // is file so just use that file + this[ConfigArraySymbol.isNormalized] = normalized; + /** + * The schema used for validating and merging configs. + * @property schema + * @type ObjectSchema + * @private + */ - return resolvedCacheFile; - } - /* - * here we known the file or directory doesn't exist, - * so we will try to infer if its a directory if it looks like a directory - * for the current operating system. - */ - // if the last character passed is a path separator we assume is a directory + this[ConfigArraySymbol.schema] = new objectSchema.ObjectSchema({ ...customSchema, + ...baseSchema + }); + /** + * The path of the config file that this array was loaded from. + * This is used to calculate filename matches. + * @property basePath + * @type string + */ + this.basePath = basePath; + assertExtraConfigTypes(extraConfigTypes); + /** + * The supported config types. + * @property configTypes + * @type Array + */ - if (looksLikeADirectory) { - return getCacheFileForDirectory(); - } + this.extraConfigTypes = Object.freeze([...extraConfigTypes]); + /** + * A cache to store calculated configs for faster repeat lookup. + * @property configCache + * @type Map + * @private + */ - return resolvedCacheFile; -} -/** - * Convert a string array to a boolean map. - * @param {string[]|null} keys The keys to assign true. - * @param {boolean} defaultValue The default value for each property. - * @param {string} displayName The property name which is used in error message. - * @throws {Error} Requires array. - * @returns {Record} The boolean map. - */ + this[ConfigArraySymbol.configCache] = new Map(); // init cache + dataCache.set(this, {}); // load the configs into this array -function toBooleanMap(keys, defaultValue, displayName) { - if (keys && !Array.isArray(keys)) { - throw new Error("".concat(displayName, " must be an array.")); + if (Array.isArray(configs)) { + this.push(...configs); + } else { + this.push(configs); + } } + /** + * Prevent normal array methods from creating a new `ConfigArray` instance. + * This is to ensure that methods such as `slice()` won't try to create a + * new instance of `ConfigArray` behind the scenes as doing so may throw + * an error due to the different constructor signature. + * @returns {Function} The `Array` constructor. + */ - if (keys && keys.length > 0) { - return keys.reduce((map, def) => { - const [key, value] = def.split(":"); - - if (key !== "__proto__") { - map[key] = value === void 0 ? defaultValue : value === "true"; - } - return map; - }, {}); + static get [Symbol.species]() { + return Array; } + /** + * Returns the `files` globs from every config object in the array. + * This can be used to determine which files will be matched by a + * config array or to use as a glob pattern when no patterns are provided + * for a command line interface. + * @returns {Array} An array of matchers. + */ - return void 0; -} -/** - * Create a config data from CLI options. - * @param {CLIEngineOptions} options The options - * @returns {ConfigData|null} The created config data. - */ + get files() { + assertNormalized(this); // if this data has been cached, retrieve it -function createConfigDataFromOptions(options) { - const { - ignorePattern, - parser, - parserOptions, - plugins, - rules - } = options; - const env = toBooleanMap(options.envs, true, "envs"); - const globals = toBooleanMap(options.globals, false, "globals"); + const cache = dataCache.get(this); - if (env === void 0 && globals === void 0 && (ignorePattern === void 0 || ignorePattern.length === 0) && parser === void 0 && parserOptions === void 0 && plugins === void 0 && rules === void 0) { - return null; - } + if (cache.files) { + return cache.files; + } // otherwise calculate it - return { - env, - globals, - ignorePatterns: ignorePattern, - parser, - parserOptions, - plugins, - rules - }; -} -/** - * Checks whether a directory exists at the given location - * @param {string} resolvedPath A path from the CWD - * @throws {Error} As thrown by `fs.statSync` or `fs.isDirectory`. - * @returns {boolean} `true` if a directory exists - */ + const result = []; -function directoryExists(resolvedPath) { - try { - return fs.statSync(resolvedPath).isDirectory(); - } catch (error) { - if (error && (error.code === "ENOENT" || error.code === "ENOTDIR")) { - return false; - } + for (const config of this) { + if (config.files) { + config.files.forEach(filePattern => { + result.push(filePattern); + }); + } + } // store result - throw error; + + cache.files = result; + dataCache.set(this, cache); + return result; } -} //------------------------------------------------------------------------------ -// Public Interface -//------------------------------------------------------------------------------ + /** + * Returns ignore matchers that should always be ignored regardless of + * the matching `files` fields in any configs. This is necessary to mimic + * the behavior of things like .gitignore and .eslintignore, allowing a + * globbing operation to be faster. + * @returns {string[]} An array of string patterns and functions to be ignored. + */ -/** - * Core CLI. - */ + get ignores() { + assertNormalized(this); // if this data has been cached, retrieve it -class CLIEngine { - /** - * Creates a new instance of the core CLI engine. - * @param {CLIEngineOptions} providedOptions The options for this instance. - * @param {Object} [additionalData] Additional settings that are not CLIEngineOptions. - * @param {Record|null} [additionalData.preloadedPlugins] Preloaded plugins. - */ - constructor(providedOptions) { - let { - preloadedPlugins - } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - const options = Object.assign(Object.create(null), defaultOptions, { - cwd: process.cwd() - }, providedOptions); + const cache = dataCache.get(this); - if (options.fix === void 0) { - options.fix = false; - } + if (cache.ignores) { + return cache.ignores; + } // otherwise calculate it - const additionalPluginPool = new Map(); - if (preloadedPlugins) { - for (const [id, plugin] of Object.entries(preloadedPlugins)) { - additionalPluginPool.set(id, plugin); + const result = []; + + for (const config of this) { + if (config.ignores && !config.files) { + result.push(...config.ignores); } - } + } // store result - const cacheFilePath = getCacheFile(options.cacheLocation || options.cacheFile, options.cwd); - const configArrayFactory = new CascadingConfigArrayFactory({ - additionalPluginPool, - baseConfig: options.baseConfig || null, - cliConfig: createConfigDataFromOptions(options), - cwd: options.cwd, - ignorePath: options.ignorePath, - resolvePluginsRelativeTo: options.resolvePluginsRelativeTo, - rulePaths: options.rulePaths, - specificConfigPath: options.configFile, - useEslintrc: options.useEslintrc, - builtInRules, - loadRules, - eslintRecommendedPath: path.resolve(__dirname, "../../conf/eslint-recommended.js"), - eslintAllPath: path.resolve(__dirname, "../../conf/eslint-all.js") - }); - const fileEnumerator = new FileEnumerator({ - configArrayFactory, - cwd: options.cwd, - extensions: options.extensions, - globInputPaths: options.globInputPaths, - errorOnUnmatchedPattern: options.errorOnUnmatchedPattern, - ignore: options.ignore - }); - const lintResultCache = options.cache ? new LintResultCache(cacheFilePath, options.cacheStrategy) : null; - const linter = new Linter({ - cwd: options.cwd - }); - /** @type {ConfigArray[]} */ - const lastConfigArrays = [configArrayFactory.getConfigArrayForFile()]; // Store private data. + cache.ignores = result; + dataCache.set(this, cache); + return result; + } + /** + * Indicates if the config array has been normalized. + * @returns {boolean} True if the config array is normalized, false if not. + */ - internalSlotsMap.set(this, { - additionalPluginPool, - cacheFilePath, - configArrayFactory, - defaultIgnores: IgnorePattern.createDefaultIgnore(options.cwd), - fileEnumerator, - lastConfigArrays, - lintResultCache, - linter, - options - }); // setup special filter for fixes - if (options.fix && options.fixTypes && options.fixTypes.length > 0) { - debug("Using fix types ".concat(options.fixTypes)); // throw an error if any invalid fix types are found + isNormalized() { + return this[ConfigArraySymbol.isNormalized]; + } + /** + * Normalizes a config array by flattening embedded arrays and executing + * config functions. + * @param {ConfigContext} context The context object for config functions. + * @returns {Promise} The current ConfigArray instance. + */ - validateFixTypes(options.fixTypes); // convert to Set for faster lookup - const fixTypes = new Set(options.fixTypes); // save original value of options.fix in case it's a function + async normalize() { + let context = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - const originalFix = typeof options.fix === "function" ? options.fix : () => true; + if (!this.isNormalized()) { + const normalizedConfigs = await normalize(this, context, this.extraConfigTypes); + this.length = 0; + this.push(...normalizedConfigs.map(this[ConfigArraySymbol.preprocessConfig])); + this[ConfigArraySymbol.isNormalized] = true; // prevent further changes - options.fix = message => shouldMessageBeFixed(message, lastConfigArrays, fixTypes) && originalFix(message); + Object.freeze(this); } - } - - getRules() { - const { - lastConfigArrays - } = internalSlotsMap.get(this); - return new Map(function* () { - yield* builtInRules; - for (const configArray of lastConfigArrays) { - yield* configArray.pluginRules; - } - }()); + return this; } /** - * Returns results that only contains errors. - * @param {LintResult[]} results The results to filter. - * @returns {LintResult[]} The filtered results. + * Normalizes a config array by flattening embedded arrays and executing + * config functions. + * @param {ConfigContext} context The context object for config functions. + * @returns {ConfigArray} The current ConfigArray instance. */ - static getErrorResults(results) { - const filtered = []; - results.forEach(result => { - const filteredMessages = result.messages.filter(isErrorMessage); + normalizeSync() { + let context = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - if (filteredMessages.length > 0) { - filtered.push({ ...result, - messages: filteredMessages, - errorCount: filteredMessages.length, - warningCount: 0, - fixableErrorCount: result.fixableErrorCount, - fixableWarningCount: 0 - }); - } - }); - return filtered; + if (!this.isNormalized()) { + const normalizedConfigs = normalizeSync(this, context, this.extraConfigTypes); + this.length = 0; + this.push(...normalizedConfigs.map(this[ConfigArraySymbol.preprocessConfig])); + this[ConfigArraySymbol.isNormalized] = true; // prevent further changes + + Object.freeze(this); + } + + return this; } /** - * Outputs fixes from the given results to files. - * @param {LintReport} report The report object created by CLIEngine. - * @returns {void} + * Finalizes the state of a config before being cached and returned by + * `getConfig()`. Does nothing by default but is provided to be + * overridden by subclasses as necessary. + * @param {Object} config The config to finalize. + * @returns {Object} The finalized config. */ - static outputFixes(report) { - report.results.filter(result => Object.prototype.hasOwnProperty.call(result, "output")).forEach(result => { - fs.writeFileSync(result.filePath, result.output); - }); + [ConfigArraySymbol.finalizeConfig](config) { + return config; } /** - * Resolves the patterns passed into executeOnFiles() into glob-based patterns - * for easier handling. - * @param {string[]} patterns The file patterns passed on the command line. - * @returns {string[]} The equivalent glob patterns. + * Preprocesses a config during the normalization process. This is the + * method to override if you want to convert an array item before it is + * validated for the first time. For example, if you want to replace a + * string with an object, this is the method to override. + * @param {Object} config The config to preprocess. + * @returns {Object} The config to use in place of the argument. */ - resolveFileGlobPatterns(patterns) { - const { - options - } = internalSlotsMap.get(this); - - if (options.globInputPaths === false) { - return patterns.filter(Boolean); - } - - const extensions = (options.extensions || [".js"]).map(ext => ext.replace(/^\./u, "")); - const dirSuffix = "/**/*.{".concat(extensions.join(","), "}"); - return patterns.filter(Boolean).map(pathname => { - const resolvedPath = path.resolve(options.cwd, pathname); - const newPath = directoryExists(resolvedPath) ? pathname.replace(/[/\\]$/u, "") + dirSuffix : pathname; - return path.normalize(newPath).replace(/\\/gu, "/"); - }); + [ConfigArraySymbol.preprocessConfig](config) { + return config; } /** - * Executes the current configuration on an array of file and directory names. - * @param {string[]} patterns An array of file and directory names. - * @throws {Error} As may be thrown by `fs.unlinkSync`. - * @returns {LintReport} The results for all files that were linted. + * Returns the config object for a given file path. + * @param {string} filePath The complete path of a file to get a config for. + * @returns {Object} The config object for this file. */ - executeOnFiles(patterns) { - const { - cacheFilePath, - fileEnumerator, - lastConfigArrays, - lintResultCache, - linter, - options: { - allowInlineConfig, - cache, - cwd, - fix, - reportUnusedDisableDirectives - } - } = internalSlotsMap.get(this); - const results = []; - const startTime = Date.now(); // Clear the last used config arrays. + getConfig(filePath) { + assertNormalized(this); // first check the cache to avoid duplicate work - lastConfigArrays.length = 0; // Delete cache file; should this do here? + let finalConfig = this[ConfigArraySymbol.configCache].get(filePath); - if (!cache) { - try { - fs.unlinkSync(cacheFilePath); - } catch (error) { - const errorCode = error && error.code; // Ignore errors when no such file exists or file system is read only (and cache file does not exist) + if (finalConfig) { + return finalConfig; + } // TODO: Maybe move elsewhere? - if (errorCode !== "ENOENT" && !(errorCode === "EROFS" && !fs.existsSync(cacheFilePath))) { - throw error; - } - } - } // Iterate source code files. + const relativeFilePath = path.relative(this.basePath, filePath); // if there is a global matcher ignoring this file, just return null - for (const { - config, - filePath, - ignored - } of fileEnumerator.iterateFiles(patterns)) { - if (ignored) { - results.push(createIgnoreResult(filePath, cwd)); - continue; + for (const shouldIgnore of this.ignores) { + if (shouldIgnoreFilePath(shouldIgnore, filePath, relativeFilePath)) { + // cache and return result - finalConfig is undefined at this point + this[ConfigArraySymbol.configCache].set(filePath, finalConfig); + return finalConfig; } - /* - * Store used configs for: - * - this method uses to collect used deprecated rules. - * - `getRules()` method uses to collect all loaded rules. - * - `--fix-type` option uses to get the loaded rule's meta data. - */ + } // filePath isn't automatically ignored, so try to construct config - if (!lastConfigArrays.includes(config)) { - lastConfigArrays.push(config); - } // Skip if there is cached result. + const matchingConfigs = []; + for (const config of this) { + if (pathMatches(filePath, this.basePath, config)) { + debug("Matching config found for ".concat(filePath)); + matchingConfigs.push(config); + } else { + debug("No matching config found for ".concat(filePath)); + } + } // if matching both files and ignores, there will be no config to create - if (lintResultCache) { - const cachedResult = lintResultCache.getCachedLintResults(filePath, config); - if (cachedResult) { - const hadMessages = cachedResult.messages && cachedResult.messages.length > 0; + if (matchingConfigs.length === 0) { + // cache and return result - finalConfig is undefined at this point + this[ConfigArraySymbol.configCache].set(filePath, finalConfig); + return finalConfig; + } // otherwise construct the config - if (hadMessages && fix) { - debug("Reprocessing cached file to allow autofix: ".concat(filePath)); - } else { - debug("Skipping file since it hasn't changed: ".concat(filePath)); - results.push(cachedResult); - continue; - } - } - } // Do lint. + finalConfig = matchingConfigs.reduce((result, config) => { + return this[ConfigArraySymbol.schema].merge(result, config); + }, {}, this); + finalConfig = this[ConfigArraySymbol.finalizeConfig](finalConfig); + this[ConfigArraySymbol.configCache].set(filePath, finalConfig); + return finalConfig; + } + /** + * Determines if the given filepath is ignored based on the configs. + * @param {string} filePath The complete path of a file to check. + * @returns {boolean} True if the path is ignored, false if not. + */ - const result = verifyText({ - text: fs.readFileSync(filePath, "utf8"), - filePath, - config, - cwd, - fix, - allowInlineConfig, - reportUnusedDisableDirectives, - fileEnumerator, - linter - }); - results.push(result); - /* - * Store the lint result in the LintResultCache. - * NOTE: The LintResultCache will remove the file source and any - * other properties that are difficult to serialize, and will - * hydrate those properties back in on future lint runs. - */ - if (lintResultCache) { - lintResultCache.setCachedLintResults(filePath, config, result); - } - } // Persist the cache to disk. + isIgnored(filePath) { + return this.getConfig(filePath) === undefined; + } +} - if (lintResultCache) { - lintResultCache.reconcile(); - } +exports.ConfigArray = ConfigArray; +exports.ConfigArraySymbol = ConfigArraySymbol; - debug("Linting complete in: ".concat(Date.now() - startTime, "ms")); - let usedDeprecatedRules; - return { - results, - ...calculateStatsPerRun(results), +/***/ }), +/* 862 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - // Initialize it lazily because CLI and `ESLint` API don't use it. - get usedDeprecatedRules() { - if (!usedDeprecatedRules) { - usedDeprecatedRules = Array.from(iterateRuleDeprecationWarnings(lastConfigArrays)); - } +/* provided dependency */ var console = __webpack_require__(438); +module.exports = minimatch; +minimatch.Minimatch = Minimatch; +var path = { + sep: '/' +}; - return usedDeprecatedRules; - } +try { + path = __webpack_require__(429); +} catch (er) {} - }; - } - /** - * Executes the current configuration on text. - * @param {string} text A string of JavaScript code to lint. - * @param {string} [filename] An optional string representing the texts filename. - * @param {boolean} [warnIgnored] Always warn when a file is ignored - * @returns {LintReport} The results for the linting. - */ +var GLOBSTAR = minimatch.GLOBSTAR = Minimatch.GLOBSTAR = {}; +var expand = __webpack_require__(863); - executeOnText(text, filename, warnIgnored) { - const { - configArrayFactory, - fileEnumerator, - lastConfigArrays, - linter, - options: { - allowInlineConfig, - cwd, - fix, - reportUnusedDisableDirectives - } - } = internalSlotsMap.get(this); - const results = []; - const startTime = Date.now(); - const resolvedFilename = filename && path.resolve(cwd, filename); // Clear the last used config arrays. +var plTypes = { + '!': { + open: '(?:(?!(?:', + close: '))[^/]*?)' + }, + '?': { + open: '(?:', + close: ')?' + }, + '+': { + open: '(?:', + close: ')+' + }, + '*': { + open: '(?:', + close: ')*' + }, + '@': { + open: '(?:', + close: ')' + } +}; // any single thing other than / +// don't need to escape / when using new RegExp() - lastConfigArrays.length = 0; +var qmark = '[^/]'; // * => any number of characters - if (resolvedFilename && this.isPathIgnored(resolvedFilename)) { - if (warnIgnored) { - results.push(createIgnoreResult(resolvedFilename, cwd)); - } - } else { - const config = configArrayFactory.getConfigArrayForFile(resolvedFilename || "__placeholder__.js"); - /* - * Store used configs for: - * - this method uses to collect used deprecated rules. - * - `getRules()` method uses to collect all loaded rules. - * - `--fix-type` option uses to get the loaded rule's meta data. - */ +var star = qmark + '*?'; // ** when dots are allowed. Anything goes, except .. and . +// not (^ or / followed by one or two dots followed by $ or /), +// followed by anything, any number of times. - lastConfigArrays.push(config); // Do lint. +var twoStarDot = '(?:(?!(?:\\\/|^)(?:\\.{1,2})($|\\\/)).)*?'; // not a ^ or / followed by a dot, +// followed by anything, any number of times. - results.push(verifyText({ - text, - filePath: resolvedFilename, - config, - cwd, - fix, - allowInlineConfig, - reportUnusedDisableDirectives, - fileEnumerator, - linter - })); - } +var twoStarNoDot = '(?:(?!(?:\\\/|^)\\.).)*?'; // characters that need to be escaped in RegExp. - debug("Linting complete in: ".concat(Date.now() - startTime, "ms")); - let usedDeprecatedRules; - return { - results, - ...calculateStatsPerRun(results), +var reSpecials = charSet('().*{}+?[]^$\\!'); // "abc" -> { a:true, b:true, c:true } - // Initialize it lazily because CLI and `ESLint` API don't use it. - get usedDeprecatedRules() { - if (!usedDeprecatedRules) { - usedDeprecatedRules = Array.from(iterateRuleDeprecationWarnings(lastConfigArrays)); - } +function charSet(s) { + return s.split('').reduce(function (set, c) { + set[c] = true; + return set; + }, {}); +} // normalizes slashes. - return usedDeprecatedRules; - } - }; - } - /** - * Returns a configuration object for the given file based on the CLI options. - * This is the same logic used by the ESLint CLI executable to determine - * configuration for each file it processes. - * @param {string} filePath The path of the file to retrieve a config object for. - * @throws {Error} If filepath a directory path. - * @returns {ConfigData} A configuration object for the file. - */ +var slashSplit = /\/+/; +minimatch.filter = filter; +function filter(pattern, options) { + options = options || {}; + return function (p, i, list) { + return minimatch(p, pattern, options); + }; +} - getConfigForFile(filePath) { - const { - configArrayFactory, - options - } = internalSlotsMap.get(this); - const absolutePath = path.resolve(options.cwd, filePath); +function ext(a, b) { + a = a || {}; + b = b || {}; + var t = {}; + Object.keys(b).forEach(function (k) { + t[k] = b[k]; + }); + Object.keys(a).forEach(function (k) { + t[k] = a[k]; + }); + return t; +} - if (directoryExists(absolutePath)) { - throw Object.assign(new Error("'filePath' should not be a directory path."), { - messageTemplate: "print-config-with-directory-path" - }); - } +minimatch.defaults = function (def) { + if (!def || !Object.keys(def).length) return minimatch; + var orig = minimatch; - return configArrayFactory.getConfigArrayForFile(absolutePath).extractConfig(absolutePath).toCompatibleObjectAsConfigFileContent(); - } - /** - * Checks if a given path is ignored by ESLint. - * @param {string} filePath The path of the file to check. - * @returns {boolean} Whether or not the given path is ignored. - */ + var m = function minimatch(p, pattern, options) { + return orig.minimatch(p, pattern, ext(def, options)); + }; + m.Minimatch = function Minimatch(pattern, options) { + return new orig.Minimatch(pattern, ext(def, options)); + }; - isPathIgnored(filePath) { - const { - configArrayFactory, - defaultIgnores, - options: { - cwd, - ignore - } - } = internalSlotsMap.get(this); - const absolutePath = path.resolve(cwd, filePath); + return m; +}; - if (ignore) { - const config = configArrayFactory.getConfigArrayForFile(absolutePath).extractConfig(absolutePath); - const ignores = config.ignores || defaultIgnores; - return ignores(absolutePath); - } +Minimatch.defaults = function (def) { + if (!def || !Object.keys(def).length) return Minimatch; + return minimatch.defaults(def).Minimatch; +}; - return defaultIgnores(absolutePath); +function minimatch(p, pattern, options) { + if (typeof pattern !== 'string') { + throw new TypeError('glob pattern string required'); } - /** - * Returns the formatter representing the given format or null if the `format` is not a string. - * @param {string} [format] The name of the format to load or the path to a - * custom formatter. - * @throws {any} As may be thrown by requiring of formatter - * @returns {(Function|null)} The formatter function or null if the `format` is not a string. - */ - - getFormatter(format) { - // default is stylish - const resolvedFormatName = format || "stylish"; // only strings are valid formatters + if (!options) options = {}; // shortcut: comments match nothing. - if (typeof resolvedFormatName === "string") { - // replace \ with / for Windows compatibility - const normalizedFormatName = resolvedFormatName.replace(/\\/gu, "/"); - const slots = internalSlotsMap.get(this); - const cwd = slots ? slots.options.cwd : process.cwd(); - const namespace = naming.getNamespaceFromTerm(normalizedFormatName); - let formatterPath; // if there's a slash, then it's a file (TODO: this check seems dubious for scoped npm packages) + if (!options.nocomment && pattern.charAt(0) === '#') { + return false; + } // "" only matches "" - if (!namespace && normalizedFormatName.indexOf("/") > -1) { - formatterPath = path.resolve(cwd, normalizedFormatName); - } else { - try { - const npmFormat = naming.normalizePackageName(normalizedFormatName, "eslint-formatter"); - formatterPath = ModuleResolver.resolve(npmFormat, path.join(cwd, "__placeholder__.js")); - } catch { - formatterPath = path.resolve(__dirname, "formatters", normalizedFormatName); - } - } - try { - return __webpack_require__(883)(formatterPath); - } catch (ex) { - if (format === "table" || format === "codeframe") { - ex.message = "The ".concat(format, " formatter is no longer part of core ESLint. Install it manually with `npm install -D eslint-formatter-").concat(format, "`"); - } else { - ex.message = "There was a problem loading formatter: ".concat(formatterPath, "\nError: ").concat(ex.message); - } + if (pattern.trim() === '') return p === ''; + return new Minimatch(pattern, options).match(p); +} - throw ex; - } - } else { - return null; - } +function Minimatch(pattern, options) { + if (!(this instanceof Minimatch)) { + return new Minimatch(pattern, options); } -} + if (typeof pattern !== 'string') { + throw new TypeError('glob pattern string required'); + } -CLIEngine.version = pkg.version; -CLIEngine.getFormatter = CLIEngine.prototype.getFormatter; -module.exports = { - CLIEngine, + if (!options) options = {}; + pattern = pattern.trim(); // windows support: need to use /, not \ - /** - * Get the internal slots of a given CLIEngine instance for tests. - * @param {CLIEngine} instance The CLIEngine instance to get. - * @returns {CLIEngineInternalSlots} The internal slots. - */ - getCLIEngineInternalSlots(instance) { - return internalSlotsMap.get(instance); + if (path.sep !== '/') { + pattern = pattern.split(path.sep).join('/'); } -}; + this.options = options; + this.set = []; + this.pattern = pattern; + this.regexp = null; + this.negate = false; + this.comment = false; + this.empty = false; // make the set of regexps etc. -/***/ }), -/* 861 */ -/***/ ((module) => { + this.make(); +} -"use strict"; -module.exports = require("fs"); +Minimatch.prototype.debug = function () {}; -/***/ }), -/* 862 */ -/***/ ((module) => { +Minimatch.prototype.make = make; -"use strict"; -/** - * @fileoverview Default CLIEngineOptions. - * @author Ian VanSchooten - */ +function make() { + // don't do it more than once. + if (this._made) return; + var pattern = this.pattern; + var options = this.options; // empty patterns and comments match nothing. + if (!options.nocomment && pattern.charAt(0) === '#') { + this.comment = true; + return; + } -module.exports = { - configFile: null, - baseConfig: false, - rulePaths: [], - useEslintrc: true, - envs: [], - globals: [], - extensions: null, - ignore: true, - ignorePath: void 0, - cache: false, + if (!pattern) { + this.empty = true; + return; + } // step 1: figure out negation, etc. - /* - * in order to honor the cacheFile option if specified - * this option should not have a default value otherwise - * it will always be used - */ - cacheLocation: "", - cacheFile: ".eslintcache", - cacheStrategy: "metadata", - fix: false, - allowInlineConfig: true, - reportUnusedDisableDirectives: void 0, - globInputPaths: true -}; -/***/ }), -/* 863 */ -/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + this.parseNegate(); // step 2: expand braces -"use strict"; -/* provided dependency */ var process = __webpack_require__(494); + var set = this.globSet = this.braceExpand(); + if (options.debug) this.debug = console.error; + this.debug(this.pattern, set); // step 3: now we have a set, so turn each one into a series of path-portion + // matching patterns. + // These will be regexps, except in the case of "**", which is + // set to the GLOBSTAR object for globstar behavior, + // and will not contain any / characters + set = this.globParts = set.map(function (s) { + return s.split(slashSplit); + }); + this.debug(this.pattern, set); // glob --> regexps -Object.defineProperty(exports, "__esModule", ({ value: true })); + set = set.map(function (s, si, set) { + return s.map(this.parse, this); + }, this); + this.debug(this.pattern, set); // filter out everything that didn't compile properly. -var fs = __webpack_require__(861); -var path = __webpack_require__(429); -var importFresh = __webpack_require__(864); -var stripComments = __webpack_require__(870); -var util = __webpack_require__(439); -var Ajv = __webpack_require__(446); -var globals = __webpack_require__(492); -var Module = __webpack_require__(866); -var assert = __webpack_require__(431); -var ignore = __webpack_require__(737); -var debugOrig = __webpack_require__(496); -var minimatch = __webpack_require__(871); -var os = __webpack_require__(875); -var url = __webpack_require__(876); + set = set.filter(function (s) { + return s.indexOf(false) === -1; + }); + this.debug(this.pattern, set); + this.set = set; +} -function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } +Minimatch.prototype.parseNegate = parseNegate; -var fs__default = /*#__PURE__*/_interopDefaultLegacy(fs); -var path__default = /*#__PURE__*/_interopDefaultLegacy(path); -var importFresh__default = /*#__PURE__*/_interopDefaultLegacy(importFresh); -var stripComments__default = /*#__PURE__*/_interopDefaultLegacy(stripComments); -var util__default = /*#__PURE__*/_interopDefaultLegacy(util); -var Ajv__default = /*#__PURE__*/_interopDefaultLegacy(Ajv); -var globals__default = /*#__PURE__*/_interopDefaultLegacy(globals); -var Module__default = /*#__PURE__*/_interopDefaultLegacy(Module); -var assert__default = /*#__PURE__*/_interopDefaultLegacy(assert); -var ignore__default = /*#__PURE__*/_interopDefaultLegacy(ignore); -var debugOrig__default = /*#__PURE__*/_interopDefaultLegacy(debugOrig); -var minimatch__default = /*#__PURE__*/_interopDefaultLegacy(minimatch); -var os__default = /*#__PURE__*/_interopDefaultLegacy(os); +function parseNegate() { + var pattern = this.pattern; + var negate = false; + var options = this.options; + var negateOffset = 0; + if (options.nonegate) return; -/** - * @fileoverview Config file operations. This file must be usable in the browser, - * so no Node-specific code can be here. - * @author Nicholas C. Zakas - */ + for (var i = 0, l = pattern.length; i < l && pattern.charAt(i) === '!'; i++) { + negate = !negate; + negateOffset++; + } -//------------------------------------------------------------------------------ -// Private -//------------------------------------------------------------------------------ + if (negateOffset) this.pattern = pattern.substr(negateOffset); + this.negate = negate; +} // Brace expansion: +// a{b,c}d -> abd acd +// a{b,}c -> abc ac +// a{0..3}d -> a0d a1d a2d a3d +// a{b,c{d,e}f}g -> abg acdfg acefg +// a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg +// +// Invalid sets are not expanded. +// a{2..}b -> a{2..}b +// a{b}c -> a{b}c -const RULE_SEVERITY_STRINGS = ["off", "warn", "error"], - RULE_SEVERITY = RULE_SEVERITY_STRINGS.reduce((map, value, index) => { - map[value] = index; - return map; - }, {}), - VALID_SEVERITIES = [0, 1, 2, "off", "warn", "error"]; -//------------------------------------------------------------------------------ -// Public Interface -//------------------------------------------------------------------------------ +minimatch.braceExpand = function (pattern, options) { + return braceExpand(pattern, options); +}; -/** - * Normalizes the severity value of a rule's configuration to a number - * @param {(number|string|[number, ...*]|[string, ...*])} ruleConfig A rule's configuration value, generally - * received from the user. A valid config value is either 0, 1, 2, the string "off" (treated the same as 0), - * the string "warn" (treated the same as 1), the string "error" (treated the same as 2), or an array - * whose first element is one of the above values. Strings are matched case-insensitively. - * @returns {(0|1|2)} The numeric severity value if the config value was valid, otherwise 0. - */ -function getRuleSeverity(ruleConfig) { - const severityValue = Array.isArray(ruleConfig) ? ruleConfig[0] : ruleConfig; +Minimatch.prototype.braceExpand = braceExpand; - if (severityValue === 0 || severityValue === 1 || severityValue === 2) { - return severityValue; +function braceExpand(pattern, options) { + if (!options) { + if (this instanceof Minimatch) { + options = this.options; + } else { + options = {}; } + } - if (typeof severityValue === "string") { - return RULE_SEVERITY[severityValue.toLowerCase()] || 0; - } + pattern = typeof pattern === 'undefined' ? this.pattern : pattern; - return 0; -} + if (typeof pattern === 'undefined') { + throw new TypeError('undefined pattern'); + } -/** - * Converts old-style severity settings (0, 1, 2) into new-style - * severity settings (off, warn, error) for all rules. Assumption is that severity - * values have already been validated as correct. - * @param {Object} config The config object to normalize. - * @returns {void} - */ -function normalizeToStrings(config) { + if (options.nobrace || !pattern.match(/\{.*\}/)) { + // shortcut. no need to expand. + return [pattern]; + } - if (config.rules) { - Object.keys(config.rules).forEach(ruleId => { - const ruleConfig = config.rules[ruleId]; + return expand(pattern); +} // parse a component of the expanded set. +// At this point, no pattern may contain "/" in it +// so we're going to return a 2d array, where each entry is the full +// pattern, split on '/', and then turned into a regular expression. +// A regexp is made at the end which joins each array with an +// escaped /, and another full one which joins each regexp with |. +// +// Following the lead of Bash 4.1, note that "**" only has special meaning +// when it is the *only* thing in a path portion. Otherwise, any series +// of * is equivalent to a single *. Globstar behavior is enabled by +// default, and can be disabled by setting options.noglobstar. - if (typeof ruleConfig === "number") { - config.rules[ruleId] = RULE_SEVERITY_STRINGS[ruleConfig] || RULE_SEVERITY_STRINGS[0]; - } else if (Array.isArray(ruleConfig) && typeof ruleConfig[0] === "number") { - ruleConfig[0] = RULE_SEVERITY_STRINGS[ruleConfig[0]] || RULE_SEVERITY_STRINGS[0]; - } - }); - } -} -/** - * Determines if the severity for the given rule configuration represents an error. - * @param {int|string|Array} ruleConfig The configuration for an individual rule. - * @returns {boolean} True if the rule represents an error, false if not. - */ -function isErrorSeverity(ruleConfig) { - return getRuleSeverity(ruleConfig) === 2; -} +Minimatch.prototype.parse = parse; +var SUBPARSE = {}; -/** - * Checks whether a given config has valid severity or not. - * @param {number|string|Array} ruleConfig The configuration for an individual rule. - * @returns {boolean} `true` if the configuration has valid severity. - */ -function isValidSeverity(ruleConfig) { - let severity = Array.isArray(ruleConfig) ? ruleConfig[0] : ruleConfig; +function parse(pattern, isSub) { + if (pattern.length > 1024 * 64) { + throw new TypeError('pattern is too long'); + } - if (typeof severity === "string") { - severity = severity.toLowerCase(); - } - return VALID_SEVERITIES.indexOf(severity) !== -1; -} + var options = this.options; // shortcuts -/** - * Checks whether every rule of a given config has valid severity or not. - * @param {Object} config The configuration for rules. - * @returns {boolean} `true` if the configuration has valid severity. - */ -function isEverySeverityValid(config) { - return Object.keys(config).every(ruleId => isValidSeverity(config[ruleId])); -} + if (!options.noglobstar && pattern === '**') return GLOBSTAR; + if (pattern === '') return ''; + var re = ''; + var hasMagic = !!options.nocase; + var escaping = false; // ? => one single character -/** - * Normalizes a value for a global in a config - * @param {(boolean|string|null)} configuredValue The value given for a global in configuration or in - * a global directive comment - * @returns {("readable"|"writeable"|"off")} The value normalized as a string - * @throws Error if global value is invalid - */ -function normalizeConfigGlobal(configuredValue) { - switch (configuredValue) { - case "off": - return "off"; + var patternListStack = []; + var negativeLists = []; + var stateChar; + var inClass = false; + var reClassStart = -1; + var classStart = -1; // . and .. never match anything that doesn't start with ., + // even when options.dot is set. - case true: - case "true": - case "writeable": - case "writable": - return "writable"; + var patternStart = pattern.charAt(0) === '.' ? '' // anything + // not (start or / followed by . or .. followed by / or end) + : options.dot ? '(?!(?:^|\\\/)\\.{1,2}(?:$|\\\/))' : '(?!\\.)'; + var self = this; - case null: - case false: - case "false": - case "readable": - case "readonly": - return "readonly"; + function clearStateChar() { + if (stateChar) { + // we had some state-tracking character + // that wasn't consumed by this pass. + switch (stateChar) { + case '*': + re += star; + hasMagic = true; + break; + + case '?': + re += qmark; + hasMagic = true; + break; default: - throw new Error(`'${configuredValue}' is not a valid configuration for a global (use 'readonly', 'writable', or 'off')`); + re += '\\' + stateChar; + break; + } + + self.debug('clearStateChar %j %j', stateChar, re); + stateChar = false; } -} + } -var ConfigOps = { - __proto__: null, - getRuleSeverity: getRuleSeverity, - normalizeToStrings: normalizeToStrings, - isErrorSeverity: isErrorSeverity, - isValidSeverity: isValidSeverity, - isEverySeverityValid: isEverySeverityValid, - normalizeConfigGlobal: normalizeConfigGlobal -}; + for (var i = 0, len = pattern.length, c; i < len && (c = pattern.charAt(i)); i++) { + this.debug('%s\t%s %s %j', pattern, i, re, c); // skip over any that are escaped. -/** - * @fileoverview Provide the function that emits deprecation warnings. - * @author Toru Nagashima - */ + if (escaping && reSpecials[c]) { + re += '\\' + c; + escaping = false; + continue; + } -//------------------------------------------------------------------------------ -// Private -//------------------------------------------------------------------------------ + switch (c) { + case '/': + // completely not allowed, even escaped. + // Should already be path-split by now. + return false; + + case '\\': + clearStateChar(); + escaping = true; + continue; + // the various stateChar values + // for the "extglob" stuff. + + case '?': + case '*': + case '+': + case '@': + case '!': + this.debug('%s\t%s %s %j <-- stateChar', pattern, i, re, c); // all of those are literals inside a class, except that + // the glob [!a] means [^a] in regexp + + if (inClass) { + this.debug(' in class'); + if (c === '!' && i === classStart + 1) c = '^'; + re += c; + continue; + } // if we already have a stateChar, then it means + // that there was something like ** or +? in there. + // Handle the stateChar, then proceed with this one. + + + self.debug('call clearStateChar %j', stateChar); + clearStateChar(); + stateChar = c; // if extglob is disabled, then +(asdf|foo) isn't a thing. + // just clear the statechar *now*, rather than even diving into + // the patternList stuff. + + if (options.noext) clearStateChar(); + continue; + + case '(': + if (inClass) { + re += '('; + continue; + } + + if (!stateChar) { + re += '\\('; + continue; + } + + patternListStack.push({ + type: stateChar, + start: i - 1, + reStart: re.length, + open: plTypes[stateChar].open, + close: plTypes[stateChar].close + }); // negation is (?:(?!js)[^/]*) + + re += stateChar === '!' ? '(?:(?!(?:' : '(?:'; + this.debug('plType %j %j', stateChar, re); + stateChar = false; + continue; + + case ')': + if (inClass || !patternListStack.length) { + re += '\\)'; + continue; + } + + clearStateChar(); + hasMagic = true; + var pl = patternListStack.pop(); // negation is (?:(?!js)[^/]*) + // The others are (?:) + + re += pl.close; + + if (pl.type === '!') { + negativeLists.push(pl); + } + + pl.reEnd = re.length; + continue; + + case '|': + if (inClass || !patternListStack.length || escaping) { + re += '\\|'; + escaping = false; + continue; + } + + clearStateChar(); + re += '|'; + continue; + // these are mostly the same in regexp and glob + + case '[': + // swallow any state-tracking char before the [ + clearStateChar(); + + if (inClass) { + re += '\\' + c; + continue; + } + + inClass = true; + classStart = i; + reClassStart = re.length; + re += c; + continue; + + case ']': + // a right bracket shall lose its special + // meaning and represent itself in + // a bracket expression if it occurs + // first in the list. -- POSIX.2 2.8.3.2 + if (i === classStart + 1 || !inClass) { + re += '\\' + c; + escaping = false; + continue; + } // handle the case where we left a class open. + // "[z-a]" is valid, equivalent to "\[z-a\]" + + + if (inClass) { + // split where the last [ was, make sure we don't have + // an invalid re. if so, re-walk the contents of the + // would-be class to re-translate any characters that + // were passed through as-is + // TODO: It would probably be faster to determine this + // without a try/catch and a new RegExp, but it's tricky + // to do safely. For now, this is safe and works. + var cs = pattern.substring(classStart + 1, i); + + try { + RegExp('[' + cs + ']'); + } catch (er) { + // not a valid class! + var sp = this.parse(cs, SUBPARSE); + re = re.substr(0, reClassStart) + '\\[' + sp[0] + '\\]'; + hasMagic = hasMagic || sp[1]; + inClass = false; + continue; + } + } // finish up the class. + + + hasMagic = true; + inClass = false; + re += c; + continue; + + default: + // swallow any state char that wasn't consumed + clearStateChar(); + + if (escaping) { + // no need + escaping = false; + } else if (reSpecials[c] && !(c === '^' && inClass)) { + re += '\\'; + } + + re += c; + } // switch + + } // for + // handle the case where we left a class open. + // "[abc" is valid, equivalent to "\[abc" + + + if (inClass) { + // split where the last [ was, and escape it + // this is a huge pita. We now have to re-walk + // the contents of the would-be class to re-translate + // any characters that were passed through as-is + cs = pattern.substr(classStart + 1); + sp = this.parse(cs, SUBPARSE); + re = re.substr(0, reClassStart) + '\\[' + sp[0]; + hasMagic = hasMagic || sp[1]; + } // handle the case where we had a +( thing at the *end* + // of the pattern. + // each pattern list stack adds 3 chars, and we need to go through + // and escape any | chars that were passed through as-is for the regexp. + // Go through and escape them, taking care not to double-escape any + // | chars that were already escaped. + + + for (pl = patternListStack.pop(); pl; pl = patternListStack.pop()) { + var tail = re.slice(pl.reStart + pl.open.length); + this.debug('setting tail', re, pl); // maybe some even number of \, then maybe 1 \, followed by a | + + tail = tail.replace(/((?:\\{2}){0,64})(\\?)\|/g, function (_, $1, $2) { + if (!$2) { + // the | isn't already escaped, so escape it. + $2 = '\\'; + } // need to escape all those slashes *again*, without escaping the + // one that we need for escaping the | character. As it works out, + // escaping an even number of slashes can be done by simply repeating + // it exactly after itself. That's why this trick works. + // + // I am sorry that you have to see this. + + + return $1 + $1 + $2 + '|'; + }); + this.debug('tail=%j\n %s', tail, tail, pl, re); + var t = pl.type === '*' ? star : pl.type === '?' ? qmark : '\\' + pl.type; + hasMagic = true; + re = re.slice(0, pl.reStart) + t + '\\(' + tail; + } // handle trailing things that only matter at the very end. + + + clearStateChar(); + + if (escaping) { + // trailing \\ + re += '\\\\'; + } // only need to apply the nodot start if the re starts with + // something that could conceivably capture a dot + + + var addPatternStart = false; + + switch (re.charAt(0)) { + case '.': + case '[': + case '(': + addPatternStart = true; + } // Hack to work around lack of negative lookbehind in JS + // A pattern like: *.!(x).!(y|z) needs to ensure that a name + // like 'a.xyz.yz' doesn't match. So, the first negative + // lookahead, has to look ALL the way ahead, to the end of + // the pattern. + + + for (var n = negativeLists.length - 1; n > -1; n--) { + var nl = negativeLists[n]; + var nlBefore = re.slice(0, nl.reStart); + var nlFirst = re.slice(nl.reStart, nl.reEnd - 8); + var nlLast = re.slice(nl.reEnd - 8, nl.reEnd); + var nlAfter = re.slice(nl.reEnd); + nlLast += nlAfter; // Handle nested stuff like *(*.js|!(*.json)), where open parens + // mean that we should *not* include the ) in the bit that is considered + // "after" the negated section. + + var openParensBefore = nlBefore.split('(').length - 1; + var cleanAfter = nlAfter; + + for (i = 0; i < openParensBefore; i++) { + cleanAfter = cleanAfter.replace(/\)[+*?]?/, ''); + } + + nlAfter = cleanAfter; + var dollar = ''; + + if (nlAfter === '' && isSub !== SUBPARSE) { + dollar = '$'; + } + + var newRe = nlBefore + nlFirst + nlAfter + dollar + nlLast; + re = newRe; + } // if the re is not "" at this point, then we need to make sure + // it doesn't match against an empty path part. + // Otherwise a/* will match a/, which it should not. + + + if (re !== '' && hasMagic) { + re = '(?=.)' + re; + } + + if (addPatternStart) { + re = patternStart + re; + } // parsing just a piece of a larger pattern. + + + if (isSub === SUBPARSE) { + return [re, hasMagic]; + } // skip the regexp for non-magical patterns + // unescape anything in it, though, so that it'll be + // an exact match against a file etc. + + + if (!hasMagic) { + return globUnescape(pattern); + } + + var flags = options.nocase ? 'i' : ''; + + try { + var regExp = new RegExp('^' + re + '$', flags); + } catch (er) { + // If it was an invalid regular expression, then it can't match + // anything. This trick looks for a character after the end of + // the string, which is of course impossible, except in multi-line + // mode, but it's not a /m regex. + return new RegExp('$.'); + } + + regExp._glob = pattern; + regExp._src = re; + return regExp; +} + +minimatch.makeRe = function (pattern, options) { + return new Minimatch(pattern, options || {}).makeRe(); +}; + +Minimatch.prototype.makeRe = makeRe; + +function makeRe() { + if (this.regexp || this.regexp === false) return this.regexp; // at this point, this.set is a 2d array of partial + // pattern strings, or "**". + // + // It's better to use .match(). This function shouldn't + // be used, really, but it's pretty convenient sometimes, + // when you just want to work with a regex. + + var set = this.set; + + if (!set.length) { + this.regexp = false; + return this.regexp; + } + + var options = this.options; + var twoStar = options.noglobstar ? star : options.dot ? twoStarDot : twoStarNoDot; + var flags = options.nocase ? 'i' : ''; + var re = set.map(function (pattern) { + return pattern.map(function (p) { + return p === GLOBSTAR ? twoStar : typeof p === 'string' ? regExpEscape(p) : p._src; + }).join('\\\/'); + }).join('|'); // must match entire pattern + // ending in a * or ** will make it less strict. + + re = '^(?:' + re + ')$'; // can match anything, as long as it's not this. + + if (this.negate) re = '^(?!' + re + ').*$'; + + try { + this.regexp = new RegExp(re, flags); + } catch (ex) { + this.regexp = false; + } + + return this.regexp; +} + +minimatch.match = function (list, pattern, options) { + options = options || {}; + var mm = new Minimatch(pattern, options); + list = list.filter(function (f) { + return mm.match(f); + }); + + if (mm.options.nonull && !list.length) { + list.push(pattern); + } + + return list; +}; + +Minimatch.prototype.match = match; + +function match(f, partial) { + this.debug('match', f, this.pattern); // short-circuit in the case of busted things. + // comments, etc. + + if (this.comment) return false; + if (this.empty) return f === ''; + if (f === '/' && partial) return true; + var options = this.options; // windows: need to use /, not \ + + if (path.sep !== '/') { + f = f.split(path.sep).join('/'); + } // treat the test path as a set of pathparts. + + + f = f.split(slashSplit); + this.debug(this.pattern, 'split', f); // just ONE of the pattern sets in this.set needs to match + // in order for it to be valid. If negating, then just one + // match means that we have failed. + // Either way, return on the first hit. + + var set = this.set; + this.debug(this.pattern, 'set', set); // Find the basename of the path by looking for the last non-empty segment + + var filename; + var i; + + for (i = f.length - 1; i >= 0; i--) { + filename = f[i]; + if (filename) break; + } + + for (i = 0; i < set.length; i++) { + var pattern = set[i]; + var file = f; + + if (options.matchBase && pattern.length === 1) { + file = [filename]; + } + + var hit = this.matchOne(file, pattern, partial); + + if (hit) { + if (options.flipNegate) return true; + return !this.negate; + } + } // didn't get any hits. this is success if it's a negative + // pattern, failure otherwise. + + + if (options.flipNegate) return false; + return this.negate; +} // set partial to true to test if, for example, +// "/a/b" matches the start of "/*/b/*/d" +// Partial means, if you run out of file before you run +// out of pattern, then that's fine, as long as all +// the parts match. + + +Minimatch.prototype.matchOne = function (file, pattern, partial) { + var options = this.options; + this.debug('matchOne', { + 'this': this, + file: file, + pattern: pattern + }); + this.debug('matchOne', file.length, pattern.length); + + for (var fi = 0, pi = 0, fl = file.length, pl = pattern.length; fi < fl && pi < pl; fi++, pi++) { + this.debug('matchOne loop'); + var p = pattern[pi]; + var f = file[fi]; + this.debug(pattern, p, f); // should be impossible. + // some invalid regexp stuff in the set. + + if (p === false) return false; + + if (p === GLOBSTAR) { + this.debug('GLOBSTAR', [pattern, p, f]); // "**" + // a/**/b/**/c would match the following: + // a/b/x/y/z/c + // a/x/y/z/b/c + // a/b/x/b/x/c + // a/b/c + // To do this, take the rest of the pattern after + // the **, and see if it would match the file remainder. + // If so, return success. + // If not, the ** "swallows" a segment, and try again. + // This is recursively awful. + // + // a/**/b/**/c matching a/b/x/y/z/c + // - a matches a + // - doublestar + // - matchOne(b/x/y/z/c, b/**/c) + // - b matches b + // - doublestar + // - matchOne(x/y/z/c, c) -> no + // - matchOne(y/z/c, c) -> no + // - matchOne(z/c, c) -> no + // - matchOne(c, c) yes, hit + + var fr = fi; + var pr = pi + 1; + + if (pr === pl) { + this.debug('** at the end'); // a ** at the end will just swallow the rest. + // We have found a match. + // however, it will not swallow /.x, unless + // options.dot is set. + // . and .. are *never* matched by **, for explosively + // exponential reasons. + + for (; fi < fl; fi++) { + if (file[fi] === '.' || file[fi] === '..' || !options.dot && file[fi].charAt(0) === '.') return false; + } + + return true; + } // ok, let's see if we can swallow whatever we can. + + + while (fr < fl) { + var swallowee = file[fr]; + this.debug('\nglobstar while', file, fr, pattern, pr, swallowee); // XXX remove this slice. Just pass the start index. + + if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) { + this.debug('globstar found match!', fr, fl, swallowee); // found a match. + + return true; + } else { + // can't swallow "." or ".." ever. + // can only swallow ".foo" when explicitly asked. + if (swallowee === '.' || swallowee === '..' || !options.dot && swallowee.charAt(0) === '.') { + this.debug('dot detected!', file, fr, pattern, pr); + break; + } // ** swallows a segment, and continue. + + + this.debug('globstar swallow a segment, and continue'); + fr++; + } + } // no match was found. + // However, in partial mode, we can't say this is necessarily over. + // If there's more *pattern* left, then + + + if (partial) { + // ran out of file + this.debug('\n>>> no match, partial?', file, fr, pattern, pr); + if (fr === fl) return true; + } + + return false; + } // something other than ** + // non-magic patterns just have to match exactly + // patterns with magic have been turned into regexps. + + + var hit; + + if (typeof p === 'string') { + if (options.nocase) { + hit = f.toLowerCase() === p.toLowerCase(); + } else { + hit = f === p; + } + + this.debug('string match', p, f, hit); + } else { + hit = f.match(p); + this.debug('pattern match', p, f, hit); + } + + if (!hit) return false; + } // Note: ending in / means that we'll get a final "" + // at the end of the pattern. This can only match a + // corresponding "" at the end of the file. + // If the file ends in /, then it can only match a + // a pattern that ends in /, unless the pattern just + // doesn't have any more for it. But, a/b/ should *not* + // match "a/b/*", even though "" matches against the + // [^/]*? pattern, except in partial mode, where it might + // simply not be reached yet. + // However, a/b/ should still satisfy a/* + // now either we fell off the end of the pattern, or we're done. + + + if (fi === fl && pi === pl) { + // ran out of pattern and filename at the same time. + // an exact hit! + return true; + } else if (fi === fl) { + // ran out of file, but still had pattern left. + // this is ok if we're doing the match as part of + // a glob fs traversal. + return partial; + } else if (pi === pl) { + // ran out of pattern, still have file left. + // this is only acceptable if we're on the very last + // empty segment of a file with a trailing slash. + // a/* should match a/b/ + var emptyFileEnd = fi === fl - 1 && file[fi] === ''; + return emptyFileEnd; + } // should be unreachable. + + + throw new Error('wtf?'); +}; // replace stuff like \* with * + + +function globUnescape(s) { + return s.replace(/\\(.)/g, '$1'); +} + +function regExpEscape(s) { + return s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&'); +} + +/***/ }), +/* 863 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var concatMap = __webpack_require__(864); + +var balanced = __webpack_require__(865); + +module.exports = expandTop; +var escSlash = '\0SLASH' + Math.random() + '\0'; +var escOpen = '\0OPEN' + Math.random() + '\0'; +var escClose = '\0CLOSE' + Math.random() + '\0'; +var escComma = '\0COMMA' + Math.random() + '\0'; +var escPeriod = '\0PERIOD' + Math.random() + '\0'; + +function numeric(str) { + return parseInt(str, 10) == str ? parseInt(str, 10) : str.charCodeAt(0); +} + +function escapeBraces(str) { + return str.split('\\\\').join(escSlash).split('\\{').join(escOpen).split('\\}').join(escClose).split('\\,').join(escComma).split('\\.').join(escPeriod); +} + +function unescapeBraces(str) { + return str.split(escSlash).join('\\').split(escOpen).join('{').split(escClose).join('}').split(escComma).join(',').split(escPeriod).join('.'); +} // Basically just str.split(","), but handling cases +// where we have nested braced sections, which should be +// treated as individual members, like {a,{b,c},d} + + +function parseCommaParts(str) { + if (!str) return ['']; + var parts = []; + var m = balanced('{', '}', str); + if (!m) return str.split(','); + var pre = m.pre; + var body = m.body; + var post = m.post; + var p = pre.split(','); + p[p.length - 1] += '{' + body + '}'; + var postParts = parseCommaParts(post); + + if (post.length) { + p[p.length - 1] += postParts.shift(); + p.push.apply(p, postParts); + } + + parts.push.apply(parts, p); + return parts; +} + +function expandTop(str) { + if (!str) return []; // I don't know why Bash 4.3 does this, but it does. + // Anything starting with {} will have the first two bytes preserved + // but *only* at the top level, so {},a}b will not expand to anything, + // but a{},b}c will be expanded to [a}c,abc]. + // One could argue that this is a bug in Bash, but since the goal of + // this module is to match Bash's rules, we escape a leading {} + + if (str.substr(0, 2) === '{}') { + str = '\\{\\}' + str.substr(2); + } + + return expand(escapeBraces(str), true).map(unescapeBraces); +} + +function identity(e) { + return e; +} + +function embrace(str) { + return '{' + str + '}'; +} + +function isPadded(el) { + return /^-?0\d/.test(el); +} + +function lte(i, y) { + return i <= y; +} + +function gte(i, y) { + return i >= y; +} + +function expand(str, isTop) { + var expansions = []; + var m = balanced('{', '}', str); + if (!m || /\$$/.test(m.pre)) return [str]; + var isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body); + var isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body); + var isSequence = isNumericSequence || isAlphaSequence; + var isOptions = m.body.indexOf(',') >= 0; + + if (!isSequence && !isOptions) { + // {a},b} + if (m.post.match(/,.*\}/)) { + str = m.pre + '{' + m.body + escClose + m.post; + return expand(str); + } + + return [str]; + } + + var n; + + if (isSequence) { + n = m.body.split(/\.\./); + } else { + n = parseCommaParts(m.body); + + if (n.length === 1) { + // x{{a,b}}y ==> x{a}y x{b}y + n = expand(n[0], false).map(embrace); + + if (n.length === 1) { + var post = m.post.length ? expand(m.post, false) : ['']; + return post.map(function (p) { + return m.pre + n[0] + p; + }); + } + } + } // at this point, n is the parts, and we know it's not a comma set + // with a single entry. + // no need to expand pre, since it is guaranteed to be free of brace-sets + + + var pre = m.pre; + var post = m.post.length ? expand(m.post, false) : ['']; + var N; + + if (isSequence) { + var x = numeric(n[0]); + var y = numeric(n[1]); + var width = Math.max(n[0].length, n[1].length); + var incr = n.length == 3 ? Math.abs(numeric(n[2])) : 1; + var test = lte; + var reverse = y < x; + + if (reverse) { + incr *= -1; + test = gte; + } + + var pad = n.some(isPadded); + N = []; + + for (var i = x; test(i, y); i += incr) { + var c; + + if (isAlphaSequence) { + c = String.fromCharCode(i); + if (c === '\\') c = ''; + } else { + c = String(i); + + if (pad) { + var need = width - c.length; + + if (need > 0) { + var z = new Array(need + 1).join('0'); + if (i < 0) c = '-' + z + c.slice(1);else c = z + c; + } + } + } + + N.push(c); + } + } else { + N = concatMap(n, function (el) { + return expand(el, false); + }); + } + + for (var j = 0; j < N.length; j++) { + for (var k = 0; k < post.length; k++) { + var expansion = pre + N[j] + post[k]; + if (!isTop || isSequence || expansion) expansions.push(expansion); + } + } + + return expansions; +} + +/***/ }), +/* 864 */ +/***/ ((module) => { + +module.exports = function (xs, fn) { + var res = []; + + for (var i = 0; i < xs.length; i++) { + var x = fn(xs[i], i); + if (isArray(x)) res.push.apply(res, x);else res.push(x); + } + + return res; +}; + +var isArray = Array.isArray || function (xs) { + return Object.prototype.toString.call(xs) === '[object Array]'; +}; + +/***/ }), +/* 865 */ +/***/ ((module) => { + +"use strict"; + + +module.exports = balanced; + +function balanced(a, b, str) { + if (a instanceof RegExp) a = maybeMatch(a, str); + if (b instanceof RegExp) b = maybeMatch(b, str); + var r = range(a, b, str); + return r && { + start: r[0], + end: r[1], + pre: str.slice(0, r[0]), + body: str.slice(r[0] + a.length, r[1]), + post: str.slice(r[1] + b.length) + }; +} + +function maybeMatch(reg, str) { + var m = str.match(reg); + return m ? m[0] : null; +} + +balanced.range = range; + +function range(a, b, str) { + var begs, beg, left, right, result; + var ai = str.indexOf(a); + var bi = str.indexOf(b, ai + 1); + var i = ai; + + if (ai >= 0 && bi > 0) { + if (a === b) { + return [ai, bi]; + } + + begs = []; + left = str.length; + + while (i >= 0 && !result) { + if (i == ai) { + begs.push(i); + ai = str.indexOf(a, i + 1); + } else if (begs.length == 1) { + result = [begs.pop(), bi]; + } else { + beg = begs.pop(); + + if (beg < left) { + left = beg; + right = bi; + } + + bi = str.indexOf(b, i + 1); + } + + i = ai < bi && ai >= 0 ? ai : bi; + } + + if (begs.length) { + result = [left, right]; + } + } + + return result; +} + +/***/ }), +/* 866 */ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +/** + * @filedescription Object Schema Package + */ +exports.ObjectSchema = __webpack_require__(867).ObjectSchema; +exports.MergeStrategy = __webpack_require__(868).MergeStrategy; +exports.ValidationStrategy = __webpack_require__(869).ValidationStrategy; + +/***/ }), +/* 867 */ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; +/** + * @filedescription Object Schema + */ + //----------------------------------------------------------------------------- +// Requirements +//----------------------------------------------------------------------------- + +const { + MergeStrategy +} = __webpack_require__(868); + +const { + ValidationStrategy +} = __webpack_require__(869); //----------------------------------------------------------------------------- +// Private +//----------------------------------------------------------------------------- + + +const strategies = Symbol("strategies"); +const requiredKeys = Symbol("requiredKeys"); +/** + * Validates a schema strategy. + * @param {string} name The name of the key this strategy is for. + * @param {Object} strategy The strategy for the object key. + * @param {boolean} [strategy.required=true] Whether the key is required. + * @param {string[]} [strategy.requires] Other keys that are required when + * this key is present. + * @param {Function} strategy.merge A method to call when merging two objects + * with the same key. + * @param {Function} strategy.validate A method to call when validating an + * object with the key. + * @returns {void} + * @throws {Error} When the strategy is missing a name. + * @throws {Error} When the strategy is missing a merge() method. + * @throws {Error} When the strategy is missing a validate() method. + */ + +function validateDefinition(name, strategy) { + let hasSchema = false; + + if (strategy.schema) { + if (typeof strategy.schema === "object") { + hasSchema = true; + } else { + throw new TypeError("Schema must be an object."); + } + } + + if (typeof strategy.merge === "string") { + if (!(strategy.merge in MergeStrategy)) { + throw new TypeError("Definition for key \"".concat(name, "\" missing valid merge strategy.")); + } + } else if (!hasSchema && typeof strategy.merge !== "function") { + throw new TypeError("Definition for key \"".concat(name, "\" must have a merge property.")); + } + + if (typeof strategy.validate === "string") { + if (!(strategy.validate in ValidationStrategy)) { + throw new TypeError("Definition for key \"".concat(name, "\" missing valid validation strategy.")); + } + } else if (!hasSchema && typeof strategy.validate !== "function") { + throw new TypeError("Definition for key \"".concat(name, "\" must have a validate() method.")); + } +} //----------------------------------------------------------------------------- +// Class +//----------------------------------------------------------------------------- + +/** + * Represents an object validation/merging schema. + */ + + +class ObjectSchema { + /** + * Creates a new instance. + */ + constructor(definitions) { + if (!definitions) { + throw new Error("Schema definitions missing."); + } + /** + * Track all strategies in the schema by key. + * @type {Map} + * @property strategies + */ + + + this[strategies] = new Map(); + /** + * Separately track any keys that are required for faster validation. + * @type {Map} + * @property requiredKeys + */ + + this[requiredKeys] = new Map(); // add in all strategies + + for (const key of Object.keys(definitions)) { + validateDefinition(key, definitions[key]); // normalize merge and validate methods if subschema is present + + if (typeof definitions[key].schema === "object") { + const schema = new ObjectSchema(definitions[key].schema); + definitions[key] = { ...definitions[key], + + merge() { + let first = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + let second = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + return schema.merge(first, second); + }, + + validate(value) { + ValidationStrategy.object(value); + schema.validate(value); + } + + }; + } // normalize the merge method in case there's a string + + + if (typeof definitions[key].merge === "string") { + definitions[key] = { ...definitions[key], + merge: MergeStrategy[definitions[key].merge] + }; + } + + ; // normalize the validate method in case there's a string + + if (typeof definitions[key].validate === "string") { + definitions[key] = { ...definitions[key], + validate: ValidationStrategy[definitions[key].validate] + }; + } + + ; + this[strategies].set(key, definitions[key]); + + if (definitions[key].required) { + this[requiredKeys].set(key, definitions[key]); + } + } + } + /** + * Determines if a strategy has been registered for the given object key. + * @param {string} key The object key to find a strategy for. + * @returns {boolean} True if the key has a strategy registered, false if not. + */ + + + hasKey(key) { + return this[strategies].has(key); + } + /** + * Merges objects together to create a new object comprised of the keys + * of the all objects. Keys are merged based on the each key's merge + * strategy. + * @param {...Object} objects The objects to merge. + * @returns {Object} A new object with a mix of all objects' keys. + * @throws {Error} If any object is invalid. + */ + + + merge() { + for (var _len = arguments.length, objects = new Array(_len), _key = 0; _key < _len; _key++) { + objects[_key] = arguments[_key]; + } + + // double check arguments + if (objects.length < 2) { + throw new Error("merge() requires at least two arguments."); + } + + if (objects.some(object => object == null || typeof object !== "object")) { + throw new Error("All arguments must be objects."); + } + + return objects.reduce((result, object) => { + this.validate(object); + + for (const [key, strategy] of this[strategies]) { + try { + if (key in result || key in object) { + const value = strategy.merge.call(this, result[key], object[key]); + + if (value !== undefined) { + result[key] = value; + } + } + } catch (ex) { + ex.message = "Key \"".concat(key, "\": ") + ex.message; + throw ex; + } + } + + return result; + }, {}); + } + /** + * Validates an object's keys based on the validate strategy for each key. + * @param {Object} object The object to validate. + * @returns {void} + * @throws {Error} When the object is invalid. + */ + + + validate(object) { + // check existing keys first + for (const key of Object.keys(object)) { + // check to see if the key is defined + if (!this.hasKey(key)) { + throw new Error("Unexpected key \"".concat(key, "\" found.")); + } // validate existing keys + + + const strategy = this[strategies].get(key); // first check to see if any other keys are required + + if (Array.isArray(strategy.requires)) { + if (!strategy.requires.every(otherKey => otherKey in object)) { + throw new Error("Key \"".concat(key, "\" requires keys \"").concat(strategy.requires.join("\", \""), "\".")); + } + } // now apply remaining validation strategy + + + try { + strategy.validate.call(strategy, object[key]); + } catch (ex) { + ex.message = "Key \"".concat(key, "\": ") + ex.message; + throw ex; + } + } // ensure required keys aren't missing + + + for (const [key] of this[requiredKeys]) { + if (!(key in object)) { + throw new Error("Missing required key \"".concat(key, "\".")); + } + } + } + +} + +exports.ObjectSchema = ObjectSchema; + +/***/ }), +/* 868 */ +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; +/** + * @filedescription Merge Strategy + */ + //----------------------------------------------------------------------------- +// Class +//----------------------------------------------------------------------------- + +/** + * Container class for several different merge strategies. + */ + +class MergeStrategy { + /** + * Merges two keys by overwriting the first with the second. + * @param {*} value1 The value from the first object key. + * @param {*} value2 The value from the second object key. + * @returns {*} The second value. + */ + static overwrite(value1, value2) { + return value2; + } + /** + * Merges two keys by replacing the first with the second only if the + * second is defined. + * @param {*} value1 The value from the first object key. + * @param {*} value2 The value from the second object key. + * @returns {*} The second value if it is defined. + */ + + + static replace(value1, value2) { + if (typeof value2 !== "undefined") { + return value2; + } + + return value1; + } + /** + * Merges two properties by assigning properties from the second to the first. + * @param {*} value1 The value from the first object key. + * @param {*} value2 The value from the second object key. + * @returns {*} A new object containing properties from both value1 and + * value2. + */ + + + static assign(value1, value2) { + return Object.assign({}, value1, value2); + } + +} + +exports.MergeStrategy = MergeStrategy; + +/***/ }), +/* 869 */ +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; +/** + * @filedescription Validation Strategy + */ + //----------------------------------------------------------------------------- +// Class +//----------------------------------------------------------------------------- + +/** + * Container class for several different validation strategies. + */ + +class ValidationStrategy { + /** + * Validates that a value is an array. + * @param {*} value The value to validate. + * @returns {void} + * @throws {TypeError} If the value is invalid. + */ + static array(value) { + if (!Array.isArray(value)) { + throw new TypeError("Expected an array."); + } + } + /** + * Validates that a value is a boolean. + * @param {*} value The value to validate. + * @returns {void} + * @throws {TypeError} If the value is invalid. + */ + + + static boolean(value) { + if (typeof value !== "boolean") { + throw new TypeError("Expected a Boolean."); + } + } + /** + * Validates that a value is a number. + * @param {*} value The value to validate. + * @returns {void} + * @throws {TypeError} If the value is invalid. + */ + + + static number(value) { + if (typeof value !== "number") { + throw new TypeError("Expected a number."); + } + } + /** + * Validates that a value is a object. + * @param {*} value The value to validate. + * @returns {void} + * @throws {TypeError} If the value is invalid. + */ + + + static object(value) { + if (!value || typeof value !== "object") { + throw new TypeError("Expected an object."); + } + } + /** + * Validates that a value is a object or null. + * @param {*} value The value to validate. + * @returns {void} + * @throws {TypeError} If the value is invalid. + */ + + + static "object?"(value) { + if (typeof value !== "object") { + throw new TypeError("Expected an object or null."); + } + } + /** + * Validates that a value is a string. + * @param {*} value The value to validate. + * @returns {void} + * @throws {TypeError} If the value is invalid. + */ + + + static string(value) { + if (typeof value !== "string") { + throw new TypeError("Expected a string."); + } + } + /** + * Validates that a value is a non-empty string. + * @param {*} value The value to validate. + * @returns {void} + * @throws {TypeError} If the value is invalid. + */ + + + static "string!"(value) { + if (typeof value !== "string" || value.length === 0) { + throw new TypeError("Expected a non-empty string."); + } + } + +} + +exports.ValidationStrategy = ValidationStrategy; + +/***/ }), +/* 870 */ +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; +/** + * @fileoverview Flat config schema + * @author Nicholas C. Zakas + */ + //----------------------------------------------------------------------------- +// Type Definitions +//----------------------------------------------------------------------------- + +/** + * @typedef ObjectPropertySchema + * @property {Function|string} merge The function or name of the function to call + * to merge multiple objects with this property. + * @property {Function|string} validate The function or name of the function to call + * to validate the value of this property. + */ +//----------------------------------------------------------------------------- +// Helpers +//----------------------------------------------------------------------------- + +const ruleSeverities = new Map([[0, 0], ["off", 0], [1, 1], ["warn", 1], [2, 2], ["error", 2]]); +const globalVariablesValues = new Set([true, "true", "writable", "writeable", false, "false", "readonly", "readable", null, "off"]); +/** + * Check if a value is a non-null object. + * @param {any} value The value to check. + * @returns {boolean} `true` if the value is a non-null object. + */ + +function isNonNullObject(value) { + return typeof value === "object" && value !== null; +} +/** + * Check if a value is undefined. + * @param {any} value The value to check. + * @returns {boolean} `true` if the value is undefined. + */ + + +function isUndefined(value) { + return typeof value === "undefined"; +} +/** + * Deeply merges two objects. + * @param {Object} first The base object. + * @param {Object} second The overrides object. + * @returns {Object} An object with properties from both first and second. + */ + + +function deepMerge() { + let first = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + let second = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + /* + * If the second value is an array, just return it. We don't merge + * arrays because order matters and we can't know the correct order. + */ + if (Array.isArray(second)) { + return second; + } + /* + * First create a result object where properties from the second object + * overwrite properties from the first. This sets up a baseline to use + * later rather than needing to inspect and change every property + * individually. + */ + + + const result = { ...first, + ...second + }; + + for (const key of Object.keys(second)) { + // avoid hairy edge case + if (key === "__proto__") { + continue; + } + + const firstValue = first[key]; + const secondValue = second[key]; + + if (isNonNullObject(firstValue)) { + result[key] = deepMerge(firstValue, secondValue); + } else if (isUndefined(firstValue)) { + if (isNonNullObject(secondValue)) { + result[key] = deepMerge(Array.isArray(secondValue) ? [] : {}, secondValue); + } else if (!isUndefined(secondValue)) { + result[key] = secondValue; + } + } + } + + return result; +} +/** + * Normalizes the rule options config for a given rule by ensuring that + * it is an array and that the first item is 0, 1, or 2. + * @param {Array|string|number} ruleOptions The rule options config. + * @returns {Array} An array of rule options. + */ + + +function normalizeRuleOptions(ruleOptions) { + const finalOptions = Array.isArray(ruleOptions) ? ruleOptions.slice(0) : [ruleOptions]; + finalOptions[0] = ruleSeverities.get(finalOptions[0]); + return finalOptions; +} //----------------------------------------------------------------------------- +// Assertions +//----------------------------------------------------------------------------- + +/** + * Validates that a value is a valid rule options entry. + * @param {any} value The value to check. + * @returns {void} + * @throws {TypeError} If the value isn't a valid rule options. + */ + + +function assertIsRuleOptions(value) { + if (typeof value !== "string" && typeof value !== "number" && !Array.isArray(value)) { + throw new TypeError("Expected a string, number, or array."); + } +} +/** + * Validates that a value is valid rule severity. + * @param {any} value The value to check. + * @returns {void} + * @throws {TypeError} If the value isn't a valid rule severity. + */ + + +function assertIsRuleSeverity(value) { + const severity = typeof value === "string" ? ruleSeverities.get(value.toLowerCase()) : ruleSeverities.get(value); + + if (typeof severity === "undefined") { + throw new TypeError("Expected severity of \"off\", 0, \"warn\", 1, \"error\", or 2."); + } +} +/** + * Validates that a given string is the form pluginName/objectName. + * @param {string} value The string to check. + * @returns {void} + * @throws {TypeError} If the string isn't in the correct format. + */ + + +function assertIsPluginMemberName(value) { + if (!/[@a-z0-9-_$]+(?:\/(?:[a-z0-9-_$]+))+$/iu.test(value)) { + throw new TypeError("Expected string in the form \"pluginName/objectName\" but found \"".concat(value, "\".")); + } +} +/** + * Validates that a value is an object. + * @param {any} value The value to check. + * @returns {void} + * @throws {TypeError} If the value isn't an object. + */ + + +function assertIsObject(value) { + if (!isNonNullObject(value)) { + throw new TypeError("Expected an object."); + } +} +/** + * Validates that a value is an object or a string. + * @param {any} value The value to check. + * @returns {void} + * @throws {TypeError} If the value isn't an object or a string. + */ + + +function assertIsObjectOrString(value) { + if ((!value || typeof value !== "object") && typeof value !== "string") { + throw new TypeError("Expected an object or string."); + } +} //----------------------------------------------------------------------------- +// Low-Level Schemas +//----------------------------------------------------------------------------- + +/** @type {ObjectPropertySchema} */ + + +const booleanSchema = { + merge: "replace", + validate: "boolean" +}; +/** @type {ObjectPropertySchema} */ + +const deepObjectAssignSchema = { + merge() { + let first = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + let second = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + return deepMerge(first, second); + }, + + validate: "object" +}; //----------------------------------------------------------------------------- +// High-Level Schemas +//----------------------------------------------------------------------------- + +/** @type {ObjectPropertySchema} */ + +const globalsSchema = { + merge: "assign", + + validate(value) { + assertIsObject(value); + + for (const key of Object.keys(value)) { + // avoid hairy edge case + if (key === "__proto__") { + continue; + } + + if (key !== key.trim()) { + throw new TypeError("Global \"".concat(key, "\" has leading or trailing whitespace.")); + } + + if (!globalVariablesValues.has(value[key])) { + throw new TypeError("Key \"".concat(key, "\": Expected \"readonly\", \"writable\", or \"off\".")); + } + } + } + +}; +/** @type {ObjectPropertySchema} */ + +const parserSchema = { + merge: "replace", + + validate(value) { + assertIsObjectOrString(value); + + if (typeof value === "object" && typeof value.parse !== "function" && typeof value.parseForESLint !== "function") { + throw new TypeError("Expected object to have a parse() or parseForESLint() method."); + } + + if (typeof value === "string") { + assertIsPluginMemberName(value); + } + } + +}; +/** @type {ObjectPropertySchema} */ + +const pluginsSchema = { + merge() { + let first = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + let second = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + const keys = new Set([...Object.keys(first), ...Object.keys(second)]); + const result = {}; // manually validate that plugins are not redefined + + for (const key of keys) { + // avoid hairy edge case + if (key === "__proto__") { + continue; + } + + if (key in first && key in second && first[key] !== second[key]) { + throw new TypeError("Cannot redefine plugin \"".concat(key, "\".")); + } + + result[key] = second[key] || first[key]; + } + + return result; + }, + + validate(value) { + // first check the value to be sure it's an object + if (value === null || typeof value !== "object") { + throw new TypeError("Expected an object."); + } // second check the keys to make sure they are objects + + + for (const key of Object.keys(value)) { + // avoid hairy edge case + if (key === "__proto__") { + continue; + } + + if (value[key] === null || typeof value[key] !== "object") { + throw new TypeError("Key \"".concat(key, "\": Expected an object.")); + } + } + } + +}; +/** @type {ObjectPropertySchema} */ + +const processorSchema = { + merge: "replace", + + validate(value) { + if (typeof value === "string") { + assertIsPluginMemberName(value); + } else if (value && typeof value === "object") { + if (typeof value.preprocess !== "function" || typeof value.postprocess !== "function") { + throw new TypeError("Object must have a preprocess() and a postprocess() method."); + } + } else { + throw new TypeError("Expected an object or a string."); + } + } + +}; +/** @type {ObjectPropertySchema} */ + +const rulesSchema = { + merge() { + let first = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + let second = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + const result = { ...first, + ...second + }; + + for (const ruleId of Object.keys(result)) { + // avoid hairy edge case + if (ruleId === "__proto__") { + /* eslint-disable-next-line no-proto -- Though deprecated, may still be present */ + delete result.__proto__; + continue; + } + + result[ruleId] = normalizeRuleOptions(result[ruleId]); + /* + * If either rule config is missing, then the correct + * config is already present and we just need to normalize + * the severity. + */ + + if (!(ruleId in first) || !(ruleId in second)) { + continue; + } + + const firstRuleOptions = normalizeRuleOptions(first[ruleId]); + const secondRuleOptions = normalizeRuleOptions(second[ruleId]); + /* + * If the second rule config only has a severity (length of 1), + * then use that severity and keep the rest of the options from + * the first rule config. + */ + + if (secondRuleOptions.length === 1) { + result[ruleId] = [secondRuleOptions[0], ...firstRuleOptions.slice(1)]; + continue; + } + /* + * In any other situation, then the second rule config takes + * precedence. That means the value at `result[ruleId]` is + * already correct and no further work is necessary. + */ + + } + + return result; + }, + + validate(value) { + assertIsObject(value); + let lastRuleId; // Performance: One try-catch has less overhead than one per loop iteration + + try { + /* + * We are not checking the rule schema here because there is no + * guarantee that the rule definition is present at this point. Instead + * we wait and check the rule schema during the finalization step + * of calculating a config. + */ + for (const ruleId of Object.keys(value)) { + // avoid hairy edge case + if (ruleId === "__proto__") { + continue; + } + + lastRuleId = ruleId; + const ruleOptions = value[ruleId]; + assertIsRuleOptions(ruleOptions); + + if (Array.isArray(ruleOptions)) { + assertIsRuleSeverity(ruleOptions[0]); + } else { + assertIsRuleSeverity(ruleOptions); + } + } + } catch (error) { + error.message = "Key \"".concat(lastRuleId, "\": ").concat(error.message); + throw error; + } + } -// Defitions for deprecation warnings. -const deprecationWarningMessages = { - ESLINT_LEGACY_ECMAFEATURES: - "The 'ecmaFeatures' config file property is deprecated and has no effect.", - ESLINT_PERSONAL_CONFIG_LOAD: - "'~/.eslintrc.*' config files have been deprecated. " + - "Please use a config file per project or the '--config' option.", - ESLINT_PERSONAL_CONFIG_SUPPRESS: - "'~/.eslintrc.*' config files have been deprecated. " + - "Please remove it or add 'root:true' to the config files in your " + - "projects in order to avoid loading '~/.eslintrc.*' accidentally." }; +/** @type {ObjectPropertySchema} */ + +const ecmaVersionSchema = { + merge: "replace", + + validate(value) { + if (typeof value === "number" || value === "latest") { + return; + } + + throw new TypeError("Expected a number or \"latest\"."); + } + +}; +/** @type {ObjectPropertySchema} */ + +const sourceTypeSchema = { + merge: "replace", + + validate(value) { + if (typeof value !== "string" || !/^(?:script|module|commonjs)$/u.test(value)) { + throw new TypeError("Expected \"script\", \"module\", or \"commonjs\"."); + } + } + +}; //----------------------------------------------------------------------------- +// Full schema +//----------------------------------------------------------------------------- + +exports.flatConfigSchema = { + settings: deepObjectAssignSchema, + linterOptions: { + schema: { + noInlineConfig: booleanSchema, + reportUnusedDisableDirectives: booleanSchema + } + }, + languageOptions: { + schema: { + ecmaVersion: ecmaVersionSchema, + sourceType: sourceTypeSchema, + globals: globalsSchema, + parser: parserSchema, + parserOptions: deepObjectAssignSchema + } + }, + processor: processorSchema, + plugins: pluginsSchema, + rules: rulesSchema +}; + +/***/ }), +/* 871 */ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; +/** + * @fileoverview Rule Validator + * @author Nicholas C. Zakas + */ + //----------------------------------------------------------------------------- +// Requirements +//----------------------------------------------------------------------------- -const sourceFileErrorCache = new Set(); +const ajv = __webpack_require__(872)(); + +const { + parseRuleId, + getRuleFromConfig +} = __webpack_require__(859); + +const ruleReplacements = __webpack_require__(858); //----------------------------------------------------------------------------- +// Helpers +//----------------------------------------------------------------------------- /** - * Emits a deprecation warning containing a given filepath. A new deprecation warning is emitted - * for each unique file path, but repeated invocations with the same file path have no effect. - * No warnings are emitted if the `--no-deprecation` or `--no-warnings` Node runtime flags are active. - * @param {string} source The name of the configuration source to report the warning for. - * @param {string} errorCode The warning message to show. + * Throws a helpful error when a rule cannot be found. + * @param {Object} ruleId The rule identifier. + * @param {string} ruleId.pluginName The ID of the rule to find. + * @param {string} ruleId.ruleName The ID of the rule to find. + * @param {Object} config The config to search in. + * @throws {TypeError} For missing plugin or rule. * @returns {void} */ -function emitDeprecationWarning(source, errorCode) { - const cacheKey = JSON.stringify({ source, errorCode }); - if (sourceFileErrorCache.has(cacheKey)) { - return; + +function throwRuleNotFoundError(_ref, config) { + let { + pluginName, + ruleName + } = _ref; + const ruleId = pluginName === "@" ? ruleName : "".concat(pluginName, "/").concat(ruleName); + const errorMessageHeader = "Key \"rules\": Key \"".concat(ruleId, "\""); + let errorMessage = "".concat(errorMessageHeader, ": Could not find plugin \"").concat(pluginName, "\"."); // if the plugin exists then we need to check if the rule exists + + if (config.plugins && config.plugins[pluginName]) { + const replacementRuleName = ruleReplacements.rules[ruleName]; + + if (pluginName === "@" && replacementRuleName) { + errorMessage = "".concat(errorMessageHeader, ": Rule \"").concat(ruleName, "\" was removed and replaced by \"").concat(replacementRuleName, "\"."); + } else { + errorMessage = "".concat(errorMessageHeader, ": Could not find \"").concat(ruleName, "\" in plugin \"").concat(pluginName, "\"."); // otherwise, let's see if we can find the rule name elsewhere + + for (const [otherPluginName, otherPlugin] of Object.entries(config.plugins)) { + if (otherPlugin.rules && otherPlugin.rules[ruleName]) { + errorMessage += " Did you mean \"".concat(otherPluginName, "/").concat(ruleName, "\"?"); + break; + } + } + } // falls through to throw error + + } + + throw new TypeError(errorMessage); +} +/** + * Gets a complete options schema for a rule. + * @param {{create: Function, schema: (Array|null)}} rule A new-style rule object + * @returns {Object} JSON Schema for the rule's options. + */ + + +function getRuleOptionsSchema(rule) { + if (!rule) { + return null; + } + + const schema = rule.schema || rule.meta && rule.meta.schema; + + if (Array.isArray(schema)) { + if (schema.length) { + return { + type: "array", + items: schema, + minItems: 0, + maxItems: schema.length + }; } - sourceFileErrorCache.add(cacheKey); - const rel = path__default["default"].relative(process.cwd(), source); - const message = deprecationWarningMessages[errorCode]; + return { + type: "array", + minItems: 0, + maxItems: 0 + }; + } // Given a full schema, leave it alone + + + return schema || null; +} //----------------------------------------------------------------------------- +// Exports +//----------------------------------------------------------------------------- + +/** + * Implements validation functionality for the rules portion of a config. + */ + + +class RuleValidator { + /** + * Creates a new instance. + */ + constructor() { + /** + * A collection of compiled validators for rules that have already + * been validated. + * @type {WeakMap} + */ + this.validators = new WeakMap(); + } + /** + * Validates all of the rule configurations in a config against each + * rule's schema. + * @param {Object} config The full config to validate. This object must + * contain both the rules section and the plugins section. + * @returns {void} + * @throws {Error} If a rule's configuration does not match its schema. + */ + + + validate(config) { + if (!config.rules) { + return; + } + + for (const [ruleId, ruleOptions] of Object.entries(config.rules)) { + // check for edge case + if (ruleId === "__proto__") { + continue; + } + /* + * If a rule is disabled, we don't do any validation. This allows + * users to safely set any value to 0 or "off" without worrying + * that it will cause a validation error. + * + * Note: ruleOptions is always an array at this point because + * this validation occurs after FlatConfigArray has merged and + * normalized values. + */ + + + if (ruleOptions[0] === 0) { + continue; + } + + const rule = getRuleFromConfig(ruleId, config); + + if (!rule) { + throwRuleNotFoundError(parseRuleId(ruleId), config); + } // Precompile and cache validator the first time + + + if (!this.validators.has(rule)) { + const schema = getRuleOptionsSchema(rule); + + if (schema) { + this.validators.set(rule, ajv.compile(schema)); + } + } + + const validateRule = this.validators.get(rule); + + if (validateRule) { + validateRule(ruleOptions.slice(1)); + + if (validateRule.errors) { + throw new Error("Key \"rules\": Key \"".concat(ruleId, "\": ").concat(validateRule.errors.map(error => "\tValue ".concat(JSON.stringify(error.data), " ").concat(error.message, ".\n")).join(""))); + } + } + } + } - process.emitWarning( - `${message} (found in "${rel}")`, - "DeprecationWarning", - errorCode - ); } +exports.RuleValidator = RuleValidator; + +/***/ }), +/* 872 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; /** * @fileoverview The instance of Ajv validator. * @author Evgeny Poberezkin */ + //------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const Ajv = __webpack_require__(446), + metaSchema = __webpack_require__(873); //------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ + + +module.exports = function () { + let additionalOptions = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + const ajv = new Ajv({ + meta: false, + useDefaults: true, + validateSchema: false, + missingRefs: "ignore", + verbose: true, + schemaId: "auto", + ...additionalOptions + }); + ajv.addMetaSchema(metaSchema); // eslint-disable-next-line no-underscore-dangle -- Ajv's API + + ajv._opts.defaultMeta = metaSchema.id; + return ajv; +}; + +/***/ }), +/* 873 */ +/***/ ((module) => { + +"use strict"; +module.exports = JSON.parse('{"id":"http://json-schema.org/draft-04/schema#","$schema":"http://json-schema.org/draft-04/schema#","description":"Core schema meta-schema","definitions":{"schemaArray":{"type":"array","minItems":1,"items":{"$ref":"#"}},"positiveInteger":{"type":"integer","minimum":0},"positiveIntegerDefault0":{"allOf":[{"$ref":"#/definitions/positiveInteger"},{"default":0}]},"simpleTypes":{"enum":["array","boolean","integer","null","number","object","string"]},"stringArray":{"type":"array","items":{"type":"string"},"minItems":1,"uniqueItems":true}},"type":"object","properties":{"id":{"type":"string"},"$schema":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"},"default":{},"multipleOf":{"type":"number","minimum":0,"exclusiveMinimum":true},"maximum":{"type":"number"},"exclusiveMaximum":{"type":"boolean","default":false},"minimum":{"type":"number"},"exclusiveMinimum":{"type":"boolean","default":false},"maxLength":{"$ref":"#/definitions/positiveInteger"},"minLength":{"$ref":"#/definitions/positiveIntegerDefault0"},"pattern":{"type":"string","format":"regex"},"additionalItems":{"anyOf":[{"type":"boolean"},{"$ref":"#"}],"default":{}},"items":{"anyOf":[{"$ref":"#"},{"$ref":"#/definitions/schemaArray"}],"default":{}},"maxItems":{"$ref":"#/definitions/positiveInteger"},"minItems":{"$ref":"#/definitions/positiveIntegerDefault0"},"uniqueItems":{"type":"boolean","default":false},"maxProperties":{"$ref":"#/definitions/positiveInteger"},"minProperties":{"$ref":"#/definitions/positiveIntegerDefault0"},"required":{"$ref":"#/definitions/stringArray"},"additionalProperties":{"anyOf":[{"type":"boolean"},{"$ref":"#"}],"default":{}},"definitions":{"type":"object","additionalProperties":{"$ref":"#"},"default":{}},"properties":{"type":"object","additionalProperties":{"$ref":"#"},"default":{}},"patternProperties":{"type":"object","additionalProperties":{"$ref":"#"},"default":{}},"dependencies":{"type":"object","additionalProperties":{"anyOf":[{"$ref":"#"},{"$ref":"#/definitions/stringArray"}]}},"enum":{"type":"array","minItems":1,"uniqueItems":true},"type":{"anyOf":[{"$ref":"#/definitions/simpleTypes"},{"type":"array","items":{"$ref":"#/definitions/simpleTypes"},"minItems":1,"uniqueItems":true}]},"format":{"type":"string"},"allOf":{"$ref":"#/definitions/schemaArray"},"anyOf":{"$ref":"#/definitions/schemaArray"},"oneOf":{"$ref":"#/definitions/schemaArray"},"not":{"$ref":"#"}},"dependencies":{"exclusiveMaximum":["maximum"],"exclusiveMinimum":["minimum"]},"default":{}}'); + +/***/ }), +/* 874 */ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { +"use strict"; +/** + * @fileoverview Default configuration + * @author Nicholas C. Zakas + */ + //----------------------------------------------------------------------------- +// Requirements //----------------------------------------------------------------------------- + +const Rules = __webpack_require__(545); //----------------------------------------------------------------------------- // Helpers //----------------------------------------------------------------------------- -/* - * Copied from ajv/lib/refs/json-schema-draft-04.json - * The MIT License (MIT) - * Copyright (c) 2015-2017 Evgeny Poberezkin - */ -const metaSchema = { - id: "http://json-schema.org/draft-04/schema#", - $schema: "http://json-schema.org/draft-04/schema#", - description: "Core schema meta-schema", - definitions: { - schemaArray: { - type: "array", - minItems: 1, - items: { $ref: "#" } - }, - positiveInteger: { - type: "integer", - minimum: 0 - }, - positiveIntegerDefault0: { - allOf: [{ $ref: "#/definitions/positiveInteger" }, { default: 0 }] - }, - simpleTypes: { - enum: ["array", "boolean", "integer", "null", "number", "object", "string"] + +exports.defaultConfig = [{ + plugins: { + "@": { + parsers: { + espree: __webpack_require__(436) + }, + + /* + * Because we try to delay loading rules until absolutely + * necessary, a proxy allows us to hook into the lazy-loading + * aspect of the rules map while still keeping all of the + * relevant configuration inside of the config array. + */ + rules: new Proxy({}, { + get(target, property) { + return Rules.get(property); }, - stringArray: { - type: "array", - items: { type: "string" }, - minItems: 1, - uniqueItems: true + + has(target, property) { + return Rules.has(property); } - }, - type: "object", - properties: { - id: { - type: "string" - }, - $schema: { - type: "string" - }, - title: { - type: "string" - }, - description: { - type: "string" - }, - default: { }, - multipleOf: { - type: "number", - minimum: 0, - exclusiveMinimum: true - }, - maximum: { - type: "number" - }, - exclusiveMaximum: { - type: "boolean", - default: false - }, - minimum: { - type: "number" - }, - exclusiveMinimum: { - type: "boolean", - default: false - }, - maxLength: { $ref: "#/definitions/positiveInteger" }, - minLength: { $ref: "#/definitions/positiveIntegerDefault0" }, - pattern: { - type: "string", - format: "regex" - }, - additionalItems: { - anyOf: [ - { type: "boolean" }, - { $ref: "#" } - ], - default: { } - }, - items: { - anyOf: [ - { $ref: "#" }, - { $ref: "#/definitions/schemaArray" } - ], - default: { } - }, - maxItems: { $ref: "#/definitions/positiveInteger" }, - minItems: { $ref: "#/definitions/positiveIntegerDefault0" }, - uniqueItems: { - type: "boolean", - default: false - }, - maxProperties: { $ref: "#/definitions/positiveInteger" }, - minProperties: { $ref: "#/definitions/positiveIntegerDefault0" }, - required: { $ref: "#/definitions/stringArray" }, - additionalProperties: { - anyOf: [ - { type: "boolean" }, - { $ref: "#" } - ], - default: { } - }, - definitions: { - type: "object", - additionalProperties: { $ref: "#" }, - default: { } - }, - properties: { - type: "object", - additionalProperties: { $ref: "#" }, - default: { } - }, - patternProperties: { - type: "object", - additionalProperties: { $ref: "#" }, - default: { } - }, - dependencies: { - type: "object", - additionalProperties: { - anyOf: [ - { $ref: "#" }, - { $ref: "#/definitions/stringArray" } - ] - } - }, - enum: { - type: "array", - minItems: 1, - uniqueItems: true - }, - type: { - anyOf: [ - { $ref: "#/definitions/simpleTypes" }, - { - type: "array", - items: { $ref: "#/definitions/simpleTypes" }, - minItems: 1, - uniqueItems: true - } - ] - }, - format: { type: "string" }, - allOf: { $ref: "#/definitions/schemaArray" }, - anyOf: { $ref: "#/definitions/schemaArray" }, - oneOf: { $ref: "#/definitions/schemaArray" }, - not: { $ref: "#" } - }, - dependencies: { - exclusiveMaximum: ["maximum"], - exclusiveMinimum: ["minimum"] - }, - default: { } + + }) + } + }, + ignores: ["**/node_modules/**", ".git/**"], + languageOptions: { + ecmaVersion: "latest", + sourceType: "module", + parser: "@/espree", + parserOptions: {} + } +}, { + files: ["**/*.cjs"], + languageOptions: { + sourceType: "commonjs" + } +}]; + +/***/ }), +/* 875 */ +/***/ ((module) => { + +"use strict"; +/** + * @fileoverview Configuration applied when a user configuration extends from + * eslint:recommended. + * @author Nicholas C. Zakas + */ + +/* eslint sort-keys: ["error", "asc"] -- Long, so make more readable */ + +/** @type {import("../lib/shared/types").ConfigData} */ + +module.exports = { + rules: { + "constructor-super": "error", + "for-direction": "error", + "getter-return": "error", + "no-async-promise-executor": "error", + "no-case-declarations": "error", + "no-class-assign": "error", + "no-compare-neg-zero": "error", + "no-cond-assign": "error", + "no-const-assign": "error", + "no-constant-condition": "error", + "no-control-regex": "error", + "no-debugger": "error", + "no-delete-var": "error", + "no-dupe-args": "error", + "no-dupe-class-members": "error", + "no-dupe-else-if": "error", + "no-dupe-keys": "error", + "no-duplicate-case": "error", + "no-empty": "error", + "no-empty-character-class": "error", + "no-empty-pattern": "error", + "no-ex-assign": "error", + "no-extra-boolean-cast": "error", + "no-extra-semi": "error", + "no-fallthrough": "error", + "no-func-assign": "error", + "no-global-assign": "error", + "no-import-assign": "error", + "no-inner-declarations": "error", + "no-invalid-regexp": "error", + "no-irregular-whitespace": "error", + "no-loss-of-precision": "error", + "no-misleading-character-class": "error", + "no-mixed-spaces-and-tabs": "error", + "no-new-symbol": "error", + "no-nonoctal-decimal-escape": "error", + "no-obj-calls": "error", + "no-octal": "error", + "no-prototype-builtins": "error", + "no-redeclare": "error", + "no-regex-spaces": "error", + "no-self-assign": "error", + "no-setter-return": "error", + "no-shadow-restricted-names": "error", + "no-sparse-arrays": "error", + "no-this-before-super": "error", + "no-undef": "error", + "no-unexpected-multiline": "error", + "no-unreachable": "error", + "no-unsafe-finally": "error", + "no-unsafe-negation": "error", + "no-unsafe-optional-chaining": "error", + "no-unused-labels": "error", + "no-unused-vars": "error", + "no-useless-backreference": "error", + "no-useless-catch": "error", + "no-useless-escape": "error", + "no-with": "error", + "require-yield": "error", + "use-isnan": "error", + "valid-typeof": "error" + } +}; + +/***/ }), +/* 876 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; +/** + * @fileoverview Config to enable all rules. + * @author Robert Fletcher + */ + //------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const builtInRules = __webpack_require__(545); //------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + + +const allRules = {}; + +for (const [ruleId, rule] of builtInRules) { + if (!rule.meta.deprecated) { + allRules[ruleId] = "error"; + } +} //------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ + +/** @type {import("../lib/shared/types").ConfigData} */ + + +module.exports = { + rules: allRules +}; + +/***/ }), +/* 877 */ +/***/ ((module) => { + +"use strict"; +/** + * @fileoverview Globals for ecmaVersion/sourceType + * @author Nicholas C. Zakas + */ + //----------------------------------------------------------------------------- +// Globals +//----------------------------------------------------------------------------- + +const commonjs = { + exports: true, + global: false, + module: false, + require: false +}; +const es3 = { + Array: false, + Boolean: false, + constructor: false, + Date: false, + decodeURI: false, + decodeURIComponent: false, + encodeURI: false, + encodeURIComponent: false, + Error: false, + escape: false, + eval: false, + EvalError: false, + Function: false, + hasOwnProperty: false, + Infinity: false, + isFinite: false, + isNaN: false, + isPrototypeOf: false, + Math: false, + NaN: false, + Number: false, + Object: false, + parseFloat: false, + parseInt: false, + propertyIsEnumerable: false, + RangeError: false, + ReferenceError: false, + RegExp: false, + String: false, + SyntaxError: false, + toLocaleString: false, + toString: false, + TypeError: false, + undefined: false, + unescape: false, + URIError: false, + valueOf: false +}; +const es5 = { ...es3, + JSON: false +}; +const es2015 = { ...es5, + ArrayBuffer: false, + DataView: false, + Float32Array: false, + Float64Array: false, + Int16Array: false, + Int32Array: false, + Int8Array: false, + Map: false, + Promise: false, + Proxy: false, + Reflect: false, + Set: false, + Symbol: false, + Uint16Array: false, + Uint32Array: false, + Uint8Array: false, + Uint8ClampedArray: false, + WeakMap: false, + WeakSet: false +}; // no new globals in ES2016 + +const es2016 = { ...es2015 +}; +const es2017 = { ...es2016, + Atomics: false, + SharedArrayBuffer: false +}; // no new globals in ES2018 + +const es2018 = { ...es2017 +}; // no new globals in ES2019 + +const es2019 = { ...es2018 +}; +const es2020 = { ...es2019, + BigInt: false, + BigInt64Array: false, + BigUint64Array: false, + globalThis: false +}; +const es2021 = { ...es2020, + AggregateError: false, + FinalizationRegistry: false, + WeakRef: false +}; +const es2022 = { ...es2021 +}; //----------------------------------------------------------------------------- +// Exports +//----------------------------------------------------------------------------- + +module.exports = { + commonjs, + es3, + es5, + es2015, + es2016, + es2017, + es2018, + es2019, + es2020, + es2021, + es2022 +}; + +/***/ }), +/* 878 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; + + +const { + ESLint +} = __webpack_require__(879); + +module.exports = { + ESLint }; -//------------------------------------------------------------------------------ -// Public Interface -//------------------------------------------------------------------------------ +/***/ }), +/* 879 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; +/* provided dependency */ var process = __webpack_require__(494); +/** + * @fileoverview Main API Class + * @author Kai Cataldo + * @author Toru Nagashima + */ + //------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const path = __webpack_require__(429); + +const fs = __webpack_require__(880); + +const { + promisify +} = __webpack_require__(439); + +const { + CLIEngine, + getCLIEngineInternalSlots +} = __webpack_require__(881); + +const BuiltinRules = __webpack_require__(545); + +const { + Legacy: { + ConfigOps: { + getRuleSeverity + } + } +} = __webpack_require__(883); + +const { + version +} = __webpack_require__(443); //------------------------------------------------------------------------------ +// Typedefs +//------------------------------------------------------------------------------ + +/** @typedef {import("../cli-engine/cli-engine").LintReport} CLIEngineLintReport */ + +/** @typedef {import("../shared/types").DeprecatedRuleInfo} DeprecatedRuleInfo */ + +/** @typedef {import("../shared/types").ConfigData} ConfigData */ + +/** @typedef {import("../shared/types").LintMessage} LintMessage */ + +/** @typedef {import("../shared/types").Plugin} Plugin */ + +/** @typedef {import("../shared/types").Rule} Rule */ + +/** + * The main formatter object. + * @typedef Formatter + * @property {function(LintResult[]): string | Promise} format format function. + */ + +/** + * The options with which to configure the ESLint instance. + * @typedef {Object} ESLintOptions + * @property {boolean} [allowInlineConfig] Enable or disable inline configuration comments. + * @property {ConfigData} [baseConfig] Base config object, extended by all configs used with this instance + * @property {boolean} [cache] Enable result caching. + * @property {string} [cacheLocation] The cache file to use instead of .eslintcache. + * @property {"metadata" | "content"} [cacheStrategy] The strategy used to detect changed files. + * @property {string} [cwd] The value to use for the current working directory. + * @property {boolean} [errorOnUnmatchedPattern] If `false` then `ESLint#lintFiles()` doesn't throw even if no target files found. Defaults to `true`. + * @property {string[]} [extensions] An array of file extensions to check. + * @property {boolean|Function} [fix] Execute in autofix mode. If a function, should return a boolean. + * @property {string[]} [fixTypes] Array of rule types to apply fixes for. + * @property {boolean} [globInputPaths] Set to false to skip glob resolution of input file paths to lint (default: true). If false, each input file paths is assumed to be a non-glob path to an existing file. + * @property {boolean} [ignore] False disables use of .eslintignore. + * @property {string} [ignorePath] The ignore file to use instead of .eslintignore. + * @property {ConfigData} [overrideConfig] Override config object, overrides all configs used with this instance + * @property {string} [overrideConfigFile] The configuration file to use. + * @property {Record|null} [plugins] Preloaded plugins. This is a map-like object, keys are plugin IDs and each value is implementation. + * @property {"error" | "warn" | "off"} [reportUnusedDisableDirectives] the severity to report unused eslint-disable directives. + * @property {string} [resolvePluginsRelativeTo] The folder where plugins should be resolved from, defaulting to the CWD. + * @property {string[]} [rulePaths] An array of directories to load custom rules from. + * @property {boolean} [useEslintrc] False disables looking for .eslintrc.* files. + */ + +/** + * A rules metadata object. + * @typedef {Object} RulesMeta + * @property {string} id The plugin ID. + * @property {Object} definition The plugin definition. + */ + +/** + * A linting result. + * @typedef {Object} LintResult + * @property {string} filePath The path to the file that was linted. + * @property {LintMessage[]} messages All of the messages for the result. + * @property {number} errorCount Number of errors for the result. + * @property {number} warningCount Number of warnings for the result. + * @property {number} fixableErrorCount Number of fixable errors for the result. + * @property {number} fixableWarningCount Number of fixable warnings for the result. + * @property {string} [source] The source code of the file that was linted. + * @property {string} [output] The source code of the file that was linted, with as many fixes applied as possible. + * @property {DeprecatedRuleInfo[]} usedDeprecatedRules The list of used deprecated rules. + */ + +/** + * Private members for the `ESLint` instance. + * @typedef {Object} ESLintPrivateMembers + * @property {CLIEngine} cliEngine The wrapped CLIEngine instance. + * @property {ESLintOptions} options The options used to instantiate the ESLint instance. + */ +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + + +const writeFile = promisify(fs.writeFile); +/** + * The map with which to store private class members. + * @type {WeakMap} + */ + +const privateMembersMap = new WeakMap(); +/** + * Check if a given value is a non-empty string or not. + * @param {any} x The value to check. + * @returns {boolean} `true` if `x` is a non-empty string. + */ + +function isNonEmptyString(x) { + return typeof x === "string" && x.trim() !== ""; +} +/** + * Check if a given value is an array of non-empty stringss or not. + * @param {any} x The value to check. + * @returns {boolean} `true` if `x` is an array of non-empty stringss. + */ + + +function isArrayOfNonEmptyString(x) { + return Array.isArray(x) && x.every(isNonEmptyString); +} +/** + * Check if a given value is a valid fix type or not. + * @param {any} x The value to check. + * @returns {boolean} `true` if `x` is valid fix type. + */ + + +function isFixType(x) { + return x === "directive" || x === "problem" || x === "suggestion" || x === "layout"; +} +/** + * Check if a given value is an array of fix types or not. + * @param {any} x The value to check. + * @returns {boolean} `true` if `x` is an array of fix types. + */ + + +function isFixTypeArray(x) { + return Array.isArray(x) && x.every(isFixType); +} +/** + * The error for invalid options. + */ + + +class ESLintInvalidOptionsError extends Error { + constructor(messages) { + super("Invalid Options:\n- ".concat(messages.join("\n- "))); + this.code = "ESLINT_INVALID_OPTIONS"; + Error.captureStackTrace(this, ESLintInvalidOptionsError); + } + +} +/** + * Validates and normalizes options for the wrapped CLIEngine instance. + * @param {ESLintOptions} options The options to process. + * @throws {ESLintInvalidOptionsError} If of any of a variety of type errors. + * @returns {ESLintOptions} The normalized options. + */ + + +function processOptions(_ref) { + let { + allowInlineConfig = true, + // ← we cannot use `overrideConfig.noInlineConfig` instead because `allowInlineConfig` has side-effect that suppress warnings that show inline configs are ignored. + baseConfig = null, + cache = false, + cacheLocation = ".eslintcache", + cacheStrategy = "metadata", + cwd = process.cwd(), + errorOnUnmatchedPattern = true, + extensions = null, + // ← should be null by default because if it's an array then it suppresses RFC20 feature. + fix = false, + fixTypes = null, + // ← should be null by default because if it's an array then it suppresses rules that don't have the `meta.type` property. + globInputPaths = true, + ignore = true, + ignorePath = null, + // ← should be null by default because if it's a string then it may throw ENOENT. + overrideConfig = null, + overrideConfigFile = null, + plugins = {}, + reportUnusedDisableDirectives = null, + // ← should be null by default because if it's a string then it overrides the 'reportUnusedDisableDirectives' setting in config files. And we cannot use `overrideConfig.reportUnusedDisableDirectives` instead because we cannot configure the `error` severity with that. + resolvePluginsRelativeTo = null, + // ← should be null by default because if it's a string then it suppresses RFC47 feature. + rulePaths = [], + useEslintrc = true, + ...unknownOptions + } = _ref; + const errors = []; + const unknownOptionKeys = Object.keys(unknownOptions); + + if (unknownOptionKeys.length >= 1) { + errors.push("Unknown options: ".concat(unknownOptionKeys.join(", "))); + + if (unknownOptionKeys.includes("cacheFile")) { + errors.push("'cacheFile' has been removed. Please use the 'cacheLocation' option instead."); + } + + if (unknownOptionKeys.includes("configFile")) { + errors.push("'configFile' has been removed. Please use the 'overrideConfigFile' option instead."); + } + + if (unknownOptionKeys.includes("envs")) { + errors.push("'envs' has been removed. Please use the 'overrideConfig.env' option instead."); + } + + if (unknownOptionKeys.includes("globals")) { + errors.push("'globals' has been removed. Please use the 'overrideConfig.globals' option instead."); + } + + if (unknownOptionKeys.includes("ignorePattern")) { + errors.push("'ignorePattern' has been removed. Please use the 'overrideConfig.ignorePatterns' option instead."); + } + + if (unknownOptionKeys.includes("parser")) { + errors.push("'parser' has been removed. Please use the 'overrideConfig.parser' option instead."); + } + + if (unknownOptionKeys.includes("parserOptions")) { + errors.push("'parserOptions' has been removed. Please use the 'overrideConfig.parserOptions' option instead."); + } + + if (unknownOptionKeys.includes("rules")) { + errors.push("'rules' has been removed. Please use the 'overrideConfig.rules' option instead."); + } + } + + if (typeof allowInlineConfig !== "boolean") { + errors.push("'allowInlineConfig' must be a boolean."); + } -var ajvOrig = (additionalOptions = {}) => { - const ajv = new Ajv__default["default"]({ - meta: false, - useDefaults: true, - validateSchema: false, - missingRefs: "ignore", - verbose: true, - schemaId: "auto", - ...additionalOptions - }); + if (typeof baseConfig !== "object") { + errors.push("'baseConfig' must be an object or null."); + } - ajv.addMetaSchema(metaSchema); - // eslint-disable-next-line no-underscore-dangle - ajv._opts.defaultMeta = metaSchema.id; + if (typeof cache !== "boolean") { + errors.push("'cache' must be a boolean."); + } - return ajv; -}; + if (!isNonEmptyString(cacheLocation)) { + errors.push("'cacheLocation' must be a non-empty string."); + } -/** - * @fileoverview Defines a schema for configs. - * @author Sylvan Mably - */ + if (cacheStrategy !== "metadata" && cacheStrategy !== "content") { + errors.push("'cacheStrategy' must be any of \"metadata\", \"content\"."); + } -const baseConfigProperties = { - $schema: { type: "string" }, - env: { type: "object" }, - extends: { $ref: "#/definitions/stringOrStrings" }, - globals: { type: "object" }, - overrides: { - type: "array", - items: { $ref: "#/definitions/overrideConfig" }, - additionalItems: false - }, - parser: { type: ["string", "null"] }, - parserOptions: { type: "object" }, - plugins: { type: "array" }, - processor: { type: "string" }, - rules: { type: "object" }, - settings: { type: "object" }, - noInlineConfig: { type: "boolean" }, - reportUnusedDisableDirectives: { type: "boolean" }, + if (!isNonEmptyString(cwd) || !path.isAbsolute(cwd)) { + errors.push("'cwd' must be an absolute path."); + } - ecmaFeatures: { type: "object" } // deprecated; logs a warning when used -}; + if (typeof errorOnUnmatchedPattern !== "boolean") { + errors.push("'errorOnUnmatchedPattern' must be a boolean."); + } -const configSchema = { - definitions: { - stringOrStrings: { - oneOf: [ - { type: "string" }, - { - type: "array", - items: { type: "string" }, - additionalItems: false - } - ] - }, - stringOrStringsRequired: { - oneOf: [ - { type: "string" }, - { - type: "array", - items: { type: "string" }, - additionalItems: false, - minItems: 1 - } - ] - }, + if (!isArrayOfNonEmptyString(extensions) && extensions !== null) { + errors.push("'extensions' must be an array of non-empty strings or null."); + } - // Config at top-level. - objectConfig: { - type: "object", - properties: { - root: { type: "boolean" }, - ignorePatterns: { $ref: "#/definitions/stringOrStrings" }, - ...baseConfigProperties - }, - additionalProperties: false - }, + if (typeof fix !== "boolean" && typeof fix !== "function") { + errors.push("'fix' must be a boolean or a function."); + } - // Config in `overrides`. - overrideConfig: { - type: "object", - properties: { - excludedFiles: { $ref: "#/definitions/stringOrStrings" }, - files: { $ref: "#/definitions/stringOrStringsRequired" }, - ...baseConfigProperties - }, - required: ["files"], - additionalProperties: false - } - }, + if (fixTypes !== null && !isFixTypeArray(fixTypes)) { + errors.push("'fixTypes' must be an array of any of \"directive\", \"problem\", \"suggestion\", and \"layout\"."); + } - $ref: "#/definitions/objectConfig" -}; + if (typeof globInputPaths !== "boolean") { + errors.push("'globInputPaths' must be a boolean."); + } + + if (typeof ignore !== "boolean") { + errors.push("'ignore' must be a boolean."); + } + + if (!isNonEmptyString(ignorePath) && ignorePath !== null) { + errors.push("'ignorePath' must be a non-empty string or null."); + } + + if (typeof overrideConfig !== "object") { + errors.push("'overrideConfig' must be an object or null."); + } + + if (!isNonEmptyString(overrideConfigFile) && overrideConfigFile !== null) { + errors.push("'overrideConfigFile' must be a non-empty string or null."); + } + + if (typeof plugins !== "object") { + errors.push("'plugins' must be an object or null."); + } else if (plugins !== null && Object.keys(plugins).includes("")) { + errors.push("'plugins' must not include an empty string."); + } + if (Array.isArray(plugins)) { + errors.push("'plugins' doesn't add plugins to configuration to load. Please use the 'overrideConfig.plugins' option instead."); + } + + if (reportUnusedDisableDirectives !== "error" && reportUnusedDisableDirectives !== "warn" && reportUnusedDisableDirectives !== "off" && reportUnusedDisableDirectives !== null) { + errors.push("'reportUnusedDisableDirectives' must be any of \"error\", \"warn\", \"off\", and null."); + } + + if (!isNonEmptyString(resolvePluginsRelativeTo) && resolvePluginsRelativeTo !== null) { + errors.push("'resolvePluginsRelativeTo' must be a non-empty string or null."); + } + + if (!isArrayOfNonEmptyString(rulePaths)) { + errors.push("'rulePaths' must be an array of non-empty strings."); + } + + if (typeof useEslintrc !== "boolean") { + errors.push("'useEslintrc' must be a boolean."); + } + + if (errors.length > 0) { + throw new ESLintInvalidOptionsError(errors); + } + + return { + allowInlineConfig, + baseConfig, + cache, + cacheLocation, + cacheStrategy, + configFile: overrideConfigFile, + cwd, + errorOnUnmatchedPattern, + extensions, + fix, + fixTypes, + globInputPaths, + ignore, + ignorePath, + reportUnusedDisableDirectives, + resolvePluginsRelativeTo, + rulePaths, + useEslintrc + }; +} /** - * @fileoverview Defines environment settings and globals. - * @author Elan Shanker + * Check if a value has one or more properties and that value is not undefined. + * @param {any} obj The value to check. + * @returns {boolean} `true` if `obj` has one or more properties that that value is not undefined. */ -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ +function hasDefinedProperty(obj) { + if (typeof obj === "object" && obj !== null) { + for (const key in obj) { + if (typeof obj[key] !== "undefined") { + return true; + } + } + } + + return false; +} /** - * Get the object that has difference. - * @param {Record} current The newer object. - * @param {Record} prev The older object. - * @returns {Record} The difference object. + * Create rulesMeta object. + * @param {Map} rules a map of rules from which to generate the object. + * @returns {Object} metadata for all enabled rules. */ -function getDiff(current, prev) { - const retv = {}; - for (const [key, value] of Object.entries(current)) { - if (!Object.hasOwnProperty.call(prev, key)) { - retv[key] = value; - } - } - return retv; +function createRulesMeta(rules) { + return Array.from(rules).reduce((retVal, _ref2) => { + let [id, rule] = _ref2; + retVal[id] = rule.meta; + return retVal; + }, {}); } +/** @type {WeakMap} */ -const newGlobals2015 = getDiff(globals__default["default"].es2015, globals__default["default"].es5); // 19 variables such as Promise, Map, ... -const newGlobals2017 = { - Atomics: false, - SharedArrayBuffer: false -}; -const newGlobals2020 = { - BigInt: false, - BigInt64Array: false, - BigUint64Array: false, - globalThis: false -}; -const newGlobals2021 = { - AggregateError: false, - FinalizationRegistry: false, - WeakRef: false -}; +const usedDeprecatedRulesCache = new WeakMap(); +/** + * Create used deprecated rule list. + * @param {CLIEngine} cliEngine The CLIEngine instance. + * @param {string} maybeFilePath The absolute path to a lint target file or `""`. + * @returns {DeprecatedRuleInfo[]} The used deprecated rule list. + */ -//------------------------------------------------------------------------------ -// Public Interface -//------------------------------------------------------------------------------ +function getOrFindUsedDeprecatedRules(cliEngine, maybeFilePath) { + const { + configArrayFactory, + options: { + cwd + } + } = getCLIEngineInternalSlots(cliEngine); + const filePath = path.isAbsolute(maybeFilePath) ? maybeFilePath : path.join(cwd, "__placeholder__.js"); + const configArray = configArrayFactory.getConfigArrayForFile(filePath); + const config = configArray.extractConfig(filePath); // Most files use the same config, so cache it. -/** @type {Map} */ -var environments = new Map(Object.entries({ + if (!usedDeprecatedRulesCache.has(config)) { + const pluginRules = configArray.pluginRules; + const retv = []; - // Language - builtin: { - globals: globals__default["default"].es5 - }, - es6: { - globals: newGlobals2015, - parserOptions: { - ecmaVersion: 6 - } - }, - es2015: { - globals: newGlobals2015, - parserOptions: { - ecmaVersion: 6 - } - }, - es2017: { - globals: { ...newGlobals2015, ...newGlobals2017 }, - parserOptions: { - ecmaVersion: 8 - } - }, - es2020: { - globals: { ...newGlobals2015, ...newGlobals2017, ...newGlobals2020 }, - parserOptions: { - ecmaVersion: 11 - } - }, - es2021: { - globals: { ...newGlobals2015, ...newGlobals2017, ...newGlobals2020, ...newGlobals2021 }, - parserOptions: { - ecmaVersion: 12 - } - }, + for (const [ruleId, ruleConf] of Object.entries(config.rules)) { + if (getRuleSeverity(ruleConf) === 0) { + continue; + } - // Platforms - browser: { - globals: globals__default["default"].browser - }, - node: { - globals: globals__default["default"].node, - parserOptions: { - ecmaFeatures: { - globalReturn: true - } - } - }, - "shared-node-browser": { - globals: globals__default["default"]["shared-node-browser"] - }, - worker: { - globals: globals__default["default"].worker - }, - serviceworker: { - globals: globals__default["default"].serviceworker - }, + const rule = pluginRules.get(ruleId) || BuiltinRules.get(ruleId); + const meta = rule && rule.meta; - // Frameworks - commonjs: { - globals: globals__default["default"].commonjs, - parserOptions: { - ecmaFeatures: { - globalReturn: true - } - } - }, - amd: { - globals: globals__default["default"].amd - }, - mocha: { - globals: globals__default["default"].mocha - }, - jasmine: { - globals: globals__default["default"].jasmine - }, - jest: { - globals: globals__default["default"].jest - }, - phantomjs: { - globals: globals__default["default"].phantomjs - }, - jquery: { - globals: globals__default["default"].jquery - }, - qunit: { - globals: globals__default["default"].qunit - }, - prototypejs: { - globals: globals__default["default"].prototypejs - }, - shelljs: { - globals: globals__default["default"].shelljs - }, - meteor: { - globals: globals__default["default"].meteor - }, - mongo: { - globals: globals__default["default"].mongo - }, - protractor: { - globals: globals__default["default"].protractor - }, - applescript: { - globals: globals__default["default"].applescript - }, - nashorn: { - globals: globals__default["default"].nashorn - }, - atomtest: { - globals: globals__default["default"].atomtest - }, - embertest: { - globals: globals__default["default"].embertest - }, - webextensions: { - globals: globals__default["default"].webextensions - }, - greasemonkey: { - globals: globals__default["default"].greasemonkey + if (meta && meta.deprecated) { + retv.push({ + ruleId, + replacedBy: meta.replacedBy || [] + }); + } } -})); + usedDeprecatedRulesCache.set(config, Object.freeze(retv)); + } + + return usedDeprecatedRulesCache.get(config); +} /** - * @fileoverview Validates configs. - * @author Brandon Mills + * Processes the linting results generated by a CLIEngine linting report to + * match the ESLint class's API. + * @param {CLIEngine} cliEngine The CLIEngine instance. + * @param {CLIEngineLintReport} report The CLIEngine linting report to process. + * @returns {LintResult[]} The processed linting results. */ -const ajv = ajvOrig(); -const ruleValidators = new WeakMap(); -const noop = Function.prototype; +function processCLIEngineLintReport(cliEngine, _ref3) { + let { + results + } = _ref3; + const descriptor = { + configurable: true, + enumerable: true, -//------------------------------------------------------------------------------ -// Private -//------------------------------------------------------------------------------ -let validateSchema; -const severityMap = { - error: 2, - warn: 1, - off: 0 -}; + get() { + return getOrFindUsedDeprecatedRules(cliEngine, this.filePath); + } -const validated = new WeakSet(); + }; -//----------------------------------------------------------------------------- -// Exports -//----------------------------------------------------------------------------- + for (const result of results) { + Object.defineProperty(result, "usedDeprecatedRules", descriptor); + } -class ConfigValidator { - constructor({ builtInRules = new Map() } = {}) { - this.builtInRules = builtInRules; - } + return results; +} +/** + * An Array.prototype.sort() compatible compare function to order results by their file path. + * @param {LintResult} a The first lint result. + * @param {LintResult} b The second lint result. + * @returns {number} An integer representing the order in which the two results should occur. + */ - /** - * Gets a complete options schema for a rule. - * @param {{create: Function, schema: (Array|null)}} rule A new-style rule object - * @returns {Object} JSON Schema for the rule's options. - */ - getRuleOptionsSchema(rule) { - if (!rule) { - return null; - } - const schema = rule.schema || rule.meta && rule.meta.schema; +function compareResultsByFilePath(a, b) { + if (a.filePath < b.filePath) { + return -1; + } - // Given a tuple of schemas, insert warning level at the beginning - if (Array.isArray(schema)) { - if (schema.length) { - return { - type: "array", - items: schema, - minItems: 0, - maxItems: schema.length - }; - } - return { - type: "array", - minItems: 0, - maxItems: 0 - }; + if (a.filePath > b.filePath) { + return 1; + } - } + return 0; +} +/** + * Main API. + */ - // Given a full schema, leave it alone - return schema || null; - } - /** - * Validates a rule's severity and returns the severity value. Throws an error if the severity is invalid. - * @param {options} options The given options for the rule. - * @returns {number|string} The rule's severity value +class ESLint { + /** + * Creates a new instance of the main ESLint API. + * @param {ESLintOptions} options The options for this instance. + */ + constructor() { + let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + const processedOptions = processOptions(options); + const cliEngine = new CLIEngine(processedOptions, { + preloadedPlugins: options.plugins + }); + const { + configArrayFactory, + lastConfigArrays + } = getCLIEngineInternalSlots(cliEngine); + let updated = false; + /* + * Address `overrideConfig` to set override config. + * Operate the `configArrayFactory` internal slot directly because this + * functionality doesn't exist as the public API of CLIEngine. */ - validateRuleSeverity(options) { - const severity = Array.isArray(options) ? options[0] : options; - const normSeverity = typeof severity === "string" ? severityMap[severity.toLowerCase()] : severity; - if (normSeverity === 0 || normSeverity === 1 || normSeverity === 2) { - return normSeverity; - } + if (hasDefinedProperty(options.overrideConfig)) { + configArrayFactory.setOverrideConfig(options.overrideConfig); + updated = true; + } // Update caches. - throw new Error(`\tSeverity should be one of the following: 0 = off, 1 = warn, 2 = error (you passed '${util__default["default"].inspect(severity).replace(/'/gu, "\"").replace(/\n/gu, "")}').\n`); - } + if (updated) { + configArrayFactory.clearCache(); + lastConfigArrays[0] = configArrayFactory.getConfigArrayForFile(); + } // Initialize private properties. - /** - * Validates the non-severity options passed to a rule, based on its schema. - * @param {{create: Function}} rule The rule to validate - * @param {Array} localOptions The options for the rule, excluding severity - * @returns {void} - */ - validateRuleSchema(rule, localOptions) { - if (!ruleValidators.has(rule)) { - const schema = this.getRuleOptionsSchema(rule); - if (schema) { - ruleValidators.set(rule, ajv.compile(schema)); - } - } + privateMembersMap.set(this, { + cliEngine, + options: processedOptions + }); + } + /** + * The version text. + * @type {string} + */ - const validateRule = ruleValidators.get(rule); - if (validateRule) { - validateRule(localOptions); - if (validateRule.errors) { - throw new Error(validateRule.errors.map( - error => `\tValue ${JSON.stringify(error.data)} ${error.message}.\n` - ).join("")); - } - } + static get version() { + return version; + } + /** + * Outputs fixes from the given results to files. + * @param {LintResult[]} results The lint results. + * @returns {Promise} Returns a promise that is used to track side effects. + */ + + + static async outputFixes(results) { + if (!Array.isArray(results)) { + throw new Error("'results' must be an array"); } - /** - * Validates a rule's options against its schema. - * @param {{create: Function}|null} rule The rule that the config is being validated for - * @param {string} ruleId The rule's unique name. - * @param {Array|number} options The given options for the rule. - * @param {string|null} source The name of the configuration source to report in any errors. If null or undefined, - * no source is prepended to the message. - * @returns {void} - */ - validateRuleOptions(rule, ruleId, options, source = null) { - try { - const severity = this.validateRuleSeverity(options); + await Promise.all(results.filter(result => { + if (typeof result !== "object" || result === null) { + throw new Error("'results' must include only objects"); + } - if (severity !== 0) { - this.validateRuleSchema(rule, Array.isArray(options) ? options.slice(1) : []); - } - } catch (err) { - const enhancedMessage = `Configuration for rule "${ruleId}" is invalid:\n${err.message}`; + return typeof result.output === "string" && path.isAbsolute(result.filePath); + }).map(r => writeFile(r.filePath, r.output))); + } + /** + * Returns results that only contains errors. + * @param {LintResult[]} results The results to filter. + * @returns {LintResult[]} The filtered results. + */ - if (typeof source === "string") { - throw new Error(`${source}:\n\t${enhancedMessage}`); - } else { - throw new Error(enhancedMessage); - } - } + + static getErrorResults(results) { + return CLIEngine.getErrorResults(results); + } + /** + * Returns meta objects for each rule represented in the lint results. + * @param {LintResult[]} results The results to fetch rules meta for. + * @returns {Object} A mapping of ruleIds to rule meta objects. + */ + + + getRulesMetaForResults(results) { + const resultRuleIds = new Set(); // first gather all ruleIds from all results + + for (const result of results) { + for (const { + ruleId + } of result.messages) { + resultRuleIds.add(ruleId); + } + } // create a map of all rules in the results + + + const { + cliEngine + } = privateMembersMap.get(this); + const rules = cliEngine.getRules(); + const resultRules = new Map(); + + for (const [ruleId, rule] of rules) { + if (resultRuleIds.has(ruleId)) { + resultRules.set(ruleId, rule); + } } - /** - * Validates an environment object - * @param {Object} environment The environment config object to validate. - * @param {string} source The name of the configuration source to report in any errors. - * @param {function(envId:string): Object} [getAdditionalEnv] A map from strings to loaded environments. - * @returns {void} - */ - validateEnvironment( - environment, - source, - getAdditionalEnv = noop - ) { + return createRulesMeta(resultRules); + } + /** + * Executes the current configuration on an array of file and directory names. + * @param {string[]} patterns An array of file and directory names. + * @returns {Promise} The results of linting the file patterns given. + */ - // not having an environment is ok - if (!environment) { - return; - } - Object.keys(environment).forEach(id => { - const env = getAdditionalEnv(id) || environments.get(id) || null; + async lintFiles(patterns) { + if (!isNonEmptyString(patterns) && !isArrayOfNonEmptyString(patterns)) { + throw new Error("'patterns' must be a non-empty string or an array of non-empty strings"); + } + + const { + cliEngine + } = privateMembersMap.get(this); + return processCLIEngineLintReport(cliEngine, cliEngine.executeOnFiles(patterns)); + } + /** + * Executes the current configuration on text. + * @param {string} code A string of JavaScript code to lint. + * @param {Object} [options] The options. + * @param {string} [options.filePath] The path to the file of the source code. + * @param {boolean} [options.warnIgnored] When set to true, warn if given filePath is an ignored path. + * @returns {Promise} The results of linting the string of code given. + */ + - if (!env) { - const message = `${source}:\n\tEnvironment key "${id}" is unknown\n`; + async lintText(code) { + let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - throw new Error(message); - } - }); + if (typeof code !== "string") { + throw new Error("'code' must be a string"); } - /** - * Validates a rules config object - * @param {Object} rulesConfig The rules config object to validate. - * @param {string} source The name of the configuration source to report in any errors. - * @param {function(ruleId:string): Object} getAdditionalRule A map from strings to loaded rules - * @returns {void} - */ - validateRules( - rulesConfig, - source, - getAdditionalRule = noop - ) { - if (!rulesConfig) { - return; - } + if (typeof options !== "object") { + throw new Error("'options' must be an object, null, or undefined"); + } - Object.keys(rulesConfig).forEach(id => { - const rule = getAdditionalRule(id) || this.builtInRules.get(id) || null; + const { + filePath, + warnIgnored = false, + ...unknownOptions + } = options || {}; + const unknownOptionKeys = Object.keys(unknownOptions); - this.validateRuleOptions(rule, id, rulesConfig[id], source); - }); + if (unknownOptionKeys.length > 0) { + throw new Error("'options' must not include the unknown option(s): ".concat(unknownOptionKeys.join(", "))); } - /** - * Validates a `globals` section of a config file - * @param {Object} globalsConfig The `globals` section - * @param {string|null} source The name of the configuration source to report in the event of an error. - * @returns {void} - */ - validateGlobals(globalsConfig, source = null) { - if (!globalsConfig) { - return; - } + if (filePath !== void 0 && !isNonEmptyString(filePath)) { + throw new Error("'options.filePath' must be a non-empty string or undefined"); + } - Object.entries(globalsConfig) - .forEach(([configuredGlobal, configuredValue]) => { - try { - normalizeConfigGlobal(configuredValue); - } catch (err) { - throw new Error(`ESLint configuration of global '${configuredGlobal}' in ${source} is invalid:\n${err.message}`); - } - }); + if (typeof warnIgnored !== "boolean") { + throw new Error("'options.warnIgnored' must be a boolean or undefined"); } - /** - * Validate `processor` configuration. - * @param {string|undefined} processorName The processor name. - * @param {string} source The name of config file. - * @param {function(id:string): Processor} getProcessor The getter of defined processors. - * @returns {void} - */ - validateProcessor(processorName, source, getProcessor) { - if (processorName && !getProcessor(processorName)) { - throw new Error(`ESLint configuration of processor in '${source}' is invalid: '${processorName}' was not found.`); - } + const { + cliEngine + } = privateMembersMap.get(this); + return processCLIEngineLintReport(cliEngine, cliEngine.executeOnText(code, filePath, warnIgnored)); + } + /** + * Returns the formatter representing the given formatter name. + * @param {string} [name] The name of the formatter to load. + * The following values are allowed: + * - `undefined` ... Load `stylish` builtin formatter. + * - A builtin formatter name ... Load the builtin formatter. + * - A thirdparty formatter name: + * - `foo` → `eslint-formatter-foo` + * - `@foo` → `@foo/eslint-formatter` + * - `@foo/bar` → `@foo/eslint-formatter-bar` + * - A file path ... Load the file. + * @returns {Promise} A promise resolving to the formatter object. + * This promise will be rejected if the given formatter was not found or not + * a function. + */ + + + async loadFormatter() { + let name = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : "stylish"; + + if (typeof name !== "string") { + throw new Error("'name' must be a string"); } - /** - * Formats an array of schema validation errors. - * @param {Array} errors An array of error messages to format. - * @returns {string} Formatted error message - */ - formatErrors(errors) { - return errors.map(error => { - if (error.keyword === "additionalProperties") { - const formattedPropertyPath = error.dataPath.length ? `${error.dataPath.slice(1)}.${error.params.additionalProperty}` : error.params.additionalProperty; + const { + cliEngine, + options + } = privateMembersMap.get(this); + const formatter = cliEngine.getFormatter(name); - return `Unexpected top-level property "${formattedPropertyPath}"`; - } - if (error.keyword === "type") { - const formattedField = error.dataPath.slice(1); - const formattedExpectedType = Array.isArray(error.schema) ? error.schema.join("/") : error.schema; - const formattedValue = JSON.stringify(error.data); + if (typeof formatter !== "function") { + throw new Error("Formatter must be a function, but got a ".concat(typeof formatter, ".")); + } - return `Property "${formattedField}" is the wrong type (expected ${formattedExpectedType} but got \`${formattedValue}\`)`; + return { + /** + * The main formatter method. + * @param {LintResults[]} results The lint results to format. + * @returns {string | Promise} The formatted lint results. + */ + format(results) { + let rulesMeta = null; + results.sort(compareResultsByFilePath); + return formatter(results, { + get cwd() { + return options.cwd; + }, + + get rulesMeta() { + if (!rulesMeta) { + rulesMeta = createRulesMeta(cliEngine.getRules()); } - const field = error.dataPath[0] === "." ? error.dataPath.slice(1) : error.dataPath; + return rulesMeta; + } - return `"${field}" ${error.message}. Value: ${JSON.stringify(error.data)}`; - }).map(message => `\t- ${message}.\n`).join(""); - } + }); + } - /** - * Validates the top level properties of the config object. - * @param {Object} config The config object to validate. - * @param {string} source The name of the configuration source to report in any errors. - * @returns {void} - */ - validateConfigSchema(config, source = null) { - validateSchema = validateSchema || ajv.compile(configSchema); + }; + } + /** + * Returns a configuration object for the given file based on the CLI options. + * This is the same logic used by the ESLint CLI executable to determine + * configuration for each file it processes. + * @param {string} filePath The path of the file to retrieve a config object for. + * @returns {Promise} A configuration object for the file. + */ - if (!validateSchema(config)) { - throw new Error(`ESLint configuration in ${source} is invalid:\n${this.formatErrors(validateSchema.errors)}`); - } - if (Object.hasOwnProperty.call(config, "ecmaFeatures")) { - emitDeprecationWarning(source, "ESLINT_LEGACY_ECMAFEATURES"); - } + async calculateConfigForFile(filePath) { + if (!isNonEmptyString(filePath)) { + throw new Error("'filePath' must be a non-empty string"); } - /** - * Validates an entire config object. - * @param {Object} config The config object to validate. - * @param {string} source The name of the configuration source to report in any errors. - * @param {function(ruleId:string): Object} [getAdditionalRule] A map from strings to loaded rules. - * @param {function(envId:string): Object} [getAdditionalEnv] A map from strings to loaded envs. - * @returns {void} - */ - validate(config, source, getAdditionalRule, getAdditionalEnv) { - this.validateConfigSchema(config, source); - this.validateRules(config.rules, source, getAdditionalRule); - this.validateEnvironment(config.env, source, getAdditionalEnv); - this.validateGlobals(config.globals, source); + const { + cliEngine + } = privateMembersMap.get(this); + return cliEngine.getConfigForFile(filePath); + } + /** + * Checks if a given path is ignored by ESLint. + * @param {string} filePath The path of the file to check. + * @returns {Promise} Whether or not the given path is ignored. + */ - for (const override of config.overrides || []) { - this.validateRules(override.rules, source, getAdditionalRule); - this.validateEnvironment(override.env, source, getAdditionalEnv); - this.validateGlobals(config.globals, source); - } + + async isPathIgnored(filePath) { + if (!isNonEmptyString(filePath)) { + throw new Error("'filePath' must be a non-empty string"); } - /** - * Validate config array object. - * @param {ConfigArray} configArray The config array to validate. - * @returns {void} - */ - validateConfigArray(configArray) { - const getPluginEnv = Map.prototype.get.bind(configArray.pluginEnvironments); - const getPluginProcessor = Map.prototype.get.bind(configArray.pluginProcessors); - const getPluginRule = Map.prototype.get.bind(configArray.pluginRules); + const { + cliEngine + } = privateMembersMap.get(this); + return cliEngine.isPathIgnored(filePath); + } - // Validate. - for (const element of configArray) { - if (validated.has(element)) { - continue; - } - validated.add(element); +} //------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ - this.validateEnvironment(element.env, element.name, getPluginEnv); - this.validateGlobals(element.globals, element.name); - this.validateProcessor(element.processor, element.name, getPluginProcessor); - this.validateRules(element.rules, element.name, getPluginRule); - } - } -} +module.exports = { + ESLint, -/** - * @fileoverview Common helpers for naming of plugins, formatters and configs - */ + /** + * Get the private class members of a given ESLint instance for tests. + * @param {ESLint} instance The ESLint instance to get. + * @returns {ESLintPrivateMembers} The instance's private class members. + */ + getESLintPrivateMembers(instance) { + return privateMembersMap.get(instance); + } -const NAMESPACE_REGEX = /^@.*\//iu; +}; + +/***/ }), +/* 880 */ +/***/ ((module) => { + +"use strict"; +module.exports = require("fs"); + +/***/ }), +/* 881 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +"use strict"; +/* provided dependency */ var process = __webpack_require__(494); /** - * Brings package name to correct format based on prefix - * @param {string} name The name of the package. - * @param {string} prefix Can be either "eslint-plugin", "eslint-config" or "eslint-formatter" - * @returns {string} Normalized name of the package - * @private + * @fileoverview Main CLI object. + * @author Nicholas C. Zakas */ -function normalizePackageName(name, prefix) { - let normalizedName = name; - /** - * On Windows, name can come in with Windows slashes instead of Unix slashes. - * Normalize to Unix first to avoid errors later on. - * https://github.com/eslint/eslint/issues/5644 - */ - if (normalizedName.includes("\\")) { - normalizedName = normalizedName.replace(/\\/gu, "/"); - } +/* + * The CLI object should *not* call process.exit() directly. It should only return + * exit codes. This allows other programs to use the CLI object and still control + * when the program exits. + */ +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ - if (normalizedName.charAt(0) === "@") { +const fs = __webpack_require__(880); - /** - * it's a scoped package - * package name is the prefix, or just a username - */ - const scopedPackageShortcutRegex = new RegExp(`^(@[^/]+)(?:/(?:${prefix})?)?$`, "u"), - scopedPackageNameRegex = new RegExp(`^${prefix}(-|$)`, "u"); +const path = __webpack_require__(429); - if (scopedPackageShortcutRegex.test(normalizedName)) { - normalizedName = normalizedName.replace(scopedPackageShortcutRegex, `$1/${prefix}`); - } else if (!scopedPackageNameRegex.test(normalizedName.split("/")[1])) { +const defaultOptions = __webpack_require__(882); - /** - * for scoped packages, insert the prefix after the first / unless - * the path is already @scope/eslint or @scope/eslint-xxx-yyy - */ - normalizedName = normalizedName.replace(/^@([^/]+)\/(.*)$/u, `@$1/${prefix}-$2`); - } - } else if (!normalizedName.startsWith(`${prefix}-`)) { - normalizedName = `${prefix}-${normalizedName}`; - } +const pkg = __webpack_require__(443); - return normalizedName; -} +const { + Legacy: { + ConfigOps, + naming, + CascadingConfigArrayFactory, + IgnorePattern, + getUsedExtractedConfigs, + ModuleResolver + } +} = __webpack_require__(883); -/** - * Removes the prefix from a fullname. - * @param {string} fullname The term which may have the prefix. - * @param {string} prefix The prefix to remove. - * @returns {string} The term without prefix. - */ -function getShorthandName(fullname, prefix) { - if (fullname[0] === "@") { - let matchResult = new RegExp(`^(@[^/]+)/${prefix}$`, "u").exec(fullname); +const { + FileEnumerator +} = __webpack_require__(893); - if (matchResult) { - return matchResult[1]; - } +const { + Linter +} = __webpack_require__(897); - matchResult = new RegExp(`^(@[^/]+)/${prefix}-(.+)$`, "u").exec(fullname); - if (matchResult) { - return `${matchResult[1]}/${matchResult[2]}`; - } - } else if (fullname.startsWith(`${prefix}-`)) { - return fullname.slice(prefix.length + 1); - } +const builtInRules = __webpack_require__(545); - return fullname; -} +const loadRules = __webpack_require__(898); + +const hash = __webpack_require__(900); + +const LintResultCache = __webpack_require__(902); + +const debug = __webpack_require__(496)("eslint:cli-engine"); + +const validFixTypes = new Set(["directive", "problem", "suggestion", "layout"]); //------------------------------------------------------------------------------ +// Typedefs +//------------------------------------------------------------------------------ +// For VSCode IntelliSense + +/** @typedef {import("../shared/types").ConfigData} ConfigData */ + +/** @typedef {import("../shared/types").DeprecatedRuleInfo} DeprecatedRuleInfo */ + +/** @typedef {import("../shared/types").LintMessage} LintMessage */ + +/** @typedef {import("../shared/types").ParserOptions} ParserOptions */ + +/** @typedef {import("../shared/types").Plugin} Plugin */ + +/** @typedef {import("../shared/types").RuleConf} RuleConf */ + +/** @typedef {import("../shared/types").Rule} Rule */ + +/** @typedef {ReturnType} ConfigArray */ + +/** @typedef {ReturnType} ExtractedConfig */ /** - * Gets the scope (namespace) of a term. - * @param {string} term The term which may have the namespace. - * @returns {string} The namespace of the term if it has one. + * The options to configure a CLI engine with. + * @typedef {Object} CLIEngineOptions + * @property {boolean} [allowInlineConfig] Enable or disable inline configuration comments. + * @property {ConfigData} [baseConfig] Base config object, extended by all configs used with this CLIEngine instance + * @property {boolean} [cache] Enable result caching. + * @property {string} [cacheLocation] The cache file to use instead of .eslintcache. + * @property {string} [configFile] The configuration file to use. + * @property {string} [cwd] The value to use for the current working directory. + * @property {string[]} [envs] An array of environments to load. + * @property {string[]|null} [extensions] An array of file extensions to check. + * @property {boolean|Function} [fix] Execute in autofix mode. If a function, should return a boolean. + * @property {string[]} [fixTypes] Array of rule types to apply fixes for. + * @property {string[]} [globals] An array of global variables to declare. + * @property {boolean} [ignore] False disables use of .eslintignore. + * @property {string} [ignorePath] The ignore file to use instead of .eslintignore. + * @property {string|string[]} [ignorePattern] One or more glob patterns to ignore. + * @property {boolean} [useEslintrc] False disables looking for .eslintrc + * @property {string} [parser] The name of the parser to use. + * @property {ParserOptions} [parserOptions] An object of parserOption settings to use. + * @property {string[]} [plugins] An array of plugins to load. + * @property {Record} [rules] An object of rules to use. + * @property {string[]} [rulePaths] An array of directories to load custom rules from. + * @property {boolean} [reportUnusedDisableDirectives] `true` adds reports for unused eslint-disable directives + * @property {boolean} [globInputPaths] Set to false to skip glob resolution of input file paths to lint (default: true). If false, each input file paths is assumed to be a non-glob path to an existing file. + * @property {string} [resolvePluginsRelativeTo] The folder where plugins should be resolved from, defaulting to the CWD */ -function getNamespaceFromTerm(term) { - const match = term.match(NAMESPACE_REGEX); - return match ? match[0] : ""; -} +/** + * A linting result. + * @typedef {Object} LintResult + * @property {string} filePath The path to the file that was linted. + * @property {LintMessage[]} messages All of the messages for the result. + * @property {number} errorCount Number of errors for the result. + * @property {number} warningCount Number of warnings for the result. + * @property {number} fixableErrorCount Number of fixable errors for the result. + * @property {number} fixableWarningCount Number of fixable warnings for the result. + * @property {string} [source] The source code of the file that was linted. + * @property {string} [output] The source code of the file that was linted, with as many fixes applied as possible. + */ -var naming = { - __proto__: null, - normalizePackageName: normalizePackageName, - getShorthandName: getShorthandName, - getNamespaceFromTerm: getNamespaceFromTerm -}; +/** + * Linting results. + * @typedef {Object} LintReport + * @property {LintResult[]} results All of the result. + * @property {number} errorCount Number of errors for the result. + * @property {number} warningCount Number of warnings for the result. + * @property {number} fixableErrorCount Number of fixable errors for the result. + * @property {number} fixableWarningCount Number of fixable warnings for the result. + * @property {DeprecatedRuleInfo[]} usedDeprecatedRules The list of used deprecated rules. + */ /** - * Utility for resolving a module relative to another module - * @author Teddy Katz + * Private data for CLIEngine. + * @typedef {Object} CLIEngineInternalSlots + * @property {Map} additionalPluginPool The map for additional plugins. + * @property {string} cacheFilePath The path to the cache of lint results. + * @property {CascadingConfigArrayFactory} configArrayFactory The factory of configs. + * @property {(filePath: string) => boolean} defaultIgnores The default predicate function to check if a file ignored or not. + * @property {FileEnumerator} fileEnumerator The file enumerator. + * @property {ConfigArray[]} lastConfigArrays The list of config arrays that the last `executeOnFiles` or `executeOnText` used. + * @property {LintResultCache|null} lintResultCache The cache of lint results. + * @property {Linter} linter The linter instance which has loaded rules. + * @property {CLIEngineOptions} options The normalized options of this instance. */ +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ -/* - * `Module.createRequire` is added in v12.2.0. It supports URL as well. - * We only support the case where the argument is a filepath, not a URL. +/** @type {WeakMap} */ + +const internalSlotsMap = new WeakMap(); +/** + * Determines if each fix type in an array is supported by ESLint and throws + * an error if not. + * @param {string[]} fixTypes An array of fix types to check. + * @returns {void} + * @throws {Error} If an invalid fix type is found. */ -const createRequire = Module__default["default"].createRequire; +function validateFixTypes(fixTypes) { + for (const fixType of fixTypes) { + if (!validFixTypes.has(fixType)) { + throw new Error("Invalid fix type \"".concat(fixType, "\" found.")); + } + } +} /** - * Resolves a Node module relative to another module - * @param {string} moduleName The name of a Node module, or a path to a Node module. - * @param {string} relativeToPath An absolute path indicating the module that `moduleName` should be resolved relative to. This must be - * a file rather than a directory, but the file need not actually exist. - * @returns {string} The absolute path that would result from calling `require.resolve(moduleName)` in a file located at `relativeToPath` + * It will calculate the error and warning count for collection of messages per file + * @param {LintMessage[]} messages Collection of messages + * @returns {Object} Contains the stats + * @private */ -function resolve(moduleName, relativeToPath) { - try { - return createRequire(relativeToPath).resolve(moduleName); - } catch (error) { - // This `if` block is for older Node.js than 12.0.0. We can remove this block in the future. - if ( - typeof error === "object" && - error !== null && - error.code === "MODULE_NOT_FOUND" && - !error.requireStack && - error.message.includes(moduleName) - ) { - error.message += `\nRequire stack:\n- ${relativeToPath}`; - } - throw error; + +function calculateStatsPerFile(messages) { + return messages.reduce((stat, message) => { + if (message.fatal || message.severity === 2) { + stat.errorCount++; + + if (message.fatal) { + stat.fatalErrorCount++; + } + + if (message.fix) { + stat.fixableErrorCount++; + } + } else { + stat.warningCount++; + + if (message.fix) { + stat.fixableWarningCount++; + } } + + return stat; + }, { + errorCount: 0, + fatalErrorCount: 0, + warningCount: 0, + fixableErrorCount: 0, + fixableWarningCount: 0 + }); } +/** + * It will calculate the error and warning count for collection of results from all files + * @param {LintResult[]} results Collection of messages from all the files + * @returns {Object} Contains the stats + * @private + */ -var ModuleResolver = { - __proto__: null, - resolve: resolve -}; +function calculateStatsPerRun(results) { + return results.reduce((stat, result) => { + stat.errorCount += result.errorCount; + stat.fatalErrorCount += result.fatalErrorCount; + stat.warningCount += result.warningCount; + stat.fixableErrorCount += result.fixableErrorCount; + stat.fixableWarningCount += result.fixableWarningCount; + return stat; + }, { + errorCount: 0, + fatalErrorCount: 0, + warningCount: 0, + fixableErrorCount: 0, + fixableWarningCount: 0 + }); +} /** - * @fileoverview `IgnorePattern` class. - * - * `IgnorePattern` class has the set of glob patterns and the base path. - * - * It provides two static methods. - * - * - `IgnorePattern.createDefaultIgnore(cwd)` - * Create the default predicate function. - * - `IgnorePattern.createIgnore(ignorePatterns)` - * Create the predicate function from multiple `IgnorePattern` objects. - * - * It provides two properties and a method. - * - * - `patterns` - * The glob patterns that ignore to lint. - * - `basePath` - * The base path of the glob patterns. If absolute paths existed in the - * glob patterns, those are handled as relative paths to the base path. - * - `getPatternsRelativeTo(basePath)` - * Get `patterns` as modified for a given base path. It modifies the - * absolute paths in the patterns as prepending the difference of two base - * paths. - * - * `ConfigArrayFactory` creates `IgnorePattern` objects when it processes - * `ignorePatterns` properties. - * - * @author Toru Nagashima + * Processes an source code using ESLint. + * @param {Object} config The config object. + * @param {string} config.text The source code to verify. + * @param {string} config.cwd The path to the current working directory. + * @param {string|undefined} config.filePath The path to the file of `text`. If this is undefined, it uses ``. + * @param {ConfigArray} config.config The config. + * @param {boolean} config.fix If `true` then it does fix. + * @param {boolean} config.allowInlineConfig If `true` then it uses directive comments. + * @param {boolean} config.reportUnusedDisableDirectives If `true` then it reports unused `eslint-disable` comments. + * @param {FileEnumerator} config.fileEnumerator The file enumerator to check if a path is a target or not. + * @param {Linter} config.linter The linter instance to verify. + * @returns {LintResult} The result of linting. + * @private */ -const debug$3 = debugOrig__default["default"]("eslintrc:ignore-pattern"); -/** @typedef {ReturnType} Ignore */ +function verifyText(_ref) { + let { + text, + cwd, + filePath: providedFilePath, + config, + fix, + allowInlineConfig, + reportUnusedDisableDirectives, + fileEnumerator, + linter + } = _ref; + const filePath = providedFilePath || ""; + debug("Lint ".concat(filePath)); + /* + * Verify. + * `config.extractConfig(filePath)` requires an absolute path, but `linter` + * doesn't know CWD, so it gives `linter` an absolute path always. + */ -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ + const filePathToVerify = filePath === "" ? path.join(cwd, filePath) : filePath; + const { + fixed, + messages, + output + } = linter.verifyAndFix(text, config, { + allowInlineConfig, + filename: filePathToVerify, + fix, + reportUnusedDisableDirectives, -/** - * Get the path to the common ancestor directory of given paths. - * @param {string[]} sourcePaths The paths to calculate the common ancestor. - * @returns {string} The path to the common ancestor directory. - */ -function getCommonAncestorPath(sourcePaths) { - let result = sourcePaths[0]; + /** + * Check if the linter should adopt a given code block or not. + * @param {string} blockFilename The virtual filename of a code block. + * @returns {boolean} `true` if the linter should adopt the code block. + */ + filterCodeBlock(blockFilename) { + return fileEnumerator.isTargetPath(blockFilename); + } - for (let i = 1; i < sourcePaths.length; ++i) { - const a = result; - const b = sourcePaths[i]; + }); // Tweak and return. - // Set the shorter one (it's the common ancestor if one includes the other). - result = a.length < b.length ? a : b; + const result = { + filePath, + messages, + ...calculateStatsPerFile(messages) + }; - // Set the common ancestor. - for (let j = 0, lastSepPos = 0; j < a.length && j < b.length; ++j) { - if (a[j] !== b[j]) { - result = a.slice(0, lastSepPos); - break; - } - if (a[j] === path__default["default"].sep) { - lastSepPos = j; - } - } - } + if (fixed) { + result.output = output; + } - let resolvedResult = result || path__default["default"].sep; + if (result.errorCount + result.warningCount > 0 && typeof result.output === "undefined") { + result.source = text; + } - // if Windows common ancestor is root of drive must have trailing slash to be absolute. - if (resolvedResult && resolvedResult.endsWith(":") && process.platform === "win32") { - resolvedResult += path__default["default"].sep; - } - return resolvedResult; + return result; } - /** - * Make relative path. - * @param {string} from The source path to get relative path. - * @param {string} to The destination path to get relative path. - * @returns {string} The relative path. + * Returns result with warning by ignore settings + * @param {string} filePath File path of checked code + * @param {string} baseDir Absolute path of base directory + * @returns {LintResult} Result with single warning + * @private */ -function relative(from, to) { - const relPath = path__default["default"].relative(from, to); - if (path__default["default"].sep === "/") { - return relPath; - } - return relPath.split(path__default["default"].sep).join("/"); -} -/** - * Get the trailing slash if existed. - * @param {string} filePath The path to check. - * @returns {string} The trailing slash if existed. - */ -function dirSuffix(filePath) { - const isDir = ( - filePath.endsWith(path__default["default"].sep) || - (process.platform === "win32" && filePath.endsWith("/")) - ); +function createIgnoreResult(filePath, baseDir) { + let message; + const isHidden = filePath.split(path.sep).find(segment => /^\./u.test(segment)); + const isInNodeModules = baseDir && path.relative(baseDir, filePath).startsWith("node_modules"); - return isDir ? "/" : ""; -} + if (isHidden) { + message = "File ignored by default. Use a negated ignore pattern (like \"--ignore-pattern '!'\") to override."; + } else if (isInNodeModules) { + message = "File ignored by default. Use \"--ignore-pattern '!node_modules/*'\" to override."; + } else { + message = "File ignored because of a matching ignore pattern. Use \"--no-ignore\" to override."; + } -const DefaultPatterns = Object.freeze(["/**/node_modules/*"]); -const DotPatterns = Object.freeze([".*", "!.eslintrc.*", "!../"]); + return { + filePath: path.resolve(filePath), + messages: [{ + fatal: false, + severity: 1, + message + }], + errorCount: 0, + warningCount: 1, + fixableErrorCount: 0, + fixableWarningCount: 0 + }; +} +/** + * Get a rule. + * @param {string} ruleId The rule ID to get. + * @param {ConfigArray[]} configArrays The config arrays that have plugin rules. + * @returns {Rule|null} The rule or null. + */ -//------------------------------------------------------------------------------ -// Public -//------------------------------------------------------------------------------ -class IgnorePattern { +function getRule(ruleId, configArrays) { + for (const configArray of configArrays) { + const rule = configArray.pluginRules.get(ruleId); - /** - * The default patterns. - * @type {string[]} - */ - static get DefaultPatterns() { - return DefaultPatterns; + if (rule) { + return rule; } + } - /** - * Create the default predicate function. - * @param {string} cwd The current working directory. - * @returns {((filePath:string, dot:boolean) => boolean) & {basePath:string; patterns:string[]}} - * The preficate function. - * The first argument is an absolute path that is checked. - * The second argument is the flag to not ignore dotfiles. - * If the predicate function returned `true`, it means the path should be ignored. - */ - static createDefaultIgnore(cwd) { - return this.createIgnore([new IgnorePattern(DefaultPatterns, cwd)]); - } + return builtInRules.get(ruleId) || null; +} +/** + * Checks whether a message's rule type should be fixed. + * @param {LintMessage} message The message to check. + * @param {ConfigArray[]} lastConfigArrays The list of config arrays that the last `executeOnFiles` or `executeOnText` used. + * @param {string[]} fixTypes An array of fix types to check. + * @returns {boolean} Whether the message should be fixed. + */ - /** - * Create the predicate function from multiple `IgnorePattern` objects. - * @param {IgnorePattern[]} ignorePatterns The list of ignore patterns. - * @returns {((filePath:string, dot?:boolean) => boolean) & {basePath:string; patterns:string[]}} - * The preficate function. - * The first argument is an absolute path that is checked. - * The second argument is the flag to not ignore dotfiles. - * If the predicate function returned `true`, it means the path should be ignored. - */ - static createIgnore(ignorePatterns) { - debug$3("Create with: %o", ignorePatterns); - const basePath = getCommonAncestorPath(ignorePatterns.map(p => p.basePath)); - const patterns = [].concat( - ...ignorePatterns.map(p => p.getPatternsRelativeTo(basePath)) - ); - const ig = ignore__default["default"]().add([...DotPatterns, ...patterns]); - const dotIg = ignore__default["default"]().add(patterns); +function shouldMessageBeFixed(message, lastConfigArrays, fixTypes) { + if (!message.ruleId) { + return fixTypes.has("directive"); + } - debug$3(" processed: %o", { basePath, patterns }); + const rule = message.ruleId && getRule(message.ruleId, lastConfigArrays); + return Boolean(rule && rule.meta && fixTypes.has(rule.meta.type)); +} +/** + * Collect used deprecated rules. + * @param {ConfigArray[]} usedConfigArrays The config arrays which were used. + * @returns {IterableIterator} Used deprecated rules. + */ - return Object.assign( - (filePath, dot = false) => { - assert__default["default"](path__default["default"].isAbsolute(filePath), "'filePath' should be an absolute path."); - const relPathRaw = relative(basePath, filePath); - const relPath = relPathRaw && (relPathRaw + dirSuffix(filePath)); - const adoptedIg = dot ? dotIg : ig; - const result = relPath !== "" && adoptedIg.ignores(relPath); - debug$3("Check", { filePath, dot, relativePath: relPath, result }); - return result; - }, - { basePath, patterns } - ); - } +function* iterateRuleDeprecationWarnings(usedConfigArrays) { + const processedRuleIds = new Set(); // Flatten used configs. - /** - * Initialize a new `IgnorePattern` instance. - * @param {string[]} patterns The glob patterns that ignore to lint. - * @param {string} basePath The base path of `patterns`. - */ - constructor(patterns, basePath) { - assert__default["default"](path__default["default"].isAbsolute(basePath), "'basePath' should be an absolute path."); + /** @type {ExtractedConfig[]} */ - /** - * The glob patterns that ignore to lint. - * @type {string[]} - */ - this.patterns = patterns; + const configs = [].concat(...usedConfigArrays.map(getUsedExtractedConfigs)); // Traverse rule configs. - /** - * The base path of `patterns`. - * @type {string} - */ - this.basePath = basePath; + for (const config of configs) { + for (const [ruleId, ruleConfig] of Object.entries(config.rules)) { + // Skip if it was processed. + if (processedRuleIds.has(ruleId)) { + continue; + } - /** - * If `true` then patterns which don't start with `/` will match the paths to the outside of `basePath`. Defaults to `false`. - * - * It's set `true` for `.eslintignore`, `package.json`, and `--ignore-path` for backward compatibility. - * It's `false` as-is for `ignorePatterns` property in config files. - * @type {boolean} - */ - this.loose = false; - } + processedRuleIds.add(ruleId); // Skip if it's not used. - /** - * Get `patterns` as modified for a given base path. It modifies the - * absolute paths in the patterns as prepending the difference of two base - * paths. - * @param {string} newBasePath The base path. - * @returns {string[]} Modifired patterns. - */ - getPatternsRelativeTo(newBasePath) { - assert__default["default"](path__default["default"].isAbsolute(newBasePath), "'newBasePath' should be an absolute path."); - const { basePath, loose, patterns } = this; + if (!ConfigOps.getRuleSeverity(ruleConfig)) { + continue; + } - if (newBasePath === basePath) { - return patterns; - } - const prefix = `/${relative(newBasePath, basePath)}`; + const rule = getRule(ruleId, usedConfigArrays); // Skip if it's not deprecated. - return patterns.map(pattern => { - const negative = pattern.startsWith("!"); - const head = negative ? "!" : ""; - const body = negative ? pattern.slice(1) : pattern; + if (!(rule && rule.meta && rule.meta.deprecated)) { + continue; + } // This rule was used and deprecated. - if (body.startsWith("/") || body.startsWith("../")) { - return `${head}${prefix}${body}`; - } - return loose ? pattern : `${head}${prefix}/**/${body}`; - }); + + yield { + ruleId, + replacedBy: rule.meta.replacedBy || [] + }; } + } } - /** - * @fileoverview `ExtractedConfig` class. - * - * `ExtractedConfig` class expresses a final configuration for a specific file. - * - * It provides one method. - * - * - `toCompatibleObjectAsConfigFileContent()` - * Convert this configuration to the compatible object as the content of - * config files. It converts the loaded parser and plugins to strings. - * `CLIEngine#getConfigForFile(filePath)` method uses this method. - * - * `ConfigArray#extractConfig(filePath)` creates a `ExtractedConfig` instance. - * - * @author Toru Nagashima + * Checks if the given message is an error message. + * @param {LintMessage} message The message to check. + * @returns {boolean} Whether or not the message is an error message. + * @private */ -// For VSCode intellisense -/** @typedef {import("../../shared/types").ConfigData} ConfigData */ -/** @typedef {import("../../shared/types").GlobalConf} GlobalConf */ -/** @typedef {import("../../shared/types").SeverityConf} SeverityConf */ -/** @typedef {import("./config-dependency").DependentParser} DependentParser */ -/** @typedef {import("./config-dependency").DependentPlugin} DependentPlugin */ -/** - * Check if `xs` starts with `ys`. - * @template T - * @param {T[]} xs The array to check. - * @param {T[]} ys The array that may be the first part of `xs`. - * @returns {boolean} `true` if `xs` starts with `ys`. - */ -function startsWith(xs, ys) { - return xs.length >= ys.length && ys.every((y, i) => y === xs[i]); +function isErrorMessage(message) { + return message.severity === 2; } - /** - * The class for extracted config data. + * return the cacheFile to be used by eslint, based on whether the provided parameter is + * a directory or looks like a directory (ends in `path.sep`), in which case the file + * name will be the `cacheFile/.cache_hashOfCWD` + * + * if cacheFile points to a file or looks like a file then in will just use that file + * @param {string} cacheFile The name of file to be used to store the cache + * @param {string} cwd Current working directory + * @returns {string} the resolved path to the cache file */ -class ExtractedConfig { - constructor() { - - /** - * The config name what `noInlineConfig` setting came from. - * @type {string} - */ - this.configNameOfNoInlineConfig = ""; - - /** - * Environments. - * @type {Record} - */ - this.env = {}; - - /** - * Global variables. - * @type {Record} - */ - this.globals = {}; - - /** - * The glob patterns that ignore to lint. - * @type {(((filePath:string, dot?:boolean) => boolean) & { basePath:string; patterns:string[] }) | undefined} - */ - this.ignores = void 0; - - /** - * The flag that disables directive comments. - * @type {boolean|undefined} - */ - this.noInlineConfig = void 0; - - /** - * Parser definition. - * @type {DependentParser|null} - */ - this.parser = null; - /** - * Options for the parser. - * @type {Object} - */ - this.parserOptions = {}; - /** - * Plugin definitions. - * @type {Record} - */ - this.plugins = {}; +function getCacheFile(cacheFile, cwd) { + /* + * make sure the path separators are normalized for the environment/os + * keeping the trailing path separator if present + */ + const normalizedCacheFile = path.normalize(cacheFile); + const resolvedCacheFile = path.resolve(cwd, normalizedCacheFile); + const looksLikeADirectory = normalizedCacheFile.slice(-1) === path.sep; + /** + * return the name for the cache file in case the provided parameter is a directory + * @returns {string} the resolved path to the cacheFile + */ - /** - * Processor ID. - * @type {string|null} - */ - this.processor = null; + function getCacheFileForDirectory() { + return path.join(resolvedCacheFile, ".cache_".concat(hash(cwd))); + } - /** - * The flag that reports unused `eslint-disable` directive comments. - * @type {boolean|undefined} - */ - this.reportUnusedDisableDirectives = void 0; + let fileStats; - /** - * Rule settings. - * @type {Record} - */ - this.rules = {}; + try { + fileStats = fs.lstatSync(resolvedCacheFile); + } catch { + fileStats = null; + } + /* + * in case the file exists we need to verify if the provided path + * is a directory or a file. If it is a directory we want to create a file + * inside that directory + */ - /** - * Shared settings. - * @type {Object} - */ - this.settings = {}; - } - /** - * Convert this config to the compatible object as a config file content. - * @returns {ConfigData} The converted object. + if (fileStats) { + /* + * is a directory or is a file, but the original file the user provided + * looks like a directory but `path.resolve` removed the `last path.sep` + * so we need to still treat this like a directory */ - toCompatibleObjectAsConfigFileContent() { - const { - /* eslint-disable no-unused-vars */ - configNameOfNoInlineConfig: _ignore1, - processor: _ignore2, - /* eslint-enable no-unused-vars */ - ignores, - ...config - } = this; - - config.parser = config.parser && config.parser.filePath; - config.plugins = Object.keys(config.plugins).filter(Boolean).reverse(); - config.ignorePatterns = ignores ? ignores.patterns : []; - - // Strip the default patterns from `ignorePatterns`. - if (startsWith(config.ignorePatterns, IgnorePattern.DefaultPatterns)) { - config.ignorePatterns = - config.ignorePatterns.slice(IgnorePattern.DefaultPatterns.length); - } + if (fileStats.isDirectory() || looksLikeADirectory) { + return getCacheFileForDirectory(); + } // is file so just use that file - return config; - } -} -/** - * @fileoverview `ConfigArray` class. - * - * `ConfigArray` class expresses the full of a configuration. It has the entry - * config file, base config files that were extended, loaded parsers, and loaded - * plugins. - * - * `ConfigArray` class provides three properties and two methods. - * - * - `pluginEnvironments` - * - `pluginProcessors` - * - `pluginRules` - * The `Map` objects that contain the members of all plugins that this - * config array contains. Those map objects don't have mutation methods. - * Those keys are the member ID such as `pluginId/memberName`. - * - `isRoot()` - * If `true` then this configuration has `root:true` property. - * - `extractConfig(filePath)` - * Extract the final configuration for a given file. This means merging - * every config array element which that `criteria` property matched. The - * `filePath` argument must be an absolute path. - * - * `ConfigArrayFactory` provides the loading logic of config files. - * - * @author Toru Nagashima - */ + return resolvedCacheFile; + } + /* + * here we known the file or directory doesn't exist, + * so we will try to infer if its a directory if it looks like a directory + * for the current operating system. + */ + // if the last character passed is a path separator we assume is a directory -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ -// Define types for VSCode IntelliSense. -/** @typedef {import("../../shared/types").Environment} Environment */ -/** @typedef {import("../../shared/types").GlobalConf} GlobalConf */ -/** @typedef {import("../../shared/types").RuleConf} RuleConf */ -/** @typedef {import("../../shared/types").Rule} Rule */ -/** @typedef {import("../../shared/types").Plugin} Plugin */ -/** @typedef {import("../../shared/types").Processor} Processor */ -/** @typedef {import("./config-dependency").DependentParser} DependentParser */ -/** @typedef {import("./config-dependency").DependentPlugin} DependentPlugin */ -/** @typedef {import("./override-tester")["OverrideTester"]} OverrideTester */ + if (looksLikeADirectory) { + return getCacheFileForDirectory(); + } + return resolvedCacheFile; +} /** - * @typedef {Object} ConfigArrayElement - * @property {string} name The name of this config element. - * @property {string} filePath The path to the source file of this config element. - * @property {InstanceType|null} criteria The tester for the `files` and `excludedFiles` of this config element. - * @property {Record|undefined} env The environment settings. - * @property {Record|undefined} globals The global variable settings. - * @property {IgnorePattern|undefined} ignorePattern The ignore patterns. - * @property {boolean|undefined} noInlineConfig The flag that disables directive comments. - * @property {DependentParser|undefined} parser The parser loader. - * @property {Object|undefined} parserOptions The parser options. - * @property {Record|undefined} plugins The plugin loaders. - * @property {string|undefined} processor The processor name to refer plugin's processor. - * @property {boolean|undefined} reportUnusedDisableDirectives The flag to report unused `eslint-disable` comments. - * @property {boolean|undefined} root The flag to express root. - * @property {Record|undefined} rules The rule settings - * @property {Object|undefined} settings The shared settings. - * @property {"config" | "ignore" | "implicit-processor"} type The element type. + * Convert a string array to a boolean map. + * @param {string[]|null} keys The keys to assign true. + * @param {boolean} defaultValue The default value for each property. + * @param {string} displayName The property name which is used in error message. + * @throws {Error} Requires array. + * @returns {Record} The boolean map. */ -/** - * @typedef {Object} ConfigArrayInternalSlots - * @property {Map} cache The cache to extract configs. - * @property {ReadonlyMap|null} envMap The map from environment ID to environment definition. - * @property {ReadonlyMap|null} processorMap The map from processor ID to environment definition. - * @property {ReadonlyMap|null} ruleMap The map from rule ID to rule definition. - */ -/** @type {WeakMap} */ -const internalSlotsMap$2 = new class extends WeakMap { - get(key) { - let value = super.get(key); +function toBooleanMap(keys, defaultValue, displayName) { + if (keys && !Array.isArray(keys)) { + throw new Error("".concat(displayName, " must be an array.")); + } - if (!value) { - value = { - cache: new Map(), - envMap: null, - processorMap: null, - ruleMap: null - }; - super.set(key, value); - } + if (keys && keys.length > 0) { + return keys.reduce((map, def) => { + const [key, value] = def.split(":"); - return value; - } -}(); + if (key !== "__proto__") { + map[key] = value === void 0 ? defaultValue : value === "true"; + } + + return map; + }, {}); + } + return void 0; +} /** - * Get the indices which are matched to a given file. - * @param {ConfigArrayElement[]} elements The elements. - * @param {string} filePath The path to a target file. - * @returns {number[]} The indices. + * Create a config data from CLI options. + * @param {CLIEngineOptions} options The options + * @returns {ConfigData|null} The created config data. */ -function getMatchedIndices(elements, filePath) { - const indices = []; - for (let i = elements.length - 1; i >= 0; --i) { - const element = elements[i]; - if (!element.criteria || (filePath && element.criteria.test(filePath))) { - indices.push(i); - } - } +function createConfigDataFromOptions(options) { + const { + ignorePattern, + parser, + parserOptions, + plugins, + rules + } = options; + const env = toBooleanMap(options.envs, true, "envs"); + const globals = toBooleanMap(options.globals, false, "globals"); - return indices; -} + if (env === void 0 && globals === void 0 && (ignorePattern === void 0 || ignorePattern.length === 0) && parser === void 0 && parserOptions === void 0 && plugins === void 0 && rules === void 0) { + return null; + } -/** - * Check if a value is a non-null object. - * @param {any} x The value to check. - * @returns {boolean} `true` if the value is a non-null object. - */ -function isNonNullObject(x) { - return typeof x === "object" && x !== null; + return { + env, + globals, + ignorePatterns: ignorePattern, + parser, + parserOptions, + plugins, + rules + }; } - /** - * Merge two objects. - * - * Assign every property values of `y` to `x` if `x` doesn't have the property. - * If `x`'s property value is an object, it does recursive. - * @param {Object} target The destination to merge - * @param {Object|undefined} source The source to merge. - * @returns {void} + * Checks whether a directory exists at the given location + * @param {string} resolvedPath A path from the CWD + * @throws {Error} As thrown by `fs.statSync` or `fs.isDirectory`. + * @returns {boolean} `true` if a directory exists */ -function mergeWithoutOverwrite(target, source) { - if (!isNonNullObject(source)) { - return; - } - for (const key of Object.keys(source)) { - if (key === "__proto__") { - continue; - } - if (isNonNullObject(target[key])) { - mergeWithoutOverwrite(target[key], source[key]); - } else if (target[key] === void 0) { - if (isNonNullObject(source[key])) { - target[key] = Array.isArray(source[key]) ? [] : {}; - mergeWithoutOverwrite(target[key], source[key]); - } else if (source[key] !== void 0) { - target[key] = source[key]; - } - } +function directoryExists(resolvedPath) { + try { + return fs.statSync(resolvedPath).isDirectory(); + } catch (error) { + if (error && (error.code === "ENOENT" || error.code === "ENOTDIR")) { + return false; } -} + + throw error; + } +} //------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ /** - * The error for plugin conflicts. + * Core CLI. */ -class PluginConflictError extends Error { - /** - * Initialize this error object. - * @param {string} pluginId The plugin ID. - * @param {{filePath:string, importerName:string}[]} plugins The resolved plugins. - */ - constructor(pluginId, plugins) { - super(`Plugin "${pluginId}" was conflicted between ${plugins.map(p => `"${p.importerName}"`).join(" and ")}.`); - this.messageTemplate = "plugin-conflict"; - this.messageData = { pluginId, plugins }; + +class CLIEngine { + /** + * Creates a new instance of the core CLI engine. + * @param {CLIEngineOptions} providedOptions The options for this instance. + * @param {Object} [additionalData] Additional settings that are not CLIEngineOptions. + * @param {Record|null} [additionalData.preloadedPlugins] Preloaded plugins. + */ + constructor(providedOptions) { + let { + preloadedPlugins + } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + const options = Object.assign(Object.create(null), defaultOptions, { + cwd: process.cwd() + }, providedOptions); + + if (options.fix === void 0) { + options.fix = false; } -} -/** - * Merge plugins. - * `target`'s definition is prior to `source`'s. - * @param {Record} target The destination to merge - * @param {Record|undefined} source The source to merge. - * @returns {void} - */ -function mergePlugins(target, source) { - if (!isNonNullObject(source)) { - return; + const additionalPluginPool = new Map(); + + if (preloadedPlugins) { + for (const [id, plugin] of Object.entries(preloadedPlugins)) { + additionalPluginPool.set(id, plugin); + } } - for (const key of Object.keys(source)) { - if (key === "__proto__") { - continue; - } - const targetValue = target[key]; - const sourceValue = source[key]; + const cacheFilePath = getCacheFile(options.cacheLocation || options.cacheFile, options.cwd); + const configArrayFactory = new CascadingConfigArrayFactory({ + additionalPluginPool, + baseConfig: options.baseConfig || null, + cliConfig: createConfigDataFromOptions(options), + cwd: options.cwd, + ignorePath: options.ignorePath, + resolvePluginsRelativeTo: options.resolvePluginsRelativeTo, + rulePaths: options.rulePaths, + specificConfigPath: options.configFile, + useEslintrc: options.useEslintrc, + builtInRules, + loadRules, + eslintRecommendedPath: path.resolve(__dirname, "../../conf/eslint-recommended.js"), + eslintAllPath: path.resolve(__dirname, "../../conf/eslint-all.js") + }); + const fileEnumerator = new FileEnumerator({ + configArrayFactory, + cwd: options.cwd, + extensions: options.extensions, + globInputPaths: options.globInputPaths, + errorOnUnmatchedPattern: options.errorOnUnmatchedPattern, + ignore: options.ignore + }); + const lintResultCache = options.cache ? new LintResultCache(cacheFilePath, options.cacheStrategy) : null; + const linter = new Linter({ + cwd: options.cwd + }); + /** @type {ConfigArray[]} */ - // Adopt the plugin which was found at first. - if (targetValue === void 0) { - if (sourceValue.error) { - throw sourceValue.error; - } - target[key] = sourceValue; - } else if (sourceValue.filePath !== targetValue.filePath) { - throw new PluginConflictError(key, [ - { - filePath: targetValue.filePath, - importerName: targetValue.importerName - }, - { - filePath: sourceValue.filePath, - importerName: sourceValue.importerName - } - ]); - } + const lastConfigArrays = [configArrayFactory.getConfigArrayForFile()]; // Store private data. + + internalSlotsMap.set(this, { + additionalPluginPool, + cacheFilePath, + configArrayFactory, + defaultIgnores: IgnorePattern.createDefaultIgnore(options.cwd), + fileEnumerator, + lastConfigArrays, + lintResultCache, + linter, + options + }); // setup special filter for fixes + + if (options.fix && options.fixTypes && options.fixTypes.length > 0) { + debug("Using fix types ".concat(options.fixTypes)); // throw an error if any invalid fix types are found + + validateFixTypes(options.fixTypes); // convert to Set for faster lookup + + const fixTypes = new Set(options.fixTypes); // save original value of options.fix in case it's a function + + const originalFix = typeof options.fix === "function" ? options.fix : () => true; + + options.fix = message => shouldMessageBeFixed(message, lastConfigArrays, fixTypes) && originalFix(message); } -} + } -/** - * Merge rule configs. - * `target`'s definition is prior to `source`'s. - * @param {Record} target The destination to merge - * @param {Record|undefined} source The source to merge. - * @returns {void} - */ -function mergeRuleConfigs(target, source) { - if (!isNonNullObject(source)) { - return; + getRules() { + const { + lastConfigArrays + } = internalSlotsMap.get(this); + return new Map(function* () { + yield* builtInRules; + + for (const configArray of lastConfigArrays) { + yield* configArray.pluginRules; + } + }()); + } + /** + * Returns results that only contains errors. + * @param {LintResult[]} results The results to filter. + * @returns {LintResult[]} The filtered results. + */ + + + static getErrorResults(results) { + const filtered = []; + results.forEach(result => { + const filteredMessages = result.messages.filter(isErrorMessage); + + if (filteredMessages.length > 0) { + filtered.push({ ...result, + messages: filteredMessages, + errorCount: filteredMessages.length, + warningCount: 0, + fixableErrorCount: result.fixableErrorCount, + fixableWarningCount: 0 + }); + } + }); + return filtered; + } + /** + * Outputs fixes from the given results to files. + * @param {LintReport} report The report object created by CLIEngine. + * @returns {void} + */ + + + static outputFixes(report) { + report.results.filter(result => Object.prototype.hasOwnProperty.call(result, "output")).forEach(result => { + fs.writeFileSync(result.filePath, result.output); + }); + } + /** + * Resolves the patterns passed into executeOnFiles() into glob-based patterns + * for easier handling. + * @param {string[]} patterns The file patterns passed on the command line. + * @returns {string[]} The equivalent glob patterns. + */ + + + resolveFileGlobPatterns(patterns) { + const { + options + } = internalSlotsMap.get(this); + + if (options.globInputPaths === false) { + return patterns.filter(Boolean); } - for (const key of Object.keys(source)) { - if (key === "__proto__") { - continue; - } - const targetDef = target[key]; - const sourceDef = source[key]; + const extensions = (options.extensions || [".js"]).map(ext => ext.replace(/^\./u, "")); + const dirSuffix = "/**/*.{".concat(extensions.join(","), "}"); + return patterns.filter(Boolean).map(pathname => { + const resolvedPath = path.resolve(options.cwd, pathname); + const newPath = directoryExists(resolvedPath) ? pathname.replace(/[/\\]$/u, "") + dirSuffix : pathname; + return path.normalize(newPath).replace(/\\/gu, "/"); + }); + } + /** + * Executes the current configuration on an array of file and directory names. + * @param {string[]} patterns An array of file and directory names. + * @throws {Error} As may be thrown by `fs.unlinkSync`. + * @returns {LintReport} The results for all files that were linted. + */ - // Adopt the rule config which was found at first. - if (targetDef === void 0) { - if (Array.isArray(sourceDef)) { - target[key] = [...sourceDef]; - } else { - target[key] = [sourceDef]; - } - /* - * If the first found rule config is severity only and the current rule - * config has options, merge the severity and the options. - */ - } else if ( - targetDef.length === 1 && - Array.isArray(sourceDef) && - sourceDef.length >= 2 - ) { - targetDef.push(...sourceDef.slice(1)); + executeOnFiles(patterns) { + const { + cacheFilePath, + fileEnumerator, + lastConfigArrays, + lintResultCache, + linter, + options: { + allowInlineConfig, + cache, + cwd, + fix, + reportUnusedDisableDirectives + } + } = internalSlotsMap.get(this); + const results = []; + const startTime = Date.now(); // Clear the last used config arrays. + + lastConfigArrays.length = 0; // Delete cache file; should this do here? + + if (!cache) { + try { + fs.unlinkSync(cacheFilePath); + } catch (error) { + const errorCode = error && error.code; // Ignore errors when no such file exists or file system is read only (and cache file does not exist) + + if (errorCode !== "ENOENT" && !(errorCode === "EROFS" && !fs.existsSync(cacheFilePath))) { + throw error; } - } -} + } + } // Iterate source code files. -/** - * Create the extracted config. - * @param {ConfigArray} instance The config elements. - * @param {number[]} indices The indices to use. - * @returns {ExtractedConfig} The extracted config. - */ -function createConfig(instance, indices) { - const config = new ExtractedConfig(); - const ignorePatterns = []; - // Merge elements. - for (const index of indices) { - const element = instance[index]; + for (const { + config, + filePath, + ignored + } of fileEnumerator.iterateFiles(patterns)) { + if (ignored) { + results.push(createIgnoreResult(filePath, cwd)); + continue; + } + /* + * Store used configs for: + * - this method uses to collect used deprecated rules. + * - `getRules()` method uses to collect all loaded rules. + * - `--fix-type` option uses to get the loaded rule's meta data. + */ - // Adopt the parser which was found at first. - if (!config.parser && element.parser) { - if (element.parser.error) { - throw element.parser.error; - } - config.parser = element.parser; + + if (!lastConfigArrays.includes(config)) { + lastConfigArrays.push(config); + } // Skip if there is cached result. + + + if (lintResultCache) { + const cachedResult = lintResultCache.getCachedLintResults(filePath, config); + + if (cachedResult) { + const hadMessages = cachedResult.messages && cachedResult.messages.length > 0; + + if (hadMessages && fix) { + debug("Reprocessing cached file to allow autofix: ".concat(filePath)); + } else { + debug("Skipping file since it hasn't changed: ".concat(filePath)); + results.push(cachedResult); + continue; + } } + } // Do lint. + + + const result = verifyText({ + text: fs.readFileSync(filePath, "utf8"), + filePath, + config, + cwd, + fix, + allowInlineConfig, + reportUnusedDisableDirectives, + fileEnumerator, + linter + }); + results.push(result); + /* + * Store the lint result in the LintResultCache. + * NOTE: The LintResultCache will remove the file source and any + * other properties that are difficult to serialize, and will + * hydrate those properties back in on future lint runs. + */ + + if (lintResultCache) { + lintResultCache.setCachedLintResults(filePath, config, result); + } + } // Persist the cache to disk. - // Adopt the processor which was found at first. - if (!config.processor && element.processor) { - config.processor = element.processor; - } - // Adopt the noInlineConfig which was found at first. - if (config.noInlineConfig === void 0 && element.noInlineConfig !== void 0) { - config.noInlineConfig = element.noInlineConfig; - config.configNameOfNoInlineConfig = element.name; - } + if (lintResultCache) { + lintResultCache.reconcile(); + } - // Adopt the reportUnusedDisableDirectives which was found at first. - if (config.reportUnusedDisableDirectives === void 0 && element.reportUnusedDisableDirectives !== void 0) { - config.reportUnusedDisableDirectives = element.reportUnusedDisableDirectives; - } + debug("Linting complete in: ".concat(Date.now() - startTime, "ms")); + let usedDeprecatedRules; + return { + results, + ...calculateStatsPerRun(results), - // Collect ignorePatterns - if (element.ignorePattern) { - ignorePatterns.push(element.ignorePattern); + // Initialize it lazily because CLI and `ESLint` API don't use it. + get usedDeprecatedRules() { + if (!usedDeprecatedRules) { + usedDeprecatedRules = Array.from(iterateRuleDeprecationWarnings(lastConfigArrays)); } - // Merge others. - mergeWithoutOverwrite(config.env, element.env); - mergeWithoutOverwrite(config.globals, element.globals); - mergeWithoutOverwrite(config.parserOptions, element.parserOptions); - mergeWithoutOverwrite(config.settings, element.settings); - mergePlugins(config.plugins, element.plugins); - mergeRuleConfigs(config.rules, element.rules); - } + return usedDeprecatedRules; + } - // Create the predicate function for ignore patterns. - if (ignorePatterns.length > 0) { - config.ignores = IgnorePattern.createIgnore(ignorePatterns.reverse()); - } + }; + } + /** + * Executes the current configuration on text. + * @param {string} text A string of JavaScript code to lint. + * @param {string} [filename] An optional string representing the texts filename. + * @param {boolean} [warnIgnored] Always warn when a file is ignored + * @returns {LintReport} The results for the linting. + */ - return config; -} -/** - * Collect definitions. - * @template T, U - * @param {string} pluginId The plugin ID for prefix. - * @param {Record} defs The definitions to collect. - * @param {Map} map The map to output. - * @param {function(T): U} [normalize] The normalize function for each value. - * @returns {void} - */ -function collect(pluginId, defs, map, normalize) { - if (defs) { - const prefix = pluginId && `${pluginId}/`; + executeOnText(text, filename, warnIgnored) { + const { + configArrayFactory, + fileEnumerator, + lastConfigArrays, + linter, + options: { + allowInlineConfig, + cwd, + fix, + reportUnusedDisableDirectives + } + } = internalSlotsMap.get(this); + const results = []; + const startTime = Date.now(); + const resolvedFilename = filename && path.resolve(cwd, filename); // Clear the last used config arrays. - for (const [key, value] of Object.entries(defs)) { - map.set( - `${prefix}${key}`, - normalize ? normalize(value) : value - ); - } - } -} + lastConfigArrays.length = 0; -/** - * Normalize a rule definition. - * @param {Function|Rule} rule The rule definition to normalize. - * @returns {Rule} The normalized rule definition. - */ -function normalizePluginRule(rule) { - return typeof rule === "function" ? { create: rule } : rule; -} + if (resolvedFilename && this.isPathIgnored(resolvedFilename)) { + if (warnIgnored) { + results.push(createIgnoreResult(resolvedFilename, cwd)); + } + } else { + const config = configArrayFactory.getConfigArrayForFile(resolvedFilename || "__placeholder__.js"); + /* + * Store used configs for: + * - this method uses to collect used deprecated rules. + * - `getRules()` method uses to collect all loaded rules. + * - `--fix-type` option uses to get the loaded rule's meta data. + */ -/** - * Delete the mutation methods from a given map. - * @param {Map} map The map object to delete. - * @returns {void} - */ -function deleteMutationMethods(map) { - Object.defineProperties(map, { - clear: { configurable: true, value: void 0 }, - delete: { configurable: true, value: void 0 }, - set: { configurable: true, value: void 0 } - }); -} + lastConfigArrays.push(config); // Do lint. -/** - * Create `envMap`, `processorMap`, `ruleMap` with the plugins in the config array. - * @param {ConfigArrayElement[]} elements The config elements. - * @param {ConfigArrayInternalSlots} slots The internal slots. - * @returns {void} - */ -function initPluginMemberMaps(elements, slots) { - const processed = new Set(); + results.push(verifyText({ + text, + filePath: resolvedFilename, + config, + cwd, + fix, + allowInlineConfig, + reportUnusedDisableDirectives, + fileEnumerator, + linter + })); + } - slots.envMap = new Map(); - slots.processorMap = new Map(); - slots.ruleMap = new Map(); + debug("Linting complete in: ".concat(Date.now() - startTime, "ms")); + let usedDeprecatedRules; + return { + results, + ...calculateStatsPerRun(results), - for (const element of elements) { - if (!element.plugins) { - continue; + // Initialize it lazily because CLI and `ESLint` API don't use it. + get usedDeprecatedRules() { + if (!usedDeprecatedRules) { + usedDeprecatedRules = Array.from(iterateRuleDeprecationWarnings(lastConfigArrays)); } - for (const [pluginId, value] of Object.entries(element.plugins)) { - const plugin = value.definition; - - if (!plugin || processed.has(pluginId)) { - continue; - } - processed.add(pluginId); + return usedDeprecatedRules; + } - collect(pluginId, plugin.environments, slots.envMap); - collect(pluginId, plugin.processors, slots.processorMap); - collect(pluginId, plugin.rules, slots.ruleMap, normalizePluginRule); - } - } + }; + } + /** + * Returns a configuration object for the given file based on the CLI options. + * This is the same logic used by the ESLint CLI executable to determine + * configuration for each file it processes. + * @param {string} filePath The path of the file to retrieve a config object for. + * @throws {Error} If filepath a directory path. + * @returns {ConfigData} A configuration object for the file. + */ - deleteMutationMethods(slots.envMap); - deleteMutationMethods(slots.processorMap); - deleteMutationMethods(slots.ruleMap); -} -/** - * Create `envMap`, `processorMap`, `ruleMap` with the plugins in the config array. - * @param {ConfigArray} instance The config elements. - * @returns {ConfigArrayInternalSlots} The extracted config. - */ -function ensurePluginMemberMaps(instance) { - const slots = internalSlotsMap$2.get(instance); + getConfigForFile(filePath) { + const { + configArrayFactory, + options + } = internalSlotsMap.get(this); + const absolutePath = path.resolve(options.cwd, filePath); - if (!slots.ruleMap) { - initPluginMemberMaps(instance, slots); + if (directoryExists(absolutePath)) { + throw Object.assign(new Error("'filePath' should not be a directory path."), { + messageTemplate: "print-config-with-directory-path" + }); } - return slots; -} + return configArrayFactory.getConfigArrayForFile(absolutePath).extractConfig(absolutePath).toCompatibleObjectAsConfigFileContent(); + } + /** + * Checks if a given path is ignored by ESLint. + * @param {string} filePath The path of the file to check. + * @returns {boolean} Whether or not the given path is ignored. + */ -//------------------------------------------------------------------------------ -// Public Interface -//------------------------------------------------------------------------------ -/** - * The Config Array. - * - * `ConfigArray` instance contains all settings, parsers, and plugins. - * You need to call `ConfigArray#extractConfig(filePath)` method in order to - * extract, merge and get only the config data which is related to an arbitrary - * file. - * @extends {Array} - */ -class ConfigArray extends Array { + isPathIgnored(filePath) { + const { + configArrayFactory, + defaultIgnores, + options: { + cwd, + ignore + } + } = internalSlotsMap.get(this); + const absolutePath = path.resolve(cwd, filePath); - /** - * Get the plugin environments. - * The returned map cannot be mutated. - * @type {ReadonlyMap} The plugin environments. - */ - get pluginEnvironments() { - return ensurePluginMemberMaps(this).envMap; + if (ignore) { + const config = configArrayFactory.getConfigArrayForFile(absolutePath).extractConfig(absolutePath); + const ignores = config.ignores || defaultIgnores; + return ignores(absolutePath); } - /** - * Get the plugin processors. - * The returned map cannot be mutated. - * @type {ReadonlyMap} The plugin processors. - */ - get pluginProcessors() { - return ensurePluginMemberMaps(this).processorMap; - } + return defaultIgnores(absolutePath); + } + /** + * Returns the formatter representing the given format or null if the `format` is not a string. + * @param {string} [format] The name of the format to load or the path to a + * custom formatter. + * @throws {any} As may be thrown by requiring of formatter + * @returns {(Function|null)} The formatter function or null if the `format` is not a string. + */ - /** - * Get the plugin rules. - * The returned map cannot be mutated. - * @returns {ReadonlyMap} The plugin rules. - */ - get pluginRules() { - return ensurePluginMemberMaps(this).ruleMap; - } - /** - * Check if this config has `root` flag. - * @returns {boolean} `true` if this config array is root. - */ - isRoot() { - for (let i = this.length - 1; i >= 0; --i) { - const root = this[i].root; + getFormatter(format) { + // default is stylish + const resolvedFormatName = format || "stylish"; // only strings are valid formatters - if (typeof root === "boolean") { - return root; - } - } - return false; - } + if (typeof resolvedFormatName === "string") { + // replace \ with / for Windows compatibility + const normalizedFormatName = resolvedFormatName.replace(/\\/gu, "/"); + const slots = internalSlotsMap.get(this); + const cwd = slots ? slots.options.cwd : process.cwd(); + const namespace = naming.getNamespaceFromTerm(normalizedFormatName); + let formatterPath; // if there's a slash, then it's a file (TODO: this check seems dubious for scoped npm packages) - /** - * Extract the config data which is related to a given file. - * @param {string} filePath The absolute path to the target file. - * @returns {ExtractedConfig} The extracted config data. - */ - extractConfig(filePath) { - const { cache } = internalSlotsMap$2.get(this); - const indices = getMatchedIndices(this, filePath); - const cacheKey = indices.join(","); + if (!namespace && normalizedFormatName.indexOf("/") > -1) { + formatterPath = path.resolve(cwd, normalizedFormatName); + } else { + try { + const npmFormat = naming.normalizePackageName(normalizedFormatName, "eslint-formatter"); + formatterPath = ModuleResolver.resolve(npmFormat, path.join(cwd, "__placeholder__.js")); + } catch { + formatterPath = path.resolve(__dirname, "formatters", normalizedFormatName); + } + } - if (!cache.has(cacheKey)) { - cache.set(cacheKey, createConfig(this, indices)); + try { + return __webpack_require__(899)(formatterPath); + } catch (ex) { + if (format === "table" || format === "codeframe") { + ex.message = "The ".concat(format, " formatter is no longer part of core ESLint. Install it manually with `npm install -D eslint-formatter-").concat(format, "`"); + } else { + ex.message = "There was a problem loading formatter: ".concat(formatterPath, "\nError: ").concat(ex.message); } - return cache.get(cacheKey); + throw ex; + } + } else { + return null; } + } - /** - * Check if a given path is an additional lint target. - * @param {string} filePath The absolute path to the target file. - * @returns {boolean} `true` if the file is an additional lint target. - */ - isAdditionalTargetPath(filePath) { - for (const { criteria, type } of this) { - if ( - type === "config" && - criteria && - !criteria.endsWithWildcard && - criteria.test(filePath) - ) { - return true; - } - } - return false; - } } -/** - * Get the used extracted configs. - * CLIEngine will use this method to collect used deprecated rules. - * @param {ConfigArray} instance The config array object to get. - * @returns {ExtractedConfig[]} The used extracted configs. - * @private - */ -function getUsedExtractedConfigs(instance) { - const { cache } = internalSlotsMap$2.get(instance); +CLIEngine.version = pkg.version; +CLIEngine.getFormatter = CLIEngine.prototype.getFormatter; +module.exports = { + CLIEngine, - return Array.from(cache.values()); -} + /** + * Get the internal slots of a given CLIEngine instance for tests. + * @param {CLIEngine} instance The CLIEngine instance to get. + * @returns {CLIEngineInternalSlots} The internal slots. + */ + getCLIEngineInternalSlots(instance) { + return internalSlotsMap.get(instance); + } -/** - * @fileoverview `ConfigDependency` class. - * - * `ConfigDependency` class expresses a loaded parser or plugin. - * - * If the parser or plugin was loaded successfully, it has `definition` property - * and `filePath` property. Otherwise, it has `error` property. - * - * When `JSON.stringify()` converted a `ConfigDependency` object to a JSON, it - * omits `definition` property. - * - * `ConfigArrayFactory` creates `ConfigDependency` objects when it loads parsers - * or plugins. - * - * @author Toru Nagashima - */ +}; + +/***/ }), +/* 882 */ +/***/ ((module) => { +"use strict"; /** - * The class is to store parsers or plugins. - * This class hides the loaded object from `JSON.stringify()` and `console.log`. - * @template T + * @fileoverview Default CLIEngineOptions. + * @author Ian VanSchooten */ -class ConfigDependency { - /** - * Initialize this instance. - * @param {Object} data The dependency data. - * @param {T} [data.definition] The dependency if the loading succeeded. - * @param {Error} [data.error] The error object if the loading failed. - * @param {string} [data.filePath] The actual path to the dependency if the loading succeeded. - * @param {string} data.id The ID of this dependency. - * @param {string} data.importerName The name of the config file which loads this dependency. - * @param {string} data.importerPath The path to the config file which loads this dependency. - */ - constructor({ - definition = null, - error = null, - filePath = null, - id, - importerName, - importerPath - }) { - /** - * The loaded dependency if the loading succeeded. - * @type {T|null} - */ - this.definition = definition; +module.exports = { + configFile: null, + baseConfig: false, + rulePaths: [], + useEslintrc: true, + envs: [], + globals: [], + extensions: null, + ignore: true, + ignorePath: void 0, + cache: false, - /** - * The error object if the loading failed. - * @type {Error|null} - */ - this.error = error; + /* + * in order to honor the cacheFile option if specified + * this option should not have a default value otherwise + * it will always be used + */ + cacheLocation: "", + cacheFile: ".eslintcache", + cacheStrategy: "metadata", + fix: false, + allowInlineConfig: true, + reportUnusedDisableDirectives: void 0, + globInputPaths: true +}; - /** - * The loaded dependency if the loading succeeded. - * @type {string|null} - */ - this.filePath = filePath; +/***/ }), +/* 883 */ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { - /** - * The ID of this dependency. - * @type {string} - */ - this.id = id; +"use strict"; +/* provided dependency */ var process = __webpack_require__(494); - /** - * The name of the config file which loads this dependency. - * @type {string} - */ - this.importerName = importerName; - /** - * The path to the config file which loads this dependency. - * @type {string} - */ - this.importerPath = importerPath; - } +Object.defineProperty(exports, "__esModule", ({ value: true })); + +var fs = __webpack_require__(880); +var path = __webpack_require__(429); +var importFresh = __webpack_require__(884); +var stripComments = __webpack_require__(890); +var util = __webpack_require__(439); +var Ajv = __webpack_require__(446); +var globals = __webpack_require__(492); +var Module = __webpack_require__(886); +var assert = __webpack_require__(431); +var ignore = __webpack_require__(737); +var debugOrig = __webpack_require__(496); +var minimatch = __webpack_require__(862); +var os = __webpack_require__(891); +var url = __webpack_require__(892); + +function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } + +var fs__default = /*#__PURE__*/_interopDefaultLegacy(fs); +var path__default = /*#__PURE__*/_interopDefaultLegacy(path); +var importFresh__default = /*#__PURE__*/_interopDefaultLegacy(importFresh); +var stripComments__default = /*#__PURE__*/_interopDefaultLegacy(stripComments); +var util__default = /*#__PURE__*/_interopDefaultLegacy(util); +var Ajv__default = /*#__PURE__*/_interopDefaultLegacy(Ajv); +var globals__default = /*#__PURE__*/_interopDefaultLegacy(globals); +var Module__default = /*#__PURE__*/_interopDefaultLegacy(Module); +var assert__default = /*#__PURE__*/_interopDefaultLegacy(assert); +var ignore__default = /*#__PURE__*/_interopDefaultLegacy(ignore); +var debugOrig__default = /*#__PURE__*/_interopDefaultLegacy(debugOrig); +var minimatch__default = /*#__PURE__*/_interopDefaultLegacy(minimatch); +var os__default = /*#__PURE__*/_interopDefaultLegacy(os); + +/** + * @fileoverview Config file operations. This file must be usable in the browser, + * so no Node-specific code can be here. + * @author Nicholas C. Zakas + */ + +//------------------------------------------------------------------------------ +// Private +//------------------------------------------------------------------------------ + +const RULE_SEVERITY_STRINGS = ["off", "warn", "error"], + RULE_SEVERITY = RULE_SEVERITY_STRINGS.reduce((map, value, index) => { + map[value] = index; + return map; + }, {}), + VALID_SEVERITIES = [0, 1, 2, "off", "warn", "error"]; - // eslint-disable-next-line jsdoc/require-description - /** - * @returns {Object} a JSON compatible object. - */ - toJSON() { - const obj = this[util__default["default"].inspect.custom](); +//------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ - // Display `error.message` (`Error#message` is unenumerable). - if (obj.error instanceof Error) { - obj.error = { ...obj.error, message: obj.error.message }; - } +/** + * Normalizes the severity value of a rule's configuration to a number + * @param {(number|string|[number, ...*]|[string, ...*])} ruleConfig A rule's configuration value, generally + * received from the user. A valid config value is either 0, 1, 2, the string "off" (treated the same as 0), + * the string "warn" (treated the same as 1), the string "error" (treated the same as 2), or an array + * whose first element is one of the above values. Strings are matched case-insensitively. + * @returns {(0|1|2)} The numeric severity value if the config value was valid, otherwise 0. + */ +function getRuleSeverity(ruleConfig) { + const severityValue = Array.isArray(ruleConfig) ? ruleConfig[0] : ruleConfig; - return obj; + if (severityValue === 0 || severityValue === 1 || severityValue === 2) { + return severityValue; } - // eslint-disable-next-line jsdoc/require-description - /** - * @returns {Object} an object to display by `console.log()`. - */ - [util__default["default"].inspect.custom]() { - const { - definition: _ignore, // eslint-disable-line no-unused-vars - ...obj - } = this; - - return obj; + if (typeof severityValue === "string") { + return RULE_SEVERITY[severityValue.toLowerCase()] || 0; } + + return 0; } /** - * @fileoverview `OverrideTester` class. - * - * `OverrideTester` class handles `files` property and `excludedFiles` property - * of `overrides` config. - * - * It provides one method. - * - * - `test(filePath)` - * Test if a file path matches the pair of `files` property and - * `excludedFiles` property. The `filePath` argument must be an absolute - * path. - * - * `ConfigArrayFactory` creates `OverrideTester` objects when it processes - * `overrides` properties. - * - * @author Toru Nagashima + * Converts old-style severity settings (0, 1, 2) into new-style + * severity settings (off, warn, error) for all rules. Assumption is that severity + * values have already been validated as correct. + * @param {Object} config The config object to normalize. + * @returns {void} */ +function normalizeToStrings(config) { -const { Minimatch } = minimatch__default["default"]; - -const minimatchOpts = { dot: true, matchBase: true }; + if (config.rules) { + Object.keys(config.rules).forEach(ruleId => { + const ruleConfig = config.rules[ruleId]; -/** - * @typedef {Object} Pattern - * @property {InstanceType[] | null} includes The positive matchers. - * @property {InstanceType[] | null} excludes The negative matchers. - */ + if (typeof ruleConfig === "number") { + config.rules[ruleId] = RULE_SEVERITY_STRINGS[ruleConfig] || RULE_SEVERITY_STRINGS[0]; + } else if (Array.isArray(ruleConfig) && typeof ruleConfig[0] === "number") { + ruleConfig[0] = RULE_SEVERITY_STRINGS[ruleConfig[0]] || RULE_SEVERITY_STRINGS[0]; + } + }); + } +} /** - * Normalize a given pattern to an array. - * @param {string|string[]|undefined} patterns A glob pattern or an array of glob patterns. - * @returns {string[]|null} Normalized patterns. - * @private + * Determines if the severity for the given rule configuration represents an error. + * @param {int|string|Array} ruleConfig The configuration for an individual rule. + * @returns {boolean} True if the rule represents an error, false if not. */ -function normalizePatterns(patterns) { - if (Array.isArray(patterns)) { - return patterns.filter(Boolean); - } - if (typeof patterns === "string" && patterns) { - return [patterns]; - } - return []; +function isErrorSeverity(ruleConfig) { + return getRuleSeverity(ruleConfig) === 2; } /** - * Create the matchers of given patterns. - * @param {string[]} patterns The patterns. - * @returns {InstanceType[] | null} The matchers. + * Checks whether a given config has valid severity or not. + * @param {number|string|Array} ruleConfig The configuration for an individual rule. + * @returns {boolean} `true` if the configuration has valid severity. */ -function toMatcher(patterns) { - if (patterns.length === 0) { - return null; - } - return patterns.map(pattern => { - if (/^\.[/\\]/u.test(pattern)) { - return new Minimatch( - pattern.slice(2), +function isValidSeverity(ruleConfig) { + let severity = Array.isArray(ruleConfig) ? ruleConfig[0] : ruleConfig; - // `./*.js` should not match with `subdir/foo.js` - { ...minimatchOpts, matchBase: false } - ); - } - return new Minimatch(pattern, minimatchOpts); - }); + if (typeof severity === "string") { + severity = severity.toLowerCase(); + } + return VALID_SEVERITIES.indexOf(severity) !== -1; } /** - * Convert a given matcher to string. - * @param {Pattern} matchers The matchers. - * @returns {string} The string expression of the matcher. + * Checks whether every rule of a given config has valid severity or not. + * @param {Object} config The configuration for rules. + * @returns {boolean} `true` if the configuration has valid severity. */ -function patternToJson({ includes, excludes }) { - return { - includes: includes && includes.map(m => m.pattern), - excludes: excludes && excludes.map(m => m.pattern) - }; +function isEverySeverityValid(config) { + return Object.keys(config).every(ruleId => isValidSeverity(config[ruleId])); } /** - * The class to test given paths are matched by the patterns. + * Normalizes a value for a global in a config + * @param {(boolean|string|null)} configuredValue The value given for a global in configuration or in + * a global directive comment + * @returns {("readable"|"writeable"|"off")} The value normalized as a string + * @throws Error if global value is invalid */ -class OverrideTester { - - /** - * Create a tester with given criteria. - * If there are no criteria, returns `null`. - * @param {string|string[]} files The glob patterns for included files. - * @param {string|string[]} excludedFiles The glob patterns for excluded files. - * @param {string} basePath The path to the base directory to test paths. - * @returns {OverrideTester|null} The created instance or `null`. - */ - static create(files, excludedFiles, basePath) { - const includePatterns = normalizePatterns(files); - const excludePatterns = normalizePatterns(excludedFiles); - let endsWithWildcard = false; - - if (includePatterns.length === 0) { - return null; - } +function normalizeConfigGlobal(configuredValue) { + switch (configuredValue) { + case "off": + return "off"; - // Rejects absolute paths or relative paths to parents. - for (const pattern of includePatterns) { - if (path__default["default"].isAbsolute(pattern) || pattern.includes("..")) { - throw new Error(`Invalid override pattern (expected relative path not containing '..'): ${pattern}`); - } - if (pattern.endsWith("*")) { - endsWithWildcard = true; - } - } - for (const pattern of excludePatterns) { - if (path__default["default"].isAbsolute(pattern) || pattern.includes("..")) { - throw new Error(`Invalid override pattern (expected relative path not containing '..'): ${pattern}`); - } - } + case true: + case "true": + case "writeable": + case "writable": + return "writable"; - const includes = toMatcher(includePatterns); - const excludes = toMatcher(excludePatterns); + case null: + case false: + case "false": + case "readable": + case "readonly": + return "readonly"; - return new OverrideTester( - [{ includes, excludes }], - basePath, - endsWithWildcard - ); + default: + throw new Error(`'${configuredValue}' is not a valid configuration for a global (use 'readonly', 'writable', or 'off')`); } +} - /** - * Combine two testers by logical and. - * If either of the testers was `null`, returns the other tester. - * The `basePath` property of the two must be the same value. - * @param {OverrideTester|null} a A tester. - * @param {OverrideTester|null} b Another tester. - * @returns {OverrideTester|null} Combined tester. - */ - static and(a, b) { - if (!b) { - return a && new OverrideTester( - a.patterns, - a.basePath, - a.endsWithWildcard - ); - } - if (!a) { - return new OverrideTester( - b.patterns, - b.basePath, - b.endsWithWildcard - ); - } - - assert__default["default"].strictEqual(a.basePath, b.basePath); - return new OverrideTester( - a.patterns.concat(b.patterns), - a.basePath, - a.endsWithWildcard || b.endsWithWildcard - ); - } +var ConfigOps = { + __proto__: null, + getRuleSeverity: getRuleSeverity, + normalizeToStrings: normalizeToStrings, + isErrorSeverity: isErrorSeverity, + isValidSeverity: isValidSeverity, + isEverySeverityValid: isEverySeverityValid, + normalizeConfigGlobal: normalizeConfigGlobal +}; - /** - * Initialize this instance. - * @param {Pattern[]} patterns The matchers. - * @param {string} basePath The base path. - * @param {boolean} endsWithWildcard If `true` then a pattern ends with `*`. - */ - constructor(patterns, basePath, endsWithWildcard = false) { +/** + * @fileoverview Provide the function that emits deprecation warnings. + * @author Toru Nagashima + */ - /** @type {Pattern[]} */ - this.patterns = patterns; +//------------------------------------------------------------------------------ +// Private +//------------------------------------------------------------------------------ - /** @type {string} */ - this.basePath = basePath; +// Defitions for deprecation warnings. +const deprecationWarningMessages = { + ESLINT_LEGACY_ECMAFEATURES: + "The 'ecmaFeatures' config file property is deprecated and has no effect.", + ESLINT_PERSONAL_CONFIG_LOAD: + "'~/.eslintrc.*' config files have been deprecated. " + + "Please use a config file per project or the '--config' option.", + ESLINT_PERSONAL_CONFIG_SUPPRESS: + "'~/.eslintrc.*' config files have been deprecated. " + + "Please remove it or add 'root:true' to the config files in your " + + "projects in order to avoid loading '~/.eslintrc.*' accidentally." +}; - /** @type {boolean} */ - this.endsWithWildcard = endsWithWildcard; - } +const sourceFileErrorCache = new Set(); - /** - * Test if a given path is matched or not. - * @param {string} filePath The absolute path to the target file. - * @returns {boolean} `true` if the path was matched. - */ - test(filePath) { - if (typeof filePath !== "string" || !path__default["default"].isAbsolute(filePath)) { - throw new Error(`'filePath' should be an absolute path, but got ${filePath}.`); - } - const relativePath = path__default["default"].relative(this.basePath, filePath); +/** + * Emits a deprecation warning containing a given filepath. A new deprecation warning is emitted + * for each unique file path, but repeated invocations with the same file path have no effect. + * No warnings are emitted if the `--no-deprecation` or `--no-warnings` Node runtime flags are active. + * @param {string} source The name of the configuration source to report the warning for. + * @param {string} errorCode The warning message to show. + * @returns {void} + */ +function emitDeprecationWarning(source, errorCode) { + const cacheKey = JSON.stringify({ source, errorCode }); - return this.patterns.every(({ includes, excludes }) => ( - (!includes || includes.some(m => m.match(relativePath))) && - (!excludes || !excludes.some(m => m.match(relativePath))) - )); + if (sourceFileErrorCache.has(cacheKey)) { + return; } + sourceFileErrorCache.add(cacheKey); - // eslint-disable-next-line jsdoc/require-description - /** - * @returns {Object} a JSON compatible object. - */ - toJSON() { - if (this.patterns.length === 1) { - return { - ...patternToJson(this.patterns[0]), - basePath: this.basePath - }; - } - return { - AND: this.patterns.map(patternToJson), - basePath: this.basePath - }; - } + const rel = path__default["default"].relative(process.cwd(), source); + const message = deprecationWarningMessages[errorCode]; - // eslint-disable-next-line jsdoc/require-description - /** - * @returns {Object} an object to display by `console.log()`. - */ - [util__default["default"].inspect.custom]() { - return this.toJSON(); - } + process.emitWarning( + `${message} (found in "${rel}")`, + "DeprecationWarning", + errorCode + ); } /** - * @fileoverview `ConfigArray` class. - * @author Toru Nagashima + * @fileoverview The instance of Ajv validator. + * @author Evgeny Poberezkin */ -/** - * @fileoverview The factory of `ConfigArray` objects. - * - * This class provides methods to create `ConfigArray` instance. - * - * - `create(configData, options)` - * Create a `ConfigArray` instance from a config data. This is to handle CLI - * options except `--config`. - * - `loadFile(filePath, options)` - * Create a `ConfigArray` instance from a config file. This is to handle - * `--config` option. If the file was not found, throws the following error: - * - If the filename was `*.js`, a `MODULE_NOT_FOUND` error. - * - If the filename was `package.json`, an IO error or an - * `ESLINT_CONFIG_FIELD_NOT_FOUND` error. - * - Otherwise, an IO error such as `ENOENT`. - * - `loadInDirectory(directoryPath, options)` - * Create a `ConfigArray` instance from a config file which is on a given - * directory. This tries to load `.eslintrc.*` or `package.json`. If not - * found, returns an empty `ConfigArray`. - * - `loadESLintIgnore(filePath)` - * Create a `ConfigArray` instance from a config file that is `.eslintignore` - * format. This is to handle `--ignore-path` option. - * - `loadDefaultESLintIgnore()` - * Create a `ConfigArray` instance from `.eslintignore` or `package.json` in - * the current working directory. - * - * `ConfigArrayFactory` class has the responsibility that loads configuration - * files, including loading `extends`, `parser`, and `plugins`. The created - * `ConfigArray` instance has the loaded `extends`, `parser`, and `plugins`. - * - * But this class doesn't handle cascading. `CascadingConfigArrayFactory` class - * handles cascading and hierarchy. - * - * @author Toru Nagashima - */ -const require$1 = Module.createRequire((typeof document === 'undefined' ? new ((__webpack_require__(876).URL))('file:' + __filename).href : (document.currentScript && document.currentScript.src || new URL('eslintrc.cjs', document.baseURI).href))); +//----------------------------------------------------------------------------- +// Helpers +//----------------------------------------------------------------------------- -const debug$2 = debugOrig__default["default"]("eslintrc:config-array-factory"); +/* + * Copied from ajv/lib/refs/json-schema-draft-04.json + * The MIT License (MIT) + * Copyright (c) 2015-2017 Evgeny Poberezkin + */ +const metaSchema = { + id: "http://json-schema.org/draft-04/schema#", + $schema: "http://json-schema.org/draft-04/schema#", + description: "Core schema meta-schema", + definitions: { + schemaArray: { + type: "array", + minItems: 1, + items: { $ref: "#" } + }, + positiveInteger: { + type: "integer", + minimum: 0 + }, + positiveIntegerDefault0: { + allOf: [{ $ref: "#/definitions/positiveInteger" }, { default: 0 }] + }, + simpleTypes: { + enum: ["array", "boolean", "integer", "null", "number", "object", "string"] + }, + stringArray: { + type: "array", + items: { type: "string" }, + minItems: 1, + uniqueItems: true + } + }, + type: "object", + properties: { + id: { + type: "string" + }, + $schema: { + type: "string" + }, + title: { + type: "string" + }, + description: { + type: "string" + }, + default: { }, + multipleOf: { + type: "number", + minimum: 0, + exclusiveMinimum: true + }, + maximum: { + type: "number" + }, + exclusiveMaximum: { + type: "boolean", + default: false + }, + minimum: { + type: "number" + }, + exclusiveMinimum: { + type: "boolean", + default: false + }, + maxLength: { $ref: "#/definitions/positiveInteger" }, + minLength: { $ref: "#/definitions/positiveIntegerDefault0" }, + pattern: { + type: "string", + format: "regex" + }, + additionalItems: { + anyOf: [ + { type: "boolean" }, + { $ref: "#" } + ], + default: { } + }, + items: { + anyOf: [ + { $ref: "#" }, + { $ref: "#/definitions/schemaArray" } + ], + default: { } + }, + maxItems: { $ref: "#/definitions/positiveInteger" }, + minItems: { $ref: "#/definitions/positiveIntegerDefault0" }, + uniqueItems: { + type: "boolean", + default: false + }, + maxProperties: { $ref: "#/definitions/positiveInteger" }, + minProperties: { $ref: "#/definitions/positiveIntegerDefault0" }, + required: { $ref: "#/definitions/stringArray" }, + additionalProperties: { + anyOf: [ + { type: "boolean" }, + { $ref: "#" } + ], + default: { } + }, + definitions: { + type: "object", + additionalProperties: { $ref: "#" }, + default: { } + }, + properties: { + type: "object", + additionalProperties: { $ref: "#" }, + default: { } + }, + patternProperties: { + type: "object", + additionalProperties: { $ref: "#" }, + default: { } + }, + dependencies: { + type: "object", + additionalProperties: { + anyOf: [ + { $ref: "#" }, + { $ref: "#/definitions/stringArray" } + ] + } + }, + enum: { + type: "array", + minItems: 1, + uniqueItems: true + }, + type: { + anyOf: [ + { $ref: "#/definitions/simpleTypes" }, + { + type: "array", + items: { $ref: "#/definitions/simpleTypes" }, + minItems: 1, + uniqueItems: true + } + ] + }, + format: { type: "string" }, + allOf: { $ref: "#/definitions/schemaArray" }, + anyOf: { $ref: "#/definitions/schemaArray" }, + oneOf: { $ref: "#/definitions/schemaArray" }, + not: { $ref: "#" } + }, + dependencies: { + exclusiveMaximum: ["maximum"], + exclusiveMinimum: ["minimum"] + }, + default: { } +}; //------------------------------------------------------------------------------ -// Helpers +// Public Interface //------------------------------------------------------------------------------ -const configFilenames = [ - ".eslintrc.js", - ".eslintrc.cjs", - ".eslintrc.yaml", - ".eslintrc.yml", - ".eslintrc.json", - ".eslintrc", - "package.json" -]; - -// Define types for VSCode IntelliSense. -/** @typedef {import("./shared/types").ConfigData} ConfigData */ -/** @typedef {import("./shared/types").OverrideConfigData} OverrideConfigData */ -/** @typedef {import("./shared/types").Parser} Parser */ -/** @typedef {import("./shared/types").Plugin} Plugin */ -/** @typedef {import("./shared/types").Rule} Rule */ -/** @typedef {import("./config-array/config-dependency").DependentParser} DependentParser */ -/** @typedef {import("./config-array/config-dependency").DependentPlugin} DependentPlugin */ -/** @typedef {ConfigArray[0]} ConfigArrayElement */ - -/** - * @typedef {Object} ConfigArrayFactoryOptions - * @property {Map} [additionalPluginPool] The map for additional plugins. - * @property {string} [cwd] The path to the current working directory. - * @property {string} [resolvePluginsRelativeTo] A path to the directory that plugins should be resolved from. Defaults to `cwd`. - * @property {Map} builtInRules The rules that are built in to ESLint. - * @property {Object} [resolver=ModuleResolver] The module resolver object. - * @property {string} eslintAllPath The path to the definitions for eslint:all. - * @property {string} eslintRecommendedPath The path to the definitions for eslint:recommended. - */ +var ajvOrig = (additionalOptions = {}) => { + const ajv = new Ajv__default["default"]({ + meta: false, + useDefaults: true, + validateSchema: false, + missingRefs: "ignore", + verbose: true, + schemaId: "auto", + ...additionalOptions + }); -/** - * @typedef {Object} ConfigArrayFactoryInternalSlots - * @property {Map} additionalPluginPool The map for additional plugins. - * @property {string} cwd The path to the current working directory. - * @property {string | undefined} resolvePluginsRelativeTo An absolute path the the directory that plugins should be resolved from. - * @property {Map} builtInRules The rules that are built in to ESLint. - * @property {Object} [resolver=ModuleResolver] The module resolver object. - * @property {string} eslintAllPath The path to the definitions for eslint:all. - * @property {string} eslintRecommendedPath The path to the definitions for eslint:recommended. - */ + ajv.addMetaSchema(metaSchema); + // eslint-disable-next-line no-underscore-dangle + ajv._opts.defaultMeta = metaSchema.id; -/** - * @typedef {Object} ConfigArrayFactoryLoadingContext - * @property {string} filePath The path to the current configuration. - * @property {string} matchBasePath The base path to resolve relative paths in `overrides[].files`, `overrides[].excludedFiles`, and `ignorePatterns`. - * @property {string} name The name of the current configuration. - * @property {string} pluginBasePath The base path to resolve plugins. - * @property {"config" | "ignore" | "implicit-processor"} type The type of the current configuration. This is `"config"` in normal. This is `"ignore"` if it came from `.eslintignore`. This is `"implicit-processor"` if it came from legacy file-extension processors. - */ + return ajv; +}; /** - * @typedef {Object} ConfigArrayFactoryLoadingContext - * @property {string} filePath The path to the current configuration. - * @property {string} matchBasePath The base path to resolve relative paths in `overrides[].files`, `overrides[].excludedFiles`, and `ignorePatterns`. - * @property {string} name The name of the current configuration. - * @property {"config" | "ignore" | "implicit-processor"} type The type of the current configuration. This is `"config"` in normal. This is `"ignore"` if it came from `.eslintignore`. This is `"implicit-processor"` if it came from legacy file-extension processors. + * @fileoverview Defines a schema for configs. + * @author Sylvan Mably */ -/** @type {WeakMap} */ -const internalSlotsMap$1 = new WeakMap(); - -/** - * Check if a given string is a file path. - * @param {string} nameOrPath A module name or file path. - * @returns {boolean} `true` if the `nameOrPath` is a file path. - */ -function isFilePath(nameOrPath) { - return ( - /^\.{1,2}[/\\]/u.test(nameOrPath) || - path__default["default"].isAbsolute(nameOrPath) - ); -} +const baseConfigProperties = { + $schema: { type: "string" }, + env: { type: "object" }, + extends: { $ref: "#/definitions/stringOrStrings" }, + globals: { type: "object" }, + overrides: { + type: "array", + items: { $ref: "#/definitions/overrideConfig" }, + additionalItems: false + }, + parser: { type: ["string", "null"] }, + parserOptions: { type: "object" }, + plugins: { type: "array" }, + processor: { type: "string" }, + rules: { type: "object" }, + settings: { type: "object" }, + noInlineConfig: { type: "boolean" }, + reportUnusedDisableDirectives: { type: "boolean" }, -/** - * Convenience wrapper for synchronously reading file contents. - * @param {string} filePath The filename to read. - * @returns {string} The file contents, with the BOM removed. - * @private - */ -function readFile(filePath) { - return fs__default["default"].readFileSync(filePath, "utf8").replace(/^\ufeff/u, ""); -} + ecmaFeatures: { type: "object" } // deprecated; logs a warning when used +}; -/** - * Loads a YAML configuration from a file. - * @param {string} filePath The filename to load. - * @returns {ConfigData} The configuration object from the file. - * @throws {Error} If the file cannot be read. - * @private - */ -function loadYAMLConfigFile(filePath) { - debug$2(`Loading YAML config file: ${filePath}`); +const configSchema = { + definitions: { + stringOrStrings: { + oneOf: [ + { type: "string" }, + { + type: "array", + items: { type: "string" }, + additionalItems: false + } + ] + }, + stringOrStringsRequired: { + oneOf: [ + { type: "string" }, + { + type: "array", + items: { type: "string" }, + additionalItems: false, + minItems: 1 + } + ] + }, - // lazy load YAML to improve performance when not used - const yaml = require$1("js-yaml"); + // Config at top-level. + objectConfig: { + type: "object", + properties: { + root: { type: "boolean" }, + ignorePatterns: { $ref: "#/definitions/stringOrStrings" }, + ...baseConfigProperties + }, + additionalProperties: false + }, - try { + // Config in `overrides`. + overrideConfig: { + type: "object", + properties: { + excludedFiles: { $ref: "#/definitions/stringOrStrings" }, + files: { $ref: "#/definitions/stringOrStringsRequired" }, + ...baseConfigProperties + }, + required: ["files"], + additionalProperties: false + } + }, - // empty YAML file can be null, so always use - return yaml.load(readFile(filePath)) || {}; - } catch (e) { - debug$2(`Error reading YAML file: ${filePath}`); - e.message = `Cannot read config file: ${filePath}\nError: ${e.message}`; - throw e; - } -} + $ref: "#/definitions/objectConfig" +}; /** - * Loads a JSON configuration from a file. - * @param {string} filePath The filename to load. - * @returns {ConfigData} The configuration object from the file. - * @throws {Error} If the file cannot be read. - * @private + * @fileoverview Defines environment settings and globals. + * @author Elan Shanker */ -function loadJSONConfigFile(filePath) { - debug$2(`Loading JSON config file: ${filePath}`); - try { - return JSON.parse(stripComments__default["default"](readFile(filePath))); - } catch (e) { - debug$2(`Error reading JSON file: ${filePath}`); - e.message = `Cannot read config file: ${filePath}\nError: ${e.message}`; - e.messageTemplate = "failed-to-read-json"; - e.messageData = { - path: filePath, - message: e.message - }; - throw e; - } -} +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ /** - * Loads a legacy (.eslintrc) configuration from a file. - * @param {string} filePath The filename to load. - * @returns {ConfigData} The configuration object from the file. - * @throws {Error} If the file cannot be read. - * @private + * Get the object that has difference. + * @param {Record} current The newer object. + * @param {Record} prev The older object. + * @returns {Record} The difference object. */ -function loadLegacyConfigFile(filePath) { - debug$2(`Loading legacy config file: ${filePath}`); - - // lazy load YAML to improve performance when not used - const yaml = require$1("js-yaml"); +function getDiff(current, prev) { + const retv = {}; - try { - return yaml.load(stripComments__default["default"](readFile(filePath))) || /* istanbul ignore next */ {}; - } catch (e) { - debug$2("Error reading YAML file: %s\n%o", filePath, e); - e.message = `Cannot read config file: ${filePath}\nError: ${e.message}`; - throw e; + for (const [key, value] of Object.entries(current)) { + if (!Object.hasOwnProperty.call(prev, key)) { + retv[key] = value; + } } -} -/** - * Loads a JavaScript configuration from a file. - * @param {string} filePath The filename to load. - * @returns {ConfigData} The configuration object from the file. - * @throws {Error} If the file cannot be read. - * @private - */ -function loadJSConfigFile(filePath) { - debug$2(`Loading JS config file: ${filePath}`); - try { - return importFresh__default["default"](filePath); - } catch (e) { - debug$2(`Error reading JavaScript file: ${filePath}`); - e.message = `Cannot read config file: ${filePath}\nError: ${e.message}`; - throw e; - } + return retv; } -/** - * Loads a configuration from a package.json file. - * @param {string} filePath The filename to load. - * @returns {ConfigData} The configuration object from the file. - * @throws {Error} If the file cannot be read. - * @private - */ -function loadPackageJSONConfigFile(filePath) { - debug$2(`Loading package.json config file: ${filePath}`); - try { - const packageData = loadJSONConfigFile(filePath); - - if (!Object.hasOwnProperty.call(packageData, "eslintConfig")) { - throw Object.assign( - new Error("package.json file doesn't have 'eslintConfig' field."), - { code: "ESLINT_CONFIG_FIELD_NOT_FOUND" } - ); - } +const newGlobals2015 = getDiff(globals__default["default"].es2015, globals__default["default"].es5); // 19 variables such as Promise, Map, ... +const newGlobals2017 = { + Atomics: false, + SharedArrayBuffer: false +}; +const newGlobals2020 = { + BigInt: false, + BigInt64Array: false, + BigUint64Array: false, + globalThis: false +}; - return packageData.eslintConfig; - } catch (e) { - debug$2(`Error reading package.json file: ${filePath}`); - e.message = `Cannot read config file: ${filePath}\nError: ${e.message}`; - throw e; - } -} +const newGlobals2021 = { + AggregateError: false, + FinalizationRegistry: false, + WeakRef: false +}; -/** - * Loads a `.eslintignore` from a file. - * @param {string} filePath The filename to load. - * @returns {string[]} The ignore patterns from the file. - * @private - */ -function loadESLintIgnoreFile(filePath) { - debug$2(`Loading .eslintignore file: ${filePath}`); +//------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ - try { - return readFile(filePath) - .split(/\r?\n/gu) - .filter(line => line.trim() !== "" && !line.startsWith("#")); - } catch (e) { - debug$2(`Error reading .eslintignore file: ${filePath}`); - e.message = `Cannot read .eslintignore file: ${filePath}\nError: ${e.message}`; - throw e; - } -} +/** @type {Map} */ +var environments = new Map(Object.entries({ -/** - * Creates an error to notify about a missing config to extend from. - * @param {string} configName The name of the missing config. - * @param {string} importerName The name of the config that imported the missing config - * @param {string} messageTemplate The text template to source error strings from. - * @returns {Error} The error object to throw - * @private - */ -function configInvalidError(configName, importerName, messageTemplate) { - return Object.assign( - new Error(`Failed to load config "${configName}" to extend from.`), - { - messageTemplate, - messageData: { configName, importerName } + // Language + builtin: { + globals: globals__default["default"].es5 + }, + es6: { + globals: newGlobals2015, + parserOptions: { + ecmaVersion: 6 } - ); -} - -/** - * Loads a configuration file regardless of the source. Inspects the file path - * to determine the correctly way to load the config file. - * @param {string} filePath The path to the configuration. - * @returns {ConfigData|null} The configuration information. - * @private - */ -function loadConfigFile(filePath) { - switch (path__default["default"].extname(filePath)) { - case ".js": - case ".cjs": - return loadJSConfigFile(filePath); + }, + es2015: { + globals: newGlobals2015, + parserOptions: { + ecmaVersion: 6 + } + }, + es2017: { + globals: { ...newGlobals2015, ...newGlobals2017 }, + parserOptions: { + ecmaVersion: 8 + } + }, + es2020: { + globals: { ...newGlobals2015, ...newGlobals2017, ...newGlobals2020 }, + parserOptions: { + ecmaVersion: 11 + } + }, + es2021: { + globals: { ...newGlobals2015, ...newGlobals2017, ...newGlobals2020, ...newGlobals2021 }, + parserOptions: { + ecmaVersion: 12 + } + }, - case ".json": - if (path__default["default"].basename(filePath) === "package.json") { - return loadPackageJSONConfigFile(filePath); + // Platforms + browser: { + globals: globals__default["default"].browser + }, + node: { + globals: globals__default["default"].node, + parserOptions: { + ecmaFeatures: { + globalReturn: true } - return loadJSONConfigFile(filePath); - - case ".yaml": - case ".yml": - return loadYAMLConfigFile(filePath); - - default: - return loadLegacyConfigFile(filePath); - } -} - -/** - * Write debug log. - * @param {string} request The requested module name. - * @param {string} relativeTo The file path to resolve the request relative to. - * @param {string} filePath The resolved file path. - * @returns {void} - */ -function writeDebugLogForLoading(request, relativeTo, filePath) { - /* istanbul ignore next */ - if (debug$2.enabled) { - let nameAndVersion = null; - - try { - const packageJsonPath = resolve( - `${request}/package.json`, - relativeTo - ); - const { version = "unknown" } = require$1(packageJsonPath); - - nameAndVersion = `${request}@${version}`; - } catch (error) { - debug$2("package.json was not found:", error.message); - nameAndVersion = request; } + }, + "shared-node-browser": { + globals: globals__default["default"]["shared-node-browser"] + }, + worker: { + globals: globals__default["default"].worker + }, + serviceworker: { + globals: globals__default["default"].serviceworker + }, - debug$2("Loaded: %s (%s)", nameAndVersion, filePath); + // Frameworks + commonjs: { + globals: globals__default["default"].commonjs, + parserOptions: { + ecmaFeatures: { + globalReturn: true + } + } + }, + amd: { + globals: globals__default["default"].amd + }, + mocha: { + globals: globals__default["default"].mocha + }, + jasmine: { + globals: globals__default["default"].jasmine + }, + jest: { + globals: globals__default["default"].jest + }, + phantomjs: { + globals: globals__default["default"].phantomjs + }, + jquery: { + globals: globals__default["default"].jquery + }, + qunit: { + globals: globals__default["default"].qunit + }, + prototypejs: { + globals: globals__default["default"].prototypejs + }, + shelljs: { + globals: globals__default["default"].shelljs + }, + meteor: { + globals: globals__default["default"].meteor + }, + mongo: { + globals: globals__default["default"].mongo + }, + protractor: { + globals: globals__default["default"].protractor + }, + applescript: { + globals: globals__default["default"].applescript + }, + nashorn: { + globals: globals__default["default"].nashorn + }, + atomtest: { + globals: globals__default["default"].atomtest + }, + embertest: { + globals: globals__default["default"].embertest + }, + webextensions: { + globals: globals__default["default"].webextensions + }, + greasemonkey: { + globals: globals__default["default"].greasemonkey } -} +})); /** - * Create a new context with default values. - * @param {ConfigArrayFactoryInternalSlots} slots The internal slots. - * @param {"config" | "ignore" | "implicit-processor" | undefined} providedType The type of the current configuration. Default is `"config"`. - * @param {string | undefined} providedName The name of the current configuration. Default is the relative path from `cwd` to `filePath`. - * @param {string | undefined} providedFilePath The path to the current configuration. Default is empty string. - * @param {string | undefined} providedMatchBasePath The type of the current configuration. Default is the directory of `filePath` or `cwd`. - * @returns {ConfigArrayFactoryLoadingContext} The created context. + * @fileoverview Validates configs. + * @author Brandon Mills */ -function createContext( - { cwd, resolvePluginsRelativeTo }, - providedType, - providedName, - providedFilePath, - providedMatchBasePath -) { - const filePath = providedFilePath - ? path__default["default"].resolve(cwd, providedFilePath) - : ""; - const matchBasePath = - (providedMatchBasePath && path__default["default"].resolve(cwd, providedMatchBasePath)) || - (filePath && path__default["default"].dirname(filePath)) || - cwd; - const name = - providedName || - (filePath && path__default["default"].relative(cwd, filePath)) || - ""; - const pluginBasePath = - resolvePluginsRelativeTo || - (filePath && path__default["default"].dirname(filePath)) || - cwd; - const type = providedType || "config"; - return { filePath, matchBasePath, name, pluginBasePath, type }; -} +const ajv = ajvOrig(); -/** - * Normalize a given plugin. - * - Ensure the object to have four properties: configs, environments, processors, and rules. - * - Ensure the object to not have other properties. - * @param {Plugin} plugin The plugin to normalize. - * @returns {Plugin} The normalized plugin. - */ -function normalizePlugin(plugin) { - return { - configs: plugin.configs || {}, - environments: plugin.environments || {}, - processors: plugin.processors || {}, - rules: plugin.rules || {} - }; -} +const ruleValidators = new WeakMap(); +const noop = Function.prototype; //------------------------------------------------------------------------------ -// Public Interface +// Private //------------------------------------------------------------------------------ +let validateSchema; +const severityMap = { + error: 2, + warn: 1, + off: 0 +}; -/** - * The factory of `ConfigArray` objects. - */ -class ConfigArrayFactory { - - /** - * Initialize this instance. - * @param {ConfigArrayFactoryOptions} [options] The map for additional plugins. - */ - constructor({ - additionalPluginPool = new Map(), - cwd = process.cwd(), - resolvePluginsRelativeTo, - builtInRules, - resolver = ModuleResolver, - eslintAllPath, - eslintRecommendedPath - } = {}) { - internalSlotsMap$1.set(this, { - additionalPluginPool, - cwd, - resolvePluginsRelativeTo: - resolvePluginsRelativeTo && - path__default["default"].resolve(cwd, resolvePluginsRelativeTo), - builtInRules, - resolver, - eslintAllPath, - eslintRecommendedPath - }); - } - - /** - * Create `ConfigArray` instance from a config data. - * @param {ConfigData|null} configData The config data to create. - * @param {Object} [options] The options. - * @param {string} [options.basePath] The base path to resolve relative paths in `overrides[].files`, `overrides[].excludedFiles`, and `ignorePatterns`. - * @param {string} [options.filePath] The path to this config data. - * @param {string} [options.name] The config name. - * @returns {ConfigArray} Loaded config. - */ - create(configData, { basePath, filePath, name } = {}) { - if (!configData) { - return new ConfigArray(); - } - - const slots = internalSlotsMap$1.get(this); - const ctx = createContext(slots, "config", name, filePath, basePath); - const elements = this._normalizeConfigData(configData, ctx); - - return new ConfigArray(...elements); - } +const validated = new WeakSet(); - /** - * Load a config file. - * @param {string} filePath The path to a config file. - * @param {Object} [options] The options. - * @param {string} [options.basePath] The base path to resolve relative paths in `overrides[].files`, `overrides[].excludedFiles`, and `ignorePatterns`. - * @param {string} [options.name] The config name. - * @returns {ConfigArray} Loaded config. - */ - loadFile(filePath, { basePath, name } = {}) { - const slots = internalSlotsMap$1.get(this); - const ctx = createContext(slots, "config", name, filePath, basePath); +//----------------------------------------------------------------------------- +// Exports +//----------------------------------------------------------------------------- - return new ConfigArray(...this._loadConfigData(ctx)); +class ConfigValidator { + constructor({ builtInRules = new Map() } = {}) { + this.builtInRules = builtInRules; } /** - * Load the config file on a given directory if exists. - * @param {string} directoryPath The path to a directory. - * @param {Object} [options] The options. - * @param {string} [options.basePath] The base path to resolve relative paths in `overrides[].files`, `overrides[].excludedFiles`, and `ignorePatterns`. - * @param {string} [options.name] The config name. - * @returns {ConfigArray} Loaded config. An empty `ConfigArray` if any config doesn't exist. + * Gets a complete options schema for a rule. + * @param {{create: Function, schema: (Array|null)}} rule A new-style rule object + * @returns {Object} JSON Schema for the rule's options. */ - loadInDirectory(directoryPath, { basePath, name } = {}) { - const slots = internalSlotsMap$1.get(this); - - for (const filename of configFilenames) { - const ctx = createContext( - slots, - "config", - name, - path__default["default"].join(directoryPath, filename), - basePath - ); - - if (fs__default["default"].existsSync(ctx.filePath) && fs__default["default"].statSync(ctx.filePath).isFile()) { - let configData; + getRuleOptionsSchema(rule) { + if (!rule) { + return null; + } - try { - configData = loadConfigFile(ctx.filePath); - } catch (error) { - if (!error || error.code !== "ESLINT_CONFIG_FIELD_NOT_FOUND") { - throw error; - } - } + const schema = rule.schema || rule.meta && rule.meta.schema; - if (configData) { - debug$2(`Config file found: ${ctx.filePath}`); - return new ConfigArray( - ...this._normalizeConfigData(configData, ctx) - ); - } + // Given a tuple of schemas, insert warning level at the beginning + if (Array.isArray(schema)) { + if (schema.length) { + return { + type: "array", + items: schema, + minItems: 0, + maxItems: schema.length + }; } + return { + type: "array", + minItems: 0, + maxItems: 0 + }; + } - debug$2(`Config file not found on ${directoryPath}`); - return new ConfigArray(); + // Given a full schema, leave it alone + return schema || null; } /** - * Check if a config file on a given directory exists or not. - * @param {string} directoryPath The path to a directory. - * @returns {string | null} The path to the found config file. If not found then null. + * Validates a rule's severity and returns the severity value. Throws an error if the severity is invalid. + * @param {options} options The given options for the rule. + * @returns {number|string} The rule's severity value */ - static getPathToConfigFileInDirectory(directoryPath) { - for (const filename of configFilenames) { - const filePath = path__default["default"].join(directoryPath, filename); + validateRuleSeverity(options) { + const severity = Array.isArray(options) ? options[0] : options; + const normSeverity = typeof severity === "string" ? severityMap[severity.toLowerCase()] : severity; - if (fs__default["default"].existsSync(filePath)) { - if (filename === "package.json") { - try { - loadPackageJSONConfigFile(filePath); - return filePath; - } catch { /* ignore */ } - } else { - return filePath; - } - } + if (normSeverity === 0 || normSeverity === 1 || normSeverity === 2) { + return normSeverity; } - return null; - } - /** - * Load `.eslintignore` file. - * @param {string} filePath The path to a `.eslintignore` file to load. - * @returns {ConfigArray} Loaded config. An empty `ConfigArray` if any config doesn't exist. - */ - loadESLintIgnore(filePath) { - const slots = internalSlotsMap$1.get(this); - const ctx = createContext( - slots, - "ignore", - void 0, - filePath, - slots.cwd - ); - const ignorePatterns = loadESLintIgnoreFile(ctx.filePath); + throw new Error(`\tSeverity should be one of the following: 0 = off, 1 = warn, 2 = error (you passed '${util__default["default"].inspect(severity).replace(/'/gu, "\"").replace(/\n/gu, "")}').\n`); - return new ConfigArray( - ...this._normalizeESLintIgnoreData(ignorePatterns, ctx) - ); } /** - * Load `.eslintignore` file in the current working directory. - * @returns {ConfigArray} Loaded config. An empty `ConfigArray` if any config doesn't exist. + * Validates the non-severity options passed to a rule, based on its schema. + * @param {{create: Function}} rule The rule to validate + * @param {Array} localOptions The options for the rule, excluding severity + * @returns {void} */ - loadDefaultESLintIgnore() { - const slots = internalSlotsMap$1.get(this); - const eslintIgnorePath = path__default["default"].resolve(slots.cwd, ".eslintignore"); - const packageJsonPath = path__default["default"].resolve(slots.cwd, "package.json"); + validateRuleSchema(rule, localOptions) { + if (!ruleValidators.has(rule)) { + const schema = this.getRuleOptionsSchema(rule); - if (fs__default["default"].existsSync(eslintIgnorePath)) { - return this.loadESLintIgnore(eslintIgnorePath); + if (schema) { + ruleValidators.set(rule, ajv.compile(schema)); + } } - if (fs__default["default"].existsSync(packageJsonPath)) { - const data = loadJSONConfigFile(packageJsonPath); - if (Object.hasOwnProperty.call(data, "eslintIgnore")) { - if (!Array.isArray(data.eslintIgnore)) { - throw new Error("Package.json eslintIgnore property requires an array of paths"); - } - const ctx = createContext( - slots, - "ignore", - "eslintIgnore in package.json", - packageJsonPath, - slots.cwd - ); + const validateRule = ruleValidators.get(rule); - return new ConfigArray( - ...this._normalizeESLintIgnoreData(data.eslintIgnore, ctx) - ); + if (validateRule) { + validateRule(localOptions); + if (validateRule.errors) { + throw new Error(validateRule.errors.map( + error => `\tValue ${JSON.stringify(error.data)} ${error.message}.\n` + ).join("")); } } - - return new ConfigArray(); } /** - * Load a given config file. - * @param {ConfigArrayFactoryLoadingContext} ctx The loading context. - * @returns {IterableIterator} Loaded config. - * @private + * Validates a rule's options against its schema. + * @param {{create: Function}|null} rule The rule that the config is being validated for + * @param {string} ruleId The rule's unique name. + * @param {Array|number} options The given options for the rule. + * @param {string|null} source The name of the configuration source to report in any errors. If null or undefined, + * no source is prepended to the message. + * @returns {void} */ - _loadConfigData(ctx) { - return this._normalizeConfigData(loadConfigFile(ctx.filePath), ctx); - } + validateRuleOptions(rule, ruleId, options, source = null) { + try { + const severity = this.validateRuleSeverity(options); - /** - * Normalize a given `.eslintignore` data to config array elements. - * @param {string[]} ignorePatterns The patterns to ignore files. - * @param {ConfigArrayFactoryLoadingContext} ctx The loading context. - * @returns {IterableIterator} The normalized config. - * @private - */ - *_normalizeESLintIgnoreData(ignorePatterns, ctx) { - const elements = this._normalizeObjectConfigData( - { ignorePatterns }, - ctx - ); + if (severity !== 0) { + this.validateRuleSchema(rule, Array.isArray(options) ? options.slice(1) : []); + } + } catch (err) { + const enhancedMessage = `Configuration for rule "${ruleId}" is invalid:\n${err.message}`; - // Set `ignorePattern.loose` flag for backward compatibility. - for (const element of elements) { - if (element.ignorePattern) { - element.ignorePattern.loose = true; + if (typeof source === "string") { + throw new Error(`${source}:\n\t${enhancedMessage}`); + } else { + throw new Error(enhancedMessage); } - yield element; } } /** - * Normalize a given config to an array. - * @param {ConfigData} configData The config data to normalize. - * @param {ConfigArrayFactoryLoadingContext} ctx The loading context. - * @returns {IterableIterator} The normalized config. - * @private + * Validates an environment object + * @param {Object} environment The environment config object to validate. + * @param {string} source The name of the configuration source to report in any errors. + * @param {function(envId:string): Object} [getAdditionalEnv] A map from strings to loaded environments. + * @returns {void} */ - _normalizeConfigData(configData, ctx) { - const validator = new ConfigValidator(); - - validator.validateConfigSchema(configData, ctx.name || ctx.filePath); - return this._normalizeObjectConfigData(configData, ctx); - } + validateEnvironment( + environment, + source, + getAdditionalEnv = noop + ) { - /** - * Normalize a given config to an array. - * @param {ConfigData|OverrideConfigData} configData The config data to normalize. - * @param {ConfigArrayFactoryLoadingContext} ctx The loading context. - * @returns {IterableIterator} The normalized config. - * @private - */ - *_normalizeObjectConfigData(configData, ctx) { - const { files, excludedFiles, ...configBody } = configData; - const criteria = OverrideTester.create( - files, - excludedFiles, - ctx.matchBasePath - ); - const elements = this._normalizeObjectConfigDataBody(configBody, ctx); + // not having an environment is ok + if (!environment) { + return; + } - // Apply the criteria to every element. - for (const element of elements) { + Object.keys(environment).forEach(id => { + const env = getAdditionalEnv(id) || environments.get(id) || null; - /* - * Merge the criteria. - * This is for the `overrides` entries that came from the - * configurations of `overrides[].extends`. - */ - element.criteria = OverrideTester.and(criteria, element.criteria); + if (!env) { + const message = `${source}:\n\tEnvironment key "${id}" is unknown\n`; - /* - * Remove `root` property to ignore `root` settings which came from - * `extends` in `overrides`. - */ - if (element.criteria) { - element.root = void 0; + throw new Error(message); } - - yield element; - } + }); } /** - * Normalize a given config to an array. - * @param {ConfigData} configData The config data to normalize. - * @param {ConfigArrayFactoryLoadingContext} ctx The loading context. - * @returns {IterableIterator} The normalized config. - * @private + * Validates a rules config object + * @param {Object} rulesConfig The rules config object to validate. + * @param {string} source The name of the configuration source to report in any errors. + * @param {function(ruleId:string): Object} getAdditionalRule A map from strings to loaded rules + * @returns {void} */ - *_normalizeObjectConfigDataBody( - { - env, - extends: extend, - globals, - ignorePatterns, - noInlineConfig, - parser: parserName, - parserOptions, - plugins: pluginList, - processor, - reportUnusedDisableDirectives, - root, - rules, - settings, - overrides: overrideList = [] - }, - ctx + validateRules( + rulesConfig, + source, + getAdditionalRule = noop ) { - const extendList = Array.isArray(extend) ? extend : [extend]; - const ignorePattern = ignorePatterns && new IgnorePattern( - Array.isArray(ignorePatterns) ? ignorePatterns : [ignorePatterns], - ctx.matchBasePath - ); - - // Flatten `extends`. - for (const extendName of extendList.filter(Boolean)) { - yield* this._loadExtends(extendName, ctx); - } - - // Load parser & plugins. - const parser = parserName && this._loadParser(parserName, ctx); - const plugins = pluginList && this._loadPlugins(pluginList, ctx); - - // Yield pseudo config data for file extension processors. - if (plugins) { - yield* this._takeFileExtensionProcessors(plugins, ctx); + if (!rulesConfig) { + return; } - // Yield the config data except `extends` and `overrides`. - yield { - - // Debug information. - type: ctx.type, - name: ctx.name, - filePath: ctx.filePath, + Object.keys(rulesConfig).forEach(id => { + const rule = getAdditionalRule(id) || this.builtInRules.get(id) || null; - // Config data. - criteria: null, - env, - globals, - ignorePattern, - noInlineConfig, - parser, - parserOptions, - plugins, - processor, - reportUnusedDisableDirectives, - root, - rules, - settings - }; + this.validateRuleOptions(rule, id, rulesConfig[id], source); + }); + } - // Flatten `overries`. - for (let i = 0; i < overrideList.length; ++i) { - yield* this._normalizeObjectConfigData( - overrideList[i], - { ...ctx, name: `${ctx.name}#overrides[${i}]` } - ); + /** + * Validates a `globals` section of a config file + * @param {Object} globalsConfig The `globals` section + * @param {string|null} source The name of the configuration source to report in the event of an error. + * @returns {void} + */ + validateGlobals(globalsConfig, source = null) { + if (!globalsConfig) { + return; } + + Object.entries(globalsConfig) + .forEach(([configuredGlobal, configuredValue]) => { + try { + normalizeConfigGlobal(configuredValue); + } catch (err) { + throw new Error(`ESLint configuration of global '${configuredGlobal}' in ${source} is invalid:\n${err.message}`); + } + }); } /** - * Load configs of an element in `extends`. - * @param {string} extendName The name of a base config. - * @param {ConfigArrayFactoryLoadingContext} ctx The loading context. - * @returns {IterableIterator} The normalized config. - * @private + * Validate `processor` configuration. + * @param {string|undefined} processorName The processor name. + * @param {string} source The name of config file. + * @param {function(id:string): Processor} getProcessor The getter of defined processors. + * @returns {void} + */ + validateProcessor(processorName, source, getProcessor) { + if (processorName && !getProcessor(processorName)) { + throw new Error(`ESLint configuration of processor in '${source}' is invalid: '${processorName}' was not found.`); + } + } + + /** + * Formats an array of schema validation errors. + * @param {Array} errors An array of error messages to format. + * @returns {string} Formatted error message */ - _loadExtends(extendName, ctx) { - debug$2("Loading {extends:%j} relative to %s", extendName, ctx.filePath); - try { - if (extendName.startsWith("eslint:")) { - return this._loadExtendedBuiltInConfig(extendName, ctx); + formatErrors(errors) { + return errors.map(error => { + if (error.keyword === "additionalProperties") { + const formattedPropertyPath = error.dataPath.length ? `${error.dataPath.slice(1)}.${error.params.additionalProperty}` : error.params.additionalProperty; + + return `Unexpected top-level property "${formattedPropertyPath}"`; } - if (extendName.startsWith("plugin:")) { - return this._loadExtendedPluginConfig(extendName, ctx); + if (error.keyword === "type") { + const formattedField = error.dataPath.slice(1); + const formattedExpectedType = Array.isArray(error.schema) ? error.schema.join("/") : error.schema; + const formattedValue = JSON.stringify(error.data); + + return `Property "${formattedField}" is the wrong type (expected ${formattedExpectedType} but got \`${formattedValue}\`)`; } - return this._loadExtendedShareableConfig(extendName, ctx); - } catch (error) { - error.message += `\nReferenced from: ${ctx.filePath || ctx.name}`; - throw error; - } + + const field = error.dataPath[0] === "." ? error.dataPath.slice(1) : error.dataPath; + + return `"${field}" ${error.message}. Value: ${JSON.stringify(error.data)}`; + }).map(message => `\t- ${message}.\n`).join(""); } /** - * Load configs of an element in `extends`. - * @param {string} extendName The name of a base config. - * @param {ConfigArrayFactoryLoadingContext} ctx The loading context. - * @returns {IterableIterator} The normalized config. - * @private + * Validates the top level properties of the config object. + * @param {Object} config The config object to validate. + * @param {string} source The name of the configuration source to report in any errors. + * @returns {void} */ - _loadExtendedBuiltInConfig(extendName, ctx) { - const { eslintAllPath, eslintRecommendedPath } = internalSlotsMap$1.get(this); + validateConfigSchema(config, source = null) { + validateSchema = validateSchema || ajv.compile(configSchema); - if (extendName === "eslint:recommended") { - return this._loadConfigData({ - ...ctx, - filePath: eslintRecommendedPath, - name: `${ctx.name} » ${extendName}` - }); - } - if (extendName === "eslint:all") { - return this._loadConfigData({ - ...ctx, - filePath: eslintAllPath, - name: `${ctx.name} » ${extendName}` - }); + if (!validateSchema(config)) { + throw new Error(`ESLint configuration in ${source} is invalid:\n${this.formatErrors(validateSchema.errors)}`); } - throw configInvalidError(extendName, ctx.name, "extend-config-missing"); + if (Object.hasOwnProperty.call(config, "ecmaFeatures")) { + emitDeprecationWarning(source, "ESLINT_LEGACY_ECMAFEATURES"); + } } /** - * Load configs of an element in `extends`. - * @param {string} extendName The name of a base config. - * @param {ConfigArrayFactoryLoadingContext} ctx The loading context. - * @returns {IterableIterator} The normalized config. - * @private + * Validates an entire config object. + * @param {Object} config The config object to validate. + * @param {string} source The name of the configuration source to report in any errors. + * @param {function(ruleId:string): Object} [getAdditionalRule] A map from strings to loaded rules. + * @param {function(envId:string): Object} [getAdditionalEnv] A map from strings to loaded envs. + * @returns {void} */ - _loadExtendedPluginConfig(extendName, ctx) { - const slashIndex = extendName.lastIndexOf("/"); + validate(config, source, getAdditionalRule, getAdditionalEnv) { + this.validateConfigSchema(config, source); + this.validateRules(config.rules, source, getAdditionalRule); + this.validateEnvironment(config.env, source, getAdditionalEnv); + this.validateGlobals(config.globals, source); - if (slashIndex === -1) { - throw configInvalidError(extendName, ctx.filePath, "plugin-invalid"); + for (const override of config.overrides || []) { + this.validateRules(override.rules, source, getAdditionalRule); + this.validateEnvironment(override.env, source, getAdditionalEnv); + this.validateGlobals(config.globals, source); } + } - const pluginName = extendName.slice("plugin:".length, slashIndex); - const configName = extendName.slice(slashIndex + 1); + /** + * Validate config array object. + * @param {ConfigArray} configArray The config array to validate. + * @returns {void} + */ + validateConfigArray(configArray) { + const getPluginEnv = Map.prototype.get.bind(configArray.pluginEnvironments); + const getPluginProcessor = Map.prototype.get.bind(configArray.pluginProcessors); + const getPluginRule = Map.prototype.get.bind(configArray.pluginRules); - if (isFilePath(pluginName)) { - throw new Error("'extends' cannot use a file path for plugins."); + // Validate. + for (const element of configArray) { + if (validated.has(element)) { + continue; + } + validated.add(element); + + this.validateEnvironment(element.env, element.name, getPluginEnv); + this.validateGlobals(element.globals, element.name); + this.validateProcessor(element.processor, element.name, getPluginProcessor); + this.validateRules(element.rules, element.name, getPluginRule); } + } - const plugin = this._loadPlugin(pluginName, ctx); - const configData = - plugin.definition && - plugin.definition.configs[configName]; +} - if (configData) { - return this._normalizeConfigData(configData, { - ...ctx, - filePath: plugin.filePath || ctx.filePath, - name: `${ctx.name} » plugin:${plugin.id}/${configName}` - }); - } +/** + * @fileoverview Common helpers for naming of plugins, formatters and configs + */ - throw plugin.error || configInvalidError(extendName, ctx.filePath, "extend-config-missing"); - } +const NAMESPACE_REGEX = /^@.*\//iu; + +/** + * Brings package name to correct format based on prefix + * @param {string} name The name of the package. + * @param {string} prefix Can be either "eslint-plugin", "eslint-config" or "eslint-formatter" + * @returns {string} Normalized name of the package + * @private + */ +function normalizePackageName(name, prefix) { + let normalizedName = name; /** - * Load configs of an element in `extends`. - * @param {string} extendName The name of a base config. - * @param {ConfigArrayFactoryLoadingContext} ctx The loading context. - * @returns {IterableIterator} The normalized config. - * @private + * On Windows, name can come in with Windows slashes instead of Unix slashes. + * Normalize to Unix first to avoid errors later on. + * https://github.com/eslint/eslint/issues/5644 */ - _loadExtendedShareableConfig(extendName, ctx) { - const { cwd, resolver } = internalSlotsMap$1.get(this); - const relativeTo = ctx.filePath || path__default["default"].join(cwd, "__placeholder__.js"); - let request; + if (normalizedName.includes("\\")) { + normalizedName = normalizedName.replace(/\\/gu, "/"); + } - if (isFilePath(extendName)) { - request = extendName; - } else if (extendName.startsWith(".")) { - request = `./${extendName}`; // For backward compatibility. A ton of tests depended on this behavior. - } else { - request = normalizePackageName( - extendName, - "eslint-config" - ); + if (normalizedName.charAt(0) === "@") { + + /** + * it's a scoped package + * package name is the prefix, or just a username + */ + const scopedPackageShortcutRegex = new RegExp(`^(@[^/]+)(?:/(?:${prefix})?)?$`, "u"), + scopedPackageNameRegex = new RegExp(`^${prefix}(-|$)`, "u"); + + if (scopedPackageShortcutRegex.test(normalizedName)) { + normalizedName = normalizedName.replace(scopedPackageShortcutRegex, `$1/${prefix}`); + } else if (!scopedPackageNameRegex.test(normalizedName.split("/")[1])) { + + /** + * for scoped packages, insert the prefix after the first / unless + * the path is already @scope/eslint or @scope/eslint-xxx-yyy + */ + normalizedName = normalizedName.replace(/^@([^/]+)\/(.*)$/u, `@$1/${prefix}-$2`); } + } else if (!normalizedName.startsWith(`${prefix}-`)) { + normalizedName = `${prefix}-${normalizedName}`; + } - let filePath; + return normalizedName; +} - try { - filePath = resolver.resolve(request, relativeTo); - } catch (error) { - /* istanbul ignore else */ - if (error && error.code === "MODULE_NOT_FOUND") { - throw configInvalidError(extendName, ctx.filePath, "extend-config-missing"); - } - throw error; +/** + * Removes the prefix from a fullname. + * @param {string} fullname The term which may have the prefix. + * @param {string} prefix The prefix to remove. + * @returns {string} The term without prefix. + */ +function getShorthandName(fullname, prefix) { + if (fullname[0] === "@") { + let matchResult = new RegExp(`^(@[^/]+)/${prefix}$`, "u").exec(fullname); + + if (matchResult) { + return matchResult[1]; } - writeDebugLogForLoading(request, relativeTo, filePath); - return this._loadConfigData({ - ...ctx, - filePath, - name: `${ctx.name} » ${request}` - }); + matchResult = new RegExp(`^(@[^/]+)/${prefix}-(.+)$`, "u").exec(fullname); + if (matchResult) { + return `${matchResult[1]}/${matchResult[2]}`; + } + } else if (fullname.startsWith(`${prefix}-`)) { + return fullname.slice(prefix.length + 1); } - /** - * Load given plugins. - * @param {string[]} names The plugin names to load. - * @param {ConfigArrayFactoryLoadingContext} ctx The loading context. - * @returns {Record} The loaded parser. - * @private - */ - _loadPlugins(names, ctx) { - return names.reduce((map, name) => { - if (isFilePath(name)) { - throw new Error("Plugins array cannot includes file paths."); - } - const plugin = this._loadPlugin(name, ctx); + return fullname; +} - map[plugin.id] = plugin; +/** + * Gets the scope (namespace) of a term. + * @param {string} term The term which may have the namespace. + * @returns {string} The namespace of the term if it has one. + */ +function getNamespaceFromTerm(term) { + const match = term.match(NAMESPACE_REGEX); - return map; - }, {}); + return match ? match[0] : ""; +} + +var naming = { + __proto__: null, + normalizePackageName: normalizePackageName, + getShorthandName: getShorthandName, + getNamespaceFromTerm: getNamespaceFromTerm +}; + +/** + * Utility for resolving a module relative to another module + * @author Teddy Katz + */ + +/* + * `Module.createRequire` is added in v12.2.0. It supports URL as well. + * We only support the case where the argument is a filepath, not a URL. + */ +const createRequire = Module__default["default"].createRequire; + +/** + * Resolves a Node module relative to another module + * @param {string} moduleName The name of a Node module, or a path to a Node module. + * @param {string} relativeToPath An absolute path indicating the module that `moduleName` should be resolved relative to. This must be + * a file rather than a directory, but the file need not actually exist. + * @returns {string} The absolute path that would result from calling `require.resolve(moduleName)` in a file located at `relativeToPath` + */ +function resolve(moduleName, relativeToPath) { + try { + return createRequire(relativeToPath).resolve(moduleName); + } catch (error) { + + // This `if` block is for older Node.js than 12.0.0. We can remove this block in the future. + if ( + typeof error === "object" && + error !== null && + error.code === "MODULE_NOT_FOUND" && + !error.requireStack && + error.message.includes(moduleName) + ) { + error.message += `\nRequire stack:\n- ${relativeToPath}`; + } + throw error; } +} - /** - * Load a given parser. - * @param {string} nameOrPath The package name or the path to a parser file. - * @param {ConfigArrayFactoryLoadingContext} ctx The loading context. - * @returns {DependentParser} The loaded parser. - */ - _loadParser(nameOrPath, ctx) { - debug$2("Loading parser %j from %s", nameOrPath, ctx.filePath); +var ModuleResolver = { + __proto__: null, + resolve: resolve +}; - const { cwd, resolver } = internalSlotsMap$1.get(this); - const relativeTo = ctx.filePath || path__default["default"].join(cwd, "__placeholder__.js"); +/** + * @fileoverview `IgnorePattern` class. + * + * `IgnorePattern` class has the set of glob patterns and the base path. + * + * It provides two static methods. + * + * - `IgnorePattern.createDefaultIgnore(cwd)` + * Create the default predicate function. + * - `IgnorePattern.createIgnore(ignorePatterns)` + * Create the predicate function from multiple `IgnorePattern` objects. + * + * It provides two properties and a method. + * + * - `patterns` + * The glob patterns that ignore to lint. + * - `basePath` + * The base path of the glob patterns. If absolute paths existed in the + * glob patterns, those are handled as relative paths to the base path. + * - `getPatternsRelativeTo(basePath)` + * Get `patterns` as modified for a given base path. It modifies the + * absolute paths in the patterns as prepending the difference of two base + * paths. + * + * `ConfigArrayFactory` creates `IgnorePattern` objects when it processes + * `ignorePatterns` properties. + * + * @author Toru Nagashima + */ - try { - const filePath = resolver.resolve(nameOrPath, relativeTo); +const debug$3 = debugOrig__default["default"]("eslintrc:ignore-pattern"); - writeDebugLogForLoading(nameOrPath, relativeTo, filePath); +/** @typedef {ReturnType} Ignore */ - return new ConfigDependency({ - definition: require$1(filePath), - filePath, - id: nameOrPath, - importerName: ctx.name, - importerPath: ctx.filePath - }); - } catch (error) { +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ - // If the parser name is "espree", load the espree of ESLint. - if (nameOrPath === "espree") { - debug$2("Fallback espree."); - return new ConfigDependency({ - definition: require$1("espree"), - filePath: require$1.resolve("espree"), - id: nameOrPath, - importerName: ctx.name, - importerPath: ctx.filePath - }); - } +/** + * Get the path to the common ancestor directory of given paths. + * @param {string[]} sourcePaths The paths to calculate the common ancestor. + * @returns {string} The path to the common ancestor directory. + */ +function getCommonAncestorPath(sourcePaths) { + let result = sourcePaths[0]; - debug$2("Failed to load parser '%s' declared in '%s'.", nameOrPath, ctx.name); - error.message = `Failed to load parser '${nameOrPath}' declared in '${ctx.name}': ${error.message}`; + for (let i = 1; i < sourcePaths.length; ++i) { + const a = result; + const b = sourcePaths[i]; - return new ConfigDependency({ - error, - id: nameOrPath, - importerName: ctx.name, - importerPath: ctx.filePath - }); + // Set the shorter one (it's the common ancestor if one includes the other). + result = a.length < b.length ? a : b; + + // Set the common ancestor. + for (let j = 0, lastSepPos = 0; j < a.length && j < b.length; ++j) { + if (a[j] !== b[j]) { + result = a.slice(0, lastSepPos); + break; + } + if (a[j] === path__default["default"].sep) { + lastSepPos = j; + } } } - /** - * Load a given plugin. - * @param {string} name The plugin name to load. - * @param {ConfigArrayFactoryLoadingContext} ctx The loading context. - * @returns {DependentPlugin} The loaded plugin. - * @private - */ - _loadPlugin(name, ctx) { - debug$2("Loading plugin %j from %s", name, ctx.filePath); + let resolvedResult = result || path__default["default"].sep; - const { additionalPluginPool, resolver } = internalSlotsMap$1.get(this); - const request = normalizePackageName(name, "eslint-plugin"); - const id = getShorthandName(request, "eslint-plugin"); - const relativeTo = path__default["default"].join(ctx.pluginBasePath, "__placeholder__.js"); + // if Windows common ancestor is root of drive must have trailing slash to be absolute. + if (resolvedResult && resolvedResult.endsWith(":") && process.platform === "win32") { + resolvedResult += path__default["default"].sep; + } + return resolvedResult; +} - if (name.match(/\s+/u)) { - const error = Object.assign( - new Error(`Whitespace found in plugin name '${name}'`), - { - messageTemplate: "whitespace-found", - messageData: { pluginName: request } - } - ); +/** + * Make relative path. + * @param {string} from The source path to get relative path. + * @param {string} to The destination path to get relative path. + * @returns {string} The relative path. + */ +function relative(from, to) { + const relPath = path__default["default"].relative(from, to); - return new ConfigDependency({ - error, - id, - importerName: ctx.name, - importerPath: ctx.filePath - }); - } + if (path__default["default"].sep === "/") { + return relPath; + } + return relPath.split(path__default["default"].sep).join("/"); +} - // Check for additional pool. - const plugin = - additionalPluginPool.get(request) || - additionalPluginPool.get(id); +/** + * Get the trailing slash if existed. + * @param {string} filePath The path to check. + * @returns {string} The trailing slash if existed. + */ +function dirSuffix(filePath) { + const isDir = ( + filePath.endsWith(path__default["default"].sep) || + (process.platform === "win32" && filePath.endsWith("/")) + ); - if (plugin) { - return new ConfigDependency({ - definition: normalizePlugin(plugin), - filePath: "", // It's unknown where the plugin came from. - id, - importerName: ctx.name, - importerPath: ctx.filePath - }); - } + return isDir ? "/" : ""; +} + +const DefaultPatterns = Object.freeze(["/**/node_modules/*"]); +const DotPatterns = Object.freeze([".*", "!.eslintrc.*", "!../"]); + +//------------------------------------------------------------------------------ +// Public +//------------------------------------------------------------------------------ + +class IgnorePattern { + + /** + * The default patterns. + * @type {string[]} + */ + static get DefaultPatterns() { + return DefaultPatterns; + } + + /** + * Create the default predicate function. + * @param {string} cwd The current working directory. + * @returns {((filePath:string, dot:boolean) => boolean) & {basePath:string; patterns:string[]}} + * The preficate function. + * The first argument is an absolute path that is checked. + * The second argument is the flag to not ignore dotfiles. + * If the predicate function returned `true`, it means the path should be ignored. + */ + static createDefaultIgnore(cwd) { + return this.createIgnore([new IgnorePattern(DefaultPatterns, cwd)]); + } + + /** + * Create the predicate function from multiple `IgnorePattern` objects. + * @param {IgnorePattern[]} ignorePatterns The list of ignore patterns. + * @returns {((filePath:string, dot?:boolean) => boolean) & {basePath:string; patterns:string[]}} + * The preficate function. + * The first argument is an absolute path that is checked. + * The second argument is the flag to not ignore dotfiles. + * If the predicate function returned `true`, it means the path should be ignored. + */ + static createIgnore(ignorePatterns) { + debug$3("Create with: %o", ignorePatterns); + + const basePath = getCommonAncestorPath(ignorePatterns.map(p => p.basePath)); + const patterns = [].concat( + ...ignorePatterns.map(p => p.getPatternsRelativeTo(basePath)) + ); + const ig = ignore__default["default"]().add([...DotPatterns, ...patterns]); + const dotIg = ignore__default["default"]().add(patterns); - let filePath; - let error; + debug$3(" processed: %o", { basePath, patterns }); - try { - filePath = resolver.resolve(request, relativeTo); - } catch (resolveError) { - error = resolveError; - /* istanbul ignore else */ - if (error && error.code === "MODULE_NOT_FOUND") { - error.messageTemplate = "plugin-missing"; - error.messageData = { - pluginName: request, - resolvePluginsRelativeTo: ctx.pluginBasePath, - importerName: ctx.name - }; - } - } + return Object.assign( + (filePath, dot = false) => { + assert__default["default"](path__default["default"].isAbsolute(filePath), "'filePath' should be an absolute path."); + const relPathRaw = relative(basePath, filePath); + const relPath = relPathRaw && (relPathRaw + dirSuffix(filePath)); + const adoptedIg = dot ? dotIg : ig; + const result = relPath !== "" && adoptedIg.ignores(relPath); - if (filePath) { - try { - writeDebugLogForLoading(request, relativeTo, filePath); + debug$3("Check", { filePath, dot, relativePath: relPath, result }); + return result; + }, + { basePath, patterns } + ); + } - const startTime = Date.now(); - const pluginDefinition = require$1(filePath); + /** + * Initialize a new `IgnorePattern` instance. + * @param {string[]} patterns The glob patterns that ignore to lint. + * @param {string} basePath The base path of `patterns`. + */ + constructor(patterns, basePath) { + assert__default["default"](path__default["default"].isAbsolute(basePath), "'basePath' should be an absolute path."); - debug$2(`Plugin ${filePath} loaded in: ${Date.now() - startTime}ms`); + /** + * The glob patterns that ignore to lint. + * @type {string[]} + */ + this.patterns = patterns; - return new ConfigDependency({ - definition: normalizePlugin(pluginDefinition), - filePath, - id, - importerName: ctx.name, - importerPath: ctx.filePath - }); - } catch (loadError) { - error = loadError; - } - } + /** + * The base path of `patterns`. + * @type {string} + */ + this.basePath = basePath; - debug$2("Failed to load plugin '%s' declared in '%s'.", name, ctx.name); - error.message = `Failed to load plugin '${name}' declared in '${ctx.name}': ${error.message}`; - return new ConfigDependency({ - error, - id, - importerName: ctx.name, - importerPath: ctx.filePath - }); + /** + * If `true` then patterns which don't start with `/` will match the paths to the outside of `basePath`. Defaults to `false`. + * + * It's set `true` for `.eslintignore`, `package.json`, and `--ignore-path` for backward compatibility. + * It's `false` as-is for `ignorePatterns` property in config files. + * @type {boolean} + */ + this.loose = false; } /** - * Take file expression processors as config array elements. - * @param {Record} plugins The plugin definitions. - * @param {ConfigArrayFactoryLoadingContext} ctx The loading context. - * @returns {IterableIterator} The config array elements of file expression processors. - * @private + * Get `patterns` as modified for a given base path. It modifies the + * absolute paths in the patterns as prepending the difference of two base + * paths. + * @param {string} newBasePath The base path. + * @returns {string[]} Modifired patterns. */ - *_takeFileExtensionProcessors(plugins, ctx) { - for (const pluginId of Object.keys(plugins)) { - const processors = - plugins[pluginId] && - plugins[pluginId].definition && - plugins[pluginId].definition.processors; + getPatternsRelativeTo(newBasePath) { + assert__default["default"](path__default["default"].isAbsolute(newBasePath), "'newBasePath' should be an absolute path."); + const { basePath, loose, patterns } = this; - if (!processors) { - continue; - } + if (newBasePath === basePath) { + return patterns; + } + const prefix = `/${relative(newBasePath, basePath)}`; - for (const processorId of Object.keys(processors)) { - if (processorId.startsWith(".")) { - yield* this._normalizeObjectConfigData( - { - files: [`*${processorId}`], - processor: `${pluginId}/${processorId}` - }, - { - ...ctx, - type: "implicit-processor", - name: `${ctx.name}#processors["${pluginId}/${processorId}"]` - } - ); - } + return patterns.map(pattern => { + const negative = pattern.startsWith("!"); + const head = negative ? "!" : ""; + const body = negative ? pattern.slice(1) : pattern; + + if (body.startsWith("/") || body.startsWith("../")) { + return `${head}${prefix}${body}`; } - } + return loose ? pattern : `${head}${prefix}/**/${body}`; + }); } } /** - * @fileoverview `CascadingConfigArrayFactory` class. + * @fileoverview `ExtractedConfig` class. * - * `CascadingConfigArrayFactory` class has a responsibility: + * `ExtractedConfig` class expresses a final configuration for a specific file. * - * 1. Handles cascading of config files. + * It provides one method. * - * It provides two methods: + * - `toCompatibleObjectAsConfigFileContent()` + * Convert this configuration to the compatible object as the content of + * config files. It converts the loaded parser and plugins to strings. + * `CLIEngine#getConfigForFile(filePath)` method uses this method. * - * - `getConfigArrayForFile(filePath)` - * Get the corresponded configuration of a given file. This method doesn't - * throw even if the given file didn't exist. - * - `clearCache()` - * Clear the internal cache. You have to call this method when - * `additionalPluginPool` was updated if `baseConfig` or `cliConfig` depends - * on the additional plugins. (`CLIEngine#addPlugin()` method calls this.) + * `ConfigArray#extractConfig(filePath)` creates a `ExtractedConfig` instance. * * @author Toru Nagashima */ -const debug$1 = debugOrig__default["default"]("eslintrc:cascading-config-array-factory"); - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -// Define types for VSCode IntelliSense. -/** @typedef {import("./shared/types").ConfigData} ConfigData */ -/** @typedef {import("./shared/types").Parser} Parser */ -/** @typedef {import("./shared/types").Plugin} Plugin */ -/** @typedef {import("./shared/types").Rule} Rule */ -/** @typedef {ReturnType} ConfigArray */ +// For VSCode intellisense +/** @typedef {import("../../shared/types").ConfigData} ConfigData */ +/** @typedef {import("../../shared/types").GlobalConf} GlobalConf */ +/** @typedef {import("../../shared/types").SeverityConf} SeverityConf */ +/** @typedef {import("./config-dependency").DependentParser} DependentParser */ +/** @typedef {import("./config-dependency").DependentPlugin} DependentPlugin */ /** - * @typedef {Object} CascadingConfigArrayFactoryOptions - * @property {Map} [additionalPluginPool] The map for additional plugins. - * @property {ConfigData} [baseConfig] The config by `baseConfig` option. - * @property {ConfigData} [cliConfig] The config by CLI options (`--env`, `--global`, `--ignore-pattern`, `--parser`, `--parser-options`, `--plugin`, and `--rule`). CLI options overwrite the setting in config files. - * @property {string} [cwd] The base directory to start lookup. - * @property {string} [ignorePath] The path to the alternative file of `.eslintignore`. - * @property {string[]} [rulePaths] The value of `--rulesdir` option. - * @property {string} [specificConfigPath] The value of `--config` option. - * @property {boolean} [useEslintrc] if `false` then it doesn't load config files. - * @property {Function} loadRules The function to use to load rules. - * @property {Map} builtInRules The rules that are built in to ESLint. - * @property {Object} [resolver=ModuleResolver] The module resolver object. - * @property {string} eslintAllPath The path to the definitions for eslint:all. - * @property {string} eslintRecommendedPath The path to the definitions for eslint:recommended. + * Check if `xs` starts with `ys`. + * @template T + * @param {T[]} xs The array to check. + * @param {T[]} ys The array that may be the first part of `xs`. + * @returns {boolean} `true` if `xs` starts with `ys`. */ +function startsWith(xs, ys) { + return xs.length >= ys.length && ys.every((y, i) => y === xs[i]); +} /** - * @typedef {Object} CascadingConfigArrayFactoryInternalSlots - * @property {ConfigArray} baseConfigArray The config array of `baseConfig` option. - * @property {ConfigData} baseConfigData The config data of `baseConfig` option. This is used to reset `baseConfigArray`. - * @property {ConfigArray} cliConfigArray The config array of CLI options. - * @property {ConfigData} cliConfigData The config data of CLI options. This is used to reset `cliConfigArray`. - * @property {ConfigArrayFactory} configArrayFactory The factory for config arrays. - * @property {Map} configCache The cache from directory paths to config arrays. - * @property {string} cwd The base directory to start lookup. - * @property {WeakMap} finalizeCache The cache from config arrays to finalized config arrays. - * @property {string} [ignorePath] The path to the alternative file of `.eslintignore`. - * @property {string[]|null} rulePaths The value of `--rulesdir` option. This is used to reset `baseConfigArray`. - * @property {string|null} specificConfigPath The value of `--config` option. This is used to reset `cliConfigArray`. - * @property {boolean} useEslintrc if `false` then it doesn't load config files. - * @property {Function} loadRules The function to use to load rules. - * @property {Map} builtInRules The rules that are built in to ESLint. - * @property {Object} [resolver=ModuleResolver] The module resolver object. - * @property {string} eslintAllPath The path to the definitions for eslint:all. - * @property {string} eslintRecommendedPath The path to the definitions for eslint:recommended. + * The class for extracted config data. */ +class ExtractedConfig { + constructor() { -/** @type {WeakMap} */ -const internalSlotsMap = new WeakMap(); + /** + * The config name what `noInlineConfig` setting came from. + * @type {string} + */ + this.configNameOfNoInlineConfig = ""; -/** - * Create the config array from `baseConfig` and `rulePaths`. - * @param {CascadingConfigArrayFactoryInternalSlots} slots The slots. - * @returns {ConfigArray} The config array of the base configs. - */ -function createBaseConfigArray({ - configArrayFactory, - baseConfigData, - rulePaths, - cwd, - loadRules -}) { - const baseConfigArray = configArrayFactory.create( - baseConfigData, - { name: "BaseConfig" } - ); + /** + * Environments. + * @type {Record} + */ + this.env = {}; - /* - * Create the config array element for the default ignore patterns. - * This element has `ignorePattern` property that ignores the default - * patterns in the current working directory. - */ - baseConfigArray.unshift(configArrayFactory.create( - { ignorePatterns: IgnorePattern.DefaultPatterns }, - { name: "DefaultIgnorePattern" } - )[0]); + /** + * Global variables. + * @type {Record} + */ + this.globals = {}; - /* - * Load rules `--rulesdir` option as a pseudo plugin. - * Use a pseudo plugin to define rules of `--rulesdir`, so we can validate - * the rule's options with only information in the config array. - */ - if (rulePaths && rulePaths.length > 0) { - baseConfigArray.push({ - type: "config", - name: "--rulesdir", - filePath: "", - plugins: { - "": new ConfigDependency({ - definition: { - rules: rulePaths.reduce( - (map, rulesPath) => Object.assign( - map, - loadRules(rulesPath, cwd) - ), - {} - ) - }, - filePath: "", - id: "", - importerName: "--rulesdir", - importerPath: "" - }) - } - }); - } + /** + * The glob patterns that ignore to lint. + * @type {(((filePath:string, dot?:boolean) => boolean) & { basePath:string; patterns:string[] }) | undefined} + */ + this.ignores = void 0; - return baseConfigArray; -} + /** + * The flag that disables directive comments. + * @type {boolean|undefined} + */ + this.noInlineConfig = void 0; -/** - * Create the config array from CLI options. - * @param {CascadingConfigArrayFactoryInternalSlots} slots The slots. - * @returns {ConfigArray} The config array of the base configs. - */ -function createCLIConfigArray({ - cliConfigData, - configArrayFactory, - cwd, - ignorePath, - specificConfigPath -}) { - const cliConfigArray = configArrayFactory.create( - cliConfigData, - { name: "CLIOptions" } - ); + /** + * Parser definition. + * @type {DependentParser|null} + */ + this.parser = null; - cliConfigArray.unshift( - ...(ignorePath - ? configArrayFactory.loadESLintIgnore(ignorePath) - : configArrayFactory.loadDefaultESLintIgnore()) - ); + /** + * Options for the parser. + * @type {Object} + */ + this.parserOptions = {}; - if (specificConfigPath) { - cliConfigArray.unshift( - ...configArrayFactory.loadFile( - specificConfigPath, - { name: "--config", basePath: cwd } - ) - ); - } + /** + * Plugin definitions. + * @type {Record} + */ + this.plugins = {}; - return cliConfigArray; -} + /** + * Processor ID. + * @type {string|null} + */ + this.processor = null; -/** - * The error type when there are files matched by a glob, but all of them have been ignored. - */ -class ConfigurationNotFoundError extends Error { + /** + * The flag that reports unused `eslint-disable` directive comments. + * @type {boolean|undefined} + */ + this.reportUnusedDisableDirectives = void 0; + + /** + * Rule settings. + * @type {Record} + */ + this.rules = {}; + + /** + * Shared settings. + * @type {Object} + */ + this.settings = {}; + } - // eslint-disable-next-line jsdoc/require-description /** - * @param {string} directoryPath The directory path. + * Convert this config to the compatible object as a config file content. + * @returns {ConfigData} The converted object. */ - constructor(directoryPath) { - super(`No ESLint configuration found in ${directoryPath}.`); - this.messageTemplate = "no-config-found"; - this.messageData = { directoryPath }; + toCompatibleObjectAsConfigFileContent() { + const { + /* eslint-disable no-unused-vars */ + configNameOfNoInlineConfig: _ignore1, + processor: _ignore2, + /* eslint-enable no-unused-vars */ + ignores, + ...config + } = this; + + config.parser = config.parser && config.parser.filePath; + config.plugins = Object.keys(config.plugins).filter(Boolean).reverse(); + config.ignorePatterns = ignores ? ignores.patterns : []; + + // Strip the default patterns from `ignorePatterns`. + if (startsWith(config.ignorePatterns, IgnorePattern.DefaultPatterns)) { + config.ignorePatterns = + config.ignorePatterns.slice(IgnorePattern.DefaultPatterns.length); + } + + return config; } } /** - * This class provides the functionality that enumerates every file which is - * matched by given glob patterns and that configuration. + * @fileoverview `ConfigArray` class. + * + * `ConfigArray` class expresses the full of a configuration. It has the entry + * config file, base config files that were extended, loaded parsers, and loaded + * plugins. + * + * `ConfigArray` class provides three properties and two methods. + * + * - `pluginEnvironments` + * - `pluginProcessors` + * - `pluginRules` + * The `Map` objects that contain the members of all plugins that this + * config array contains. Those map objects don't have mutation methods. + * Those keys are the member ID such as `pluginId/memberName`. + * - `isRoot()` + * If `true` then this configuration has `root:true` property. + * - `extractConfig(filePath)` + * Extract the final configuration for a given file. This means merging + * every config array element which that `criteria` property matched. The + * `filePath` argument must be an absolute path. + * + * `ConfigArrayFactory` provides the loading logic of config files. + * + * @author Toru Nagashima */ -class CascadingConfigArrayFactory { - /** - * Initialize this enumerator. - * @param {CascadingConfigArrayFactoryOptions} options The options. - */ - constructor({ - additionalPluginPool = new Map(), - baseConfig: baseConfigData = null, - cliConfig: cliConfigData = null, - cwd = process.cwd(), - ignorePath, - resolvePluginsRelativeTo, - rulePaths = [], - specificConfigPath = null, - useEslintrc = true, - builtInRules = new Map(), - loadRules, - resolver, - eslintRecommendedPath, - eslintAllPath - } = {}) { - const configArrayFactory = new ConfigArrayFactory({ - additionalPluginPool, - cwd, - resolvePluginsRelativeTo, - builtInRules, - resolver, - eslintRecommendedPath, - eslintAllPath - }); +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +// Define types for VSCode IntelliSense. +/** @typedef {import("../../shared/types").Environment} Environment */ +/** @typedef {import("../../shared/types").GlobalConf} GlobalConf */ +/** @typedef {import("../../shared/types").RuleConf} RuleConf */ +/** @typedef {import("../../shared/types").Rule} Rule */ +/** @typedef {import("../../shared/types").Plugin} Plugin */ +/** @typedef {import("../../shared/types").Processor} Processor */ +/** @typedef {import("./config-dependency").DependentParser} DependentParser */ +/** @typedef {import("./config-dependency").DependentPlugin} DependentPlugin */ +/** @typedef {import("./override-tester")["OverrideTester"]} OverrideTester */ + +/** + * @typedef {Object} ConfigArrayElement + * @property {string} name The name of this config element. + * @property {string} filePath The path to the source file of this config element. + * @property {InstanceType|null} criteria The tester for the `files` and `excludedFiles` of this config element. + * @property {Record|undefined} env The environment settings. + * @property {Record|undefined} globals The global variable settings. + * @property {IgnorePattern|undefined} ignorePattern The ignore patterns. + * @property {boolean|undefined} noInlineConfig The flag that disables directive comments. + * @property {DependentParser|undefined} parser The parser loader. + * @property {Object|undefined} parserOptions The parser options. + * @property {Record|undefined} plugins The plugin loaders. + * @property {string|undefined} processor The processor name to refer plugin's processor. + * @property {boolean|undefined} reportUnusedDisableDirectives The flag to report unused `eslint-disable` comments. + * @property {boolean|undefined} root The flag to express root. + * @property {Record|undefined} rules The rule settings + * @property {Object|undefined} settings The shared settings. + * @property {"config" | "ignore" | "implicit-processor"} type The element type. + */ + +/** + * @typedef {Object} ConfigArrayInternalSlots + * @property {Map} cache The cache to extract configs. + * @property {ReadonlyMap|null} envMap The map from environment ID to environment definition. + * @property {ReadonlyMap|null} processorMap The map from processor ID to environment definition. + * @property {ReadonlyMap|null} ruleMap The map from rule ID to rule definition. + */ + +/** @type {WeakMap} */ +const internalSlotsMap$2 = new class extends WeakMap { + get(key) { + let value = super.get(key); + + if (!value) { + value = { + cache: new Map(), + envMap: null, + processorMap: null, + ruleMap: null + }; + super.set(key, value); + } - internalSlotsMap.set(this, { - baseConfigArray: createBaseConfigArray({ - baseConfigData, - configArrayFactory, - cwd, - rulePaths, - loadRules, - resolver - }), - baseConfigData, - cliConfigArray: createCLIConfigArray({ - cliConfigData, - configArrayFactory, - cwd, - ignorePath, - specificConfigPath - }), - cliConfigData, - configArrayFactory, - configCache: new Map(), - cwd, - finalizeCache: new WeakMap(), - ignorePath, - rulePaths, - specificConfigPath, - useEslintrc, - builtInRules, - loadRules - }); + return value; } +}(); - /** - * The path to the current working directory. - * This is used by tests. - * @type {string} - */ - get cwd() { - const { cwd } = internalSlotsMap.get(this); +/** + * Get the indices which are matched to a given file. + * @param {ConfigArrayElement[]} elements The elements. + * @param {string} filePath The path to a target file. + * @returns {number[]} The indices. + */ +function getMatchedIndices(elements, filePath) { + const indices = []; - return cwd; + for (let i = elements.length - 1; i >= 0; --i) { + const element = elements[i]; + + if (!element.criteria || (filePath && element.criteria.test(filePath))) { + indices.push(i); + } } - /** - * Get the config array of a given file. - * If `filePath` was not given, it returns the config which contains only - * `baseConfigData` and `cliConfigData`. - * @param {string} [filePath] The file path to a file. - * @param {Object} [options] The options. - * @param {boolean} [options.ignoreNotFoundError] If `true` then it doesn't throw `ConfigurationNotFoundError`. - * @returns {ConfigArray} The config array of the file. - */ - getConfigArrayForFile(filePath, { ignoreNotFoundError = false } = {}) { - const { - baseConfigArray, - cliConfigArray, - cwd - } = internalSlotsMap.get(this); + return indices; +} - if (!filePath) { - return new ConfigArray(...baseConfigArray, ...cliConfigArray); - } +/** + * Check if a value is a non-null object. + * @param {any} x The value to check. + * @returns {boolean} `true` if the value is a non-null object. + */ +function isNonNullObject(x) { + return typeof x === "object" && x !== null; +} - const directoryPath = path__default["default"].dirname(path__default["default"].resolve(cwd, filePath)); +/** + * Merge two objects. + * + * Assign every property values of `y` to `x` if `x` doesn't have the property. + * If `x`'s property value is an object, it does recursive. + * @param {Object} target The destination to merge + * @param {Object|undefined} source The source to merge. + * @returns {void} + */ +function mergeWithoutOverwrite(target, source) { + if (!isNonNullObject(source)) { + return; + } - debug$1(`Load config files for ${directoryPath}.`); + for (const key of Object.keys(source)) { + if (key === "__proto__") { + continue; + } - return this._finalizeConfigArray( - this._loadConfigInAncestors(directoryPath), - directoryPath, - ignoreNotFoundError - ); + if (isNonNullObject(target[key])) { + mergeWithoutOverwrite(target[key], source[key]); + } else if (target[key] === void 0) { + if (isNonNullObject(source[key])) { + target[key] = Array.isArray(source[key]) ? [] : {}; + mergeWithoutOverwrite(target[key], source[key]); + } else if (source[key] !== void 0) { + target[key] = source[key]; + } + } } +} + +/** + * The error for plugin conflicts. + */ +class PluginConflictError extends Error { /** - * Set the config data to override all configs. - * Require to call `clearCache()` method after this method is called. - * @param {ConfigData} configData The config data to override all configs. - * @returns {void} + * Initialize this error object. + * @param {string} pluginId The plugin ID. + * @param {{filePath:string, importerName:string}[]} plugins The resolved plugins. */ - setOverrideConfig(configData) { - const slots = internalSlotsMap.get(this); + constructor(pluginId, plugins) { + super(`Plugin "${pluginId}" was conflicted between ${plugins.map(p => `"${p.importerName}"`).join(" and ")}.`); + this.messageTemplate = "plugin-conflict"; + this.messageData = { pluginId, plugins }; + } +} - slots.cliConfigData = configData; +/** + * Merge plugins. + * `target`'s definition is prior to `source`'s. + * @param {Record} target The destination to merge + * @param {Record|undefined} source The source to merge. + * @returns {void} + */ +function mergePlugins(target, source) { + if (!isNonNullObject(source)) { + return; } - /** - * Clear config cache. - * @returns {void} - */ - clearCache() { - const slots = internalSlotsMap.get(this); + for (const key of Object.keys(source)) { + if (key === "__proto__") { + continue; + } + const targetValue = target[key]; + const sourceValue = source[key]; - slots.baseConfigArray = createBaseConfigArray(slots); - slots.cliConfigArray = createCLIConfigArray(slots); - slots.configCache.clear(); + // Adopt the plugin which was found at first. + if (targetValue === void 0) { + if (sourceValue.error) { + throw sourceValue.error; + } + target[key] = sourceValue; + } else if (sourceValue.filePath !== targetValue.filePath) { + throw new PluginConflictError(key, [ + { + filePath: targetValue.filePath, + importerName: targetValue.importerName + }, + { + filePath: sourceValue.filePath, + importerName: sourceValue.importerName + } + ]); + } } +} - /** - * Load and normalize config files from the ancestor directories. - * @param {string} directoryPath The path to a leaf directory. - * @param {boolean} configsExistInSubdirs `true` if configurations exist in subdirectories. - * @returns {ConfigArray} The loaded config. - * @private - */ - _loadConfigInAncestors(directoryPath, configsExistInSubdirs = false) { - const { - baseConfigArray, - configArrayFactory, - configCache, - cwd, - useEslintrc - } = internalSlotsMap.get(this); +/** + * Merge rule configs. + * `target`'s definition is prior to `source`'s. + * @param {Record} target The destination to merge + * @param {Record|undefined} source The source to merge. + * @returns {void} + */ +function mergeRuleConfigs(target, source) { + if (!isNonNullObject(source)) { + return; + } - if (!useEslintrc) { - return baseConfigArray; + for (const key of Object.keys(source)) { + if (key === "__proto__") { + continue; } + const targetDef = target[key]; + const sourceDef = source[key]; - let configArray = configCache.get(directoryPath); + // Adopt the rule config which was found at first. + if (targetDef === void 0) { + if (Array.isArray(sourceDef)) { + target[key] = [...sourceDef]; + } else { + target[key] = [sourceDef]; + } - // Hit cache. - if (configArray) { - debug$1(`Cache hit: ${directoryPath}.`); - return configArray; + /* + * If the first found rule config is severity only and the current rule + * config has options, merge the severity and the options. + */ + } else if ( + targetDef.length === 1 && + Array.isArray(sourceDef) && + sourceDef.length >= 2 + ) { + targetDef.push(...sourceDef.slice(1)); } - debug$1(`No cache found: ${directoryPath}.`); + } +} - const homePath = os__default["default"].homedir(); +/** + * Create the extracted config. + * @param {ConfigArray} instance The config elements. + * @param {number[]} indices The indices to use. + * @returns {ExtractedConfig} The extracted config. + */ +function createConfig(instance, indices) { + const config = new ExtractedConfig(); + const ignorePatterns = []; - // Consider this is root. - if (directoryPath === homePath && cwd !== homePath) { - debug$1("Stop traversing because of considered root."); - if (configsExistInSubdirs) { - const filePath = ConfigArrayFactory.getPathToConfigFileInDirectory(directoryPath); + // Merge elements. + for (const index of indices) { + const element = instance[index]; - if (filePath) { - emitDeprecationWarning( - filePath, - "ESLINT_PERSONAL_CONFIG_SUPPRESS" - ); - } + // Adopt the parser which was found at first. + if (!config.parser && element.parser) { + if (element.parser.error) { + throw element.parser.error; } - return this._cacheConfig(directoryPath, baseConfigArray); + config.parser = element.parser; } - // Load the config on this directory. - try { - configArray = configArrayFactory.loadInDirectory(directoryPath); - } catch (error) { - /* istanbul ignore next */ - if (error.code === "EACCES") { - debug$1("Stop traversing because of 'EACCES' error."); - return this._cacheConfig(directoryPath, baseConfigArray); - } - throw error; + // Adopt the processor which was found at first. + if (!config.processor && element.processor) { + config.processor = element.processor; } - if (configArray.length > 0 && configArray.isRoot()) { - debug$1("Stop traversing because of 'root:true'."); - configArray.unshift(...baseConfigArray); - return this._cacheConfig(directoryPath, configArray); + // Adopt the noInlineConfig which was found at first. + if (config.noInlineConfig === void 0 && element.noInlineConfig !== void 0) { + config.noInlineConfig = element.noInlineConfig; + config.configNameOfNoInlineConfig = element.name; } - // Load from the ancestors and merge it. - const parentPath = path__default["default"].dirname(directoryPath); - const parentConfigArray = parentPath && parentPath !== directoryPath - ? this._loadConfigInAncestors( - parentPath, - configsExistInSubdirs || configArray.length > 0 - ) - : baseConfigArray; + // Adopt the reportUnusedDisableDirectives which was found at first. + if (config.reportUnusedDisableDirectives === void 0 && element.reportUnusedDisableDirectives !== void 0) { + config.reportUnusedDisableDirectives = element.reportUnusedDisableDirectives; + } - if (configArray.length > 0) { - configArray.unshift(...parentConfigArray); - } else { - configArray = parentConfigArray; + // Collect ignorePatterns + if (element.ignorePattern) { + ignorePatterns.push(element.ignorePattern); } - // Cache and return. - return this._cacheConfig(directoryPath, configArray); + // Merge others. + mergeWithoutOverwrite(config.env, element.env); + mergeWithoutOverwrite(config.globals, element.globals); + mergeWithoutOverwrite(config.parserOptions, element.parserOptions); + mergeWithoutOverwrite(config.settings, element.settings); + mergePlugins(config.plugins, element.plugins); + mergeRuleConfigs(config.rules, element.rules); } - /** - * Freeze and cache a given config. - * @param {string} directoryPath The path to a directory as a cache key. - * @param {ConfigArray} configArray The config array as a cache value. - * @returns {ConfigArray} The `configArray` (frozen). - */ - _cacheConfig(directoryPath, configArray) { - const { configCache } = internalSlotsMap.get(this); - - Object.freeze(configArray); - configCache.set(directoryPath, configArray); - - return configArray; + // Create the predicate function for ignore patterns. + if (ignorePatterns.length > 0) { + config.ignores = IgnorePattern.createIgnore(ignorePatterns.reverse()); } - /** - * Finalize a given config array. - * Concatenate `--config` and other CLI options. - * @param {ConfigArray} configArray The parent config array. - * @param {string} directoryPath The path to the leaf directory to find config files. - * @param {boolean} ignoreNotFoundError If `true` then it doesn't throw `ConfigurationNotFoundError`. - * @returns {ConfigArray} The loaded config. - * @private - */ - _finalizeConfigArray(configArray, directoryPath, ignoreNotFoundError) { - const { - cliConfigArray, - configArrayFactory, - finalizeCache, - useEslintrc, - builtInRules - } = internalSlotsMap.get(this); - - let finalConfigArray = finalizeCache.get(configArray); - - if (!finalConfigArray) { - finalConfigArray = configArray; - - // Load the personal config if there are no regular config files. - if ( - useEslintrc && - configArray.every(c => !c.filePath) && - cliConfigArray.every(c => !c.filePath) // `--config` option can be a file. - ) { - const homePath = os__default["default"].homedir(); - - debug$1("Loading the config file of the home directory:", homePath); - - const personalConfigArray = configArrayFactory.loadInDirectory( - homePath, - { name: "PersonalConfig" } - ); - - if ( - personalConfigArray.length > 0 && - !directoryPath.startsWith(homePath) - ) { - const lastElement = - personalConfigArray[personalConfigArray.length - 1]; - - emitDeprecationWarning( - lastElement.filePath, - "ESLINT_PERSONAL_CONFIG_LOAD" - ); - } - - finalConfigArray = finalConfigArray.concat(personalConfigArray); - } - - // Apply CLI options. - if (cliConfigArray.length > 0) { - finalConfigArray = finalConfigArray.concat(cliConfigArray); - } - - // Validate rule settings and environments. - const validator = new ConfigValidator({ - builtInRules - }); - - validator.validateConfigArray(finalConfigArray); + return config; +} - // Cache it. - Object.freeze(finalConfigArray); - finalizeCache.set(configArray, finalConfigArray); +/** + * Collect definitions. + * @template T, U + * @param {string} pluginId The plugin ID for prefix. + * @param {Record} defs The definitions to collect. + * @param {Map} map The map to output. + * @param {function(T): U} [normalize] The normalize function for each value. + * @returns {void} + */ +function collect(pluginId, defs, map, normalize) { + if (defs) { + const prefix = pluginId && `${pluginId}/`; - debug$1( - "Configuration was determined: %o on %s", - finalConfigArray, - directoryPath + for (const [key, value] of Object.entries(defs)) { + map.set( + `${prefix}${key}`, + normalize ? normalize(value) : value ); } - - // At least one element (the default ignore patterns) exists. - if (!ignoreNotFoundError && useEslintrc && finalConfigArray.length <= 1) { - throw new ConfigurationNotFoundError(directoryPath); - } - - return finalConfigArray; } } /** - * @fileoverview Compatibility class for flat config. - * @author Nicholas C. Zakas + * Normalize a rule definition. + * @param {Function|Rule} rule The rule definition to normalize. + * @returns {Rule} The normalized rule definition. */ +function normalizePluginRule(rule) { + return typeof rule === "function" ? { create: rule } : rule; +} -const dirname = path__default["default"].dirname(url.fileURLToPath((typeof document === 'undefined' ? new ((__webpack_require__(876).URL))('file:' + __filename).href : (document.currentScript && document.currentScript.src || new URL('eslintrc.cjs', document.baseURI).href)))); - -//----------------------------------------------------------------------------- -// Helpers -//----------------------------------------------------------------------------- - -/** @typedef {import("../../shared/types").Environment} Environment */ -/** @typedef {import("../../shared/types").Processor} Processor */ - -const debug = debugOrig__default["default"]("eslintrc:flat-compat"); -const cafactory = Symbol("cafactory"); +/** + * Delete the mutation methods from a given map. + * @param {Map} map The map object to delete. + * @returns {void} + */ +function deleteMutationMethods(map) { + Object.defineProperties(map, { + clear: { configurable: true, value: void 0 }, + delete: { configurable: true, value: void 0 }, + set: { configurable: true, value: void 0 } + }); +} /** - * Translates an ESLintRC-style config object into a flag-config-style config - * object. - * @param {Object} eslintrcConfig An ESLintRC-style config object. - * @param {Object} options Options to help translate the config. - * @param {string} options.resolveConfigRelativeTo To the directory to resolve - * configs from. - * @param {string} options.resolvePluginsRelativeTo The directory to resolve - * plugins from. - * @param {ReadOnlyMap} options.pluginEnvironments A map of plugin environment - * names to objects. - * @param {ReadOnlyMap} options.pluginProcessors A map of plugin processor - * names to objects. - * @returns {Object} A flag-config-style config object. + * Create `envMap`, `processorMap`, `ruleMap` with the plugins in the config array. + * @param {ConfigArrayElement[]} elements The config elements. + * @param {ConfigArrayInternalSlots} slots The internal slots. + * @returns {void} */ -function translateESLintRC(eslintrcConfig, { - resolveConfigRelativeTo, - resolvePluginsRelativeTo, - pluginEnvironments, - pluginProcessors -}) { +function initPluginMemberMaps(elements, slots) { + const processed = new Set(); - const flatConfig = {}; - const configs = []; - const languageOptions = {}; - const linterOptions = {}; - const keysToCopy = ["settings", "rules", "processor"]; - const languageOptionsKeysToCopy = ["globals", "parser", "parserOptions"]; - const linterOptionsKeysToCopy = ["noInlineConfig", "reportUnusedDisableDirectives"]; + slots.envMap = new Map(); + slots.processorMap = new Map(); + slots.ruleMap = new Map(); - // check for special settings for eslint:all and eslint:recommended: - if (eslintrcConfig.settings) { - if (eslintrcConfig.settings["eslint:all"] === true) { - return ["eslint:all"]; + for (const element of elements) { + if (!element.plugins) { + continue; } - if (eslintrcConfig.settings["eslint:recommended"] === true) { - return ["eslint:recommended"]; + for (const [pluginId, value] of Object.entries(element.plugins)) { + const plugin = value.definition; + + if (!plugin || processed.has(pluginId)) { + continue; + } + processed.add(pluginId); + + collect(pluginId, plugin.environments, slots.envMap); + collect(pluginId, plugin.processors, slots.processorMap); + collect(pluginId, plugin.rules, slots.ruleMap, normalizePluginRule); } } - // copy over simple translations - for (const key of keysToCopy) { - if (key in eslintrcConfig && typeof eslintrcConfig[key] !== "undefined") { - flatConfig[key] = eslintrcConfig[key]; - } + deleteMutationMethods(slots.envMap); + deleteMutationMethods(slots.processorMap); + deleteMutationMethods(slots.ruleMap); +} + +/** + * Create `envMap`, `processorMap`, `ruleMap` with the plugins in the config array. + * @param {ConfigArray} instance The config elements. + * @returns {ConfigArrayInternalSlots} The extracted config. + */ +function ensurePluginMemberMaps(instance) { + const slots = internalSlotsMap$2.get(instance); + + if (!slots.ruleMap) { + initPluginMemberMaps(instance, slots); } - // copy over languageOptions - for (const key of languageOptionsKeysToCopy) { - if (key in eslintrcConfig && typeof eslintrcConfig[key] !== "undefined") { + return slots; +} - // create the languageOptions key in the flat config - flatConfig.languageOptions = languageOptions; +//------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ - if (key === "parser") { - debug(`Resolving parser '${languageOptions[key]}' relative to ${resolveConfigRelativeTo}`); +/** + * The Config Array. + * + * `ConfigArray` instance contains all settings, parsers, and plugins. + * You need to call `ConfigArray#extractConfig(filePath)` method in order to + * extract, merge and get only the config data which is related to an arbitrary + * file. + * @extends {Array} + */ +class ConfigArray extends Array { - if (eslintrcConfig[key].error) { - throw eslintrcConfig[key].error; - } + /** + * Get the plugin environments. + * The returned map cannot be mutated. + * @type {ReadonlyMap} The plugin environments. + */ + get pluginEnvironments() { + return ensurePluginMemberMaps(this).envMap; + } - languageOptions[key] = eslintrcConfig[key].definition; - continue; - } + /** + * Get the plugin processors. + * The returned map cannot be mutated. + * @type {ReadonlyMap} The plugin processors. + */ + get pluginProcessors() { + return ensurePluginMemberMaps(this).processorMap; + } - // clone any object values that are in the eslintrc config - if (eslintrcConfig[key] && typeof eslintrcConfig[key] === "object") { - languageOptions[key] = { - ...eslintrcConfig[key] - }; - } else { - languageOptions[key] = eslintrcConfig[key]; - } - } + /** + * Get the plugin rules. + * The returned map cannot be mutated. + * @returns {ReadonlyMap} The plugin rules. + */ + get pluginRules() { + return ensurePluginMemberMaps(this).ruleMap; } - // copy over linterOptions - for (const key of linterOptionsKeysToCopy) { - if (key in eslintrcConfig && typeof eslintrcConfig[key] !== "undefined") { - flatConfig.linterOptions = linterOptions; - linterOptions[key] = eslintrcConfig[key]; + /** + * Check if this config has `root` flag. + * @returns {boolean} `true` if this config array is root. + */ + isRoot() { + for (let i = this.length - 1; i >= 0; --i) { + const root = this[i].root; + + if (typeof root === "boolean") { + return root; + } } + return false; } - // move ecmaVersion a level up - if (languageOptions.parserOptions) { + /** + * Extract the config data which is related to a given file. + * @param {string} filePath The absolute path to the target file. + * @returns {ExtractedConfig} The extracted config data. + */ + extractConfig(filePath) { + const { cache } = internalSlotsMap$2.get(this); + const indices = getMatchedIndices(this, filePath); + const cacheKey = indices.join(","); - if ("ecmaVersion" in languageOptions.parserOptions) { - languageOptions.ecmaVersion = languageOptions.parserOptions.ecmaVersion; - delete languageOptions.parserOptions.ecmaVersion; + if (!cache.has(cacheKey)) { + cache.set(cacheKey, createConfig(this, indices)); } - if ("sourceType" in languageOptions.parserOptions) { - languageOptions.sourceType = languageOptions.parserOptions.sourceType; - delete languageOptions.parserOptions.sourceType; - } + return cache.get(cacheKey); + } - // check to see if we even need parserOptions anymore and remove it if not - if (Object.keys(languageOptions.parserOptions).length === 0) { - delete languageOptions.parserOptions; + /** + * Check if a given path is an additional lint target. + * @param {string} filePath The absolute path to the target file. + * @returns {boolean} `true` if the file is an additional lint target. + */ + isAdditionalTargetPath(filePath) { + for (const { criteria, type } of this) { + if ( + type === "config" && + criteria && + !criteria.endsWithWildcard && + criteria.test(filePath) + ) { + return true; + } } + return false; } +} - // overrides - if (eslintrcConfig.criteria) { - flatConfig.files = [absoluteFilePath => eslintrcConfig.criteria.test(absoluteFilePath)]; - } +/** + * Get the used extracted configs. + * CLIEngine will use this method to collect used deprecated rules. + * @param {ConfigArray} instance The config array object to get. + * @returns {ExtractedConfig[]} The used extracted configs. + * @private + */ +function getUsedExtractedConfigs(instance) { + const { cache } = internalSlotsMap$2.get(instance); - // translate plugins - if (eslintrcConfig.plugins && typeof eslintrcConfig.plugins === "object") { - debug(`Translating plugins: ${eslintrcConfig.plugins}`); + return Array.from(cache.values()); +} - flatConfig.plugins = {}; +/** + * @fileoverview `ConfigDependency` class. + * + * `ConfigDependency` class expresses a loaded parser or plugin. + * + * If the parser or plugin was loaded successfully, it has `definition` property + * and `filePath` property. Otherwise, it has `error` property. + * + * When `JSON.stringify()` converted a `ConfigDependency` object to a JSON, it + * omits `definition` property. + * + * `ConfigArrayFactory` creates `ConfigDependency` objects when it loads parsers + * or plugins. + * + * @author Toru Nagashima + */ - for (const pluginName of Object.keys(eslintrcConfig.plugins)) { +/** + * The class is to store parsers or plugins. + * This class hides the loaded object from `JSON.stringify()` and `console.log`. + * @template T + */ +class ConfigDependency { - debug(`Translating plugin: ${pluginName}`); - debug(`Resolving plugin '${pluginName} relative to ${resolvePluginsRelativeTo}`); + /** + * Initialize this instance. + * @param {Object} data The dependency data. + * @param {T} [data.definition] The dependency if the loading succeeded. + * @param {Error} [data.error] The error object if the loading failed. + * @param {string} [data.filePath] The actual path to the dependency if the loading succeeded. + * @param {string} data.id The ID of this dependency. + * @param {string} data.importerName The name of the config file which loads this dependency. + * @param {string} data.importerPath The path to the config file which loads this dependency. + */ + constructor({ + definition = null, + error = null, + filePath = null, + id, + importerName, + importerPath + }) { - const { definition: plugin, error } = eslintrcConfig.plugins[pluginName]; + /** + * The loaded dependency if the loading succeeded. + * @type {T|null} + */ + this.definition = definition; - if (error) { - throw error; - } + /** + * The error object if the loading failed. + * @type {Error|null} + */ + this.error = error; - flatConfig.plugins[pluginName] = plugin; + /** + * The loaded dependency if the loading succeeded. + * @type {string|null} + */ + this.filePath = filePath; - // create a config for any processors - if (plugin.processors) { - for (const processorName of Object.keys(plugin.processors)) { - if (processorName.startsWith(".")) { - debug(`Assigning processor: ${pluginName}/${processorName}`); + /** + * The ID of this dependency. + * @type {string} + */ + this.id = id; - configs.unshift({ - files: [`**/*${processorName}`], - processor: pluginProcessors.get(`${pluginName}/${processorName}`) - }); - } + /** + * The name of the config file which loads this dependency. + * @type {string} + */ + this.importerName = importerName; - } - } - } + /** + * The path to the config file which loads this dependency. + * @type {string} + */ + this.importerPath = importerPath; } - // translate env - must come after plugins - if (eslintrcConfig.env && typeof eslintrcConfig.env === "object") { - for (const envName of Object.keys(eslintrcConfig.env)) { + // eslint-disable-next-line jsdoc/require-description + /** + * @returns {Object} a JSON compatible object. + */ + toJSON() { + const obj = this[util__default["default"].inspect.custom](); - // only add environments that are true - if (eslintrcConfig.env[envName]) { - debug(`Translating environment: ${envName}`); + // Display `error.message` (`Error#message` is unenumerable). + if (obj.error instanceof Error) { + obj.error = { ...obj.error, message: obj.error.message }; + } - if (environments.has(envName)) { + return obj; + } - // built-in environments should be defined first - configs.unshift(...translateESLintRC(environments.get(envName), { - resolveConfigRelativeTo, - resolvePluginsRelativeTo - })); - } else if (pluginEnvironments.has(envName)) { + // eslint-disable-next-line jsdoc/require-description + /** + * @returns {Object} an object to display by `console.log()`. + */ + [util__default["default"].inspect.custom]() { + const { + definition: _ignore, // eslint-disable-line no-unused-vars + ...obj + } = this; - // if the environment comes from a plugin, it should come after the plugin config - configs.push(...translateESLintRC(pluginEnvironments.get(envName), { - resolveConfigRelativeTo, - resolvePluginsRelativeTo - })); - } - } - } + return obj; } +} - // only add if there are actually keys in the config - if (Object.keys(flatConfig).length > 0) { - configs.push(flatConfig); - } +/** + * @fileoverview `OverrideTester` class. + * + * `OverrideTester` class handles `files` property and `excludedFiles` property + * of `overrides` config. + * + * It provides one method. + * + * - `test(filePath)` + * Test if a file path matches the pair of `files` property and + * `excludedFiles` property. The `filePath` argument must be an absolute + * path. + * + * `ConfigArrayFactory` creates `OverrideTester` objects when it processes + * `overrides` properties. + * + * @author Toru Nagashima + */ - return configs; -} +const { Minimatch } = minimatch__default["default"]; +const minimatchOpts = { dot: true, matchBase: true }; -//----------------------------------------------------------------------------- -// Exports -//----------------------------------------------------------------------------- +/** + * @typedef {Object} Pattern + * @property {InstanceType[] | null} includes The positive matchers. + * @property {InstanceType[] | null} excludes The negative matchers. + */ /** - * A compatibility class for working with configs. + * Normalize a given pattern to an array. + * @param {string|string[]|undefined} patterns A glob pattern or an array of glob patterns. + * @returns {string[]|null} Normalized patterns. + * @private */ -class FlatCompat { +function normalizePatterns(patterns) { + if (Array.isArray(patterns)) { + return patterns.filter(Boolean); + } + if (typeof patterns === "string" && patterns) { + return [patterns]; + } + return []; +} - constructor({ - baseDirectory = process.cwd(), - resolvePluginsRelativeTo = baseDirectory - } = {}) { - this.baseDirectory = baseDirectory; - this.resolvePluginsRelativeTo = resolvePluginsRelativeTo; - this[cafactory] = new ConfigArrayFactory({ - cwd: baseDirectory, - resolvePluginsRelativeTo, - eslintAllPath: path__default["default"].resolve(dirname, "../conf/eslint-all.cjs"), - eslintRecommendedPath: path__default["default"].resolve(dirname, "../conf/eslint-recommended.cjs") - }); +/** + * Create the matchers of given patterns. + * @param {string[]} patterns The patterns. + * @returns {InstanceType[] | null} The matchers. + */ +function toMatcher(patterns) { + if (patterns.length === 0) { + return null; } + return patterns.map(pattern => { + if (/^\.[/\\]/u.test(pattern)) { + return new Minimatch( + pattern.slice(2), + + // `./*.js` should not match with `subdir/foo.js` + { ...minimatchOpts, matchBase: false } + ); + } + return new Minimatch(pattern, minimatchOpts); + }); +} + +/** + * Convert a given matcher to string. + * @param {Pattern} matchers The matchers. + * @returns {string} The string expression of the matcher. + */ +function patternToJson({ includes, excludes }) { + return { + includes: includes && includes.map(m => m.pattern), + excludes: excludes && excludes.map(m => m.pattern) + }; +} + +/** + * The class to test given paths are matched by the patterns. + */ +class OverrideTester { /** - * Translates an ESLintRC-style config into a flag-config-style config. - * @param {Object} eslintrcConfig The ESLintRC-style config object. - * @returns {Object} A flag-config-style config object. + * Create a tester with given criteria. + * If there are no criteria, returns `null`. + * @param {string|string[]} files The glob patterns for included files. + * @param {string|string[]} excludedFiles The glob patterns for excluded files. + * @param {string} basePath The path to the base directory to test paths. + * @returns {OverrideTester|null} The created instance or `null`. */ - config(eslintrcConfig) { - const eslintrcArray = this[cafactory].create(eslintrcConfig, { - basePath: this.baseDirectory - }); + static create(files, excludedFiles, basePath) { + const includePatterns = normalizePatterns(files); + const excludePatterns = normalizePatterns(excludedFiles); + let endsWithWildcard = false; - const flatArray = []; - let hasIgnorePatterns = false; + if (includePatterns.length === 0) { + return null; + } - eslintrcArray.forEach(configData => { - if (configData.type === "config") { - hasIgnorePatterns = hasIgnorePatterns || configData.ignorePattern; - flatArray.push(...translateESLintRC(configData, { - resolveConfigRelativeTo: path__default["default"].join(this.baseDirectory, "__placeholder.js"), - resolvePluginsRelativeTo: path__default["default"].join(this.resolvePluginsRelativeTo, "__placeholder.js"), - pluginEnvironments: eslintrcArray.pluginEnvironments, - pluginProcessors: eslintrcArray.pluginProcessors - })); + // Rejects absolute paths or relative paths to parents. + for (const pattern of includePatterns) { + if (path__default["default"].isAbsolute(pattern) || pattern.includes("..")) { + throw new Error(`Invalid override pattern (expected relative path not containing '..'): ${pattern}`); } - }); + if (pattern.endsWith("*")) { + endsWithWildcard = true; + } + } + for (const pattern of excludePatterns) { + if (path__default["default"].isAbsolute(pattern) || pattern.includes("..")) { + throw new Error(`Invalid override pattern (expected relative path not containing '..'): ${pattern}`); + } + } - // combine ignorePatterns to emulate ESLintRC behavior better - if (hasIgnorePatterns) { - flatArray.unshift({ - ignores: [filePath => { + const includes = toMatcher(includePatterns); + const excludes = toMatcher(excludePatterns); - // Compute the final config for this file. - // This filters config array elements by `files`/`excludedFiles` then merges the elements. - const finalConfig = eslintrcArray.extractConfig(filePath); + return new OverrideTester( + [{ includes, excludes }], + basePath, + endsWithWildcard + ); + } - // Test the `ignorePattern` properties of the final config. - return Boolean(finalConfig.ignores) && finalConfig.ignores(filePath); - }] - }); + /** + * Combine two testers by logical and. + * If either of the testers was `null`, returns the other tester. + * The `basePath` property of the two must be the same value. + * @param {OverrideTester|null} a A tester. + * @param {OverrideTester|null} b Another tester. + * @returns {OverrideTester|null} Combined tester. + */ + static and(a, b) { + if (!b) { + return a && new OverrideTester( + a.patterns, + a.basePath, + a.endsWithWildcard + ); + } + if (!a) { + return new OverrideTester( + b.patterns, + b.basePath, + b.endsWithWildcard + ); } - return flatArray; + assert__default["default"].strictEqual(a.basePath, b.basePath); + return new OverrideTester( + a.patterns.concat(b.patterns), + a.basePath, + a.endsWithWildcard || b.endsWithWildcard + ); } /** - * Translates the `env` section of an ESLintRC-style config. - * @param {Object} envConfig The `env` section of an ESLintRC config. - * @returns {Object} A flag-config object representing the environments. + * Initialize this instance. + * @param {Pattern[]} patterns The matchers. + * @param {string} basePath The base path. + * @param {boolean} endsWithWildcard If `true` then a pattern ends with `*`. + */ + constructor(patterns, basePath, endsWithWildcard = false) { + + /** @type {Pattern[]} */ + this.patterns = patterns; + + /** @type {string} */ + this.basePath = basePath; + + /** @type {boolean} */ + this.endsWithWildcard = endsWithWildcard; + } + + /** + * Test if a given path is matched or not. + * @param {string} filePath The absolute path to the target file. + * @returns {boolean} `true` if the path was matched. */ - env(envConfig) { - return this.config({ - env: envConfig - }); + test(filePath) { + if (typeof filePath !== "string" || !path__default["default"].isAbsolute(filePath)) { + throw new Error(`'filePath' should be an absolute path, but got ${filePath}.`); + } + const relativePath = path__default["default"].relative(this.basePath, filePath); + + return this.patterns.every(({ includes, excludes }) => ( + (!includes || includes.some(m => m.match(relativePath))) && + (!excludes || !excludes.some(m => m.match(relativePath))) + )); } + // eslint-disable-next-line jsdoc/require-description /** - * Translates the `extends` section of an ESLintRC-style config. - * @param {...string} configsToExtend The names of the configs to load. - * @returns {Object} A flag-config object representing the config. + * @returns {Object} a JSON compatible object. */ - extends(...configsToExtend) { - return this.config({ - extends: configsToExtend - }); + toJSON() { + if (this.patterns.length === 1) { + return { + ...patternToJson(this.patterns[0]), + basePath: this.basePath + }; + } + return { + AND: this.patterns.map(patternToJson), + basePath: this.basePath + }; } + // eslint-disable-next-line jsdoc/require-description /** - * Translates the `plugins` section of an ESLintRC-style config. - * @param {...string} plugins The names of the plugins to load. - * @returns {Object} A flag-config object representing the plugins. + * @returns {Object} an object to display by `console.log()`. */ - plugins(...plugins) { - return this.config({ - plugins - }); + [util__default["default"].inspect.custom]() { + return this.toJSON(); } } /** - * @fileoverview Package exports for @eslint/eslintrc - * @author Nicholas C. Zakas + * @fileoverview `ConfigArray` class. + * @author Toru Nagashima */ -//----------------------------------------------------------------------------- -// Exports -//----------------------------------------------------------------------------- +/** + * @fileoverview The factory of `ConfigArray` objects. + * + * This class provides methods to create `ConfigArray` instance. + * + * - `create(configData, options)` + * Create a `ConfigArray` instance from a config data. This is to handle CLI + * options except `--config`. + * - `loadFile(filePath, options)` + * Create a `ConfigArray` instance from a config file. This is to handle + * `--config` option. If the file was not found, throws the following error: + * - If the filename was `*.js`, a `MODULE_NOT_FOUND` error. + * - If the filename was `package.json`, an IO error or an + * `ESLINT_CONFIG_FIELD_NOT_FOUND` error. + * - Otherwise, an IO error such as `ENOENT`. + * - `loadInDirectory(directoryPath, options)` + * Create a `ConfigArray` instance from a config file which is on a given + * directory. This tries to load `.eslintrc.*` or `package.json`. If not + * found, returns an empty `ConfigArray`. + * - `loadESLintIgnore(filePath)` + * Create a `ConfigArray` instance from a config file that is `.eslintignore` + * format. This is to handle `--ignore-path` option. + * - `loadDefaultESLintIgnore()` + * Create a `ConfigArray` instance from `.eslintignore` or `package.json` in + * the current working directory. + * + * `ConfigArrayFactory` class has the responsibility that loads configuration + * files, including loading `extends`, `parser`, and `plugins`. The created + * `ConfigArray` instance has the loaded `extends`, `parser`, and `plugins`. + * + * But this class doesn't handle cascading. `CascadingConfigArrayFactory` class + * handles cascading and hierarchy. + * + * @author Toru Nagashima + */ +const require$1 = Module.createRequire((typeof document === 'undefined' ? new ((__webpack_require__(892).URL))('file:' + __filename).href : (document.currentScript && document.currentScript.src || new URL('eslintrc.cjs', document.baseURI).href))); -const Legacy = { - ConfigArray, - createConfigArrayFactoryContext: createContext, - CascadingConfigArrayFactory, - ConfigArrayFactory, - ConfigDependency, - ExtractedConfig, - IgnorePattern, - OverrideTester, - getUsedExtractedConfigs, - environments, +const debug$2 = debugOrig__default["default"]("eslintrc:config-array-factory"); - // shared - ConfigOps, - ConfigValidator, - ModuleResolver, - naming -}; +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ -exports.FlatCompat = FlatCompat; -exports.Legacy = Legacy; -//# sourceMappingURL=eslintrc.cjs.map +const configFilenames = [ + ".eslintrc.js", + ".eslintrc.cjs", + ".eslintrc.yaml", + ".eslintrc.yml", + ".eslintrc.json", + ".eslintrc", + "package.json" +]; + +// Define types for VSCode IntelliSense. +/** @typedef {import("./shared/types").ConfigData} ConfigData */ +/** @typedef {import("./shared/types").OverrideConfigData} OverrideConfigData */ +/** @typedef {import("./shared/types").Parser} Parser */ +/** @typedef {import("./shared/types").Plugin} Plugin */ +/** @typedef {import("./shared/types").Rule} Rule */ +/** @typedef {import("./config-array/config-dependency").DependentParser} DependentParser */ +/** @typedef {import("./config-array/config-dependency").DependentPlugin} DependentPlugin */ +/** @typedef {ConfigArray[0]} ConfigArrayElement */ +/** + * @typedef {Object} ConfigArrayFactoryOptions + * @property {Map} [additionalPluginPool] The map for additional plugins. + * @property {string} [cwd] The path to the current working directory. + * @property {string} [resolvePluginsRelativeTo] A path to the directory that plugins should be resolved from. Defaults to `cwd`. + * @property {Map} builtInRules The rules that are built in to ESLint. + * @property {Object} [resolver=ModuleResolver] The module resolver object. + * @property {string} eslintAllPath The path to the definitions for eslint:all. + * @property {string} eslintRecommendedPath The path to the definitions for eslint:recommended. + */ -/***/ }), -/* 864 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +/** + * @typedef {Object} ConfigArrayFactoryInternalSlots + * @property {Map} additionalPluginPool The map for additional plugins. + * @property {string} cwd The path to the current working directory. + * @property {string | undefined} resolvePluginsRelativeTo An absolute path the the directory that plugins should be resolved from. + * @property {Map} builtInRules The rules that are built in to ESLint. + * @property {Object} [resolver=ModuleResolver] The module resolver object. + * @property {string} eslintAllPath The path to the definitions for eslint:all. + * @property {string} eslintRecommendedPath The path to the definitions for eslint:recommended. + */ -"use strict"; +/** + * @typedef {Object} ConfigArrayFactoryLoadingContext + * @property {string} filePath The path to the current configuration. + * @property {string} matchBasePath The base path to resolve relative paths in `overrides[].files`, `overrides[].excludedFiles`, and `ignorePatterns`. + * @property {string} name The name of the current configuration. + * @property {string} pluginBasePath The base path to resolve plugins. + * @property {"config" | "ignore" | "implicit-processor"} type The type of the current configuration. This is `"config"` in normal. This is `"ignore"` if it came from `.eslintignore`. This is `"implicit-processor"` if it came from legacy file-extension processors. + */ +/** + * @typedef {Object} ConfigArrayFactoryLoadingContext + * @property {string} filePath The path to the current configuration. + * @property {string} matchBasePath The base path to resolve relative paths in `overrides[].files`, `overrides[].excludedFiles`, and `ignorePatterns`. + * @property {string} name The name of the current configuration. + * @property {"config" | "ignore" | "implicit-processor"} type The type of the current configuration. This is `"config"` in normal. This is `"ignore"` if it came from `.eslintignore`. This is `"implicit-processor"` if it came from legacy file-extension processors. + */ -const path = __webpack_require__(429); +/** @type {WeakMap} */ +const internalSlotsMap$1 = new WeakMap(); -const resolveFrom = __webpack_require__(865); +/** + * Check if a given string is a file path. + * @param {string} nameOrPath A module name or file path. + * @returns {boolean} `true` if the `nameOrPath` is a file path. + */ +function isFilePath(nameOrPath) { + return ( + /^\.{1,2}[/\\]/u.test(nameOrPath) || + path__default["default"].isAbsolute(nameOrPath) + ); +} -const parentModule = __webpack_require__(867); +/** + * Convenience wrapper for synchronously reading file contents. + * @param {string} filePath The filename to read. + * @returns {string} The file contents, with the BOM removed. + * @private + */ +function readFile(filePath) { + return fs__default["default"].readFileSync(filePath, "utf8").replace(/^\ufeff/u, ""); +} -module.exports = moduleId => { - if (typeof moduleId !== 'string') { - throw new TypeError('Expected a string'); - } +/** + * Loads a YAML configuration from a file. + * @param {string} filePath The filename to load. + * @returns {ConfigData} The configuration object from the file. + * @throws {Error} If the file cannot be read. + * @private + */ +function loadYAMLConfigFile(filePath) { + debug$2(`Loading YAML config file: ${filePath}`); - const parentPath = parentModule(__filename); - const cwd = parentPath ? path.dirname(parentPath) : __dirname; - const filePath = resolveFrom(cwd, moduleId); - const oldModule = __webpack_require__.c[filePath]; // Delete itself from module parent + // lazy load YAML to improve performance when not used + const yaml = require$1("js-yaml"); - if (oldModule && oldModule.parent) { - let i = oldModule.parent.children.length; + try { - while (i--) { - if (oldModule.parent.children[i].id === filePath) { - oldModule.parent.children.splice(i, 1); - } + // empty YAML file can be null, so always use + return yaml.load(readFile(filePath)) || {}; + } catch (e) { + debug$2(`Error reading YAML file: ${filePath}`); + e.message = `Cannot read config file: ${filePath}\nError: ${e.message}`; + throw e; } - } +} - delete __webpack_require__.c[filePath]; // Delete module from cache +/** + * Loads a JSON configuration from a file. + * @param {string} filePath The filename to load. + * @returns {ConfigData} The configuration object from the file. + * @throws {Error} If the file cannot be read. + * @private + */ +function loadJSONConfigFile(filePath) { + debug$2(`Loading JSON config file: ${filePath}`); - const parent = __webpack_require__.c[parentPath]; // If `filePath` and `parentPath` are the same, cache will already be deleted so we won't get a memory leak in next step + try { + return JSON.parse(stripComments__default["default"](readFile(filePath))); + } catch (e) { + debug$2(`Error reading JSON file: ${filePath}`); + e.message = `Cannot read config file: ${filePath}\nError: ${e.message}`; + e.messageTemplate = "failed-to-read-json"; + e.messageData = { + path: filePath, + message: e.message + }; + throw e; + } +} - return parent === undefined ? __webpack_require__(869)(filePath) : parent.require(filePath); // In case cache doesn't have parent, fall back to normal require -}; +/** + * Loads a legacy (.eslintrc) configuration from a file. + * @param {string} filePath The filename to load. + * @returns {ConfigData} The configuration object from the file. + * @throws {Error} If the file cannot be read. + * @private + */ +function loadLegacyConfigFile(filePath) { + debug$2(`Loading legacy config file: ${filePath}`); -/***/ }), -/* 865 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + // lazy load YAML to improve performance when not used + const yaml = require$1("js-yaml"); -"use strict"; + try { + return yaml.load(stripComments__default["default"](readFile(filePath))) || /* istanbul ignore next */ {}; + } catch (e) { + debug$2("Error reading YAML file: %s\n%o", filePath, e); + e.message = `Cannot read config file: ${filePath}\nError: ${e.message}`; + throw e; + } +} +/** + * Loads a JavaScript configuration from a file. + * @param {string} filePath The filename to load. + * @returns {ConfigData} The configuration object from the file. + * @throws {Error} If the file cannot be read. + * @private + */ +function loadJSConfigFile(filePath) { + debug$2(`Loading JS config file: ${filePath}`); + try { + return importFresh__default["default"](filePath); + } catch (e) { + debug$2(`Error reading JavaScript file: ${filePath}`); + e.message = `Cannot read config file: ${filePath}\nError: ${e.message}`; + throw e; + } +} -const path = __webpack_require__(429); +/** + * Loads a configuration from a package.json file. + * @param {string} filePath The filename to load. + * @returns {ConfigData} The configuration object from the file. + * @throws {Error} If the file cannot be read. + * @private + */ +function loadPackageJSONConfigFile(filePath) { + debug$2(`Loading package.json config file: ${filePath}`); + try { + const packageData = loadJSONConfigFile(filePath); -const Module = __webpack_require__(866); + if (!Object.hasOwnProperty.call(packageData, "eslintConfig")) { + throw Object.assign( + new Error("package.json file doesn't have 'eslintConfig' field."), + { code: "ESLINT_CONFIG_FIELD_NOT_FOUND" } + ); + } -const fs = __webpack_require__(861); + return packageData.eslintConfig; + } catch (e) { + debug$2(`Error reading package.json file: ${filePath}`); + e.message = `Cannot read config file: ${filePath}\nError: ${e.message}`; + throw e; + } +} -const resolveFrom = (fromDir, moduleId, silent) => { - if (typeof fromDir !== 'string') { - throw new TypeError("Expected `fromDir` to be of type `string`, got `".concat(typeof fromDir, "`")); - } +/** + * Loads a `.eslintignore` from a file. + * @param {string} filePath The filename to load. + * @returns {string[]} The ignore patterns from the file. + * @private + */ +function loadESLintIgnoreFile(filePath) { + debug$2(`Loading .eslintignore file: ${filePath}`); - if (typeof moduleId !== 'string') { - throw new TypeError("Expected `moduleId` to be of type `string`, got `".concat(typeof moduleId, "`")); - } + try { + return readFile(filePath) + .split(/\r?\n/gu) + .filter(line => line.trim() !== "" && !line.startsWith("#")); + } catch (e) { + debug$2(`Error reading .eslintignore file: ${filePath}`); + e.message = `Cannot read .eslintignore file: ${filePath}\nError: ${e.message}`; + throw e; + } +} - try { - fromDir = fs.realpathSync(fromDir); - } catch (err) { - if (err.code === 'ENOENT') { - fromDir = path.resolve(fromDir); - } else if (silent) { - return null; - } else { - throw err; +/** + * Creates an error to notify about a missing config to extend from. + * @param {string} configName The name of the missing config. + * @param {string} importerName The name of the config that imported the missing config + * @param {string} messageTemplate The text template to source error strings from. + * @returns {Error} The error object to throw + * @private + */ +function configInvalidError(configName, importerName, messageTemplate) { + return Object.assign( + new Error(`Failed to load config "${configName}" to extend from.`), + { + messageTemplate, + messageData: { configName, importerName } + } + ); +} + +/** + * Loads a configuration file regardless of the source. Inspects the file path + * to determine the correctly way to load the config file. + * @param {string} filePath The path to the configuration. + * @returns {ConfigData|null} The configuration information. + * @private + */ +function loadConfigFile(filePath) { + switch (path__default["default"].extname(filePath)) { + case ".js": + case ".cjs": + return loadJSConfigFile(filePath); + + case ".json": + if (path__default["default"].basename(filePath) === "package.json") { + return loadPackageJSONConfigFile(filePath); + } + return loadJSONConfigFile(filePath); + + case ".yaml": + case ".yml": + return loadYAMLConfigFile(filePath); + + default: + return loadLegacyConfigFile(filePath); } - } +} - const fromFile = path.join(fromDir, 'noop.js'); +/** + * Write debug log. + * @param {string} request The requested module name. + * @param {string} relativeTo The file path to resolve the request relative to. + * @param {string} filePath The resolved file path. + * @returns {void} + */ +function writeDebugLogForLoading(request, relativeTo, filePath) { + /* istanbul ignore next */ + if (debug$2.enabled) { + let nameAndVersion = null; - const resolveFileName = () => Module._resolveFilename(moduleId, { - id: fromFile, - filename: fromFile, - paths: Module._nodeModulePaths(fromDir) - }); + try { + const packageJsonPath = resolve( + `${request}/package.json`, + relativeTo + ); + const { version = "unknown" } = require$1(packageJsonPath); - if (silent) { - try { - return resolveFileName(); - } catch (err) { - return null; + nameAndVersion = `${request}@${version}`; + } catch (error) { + debug$2("package.json was not found:", error.message); + nameAndVersion = request; + } + + debug$2("Loaded: %s (%s)", nameAndVersion, filePath); } - } +} - return resolveFileName(); -}; +/** + * Create a new context with default values. + * @param {ConfigArrayFactoryInternalSlots} slots The internal slots. + * @param {"config" | "ignore" | "implicit-processor" | undefined} providedType The type of the current configuration. Default is `"config"`. + * @param {string | undefined} providedName The name of the current configuration. Default is the relative path from `cwd` to `filePath`. + * @param {string | undefined} providedFilePath The path to the current configuration. Default is empty string. + * @param {string | undefined} providedMatchBasePath The type of the current configuration. Default is the directory of `filePath` or `cwd`. + * @returns {ConfigArrayFactoryLoadingContext} The created context. + */ +function createContext( + { cwd, resolvePluginsRelativeTo }, + providedType, + providedName, + providedFilePath, + providedMatchBasePath +) { + const filePath = providedFilePath + ? path__default["default"].resolve(cwd, providedFilePath) + : ""; + const matchBasePath = + (providedMatchBasePath && path__default["default"].resolve(cwd, providedMatchBasePath)) || + (filePath && path__default["default"].dirname(filePath)) || + cwd; + const name = + providedName || + (filePath && path__default["default"].relative(cwd, filePath)) || + ""; + const pluginBasePath = + resolvePluginsRelativeTo || + (filePath && path__default["default"].dirname(filePath)) || + cwd; + const type = providedType || "config"; -module.exports = (fromDir, moduleId) => resolveFrom(fromDir, moduleId); + return { filePath, matchBasePath, name, pluginBasePath, type }; +} -module.exports.silent = (fromDir, moduleId) => resolveFrom(fromDir, moduleId, true); +/** + * Normalize a given plugin. + * - Ensure the object to have four properties: configs, environments, processors, and rules. + * - Ensure the object to not have other properties. + * @param {Plugin} plugin The plugin to normalize. + * @returns {Plugin} The normalized plugin. + */ +function normalizePlugin(plugin) { + return { + configs: plugin.configs || {}, + environments: plugin.environments || {}, + processors: plugin.processors || {}, + rules: plugin.rules || {} + }; +} -/***/ }), -/* 866 */ -/***/ ((module) => { +//------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ + +/** + * The factory of `ConfigArray` objects. + */ +class ConfigArrayFactory { + + /** + * Initialize this instance. + * @param {ConfigArrayFactoryOptions} [options] The map for additional plugins. + */ + constructor({ + additionalPluginPool = new Map(), + cwd = process.cwd(), + resolvePluginsRelativeTo, + builtInRules, + resolver = ModuleResolver, + eslintAllPath, + eslintRecommendedPath + } = {}) { + internalSlotsMap$1.set(this, { + additionalPluginPool, + cwd, + resolvePluginsRelativeTo: + resolvePluginsRelativeTo && + path__default["default"].resolve(cwd, resolvePluginsRelativeTo), + builtInRules, + resolver, + eslintAllPath, + eslintRecommendedPath + }); + } -"use strict"; -module.exports = require("module"); + /** + * Create `ConfigArray` instance from a config data. + * @param {ConfigData|null} configData The config data to create. + * @param {Object} [options] The options. + * @param {string} [options.basePath] The base path to resolve relative paths in `overrides[].files`, `overrides[].excludedFiles`, and `ignorePatterns`. + * @param {string} [options.filePath] The path to this config data. + * @param {string} [options.name] The config name. + * @returns {ConfigArray} Loaded config. + */ + create(configData, { basePath, filePath, name } = {}) { + if (!configData) { + return new ConfigArray(); + } -/***/ }), -/* 867 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + const slots = internalSlotsMap$1.get(this); + const ctx = createContext(slots, "config", name, filePath, basePath); + const elements = this._normalizeConfigData(configData, ctx); -"use strict"; + return new ConfigArray(...elements); + } + /** + * Load a config file. + * @param {string} filePath The path to a config file. + * @param {Object} [options] The options. + * @param {string} [options.basePath] The base path to resolve relative paths in `overrides[].files`, `overrides[].excludedFiles`, and `ignorePatterns`. + * @param {string} [options.name] The config name. + * @returns {ConfigArray} Loaded config. + */ + loadFile(filePath, { basePath, name } = {}) { + const slots = internalSlotsMap$1.get(this); + const ctx = createContext(slots, "config", name, filePath, basePath); -const callsites = __webpack_require__(868); + return new ConfigArray(...this._loadConfigData(ctx)); + } -module.exports = filepath => { - const stacks = callsites(); + /** + * Load the config file on a given directory if exists. + * @param {string} directoryPath The path to a directory. + * @param {Object} [options] The options. + * @param {string} [options.basePath] The base path to resolve relative paths in `overrides[].files`, `overrides[].excludedFiles`, and `ignorePatterns`. + * @param {string} [options.name] The config name. + * @returns {ConfigArray} Loaded config. An empty `ConfigArray` if any config doesn't exist. + */ + loadInDirectory(directoryPath, { basePath, name } = {}) { + const slots = internalSlotsMap$1.get(this); - if (!filepath) { - return stacks[2].getFileName(); - } + for (const filename of configFilenames) { + const ctx = createContext( + slots, + "config", + name, + path__default["default"].join(directoryPath, filename), + basePath + ); - let seenVal = false; // Skip the first stack as it's this function + if (fs__default["default"].existsSync(ctx.filePath) && fs__default["default"].statSync(ctx.filePath).isFile()) { + let configData; - stacks.shift(); + try { + configData = loadConfigFile(ctx.filePath); + } catch (error) { + if (!error || error.code !== "ESLINT_CONFIG_FIELD_NOT_FOUND") { + throw error; + } + } - for (const stack of stacks) { - const parentFilepath = stack.getFileName(); + if (configData) { + debug$2(`Config file found: ${ctx.filePath}`); + return new ConfigArray( + ...this._normalizeConfigData(configData, ctx) + ); + } + } + } - if (typeof parentFilepath !== 'string') { - continue; + debug$2(`Config file not found on ${directoryPath}`); + return new ConfigArray(); } - if (parentFilepath === filepath) { - seenVal = true; - continue; - } // Skip native modules - - - if (parentFilepath === 'module.js') { - continue; - } + /** + * Check if a config file on a given directory exists or not. + * @param {string} directoryPath The path to a directory. + * @returns {string | null} The path to the found config file. If not found then null. + */ + static getPathToConfigFileInDirectory(directoryPath) { + for (const filename of configFilenames) { + const filePath = path__default["default"].join(directoryPath, filename); - if (seenVal && parentFilepath !== filepath) { - return parentFilepath; + if (fs__default["default"].existsSync(filePath)) { + if (filename === "package.json") { + try { + loadPackageJSONConfigFile(filePath); + return filePath; + } catch { /* ignore */ } + } else { + return filePath; + } + } + } + return null; } - } -}; -/***/ }), -/* 868 */ -/***/ ((module) => { - -"use strict"; + /** + * Load `.eslintignore` file. + * @param {string} filePath The path to a `.eslintignore` file to load. + * @returns {ConfigArray} Loaded config. An empty `ConfigArray` if any config doesn't exist. + */ + loadESLintIgnore(filePath) { + const slots = internalSlotsMap$1.get(this); + const ctx = createContext( + slots, + "ignore", + void 0, + filePath, + slots.cwd + ); + const ignorePatterns = loadESLintIgnoreFile(ctx.filePath); + return new ConfigArray( + ...this._normalizeESLintIgnoreData(ignorePatterns, ctx) + ); + } -const callsites = () => { - const _prepareStackTrace = Error.prepareStackTrace; + /** + * Load `.eslintignore` file in the current working directory. + * @returns {ConfigArray} Loaded config. An empty `ConfigArray` if any config doesn't exist. + */ + loadDefaultESLintIgnore() { + const slots = internalSlotsMap$1.get(this); + const eslintIgnorePath = path__default["default"].resolve(slots.cwd, ".eslintignore"); + const packageJsonPath = path__default["default"].resolve(slots.cwd, "package.json"); - Error.prepareStackTrace = (_, stack) => stack; + if (fs__default["default"].existsSync(eslintIgnorePath)) { + return this.loadESLintIgnore(eslintIgnorePath); + } + if (fs__default["default"].existsSync(packageJsonPath)) { + const data = loadJSONConfigFile(packageJsonPath); - const stack = new Error().stack.slice(1); - Error.prepareStackTrace = _prepareStackTrace; - return stack; -}; + if (Object.hasOwnProperty.call(data, "eslintIgnore")) { + if (!Array.isArray(data.eslintIgnore)) { + throw new Error("Package.json eslintIgnore property requires an array of paths"); + } + const ctx = createContext( + slots, + "ignore", + "eslintIgnore in package.json", + packageJsonPath, + slots.cwd + ); -module.exports = callsites; // TODO: Remove this for the next major release + return new ConfigArray( + ...this._normalizeESLintIgnoreData(data.eslintIgnore, ctx) + ); + } + } -module.exports["default"] = callsites; + return new ConfigArray(); + } -/***/ }), -/* 869 */ -/***/ ((module) => { + /** + * Load a given config file. + * @param {ConfigArrayFactoryLoadingContext} ctx The loading context. + * @returns {IterableIterator} Loaded config. + * @private + */ + _loadConfigData(ctx) { + return this._normalizeConfigData(loadConfigFile(ctx.filePath), ctx); + } -function webpackEmptyContext(req) { - var e = new Error("Cannot find module '" + req + "'"); - e.code = 'MODULE_NOT_FOUND'; - throw e; -} -webpackEmptyContext.keys = () => ([]); -webpackEmptyContext.resolve = webpackEmptyContext; -webpackEmptyContext.id = 869; -module.exports = webpackEmptyContext; + /** + * Normalize a given `.eslintignore` data to config array elements. + * @param {string[]} ignorePatterns The patterns to ignore files. + * @param {ConfigArrayFactoryLoadingContext} ctx The loading context. + * @returns {IterableIterator} The normalized config. + * @private + */ + *_normalizeESLintIgnoreData(ignorePatterns, ctx) { + const elements = this._normalizeObjectConfigData( + { ignorePatterns }, + ctx + ); -/***/ }), -/* 870 */ -/***/ ((module) => { + // Set `ignorePattern.loose` flag for backward compatibility. + for (const element of elements) { + if (element.ignorePattern) { + element.ignorePattern.loose = true; + } + yield element; + } + } -"use strict"; + /** + * Normalize a given config to an array. + * @param {ConfigData} configData The config data to normalize. + * @param {ConfigArrayFactoryLoadingContext} ctx The loading context. + * @returns {IterableIterator} The normalized config. + * @private + */ + _normalizeConfigData(configData, ctx) { + const validator = new ConfigValidator(); + validator.validateConfigSchema(configData, ctx.name || ctx.filePath); + return this._normalizeObjectConfigData(configData, ctx); + } -const singleComment = Symbol('singleComment'); -const multiComment = Symbol('multiComment'); + /** + * Normalize a given config to an array. + * @param {ConfigData|OverrideConfigData} configData The config data to normalize. + * @param {ConfigArrayFactoryLoadingContext} ctx The loading context. + * @returns {IterableIterator} The normalized config. + * @private + */ + *_normalizeObjectConfigData(configData, ctx) { + const { files, excludedFiles, ...configBody } = configData; + const criteria = OverrideTester.create( + files, + excludedFiles, + ctx.matchBasePath + ); + const elements = this._normalizeObjectConfigDataBody(configBody, ctx); -const stripWithoutWhitespace = () => ''; + // Apply the criteria to every element. + for (const element of elements) { -const stripWithWhitespace = (string, start, end) => string.slice(start, end).replace(/\S/g, ' '); + /* + * Merge the criteria. + * This is for the `overrides` entries that came from the + * configurations of `overrides[].extends`. + */ + element.criteria = OverrideTester.and(criteria, element.criteria); -const isEscaped = (jsonString, quotePosition) => { - let index = quotePosition - 1; - let backslashCount = 0; + /* + * Remove `root` property to ignore `root` settings which came from + * `extends` in `overrides`. + */ + if (element.criteria) { + element.root = void 0; + } - while (jsonString[index] === '\\') { - index -= 1; - backslashCount += 1; - } + yield element; + } + } - return Boolean(backslashCount % 2); -}; + /** + * Normalize a given config to an array. + * @param {ConfigData} configData The config data to normalize. + * @param {ConfigArrayFactoryLoadingContext} ctx The loading context. + * @returns {IterableIterator} The normalized config. + * @private + */ + *_normalizeObjectConfigDataBody( + { + env, + extends: extend, + globals, + ignorePatterns, + noInlineConfig, + parser: parserName, + parserOptions, + plugins: pluginList, + processor, + reportUnusedDisableDirectives, + root, + rules, + settings, + overrides: overrideList = [] + }, + ctx + ) { + const extendList = Array.isArray(extend) ? extend : [extend]; + const ignorePattern = ignorePatterns && new IgnorePattern( + Array.isArray(ignorePatterns) ? ignorePatterns : [ignorePatterns], + ctx.matchBasePath + ); -module.exports = function (jsonString) { - let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + // Flatten `extends`. + for (const extendName of extendList.filter(Boolean)) { + yield* this._loadExtends(extendName, ctx); + } - if (typeof jsonString !== 'string') { - throw new TypeError("Expected argument `jsonString` to be a `string`, got `".concat(typeof jsonString, "`")); - } + // Load parser & plugins. + const parser = parserName && this._loadParser(parserName, ctx); + const plugins = pluginList && this._loadPlugins(pluginList, ctx); - const strip = options.whitespace === false ? stripWithoutWhitespace : stripWithWhitespace; - let insideString = false; - let insideComment = false; - let offset = 0; - let result = ''; + // Yield pseudo config data for file extension processors. + if (plugins) { + yield* this._takeFileExtensionProcessors(plugins, ctx); + } - for (let i = 0; i < jsonString.length; i++) { - const currentCharacter = jsonString[i]; - const nextCharacter = jsonString[i + 1]; + // Yield the config data except `extends` and `overrides`. + yield { - if (!insideComment && currentCharacter === '"') { - const escaped = isEscaped(jsonString, i); + // Debug information. + type: ctx.type, + name: ctx.name, + filePath: ctx.filePath, - if (!escaped) { - insideString = !insideString; - } - } + // Config data. + criteria: null, + env, + globals, + ignorePattern, + noInlineConfig, + parser, + parserOptions, + plugins, + processor, + reportUnusedDisableDirectives, + root, + rules, + settings + }; - if (insideString) { - continue; + // Flatten `overries`. + for (let i = 0; i < overrideList.length; ++i) { + yield* this._normalizeObjectConfigData( + overrideList[i], + { ...ctx, name: `${ctx.name}#overrides[${i}]` } + ); + } } - if (!insideComment && currentCharacter + nextCharacter === '//') { - result += jsonString.slice(offset, i); - offset = i; - insideComment = singleComment; - i++; - } else if (insideComment === singleComment && currentCharacter + nextCharacter === '\r\n') { - i++; - insideComment = false; - result += strip(jsonString, offset, i); - offset = i; - continue; - } else if (insideComment === singleComment && currentCharacter === '\n') { - insideComment = false; - result += strip(jsonString, offset, i); - offset = i; - } else if (!insideComment && currentCharacter + nextCharacter === '/*') { - result += jsonString.slice(offset, i); - offset = i; - insideComment = multiComment; - i++; - continue; - } else if (insideComment === multiComment && currentCharacter + nextCharacter === '*/') { - i++; - insideComment = false; - result += strip(jsonString, offset, i + 1); - offset = i + 1; - continue; + /** + * Load configs of an element in `extends`. + * @param {string} extendName The name of a base config. + * @param {ConfigArrayFactoryLoadingContext} ctx The loading context. + * @returns {IterableIterator} The normalized config. + * @private + */ + _loadExtends(extendName, ctx) { + debug$2("Loading {extends:%j} relative to %s", extendName, ctx.filePath); + try { + if (extendName.startsWith("eslint:")) { + return this._loadExtendedBuiltInConfig(extendName, ctx); + } + if (extendName.startsWith("plugin:")) { + return this._loadExtendedPluginConfig(extendName, ctx); + } + return this._loadExtendedShareableConfig(extendName, ctx); + } catch (error) { + error.message += `\nReferenced from: ${ctx.filePath || ctx.name}`; + throw error; + } } - } - - return result + (insideComment ? strip(jsonString.slice(offset)) : jsonString.slice(offset)); -}; - -/***/ }), -/* 871 */ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -/* provided dependency */ var console = __webpack_require__(438); -module.exports = minimatch; -minimatch.Minimatch = Minimatch; -var path = { - sep: '/' -}; + /** + * Load configs of an element in `extends`. + * @param {string} extendName The name of a base config. + * @param {ConfigArrayFactoryLoadingContext} ctx The loading context. + * @returns {IterableIterator} The normalized config. + * @private + */ + _loadExtendedBuiltInConfig(extendName, ctx) { + const { eslintAllPath, eslintRecommendedPath } = internalSlotsMap$1.get(this); -try { - path = __webpack_require__(429); -} catch (er) {} + if (extendName === "eslint:recommended") { + return this._loadConfigData({ + ...ctx, + filePath: eslintRecommendedPath, + name: `${ctx.name} » ${extendName}` + }); + } + if (extendName === "eslint:all") { + return this._loadConfigData({ + ...ctx, + filePath: eslintAllPath, + name: `${ctx.name} » ${extendName}` + }); + } -var GLOBSTAR = minimatch.GLOBSTAR = Minimatch.GLOBSTAR = {}; + throw configInvalidError(extendName, ctx.name, "extend-config-missing"); + } -var expand = __webpack_require__(872); + /** + * Load configs of an element in `extends`. + * @param {string} extendName The name of a base config. + * @param {ConfigArrayFactoryLoadingContext} ctx The loading context. + * @returns {IterableIterator} The normalized config. + * @private + */ + _loadExtendedPluginConfig(extendName, ctx) { + const slashIndex = extendName.lastIndexOf("/"); -var plTypes = { - '!': { - open: '(?:(?!(?:', - close: '))[^/]*?)' - }, - '?': { - open: '(?:', - close: ')?' - }, - '+': { - open: '(?:', - close: ')+' - }, - '*': { - open: '(?:', - close: ')*' - }, - '@': { - open: '(?:', - close: ')' - } -}; // any single thing other than / -// don't need to escape / when using new RegExp() + if (slashIndex === -1) { + throw configInvalidError(extendName, ctx.filePath, "plugin-invalid"); + } -var qmark = '[^/]'; // * => any number of characters + const pluginName = extendName.slice("plugin:".length, slashIndex); + const configName = extendName.slice(slashIndex + 1); -var star = qmark + '*?'; // ** when dots are allowed. Anything goes, except .. and . -// not (^ or / followed by one or two dots followed by $ or /), -// followed by anything, any number of times. + if (isFilePath(pluginName)) { + throw new Error("'extends' cannot use a file path for plugins."); + } -var twoStarDot = '(?:(?!(?:\\\/|^)(?:\\.{1,2})($|\\\/)).)*?'; // not a ^ or / followed by a dot, -// followed by anything, any number of times. + const plugin = this._loadPlugin(pluginName, ctx); + const configData = + plugin.definition && + plugin.definition.configs[configName]; -var twoStarNoDot = '(?:(?!(?:\\\/|^)\\.).)*?'; // characters that need to be escaped in RegExp. + if (configData) { + return this._normalizeConfigData(configData, { + ...ctx, + filePath: plugin.filePath || ctx.filePath, + name: `${ctx.name} » plugin:${plugin.id}/${configName}` + }); + } -var reSpecials = charSet('().*{}+?[]^$\\!'); // "abc" -> { a:true, b:true, c:true } + throw plugin.error || configInvalidError(extendName, ctx.filePath, "extend-config-missing"); + } -function charSet(s) { - return s.split('').reduce(function (set, c) { - set[c] = true; - return set; - }, {}); -} // normalizes slashes. + /** + * Load configs of an element in `extends`. + * @param {string} extendName The name of a base config. + * @param {ConfigArrayFactoryLoadingContext} ctx The loading context. + * @returns {IterableIterator} The normalized config. + * @private + */ + _loadExtendedShareableConfig(extendName, ctx) { + const { cwd, resolver } = internalSlotsMap$1.get(this); + const relativeTo = ctx.filePath || path__default["default"].join(cwd, "__placeholder__.js"); + let request; + if (isFilePath(extendName)) { + request = extendName; + } else if (extendName.startsWith(".")) { + request = `./${extendName}`; // For backward compatibility. A ton of tests depended on this behavior. + } else { + request = normalizePackageName( + extendName, + "eslint-config" + ); + } -var slashSplit = /\/+/; -minimatch.filter = filter; + let filePath; -function filter(pattern, options) { - options = options || {}; - return function (p, i, list) { - return minimatch(p, pattern, options); - }; -} + try { + filePath = resolver.resolve(request, relativeTo); + } catch (error) { + /* istanbul ignore else */ + if (error && error.code === "MODULE_NOT_FOUND") { + throw configInvalidError(extendName, ctx.filePath, "extend-config-missing"); + } + throw error; + } -function ext(a, b) { - a = a || {}; - b = b || {}; - var t = {}; - Object.keys(b).forEach(function (k) { - t[k] = b[k]; - }); - Object.keys(a).forEach(function (k) { - t[k] = a[k]; - }); - return t; -} + writeDebugLogForLoading(request, relativeTo, filePath); + return this._loadConfigData({ + ...ctx, + filePath, + name: `${ctx.name} » ${request}` + }); + } -minimatch.defaults = function (def) { - if (!def || !Object.keys(def).length) return minimatch; - var orig = minimatch; + /** + * Load given plugins. + * @param {string[]} names The plugin names to load. + * @param {ConfigArrayFactoryLoadingContext} ctx The loading context. + * @returns {Record} The loaded parser. + * @private + */ + _loadPlugins(names, ctx) { + return names.reduce((map, name) => { + if (isFilePath(name)) { + throw new Error("Plugins array cannot includes file paths."); + } + const plugin = this._loadPlugin(name, ctx); - var m = function minimatch(p, pattern, options) { - return orig.minimatch(p, pattern, ext(def, options)); - }; + map[plugin.id] = plugin; - m.Minimatch = function Minimatch(pattern, options) { - return new orig.Minimatch(pattern, ext(def, options)); - }; + return map; + }, {}); + } - return m; -}; + /** + * Load a given parser. + * @param {string} nameOrPath The package name or the path to a parser file. + * @param {ConfigArrayFactoryLoadingContext} ctx The loading context. + * @returns {DependentParser} The loaded parser. + */ + _loadParser(nameOrPath, ctx) { + debug$2("Loading parser %j from %s", nameOrPath, ctx.filePath); -Minimatch.defaults = function (def) { - if (!def || !Object.keys(def).length) return Minimatch; - return minimatch.defaults(def).Minimatch; -}; + const { cwd, resolver } = internalSlotsMap$1.get(this); + const relativeTo = ctx.filePath || path__default["default"].join(cwd, "__placeholder__.js"); -function minimatch(p, pattern, options) { - if (typeof pattern !== 'string') { - throw new TypeError('glob pattern string required'); - } + try { + const filePath = resolver.resolve(nameOrPath, relativeTo); - if (!options) options = {}; // shortcut: comments match nothing. + writeDebugLogForLoading(nameOrPath, relativeTo, filePath); - if (!options.nocomment && pattern.charAt(0) === '#') { - return false; - } // "" only matches "" + return new ConfigDependency({ + definition: require$1(filePath), + filePath, + id: nameOrPath, + importerName: ctx.name, + importerPath: ctx.filePath + }); + } catch (error) { + // If the parser name is "espree", load the espree of ESLint. + if (nameOrPath === "espree") { + debug$2("Fallback espree."); + return new ConfigDependency({ + definition: require$1("espree"), + filePath: require$1.resolve("espree"), + id: nameOrPath, + importerName: ctx.name, + importerPath: ctx.filePath + }); + } - if (pattern.trim() === '') return p === ''; - return new Minimatch(pattern, options).match(p); -} + debug$2("Failed to load parser '%s' declared in '%s'.", nameOrPath, ctx.name); + error.message = `Failed to load parser '${nameOrPath}' declared in '${ctx.name}': ${error.message}`; -function Minimatch(pattern, options) { - if (!(this instanceof Minimatch)) { - return new Minimatch(pattern, options); - } + return new ConfigDependency({ + error, + id: nameOrPath, + importerName: ctx.name, + importerPath: ctx.filePath + }); + } + } - if (typeof pattern !== 'string') { - throw new TypeError('glob pattern string required'); - } + /** + * Load a given plugin. + * @param {string} name The plugin name to load. + * @param {ConfigArrayFactoryLoadingContext} ctx The loading context. + * @returns {DependentPlugin} The loaded plugin. + * @private + */ + _loadPlugin(name, ctx) { + debug$2("Loading plugin %j from %s", name, ctx.filePath); - if (!options) options = {}; - pattern = pattern.trim(); // windows support: need to use /, not \ + const { additionalPluginPool, resolver } = internalSlotsMap$1.get(this); + const request = normalizePackageName(name, "eslint-plugin"); + const id = getShorthandName(request, "eslint-plugin"); + const relativeTo = path__default["default"].join(ctx.pluginBasePath, "__placeholder__.js"); - if (path.sep !== '/') { - pattern = pattern.split(path.sep).join('/'); - } + if (name.match(/\s+/u)) { + const error = Object.assign( + new Error(`Whitespace found in plugin name '${name}'`), + { + messageTemplate: "whitespace-found", + messageData: { pluginName: request } + } + ); - this.options = options; - this.set = []; - this.pattern = pattern; - this.regexp = null; - this.negate = false; - this.comment = false; - this.empty = false; // make the set of regexps etc. + return new ConfigDependency({ + error, + id, + importerName: ctx.name, + importerPath: ctx.filePath + }); + } - this.make(); -} + // Check for additional pool. + const plugin = + additionalPluginPool.get(request) || + additionalPluginPool.get(id); -Minimatch.prototype.debug = function () {}; + if (plugin) { + return new ConfigDependency({ + definition: normalizePlugin(plugin), + filePath: "", // It's unknown where the plugin came from. + id, + importerName: ctx.name, + importerPath: ctx.filePath + }); + } -Minimatch.prototype.make = make; + let filePath; + let error; -function make() { - // don't do it more than once. - if (this._made) return; - var pattern = this.pattern; - var options = this.options; // empty patterns and comments match nothing. + try { + filePath = resolver.resolve(request, relativeTo); + } catch (resolveError) { + error = resolveError; + /* istanbul ignore else */ + if (error && error.code === "MODULE_NOT_FOUND") { + error.messageTemplate = "plugin-missing"; + error.messageData = { + pluginName: request, + resolvePluginsRelativeTo: ctx.pluginBasePath, + importerName: ctx.name + }; + } + } - if (!options.nocomment && pattern.charAt(0) === '#') { - this.comment = true; - return; - } + if (filePath) { + try { + writeDebugLogForLoading(request, relativeTo, filePath); - if (!pattern) { - this.empty = true; - return; - } // step 1: figure out negation, etc. + const startTime = Date.now(); + const pluginDefinition = require$1(filePath); + debug$2(`Plugin ${filePath} loaded in: ${Date.now() - startTime}ms`); - this.parseNegate(); // step 2: expand braces + return new ConfigDependency({ + definition: normalizePlugin(pluginDefinition), + filePath, + id, + importerName: ctx.name, + importerPath: ctx.filePath + }); + } catch (loadError) { + error = loadError; + } + } - var set = this.globSet = this.braceExpand(); - if (options.debug) this.debug = console.error; - this.debug(this.pattern, set); // step 3: now we have a set, so turn each one into a series of path-portion - // matching patterns. - // These will be regexps, except in the case of "**", which is - // set to the GLOBSTAR object for globstar behavior, - // and will not contain any / characters + debug$2("Failed to load plugin '%s' declared in '%s'.", name, ctx.name); + error.message = `Failed to load plugin '${name}' declared in '${ctx.name}': ${error.message}`; + return new ConfigDependency({ + error, + id, + importerName: ctx.name, + importerPath: ctx.filePath + }); + } - set = this.globParts = set.map(function (s) { - return s.split(slashSplit); - }); - this.debug(this.pattern, set); // glob --> regexps + /** + * Take file expression processors as config array elements. + * @param {Record} plugins The plugin definitions. + * @param {ConfigArrayFactoryLoadingContext} ctx The loading context. + * @returns {IterableIterator} The config array elements of file expression processors. + * @private + */ + *_takeFileExtensionProcessors(plugins, ctx) { + for (const pluginId of Object.keys(plugins)) { + const processors = + plugins[pluginId] && + plugins[pluginId].definition && + plugins[pluginId].definition.processors; - set = set.map(function (s, si, set) { - return s.map(this.parse, this); - }, this); - this.debug(this.pattern, set); // filter out everything that didn't compile properly. + if (!processors) { + continue; + } - set = set.filter(function (s) { - return s.indexOf(false) === -1; - }); - this.debug(this.pattern, set); - this.set = set; + for (const processorId of Object.keys(processors)) { + if (processorId.startsWith(".")) { + yield* this._normalizeObjectConfigData( + { + files: [`*${processorId}`], + processor: `${pluginId}/${processorId}` + }, + { + ...ctx, + type: "implicit-processor", + name: `${ctx.name}#processors["${pluginId}/${processorId}"]` + } + ); + } + } + } + } } -Minimatch.prototype.parseNegate = parseNegate; - -function parseNegate() { - var pattern = this.pattern; - var negate = false; - var options = this.options; - var negateOffset = 0; - if (options.nonegate) return; +/** + * @fileoverview `CascadingConfigArrayFactory` class. + * + * `CascadingConfigArrayFactory` class has a responsibility: + * + * 1. Handles cascading of config files. + * + * It provides two methods: + * + * - `getConfigArrayForFile(filePath)` + * Get the corresponded configuration of a given file. This method doesn't + * throw even if the given file didn't exist. + * - `clearCache()` + * Clear the internal cache. You have to call this method when + * `additionalPluginPool` was updated if `baseConfig` or `cliConfig` depends + * on the additional plugins. (`CLIEngine#addPlugin()` method calls this.) + * + * @author Toru Nagashima + */ - for (var i = 0, l = pattern.length; i < l && pattern.charAt(i) === '!'; i++) { - negate = !negate; - negateOffset++; - } +const debug$1 = debugOrig__default["default"]("eslintrc:cascading-config-array-factory"); - if (negateOffset) this.pattern = pattern.substr(negateOffset); - this.negate = negate; -} // Brace expansion: -// a{b,c}d -> abd acd -// a{b,}c -> abc ac -// a{0..3}d -> a0d a1d a2d a3d -// a{b,c{d,e}f}g -> abg acdfg acefg -// a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg -// -// Invalid sets are not expanded. -// a{2..}b -> a{2..}b -// a{b}c -> a{b}c +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ +// Define types for VSCode IntelliSense. +/** @typedef {import("./shared/types").ConfigData} ConfigData */ +/** @typedef {import("./shared/types").Parser} Parser */ +/** @typedef {import("./shared/types").Plugin} Plugin */ +/** @typedef {import("./shared/types").Rule} Rule */ +/** @typedef {ReturnType} ConfigArray */ -minimatch.braceExpand = function (pattern, options) { - return braceExpand(pattern, options); -}; +/** + * @typedef {Object} CascadingConfigArrayFactoryOptions + * @property {Map} [additionalPluginPool] The map for additional plugins. + * @property {ConfigData} [baseConfig] The config by `baseConfig` option. + * @property {ConfigData} [cliConfig] The config by CLI options (`--env`, `--global`, `--ignore-pattern`, `--parser`, `--parser-options`, `--plugin`, and `--rule`). CLI options overwrite the setting in config files. + * @property {string} [cwd] The base directory to start lookup. + * @property {string} [ignorePath] The path to the alternative file of `.eslintignore`. + * @property {string[]} [rulePaths] The value of `--rulesdir` option. + * @property {string} [specificConfigPath] The value of `--config` option. + * @property {boolean} [useEslintrc] if `false` then it doesn't load config files. + * @property {Function} loadRules The function to use to load rules. + * @property {Map} builtInRules The rules that are built in to ESLint. + * @property {Object} [resolver=ModuleResolver] The module resolver object. + * @property {string} eslintAllPath The path to the definitions for eslint:all. + * @property {string} eslintRecommendedPath The path to the definitions for eslint:recommended. + */ -Minimatch.prototype.braceExpand = braceExpand; +/** + * @typedef {Object} CascadingConfigArrayFactoryInternalSlots + * @property {ConfigArray} baseConfigArray The config array of `baseConfig` option. + * @property {ConfigData} baseConfigData The config data of `baseConfig` option. This is used to reset `baseConfigArray`. + * @property {ConfigArray} cliConfigArray The config array of CLI options. + * @property {ConfigData} cliConfigData The config data of CLI options. This is used to reset `cliConfigArray`. + * @property {ConfigArrayFactory} configArrayFactory The factory for config arrays. + * @property {Map} configCache The cache from directory paths to config arrays. + * @property {string} cwd The base directory to start lookup. + * @property {WeakMap} finalizeCache The cache from config arrays to finalized config arrays. + * @property {string} [ignorePath] The path to the alternative file of `.eslintignore`. + * @property {string[]|null} rulePaths The value of `--rulesdir` option. This is used to reset `baseConfigArray`. + * @property {string|null} specificConfigPath The value of `--config` option. This is used to reset `cliConfigArray`. + * @property {boolean} useEslintrc if `false` then it doesn't load config files. + * @property {Function} loadRules The function to use to load rules. + * @property {Map} builtInRules The rules that are built in to ESLint. + * @property {Object} [resolver=ModuleResolver] The module resolver object. + * @property {string} eslintAllPath The path to the definitions for eslint:all. + * @property {string} eslintRecommendedPath The path to the definitions for eslint:recommended. + */ -function braceExpand(pattern, options) { - if (!options) { - if (this instanceof Minimatch) { - options = this.options; - } else { - options = {}; - } - } +/** @type {WeakMap} */ +const internalSlotsMap = new WeakMap(); - pattern = typeof pattern === 'undefined' ? this.pattern : pattern; +/** + * Create the config array from `baseConfig` and `rulePaths`. + * @param {CascadingConfigArrayFactoryInternalSlots} slots The slots. + * @returns {ConfigArray} The config array of the base configs. + */ +function createBaseConfigArray({ + configArrayFactory, + baseConfigData, + rulePaths, + cwd, + loadRules +}) { + const baseConfigArray = configArrayFactory.create( + baseConfigData, + { name: "BaseConfig" } + ); - if (typeof pattern === 'undefined') { - throw new TypeError('undefined pattern'); - } + /* + * Create the config array element for the default ignore patterns. + * This element has `ignorePattern` property that ignores the default + * patterns in the current working directory. + */ + baseConfigArray.unshift(configArrayFactory.create( + { ignorePatterns: IgnorePattern.DefaultPatterns }, + { name: "DefaultIgnorePattern" } + )[0]); - if (options.nobrace || !pattern.match(/\{.*\}/)) { - // shortcut. no need to expand. - return [pattern]; - } + /* + * Load rules `--rulesdir` option as a pseudo plugin. + * Use a pseudo plugin to define rules of `--rulesdir`, so we can validate + * the rule's options with only information in the config array. + */ + if (rulePaths && rulePaths.length > 0) { + baseConfigArray.push({ + type: "config", + name: "--rulesdir", + filePath: "", + plugins: { + "": new ConfigDependency({ + definition: { + rules: rulePaths.reduce( + (map, rulesPath) => Object.assign( + map, + loadRules(rulesPath, cwd) + ), + {} + ) + }, + filePath: "", + id: "", + importerName: "--rulesdir", + importerPath: "" + }) + } + }); + } - return expand(pattern); -} // parse a component of the expanded set. -// At this point, no pattern may contain "/" in it -// so we're going to return a 2d array, where each entry is the full -// pattern, split on '/', and then turned into a regular expression. -// A regexp is made at the end which joins each array with an -// escaped /, and another full one which joins each regexp with |. -// -// Following the lead of Bash 4.1, note that "**" only has special meaning -// when it is the *only* thing in a path portion. Otherwise, any series -// of * is equivalent to a single *. Globstar behavior is enabled by -// default, and can be disabled by setting options.noglobstar. + return baseConfigArray; +} +/** + * Create the config array from CLI options. + * @param {CascadingConfigArrayFactoryInternalSlots} slots The slots. + * @returns {ConfigArray} The config array of the base configs. + */ +function createCLIConfigArray({ + cliConfigData, + configArrayFactory, + cwd, + ignorePath, + specificConfigPath +}) { + const cliConfigArray = configArrayFactory.create( + cliConfigData, + { name: "CLIOptions" } + ); -Minimatch.prototype.parse = parse; -var SUBPARSE = {}; + cliConfigArray.unshift( + ...(ignorePath + ? configArrayFactory.loadESLintIgnore(ignorePath) + : configArrayFactory.loadDefaultESLintIgnore()) + ); -function parse(pattern, isSub) { - if (pattern.length > 1024 * 64) { - throw new TypeError('pattern is too long'); - } + if (specificConfigPath) { + cliConfigArray.unshift( + ...configArrayFactory.loadFile( + specificConfigPath, + { name: "--config", basePath: cwd } + ) + ); + } - var options = this.options; // shortcuts + return cliConfigArray; +} - if (!options.noglobstar && pattern === '**') return GLOBSTAR; - if (pattern === '') return ''; - var re = ''; - var hasMagic = !!options.nocase; - var escaping = false; // ? => one single character +/** + * The error type when there are files matched by a glob, but all of them have been ignored. + */ +class ConfigurationNotFoundError extends Error { - var patternListStack = []; - var negativeLists = []; - var stateChar; - var inClass = false; - var reClassStart = -1; - var classStart = -1; // . and .. never match anything that doesn't start with ., - // even when options.dot is set. + // eslint-disable-next-line jsdoc/require-description + /** + * @param {string} directoryPath The directory path. + */ + constructor(directoryPath) { + super(`No ESLint configuration found in ${directoryPath}.`); + this.messageTemplate = "no-config-found"; + this.messageData = { directoryPath }; + } +} - var patternStart = pattern.charAt(0) === '.' ? '' // anything - // not (start or / followed by . or .. followed by / or end) - : options.dot ? '(?!(?:^|\\\/)\\.{1,2}(?:$|\\\/))' : '(?!\\.)'; - var self = this; +/** + * This class provides the functionality that enumerates every file which is + * matched by given glob patterns and that configuration. + */ +class CascadingConfigArrayFactory { - function clearStateChar() { - if (stateChar) { - // we had some state-tracking character - // that wasn't consumed by this pass. - switch (stateChar) { - case '*': - re += star; - hasMagic = true; - break; + /** + * Initialize this enumerator. + * @param {CascadingConfigArrayFactoryOptions} options The options. + */ + constructor({ + additionalPluginPool = new Map(), + baseConfig: baseConfigData = null, + cliConfig: cliConfigData = null, + cwd = process.cwd(), + ignorePath, + resolvePluginsRelativeTo, + rulePaths = [], + specificConfigPath = null, + useEslintrc = true, + builtInRules = new Map(), + loadRules, + resolver, + eslintRecommendedPath, + eslintAllPath + } = {}) { + const configArrayFactory = new ConfigArrayFactory({ + additionalPluginPool, + cwd, + resolvePluginsRelativeTo, + builtInRules, + resolver, + eslintRecommendedPath, + eslintAllPath + }); - case '?': - re += qmark; - hasMagic = true; - break; + internalSlotsMap.set(this, { + baseConfigArray: createBaseConfigArray({ + baseConfigData, + configArrayFactory, + cwd, + rulePaths, + loadRules, + resolver + }), + baseConfigData, + cliConfigArray: createCLIConfigArray({ + cliConfigData, + configArrayFactory, + cwd, + ignorePath, + specificConfigPath + }), + cliConfigData, + configArrayFactory, + configCache: new Map(), + cwd, + finalizeCache: new WeakMap(), + ignorePath, + rulePaths, + specificConfigPath, + useEslintrc, + builtInRules, + loadRules + }); + } - default: - re += '\\' + stateChar; - break; - } + /** + * The path to the current working directory. + * This is used by tests. + * @type {string} + */ + get cwd() { + const { cwd } = internalSlotsMap.get(this); - self.debug('clearStateChar %j %j', stateChar, re); - stateChar = false; + return cwd; } - } - for (var i = 0, len = pattern.length, c; i < len && (c = pattern.charAt(i)); i++) { - this.debug('%s\t%s %s %j', pattern, i, re, c); // skip over any that are escaped. + /** + * Get the config array of a given file. + * If `filePath` was not given, it returns the config which contains only + * `baseConfigData` and `cliConfigData`. + * @param {string} [filePath] The file path to a file. + * @param {Object} [options] The options. + * @param {boolean} [options.ignoreNotFoundError] If `true` then it doesn't throw `ConfigurationNotFoundError`. + * @returns {ConfigArray} The config array of the file. + */ + getConfigArrayForFile(filePath, { ignoreNotFoundError = false } = {}) { + const { + baseConfigArray, + cliConfigArray, + cwd + } = internalSlotsMap.get(this); - if (escaping && reSpecials[c]) { - re += '\\' + c; - escaping = false; - continue; - } + if (!filePath) { + return new ConfigArray(...baseConfigArray, ...cliConfigArray); + } - switch (c) { - case '/': - // completely not allowed, even escaped. - // Should already be path-split by now. - return false; + const directoryPath = path__default["default"].dirname(path__default["default"].resolve(cwd, filePath)); - case '\\': - clearStateChar(); - escaping = true; - continue; - // the various stateChar values - // for the "extglob" stuff. + debug$1(`Load config files for ${directoryPath}.`); - case '?': - case '*': - case '+': - case '@': - case '!': - this.debug('%s\t%s %s %j <-- stateChar', pattern, i, re, c); // all of those are literals inside a class, except that - // the glob [!a] means [^a] in regexp + return this._finalizeConfigArray( + this._loadConfigInAncestors(directoryPath), + directoryPath, + ignoreNotFoundError + ); + } - if (inClass) { - this.debug(' in class'); - if (c === '!' && i === classStart + 1) c = '^'; - re += c; - continue; - } // if we already have a stateChar, then it means - // that there was something like ** or +? in there. - // Handle the stateChar, then proceed with this one. + /** + * Set the config data to override all configs. + * Require to call `clearCache()` method after this method is called. + * @param {ConfigData} configData The config data to override all configs. + * @returns {void} + */ + setOverrideConfig(configData) { + const slots = internalSlotsMap.get(this); + slots.cliConfigData = configData; + } - self.debug('call clearStateChar %j', stateChar); - clearStateChar(); - stateChar = c; // if extglob is disabled, then +(asdf|foo) isn't a thing. - // just clear the statechar *now*, rather than even diving into - // the patternList stuff. + /** + * Clear config cache. + * @returns {void} + */ + clearCache() { + const slots = internalSlotsMap.get(this); - if (options.noext) clearStateChar(); - continue; + slots.baseConfigArray = createBaseConfigArray(slots); + slots.cliConfigArray = createCLIConfigArray(slots); + slots.configCache.clear(); + } - case '(': - if (inClass) { - re += '('; - continue; - } + /** + * Load and normalize config files from the ancestor directories. + * @param {string} directoryPath The path to a leaf directory. + * @param {boolean} configsExistInSubdirs `true` if configurations exist in subdirectories. + * @returns {ConfigArray} The loaded config. + * @private + */ + _loadConfigInAncestors(directoryPath, configsExistInSubdirs = false) { + const { + baseConfigArray, + configArrayFactory, + configCache, + cwd, + useEslintrc + } = internalSlotsMap.get(this); - if (!stateChar) { - re += '\\('; - continue; + if (!useEslintrc) { + return baseConfigArray; } - patternListStack.push({ - type: stateChar, - start: i - 1, - reStart: re.length, - open: plTypes[stateChar].open, - close: plTypes[stateChar].close - }); // negation is (?:(?!js)[^/]*) - - re += stateChar === '!' ? '(?:(?!(?:' : '(?:'; - this.debug('plType %j %j', stateChar, re); - stateChar = false; - continue; + let configArray = configCache.get(directoryPath); - case ')': - if (inClass || !patternListStack.length) { - re += '\\)'; - continue; + // Hit cache. + if (configArray) { + debug$1(`Cache hit: ${directoryPath}.`); + return configArray; } + debug$1(`No cache found: ${directoryPath}.`); - clearStateChar(); - hasMagic = true; - var pl = patternListStack.pop(); // negation is (?:(?!js)[^/]*) - // The others are (?:) + const homePath = os__default["default"].homedir(); - re += pl.close; + // Consider this is root. + if (directoryPath === homePath && cwd !== homePath) { + debug$1("Stop traversing because of considered root."); + if (configsExistInSubdirs) { + const filePath = ConfigArrayFactory.getPathToConfigFileInDirectory(directoryPath); - if (pl.type === '!') { - negativeLists.push(pl); + if (filePath) { + emitDeprecationWarning( + filePath, + "ESLINT_PERSONAL_CONFIG_SUPPRESS" + ); + } + } + return this._cacheConfig(directoryPath, baseConfigArray); } - pl.reEnd = re.length; - continue; - - case '|': - if (inClass || !patternListStack.length || escaping) { - re += '\\|'; - escaping = false; - continue; + // Load the config on this directory. + try { + configArray = configArrayFactory.loadInDirectory(directoryPath); + } catch (error) { + /* istanbul ignore next */ + if (error.code === "EACCES") { + debug$1("Stop traversing because of 'EACCES' error."); + return this._cacheConfig(directoryPath, baseConfigArray); + } + throw error; } - clearStateChar(); - re += '|'; - continue; - // these are mostly the same in regexp and glob - - case '[': - // swallow any state-tracking char before the [ - clearStateChar(); - - if (inClass) { - re += '\\' + c; - continue; + if (configArray.length > 0 && configArray.isRoot()) { + debug$1("Stop traversing because of 'root:true'."); + configArray.unshift(...baseConfigArray); + return this._cacheConfig(directoryPath, configArray); } - inClass = true; - classStart = i; - reClassStart = re.length; - re += c; - continue; - - case ']': - // a right bracket shall lose its special - // meaning and represent itself in - // a bracket expression if it occurs - // first in the list. -- POSIX.2 2.8.3.2 - if (i === classStart + 1 || !inClass) { - re += '\\' + c; - escaping = false; - continue; - } // handle the case where we left a class open. - // "[z-a]" is valid, equivalent to "\[z-a\]" - - - if (inClass) { - // split where the last [ was, make sure we don't have - // an invalid re. if so, re-walk the contents of the - // would-be class to re-translate any characters that - // were passed through as-is - // TODO: It would probably be faster to determine this - // without a try/catch and a new RegExp, but it's tricky - // to do safely. For now, this is safe and works. - var cs = pattern.substring(classStart + 1, i); - - try { - RegExp('[' + cs + ']'); - } catch (er) { - // not a valid class! - var sp = this.parse(cs, SUBPARSE); - re = re.substr(0, reClassStart) + '\\[' + sp[0] + '\\]'; - hasMagic = hasMagic || sp[1]; - inClass = false; - continue; - } - } // finish up the class. - - - hasMagic = true; - inClass = false; - re += c; - continue; - - default: - // swallow any state char that wasn't consumed - clearStateChar(); + // Load from the ancestors and merge it. + const parentPath = path__default["default"].dirname(directoryPath); + const parentConfigArray = parentPath && parentPath !== directoryPath + ? this._loadConfigInAncestors( + parentPath, + configsExistInSubdirs || configArray.length > 0 + ) + : baseConfigArray; - if (escaping) { - // no need - escaping = false; - } else if (reSpecials[c] && !(c === '^' && inClass)) { - re += '\\'; + if (configArray.length > 0) { + configArray.unshift(...parentConfigArray); + } else { + configArray = parentConfigArray; } - re += c; - } // switch + // Cache and return. + return this._cacheConfig(directoryPath, configArray); + } - } // for - // handle the case where we left a class open. - // "[abc" is valid, equivalent to "\[abc" + /** + * Freeze and cache a given config. + * @param {string} directoryPath The path to a directory as a cache key. + * @param {ConfigArray} configArray The config array as a cache value. + * @returns {ConfigArray} The `configArray` (frozen). + */ + _cacheConfig(directoryPath, configArray) { + const { configCache } = internalSlotsMap.get(this); + Object.freeze(configArray); + configCache.set(directoryPath, configArray); - if (inClass) { - // split where the last [ was, and escape it - // this is a huge pita. We now have to re-walk - // the contents of the would-be class to re-translate - // any characters that were passed through as-is - cs = pattern.substr(classStart + 1); - sp = this.parse(cs, SUBPARSE); - re = re.substr(0, reClassStart) + '\\[' + sp[0]; - hasMagic = hasMagic || sp[1]; - } // handle the case where we had a +( thing at the *end* - // of the pattern. - // each pattern list stack adds 3 chars, and we need to go through - // and escape any | chars that were passed through as-is for the regexp. - // Go through and escape them, taking care not to double-escape any - // | chars that were already escaped. + return configArray; + } + /** + * Finalize a given config array. + * Concatenate `--config` and other CLI options. + * @param {ConfigArray} configArray The parent config array. + * @param {string} directoryPath The path to the leaf directory to find config files. + * @param {boolean} ignoreNotFoundError If `true` then it doesn't throw `ConfigurationNotFoundError`. + * @returns {ConfigArray} The loaded config. + * @private + */ + _finalizeConfigArray(configArray, directoryPath, ignoreNotFoundError) { + const { + cliConfigArray, + configArrayFactory, + finalizeCache, + useEslintrc, + builtInRules + } = internalSlotsMap.get(this); - for (pl = patternListStack.pop(); pl; pl = patternListStack.pop()) { - var tail = re.slice(pl.reStart + pl.open.length); - this.debug('setting tail', re, pl); // maybe some even number of \, then maybe 1 \, followed by a | + let finalConfigArray = finalizeCache.get(configArray); - tail = tail.replace(/((?:\\{2}){0,64})(\\?)\|/g, function (_, $1, $2) { - if (!$2) { - // the | isn't already escaped, so escape it. - $2 = '\\'; - } // need to escape all those slashes *again*, without escaping the - // one that we need for escaping the | character. As it works out, - // escaping an even number of slashes can be done by simply repeating - // it exactly after itself. That's why this trick works. - // - // I am sorry that you have to see this. + if (!finalConfigArray) { + finalConfigArray = configArray; + // Load the personal config if there are no regular config files. + if ( + useEslintrc && + configArray.every(c => !c.filePath) && + cliConfigArray.every(c => !c.filePath) // `--config` option can be a file. + ) { + const homePath = os__default["default"].homedir(); - return $1 + $1 + $2 + '|'; - }); - this.debug('tail=%j\n %s', tail, tail, pl, re); - var t = pl.type === '*' ? star : pl.type === '?' ? qmark : '\\' + pl.type; - hasMagic = true; - re = re.slice(0, pl.reStart) + t + '\\(' + tail; - } // handle trailing things that only matter at the very end. + debug$1("Loading the config file of the home directory:", homePath); + const personalConfigArray = configArrayFactory.loadInDirectory( + homePath, + { name: "PersonalConfig" } + ); - clearStateChar(); + if ( + personalConfigArray.length > 0 && + !directoryPath.startsWith(homePath) + ) { + const lastElement = + personalConfigArray[personalConfigArray.length - 1]; - if (escaping) { - // trailing \\ - re += '\\\\'; - } // only need to apply the nodot start if the re starts with - // something that could conceivably capture a dot + emitDeprecationWarning( + lastElement.filePath, + "ESLINT_PERSONAL_CONFIG_LOAD" + ); + } + finalConfigArray = finalConfigArray.concat(personalConfigArray); + } - var addPatternStart = false; + // Apply CLI options. + if (cliConfigArray.length > 0) { + finalConfigArray = finalConfigArray.concat(cliConfigArray); + } - switch (re.charAt(0)) { - case '.': - case '[': - case '(': - addPatternStart = true; - } // Hack to work around lack of negative lookbehind in JS - // A pattern like: *.!(x).!(y|z) needs to ensure that a name - // like 'a.xyz.yz' doesn't match. So, the first negative - // lookahead, has to look ALL the way ahead, to the end of - // the pattern. + // Validate rule settings and environments. + const validator = new ConfigValidator({ + builtInRules + }); + validator.validateConfigArray(finalConfigArray); - for (var n = negativeLists.length - 1; n > -1; n--) { - var nl = negativeLists[n]; - var nlBefore = re.slice(0, nl.reStart); - var nlFirst = re.slice(nl.reStart, nl.reEnd - 8); - var nlLast = re.slice(nl.reEnd - 8, nl.reEnd); - var nlAfter = re.slice(nl.reEnd); - nlLast += nlAfter; // Handle nested stuff like *(*.js|!(*.json)), where open parens - // mean that we should *not* include the ) in the bit that is considered - // "after" the negated section. + // Cache it. + Object.freeze(finalConfigArray); + finalizeCache.set(configArray, finalConfigArray); - var openParensBefore = nlBefore.split('(').length - 1; - var cleanAfter = nlAfter; + debug$1( + "Configuration was determined: %o on %s", + finalConfigArray, + directoryPath + ); + } - for (i = 0; i < openParensBefore; i++) { - cleanAfter = cleanAfter.replace(/\)[+*?]?/, ''); + // At least one element (the default ignore patterns) exists. + if (!ignoreNotFoundError && useEslintrc && finalConfigArray.length <= 1) { + throw new ConfigurationNotFoundError(directoryPath); + } + + return finalConfigArray; } +} - nlAfter = cleanAfter; - var dollar = ''; +/** + * @fileoverview Compatibility class for flat config. + * @author Nicholas C. Zakas + */ - if (nlAfter === '' && isSub !== SUBPARSE) { - dollar = '$'; - } +const dirname = path__default["default"].dirname(url.fileURLToPath((typeof document === 'undefined' ? new ((__webpack_require__(892).URL))('file:' + __filename).href : (document.currentScript && document.currentScript.src || new URL('eslintrc.cjs', document.baseURI).href)))); - var newRe = nlBefore + nlFirst + nlAfter + dollar + nlLast; - re = newRe; - } // if the re is not "" at this point, then we need to make sure - // it doesn't match against an empty path part. - // Otherwise a/* will match a/, which it should not. +//----------------------------------------------------------------------------- +// Helpers +//----------------------------------------------------------------------------- +/** @typedef {import("../../shared/types").Environment} Environment */ +/** @typedef {import("../../shared/types").Processor} Processor */ - if (re !== '' && hasMagic) { - re = '(?=.)' + re; - } +const debug = debugOrig__default["default"]("eslintrc:flat-compat"); +const cafactory = Symbol("cafactory"); - if (addPatternStart) { - re = patternStart + re; - } // parsing just a piece of a larger pattern. +/** + * Translates an ESLintRC-style config object into a flag-config-style config + * object. + * @param {Object} eslintrcConfig An ESLintRC-style config object. + * @param {Object} options Options to help translate the config. + * @param {string} options.resolveConfigRelativeTo To the directory to resolve + * configs from. + * @param {string} options.resolvePluginsRelativeTo The directory to resolve + * plugins from. + * @param {ReadOnlyMap} options.pluginEnvironments A map of plugin environment + * names to objects. + * @param {ReadOnlyMap} options.pluginProcessors A map of plugin processor + * names to objects. + * @returns {Object} A flag-config-style config object. + */ +function translateESLintRC(eslintrcConfig, { + resolveConfigRelativeTo, + resolvePluginsRelativeTo, + pluginEnvironments, + pluginProcessors +}) { + const flatConfig = {}; + const configs = []; + const languageOptions = {}; + const linterOptions = {}; + const keysToCopy = ["settings", "rules", "processor"]; + const languageOptionsKeysToCopy = ["globals", "parser", "parserOptions"]; + const linterOptionsKeysToCopy = ["noInlineConfig", "reportUnusedDisableDirectives"]; - if (isSub === SUBPARSE) { - return [re, hasMagic]; - } // skip the regexp for non-magical patterns - // unescape anything in it, though, so that it'll be - // an exact match against a file etc. + // check for special settings for eslint:all and eslint:recommended: + if (eslintrcConfig.settings) { + if (eslintrcConfig.settings["eslint:all"] === true) { + return ["eslint:all"]; + } + if (eslintrcConfig.settings["eslint:recommended"] === true) { + return ["eslint:recommended"]; + } + } - if (!hasMagic) { - return globUnescape(pattern); - } + // copy over simple translations + for (const key of keysToCopy) { + if (key in eslintrcConfig && typeof eslintrcConfig[key] !== "undefined") { + flatConfig[key] = eslintrcConfig[key]; + } + } - var flags = options.nocase ? 'i' : ''; + // copy over languageOptions + for (const key of languageOptionsKeysToCopy) { + if (key in eslintrcConfig && typeof eslintrcConfig[key] !== "undefined") { - try { - var regExp = new RegExp('^' + re + '$', flags); - } catch (er) { - // If it was an invalid regular expression, then it can't match - // anything. This trick looks for a character after the end of - // the string, which is of course impossible, except in multi-line - // mode, but it's not a /m regex. - return new RegExp('$.'); - } + // create the languageOptions key in the flat config + flatConfig.languageOptions = languageOptions; - regExp._glob = pattern; - regExp._src = re; - return regExp; -} + if (key === "parser") { + debug(`Resolving parser '${languageOptions[key]}' relative to ${resolveConfigRelativeTo}`); -minimatch.makeRe = function (pattern, options) { - return new Minimatch(pattern, options || {}).makeRe(); -}; + if (eslintrcConfig[key].error) { + throw eslintrcConfig[key].error; + } -Minimatch.prototype.makeRe = makeRe; + languageOptions[key] = eslintrcConfig[key].definition; + continue; + } -function makeRe() { - if (this.regexp || this.regexp === false) return this.regexp; // at this point, this.set is a 2d array of partial - // pattern strings, or "**". - // - // It's better to use .match(). This function shouldn't - // be used, really, but it's pretty convenient sometimes, - // when you just want to work with a regex. + // clone any object values that are in the eslintrc config + if (eslintrcConfig[key] && typeof eslintrcConfig[key] === "object") { + languageOptions[key] = { + ...eslintrcConfig[key] + }; + } else { + languageOptions[key] = eslintrcConfig[key]; + } + } + } - var set = this.set; + // copy over linterOptions + for (const key of linterOptionsKeysToCopy) { + if (key in eslintrcConfig && typeof eslintrcConfig[key] !== "undefined") { + flatConfig.linterOptions = linterOptions; + linterOptions[key] = eslintrcConfig[key]; + } + } - if (!set.length) { - this.regexp = false; - return this.regexp; - } + // move ecmaVersion a level up + if (languageOptions.parserOptions) { - var options = this.options; - var twoStar = options.noglobstar ? star : options.dot ? twoStarDot : twoStarNoDot; - var flags = options.nocase ? 'i' : ''; - var re = set.map(function (pattern) { - return pattern.map(function (p) { - return p === GLOBSTAR ? twoStar : typeof p === 'string' ? regExpEscape(p) : p._src; - }).join('\\\/'); - }).join('|'); // must match entire pattern - // ending in a * or ** will make it less strict. + if ("ecmaVersion" in languageOptions.parserOptions) { + languageOptions.ecmaVersion = languageOptions.parserOptions.ecmaVersion; + delete languageOptions.parserOptions.ecmaVersion; + } - re = '^(?:' + re + ')$'; // can match anything, as long as it's not this. + if ("sourceType" in languageOptions.parserOptions) { + languageOptions.sourceType = languageOptions.parserOptions.sourceType; + delete languageOptions.parserOptions.sourceType; + } - if (this.negate) re = '^(?!' + re + ').*$'; + // check to see if we even need parserOptions anymore and remove it if not + if (Object.keys(languageOptions.parserOptions).length === 0) { + delete languageOptions.parserOptions; + } + } - try { - this.regexp = new RegExp(re, flags); - } catch (ex) { - this.regexp = false; - } + // overrides + if (eslintrcConfig.criteria) { + flatConfig.files = [absoluteFilePath => eslintrcConfig.criteria.test(absoluteFilePath)]; + } - return this.regexp; -} + // translate plugins + if (eslintrcConfig.plugins && typeof eslintrcConfig.plugins === "object") { + debug(`Translating plugins: ${eslintrcConfig.plugins}`); -minimatch.match = function (list, pattern, options) { - options = options || {}; - var mm = new Minimatch(pattern, options); - list = list.filter(function (f) { - return mm.match(f); - }); + flatConfig.plugins = {}; - if (mm.options.nonull && !list.length) { - list.push(pattern); - } + for (const pluginName of Object.keys(eslintrcConfig.plugins)) { - return list; -}; + debug(`Translating plugin: ${pluginName}`); + debug(`Resolving plugin '${pluginName} relative to ${resolvePluginsRelativeTo}`); -Minimatch.prototype.match = match; + const { definition: plugin, error } = eslintrcConfig.plugins[pluginName]; -function match(f, partial) { - this.debug('match', f, this.pattern); // short-circuit in the case of busted things. - // comments, etc. + if (error) { + throw error; + } - if (this.comment) return false; - if (this.empty) return f === ''; - if (f === '/' && partial) return true; - var options = this.options; // windows: need to use /, not \ + flatConfig.plugins[pluginName] = plugin; - if (path.sep !== '/') { - f = f.split(path.sep).join('/'); - } // treat the test path as a set of pathparts. + // create a config for any processors + if (plugin.processors) { + for (const processorName of Object.keys(plugin.processors)) { + if (processorName.startsWith(".")) { + debug(`Assigning processor: ${pluginName}/${processorName}`); + configs.unshift({ + files: [`**/*${processorName}`], + processor: pluginProcessors.get(`${pluginName}/${processorName}`) + }); + } - f = f.split(slashSplit); - this.debug(this.pattern, 'split', f); // just ONE of the pattern sets in this.set needs to match - // in order for it to be valid. If negating, then just one - // match means that we have failed. - // Either way, return on the first hit. + } + } + } + } - var set = this.set; - this.debug(this.pattern, 'set', set); // Find the basename of the path by looking for the last non-empty segment + // translate env - must come after plugins + if (eslintrcConfig.env && typeof eslintrcConfig.env === "object") { + for (const envName of Object.keys(eslintrcConfig.env)) { - var filename; - var i; + // only add environments that are true + if (eslintrcConfig.env[envName]) { + debug(`Translating environment: ${envName}`); - for (i = f.length - 1; i >= 0; i--) { - filename = f[i]; - if (filename) break; - } + if (environments.has(envName)) { - for (i = 0; i < set.length; i++) { - var pattern = set[i]; - var file = f; + // built-in environments should be defined first + configs.unshift(...translateESLintRC(environments.get(envName), { + resolveConfigRelativeTo, + resolvePluginsRelativeTo + })); + } else if (pluginEnvironments.has(envName)) { - if (options.matchBase && pattern.length === 1) { - file = [filename]; + // if the environment comes from a plugin, it should come after the plugin config + configs.push(...translateESLintRC(pluginEnvironments.get(envName), { + resolveConfigRelativeTo, + resolvePluginsRelativeTo + })); + } + } + } } - var hit = this.matchOne(file, pattern, partial); - - if (hit) { - if (options.flipNegate) return true; - return !this.negate; + // only add if there are actually keys in the config + if (Object.keys(flatConfig).length > 0) { + configs.push(flatConfig); } - } // didn't get any hits. this is success if it's a negative - // pattern, failure otherwise. + return configs; +} - if (options.flipNegate) return false; - return this.negate; -} // set partial to true to test if, for example, -// "/a/b" matches the start of "/*/b/*/d" -// Partial means, if you run out of file before you run -// out of pattern, then that's fine, as long as all -// the parts match. +//----------------------------------------------------------------------------- +// Exports +//----------------------------------------------------------------------------- -Minimatch.prototype.matchOne = function (file, pattern, partial) { - var options = this.options; - this.debug('matchOne', { - 'this': this, - file: file, - pattern: pattern - }); - this.debug('matchOne', file.length, pattern.length); +/** + * A compatibility class for working with configs. + */ +class FlatCompat { - for (var fi = 0, pi = 0, fl = file.length, pl = pattern.length; fi < fl && pi < pl; fi++, pi++) { - this.debug('matchOne loop'); - var p = pattern[pi]; - var f = file[fi]; - this.debug(pattern, p, f); // should be impossible. - // some invalid regexp stuff in the set. + constructor({ + baseDirectory = process.cwd(), + resolvePluginsRelativeTo = baseDirectory + } = {}) { + this.baseDirectory = baseDirectory; + this.resolvePluginsRelativeTo = resolvePluginsRelativeTo; + this[cafactory] = new ConfigArrayFactory({ + cwd: baseDirectory, + resolvePluginsRelativeTo, + eslintAllPath: path__default["default"].resolve(dirname, "../conf/eslint-all.cjs"), + eslintRecommendedPath: path__default["default"].resolve(dirname, "../conf/eslint-recommended.cjs") + }); + } - if (p === false) return false; + /** + * Translates an ESLintRC-style config into a flag-config-style config. + * @param {Object} eslintrcConfig The ESLintRC-style config object. + * @returns {Object} A flag-config-style config object. + */ + config(eslintrcConfig) { + const eslintrcArray = this[cafactory].create(eslintrcConfig, { + basePath: this.baseDirectory + }); - if (p === GLOBSTAR) { - this.debug('GLOBSTAR', [pattern, p, f]); // "**" - // a/**/b/**/c would match the following: - // a/b/x/y/z/c - // a/x/y/z/b/c - // a/b/x/b/x/c - // a/b/c - // To do this, take the rest of the pattern after - // the **, and see if it would match the file remainder. - // If so, return success. - // If not, the ** "swallows" a segment, and try again. - // This is recursively awful. - // - // a/**/b/**/c matching a/b/x/y/z/c - // - a matches a - // - doublestar - // - matchOne(b/x/y/z/c, b/**/c) - // - b matches b - // - doublestar - // - matchOne(x/y/z/c, c) -> no - // - matchOne(y/z/c, c) -> no - // - matchOne(z/c, c) -> no - // - matchOne(c, c) yes, hit + const flatArray = []; + let hasIgnorePatterns = false; - var fr = fi; - var pr = pi + 1; + eslintrcArray.forEach(configData => { + if (configData.type === "config") { + hasIgnorePatterns = hasIgnorePatterns || configData.ignorePattern; + flatArray.push(...translateESLintRC(configData, { + resolveConfigRelativeTo: path__default["default"].join(this.baseDirectory, "__placeholder.js"), + resolvePluginsRelativeTo: path__default["default"].join(this.resolvePluginsRelativeTo, "__placeholder.js"), + pluginEnvironments: eslintrcArray.pluginEnvironments, + pluginProcessors: eslintrcArray.pluginProcessors + })); + } + }); - if (pr === pl) { - this.debug('** at the end'); // a ** at the end will just swallow the rest. - // We have found a match. - // however, it will not swallow /.x, unless - // options.dot is set. - // . and .. are *never* matched by **, for explosively - // exponential reasons. + // combine ignorePatterns to emulate ESLintRC behavior better + if (hasIgnorePatterns) { + flatArray.unshift({ + ignores: [filePath => { - for (; fi < fl; fi++) { - if (file[fi] === '.' || file[fi] === '..' || !options.dot && file[fi].charAt(0) === '.') return false; + // Compute the final config for this file. + // This filters config array elements by `files`/`excludedFiles` then merges the elements. + const finalConfig = eslintrcArray.extractConfig(filePath); + + // Test the `ignorePattern` properties of the final config. + return Boolean(finalConfig.ignores) && finalConfig.ignores(filePath); + }] + }); } - return true; - } // ok, let's see if we can swallow whatever we can. + return flatArray; + } + /** + * Translates the `env` section of an ESLintRC-style config. + * @param {Object} envConfig The `env` section of an ESLintRC config. + * @returns {Object} A flag-config object representing the environments. + */ + env(envConfig) { + return this.config({ + env: envConfig + }); + } - while (fr < fl) { - var swallowee = file[fr]; - this.debug('\nglobstar while', file, fr, pattern, pr, swallowee); // XXX remove this slice. Just pass the start index. + /** + * Translates the `extends` section of an ESLintRC-style config. + * @param {...string} configsToExtend The names of the configs to load. + * @returns {Object} A flag-config object representing the config. + */ + extends(...configsToExtend) { + return this.config({ + extends: configsToExtend + }); + } - if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) { - this.debug('globstar found match!', fr, fl, swallowee); // found a match. + /** + * Translates the `plugins` section of an ESLintRC-style config. + * @param {...string} plugins The names of the plugins to load. + * @returns {Object} A flag-config object representing the plugins. + */ + plugins(...plugins) { + return this.config({ + plugins + }); + } +} - return true; - } else { - // can't swallow "." or ".." ever. - // can only swallow ".foo" when explicitly asked. - if (swallowee === '.' || swallowee === '..' || !options.dot && swallowee.charAt(0) === '.') { - this.debug('dot detected!', file, fr, pattern, pr); - break; - } // ** swallows a segment, and continue. +/** + * @fileoverview Package exports for @eslint/eslintrc + * @author Nicholas C. Zakas + */ + +//----------------------------------------------------------------------------- +// Exports +//----------------------------------------------------------------------------- +const Legacy = { + ConfigArray, + createConfigArrayFactoryContext: createContext, + CascadingConfigArrayFactory, + ConfigArrayFactory, + ConfigDependency, + ExtractedConfig, + IgnorePattern, + OverrideTester, + getUsedExtractedConfigs, + environments, - this.debug('globstar swallow a segment, and continue'); - fr++; - } - } // no match was found. - // However, in partial mode, we can't say this is necessarily over. - // If there's more *pattern* left, then + // shared + ConfigOps, + ConfigValidator, + ModuleResolver, + naming +}; +exports.FlatCompat = FlatCompat; +exports.Legacy = Legacy; +//# sourceMappingURL=eslintrc.cjs.map - if (partial) { - // ran out of file - this.debug('\n>>> no match, partial?', file, fr, pattern, pr); - if (fr === fl) return true; - } - return false; - } // something other than ** - // non-magic patterns just have to match exactly - // patterns with magic have been turned into regexps. +/***/ }), +/* 884 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +"use strict"; - var hit; - if (typeof p === 'string') { - if (options.nocase) { - hit = f.toLowerCase() === p.toLowerCase(); - } else { - hit = f === p; - } +const path = __webpack_require__(429); - this.debug('string match', p, f, hit); - } else { - hit = f.match(p); - this.debug('pattern match', p, f, hit); - } +const resolveFrom = __webpack_require__(885); - if (!hit) return false; - } // Note: ending in / means that we'll get a final "" - // at the end of the pattern. This can only match a - // corresponding "" at the end of the file. - // If the file ends in /, then it can only match a - // a pattern that ends in /, unless the pattern just - // doesn't have any more for it. But, a/b/ should *not* - // match "a/b/*", even though "" matches against the - // [^/]*? pattern, except in partial mode, where it might - // simply not be reached yet. - // However, a/b/ should still satisfy a/* - // now either we fell off the end of the pattern, or we're done. +const parentModule = __webpack_require__(887); +module.exports = moduleId => { + if (typeof moduleId !== 'string') { + throw new TypeError('Expected a string'); + } - if (fi === fl && pi === pl) { - // ran out of pattern and filename at the same time. - // an exact hit! - return true; - } else if (fi === fl) { - // ran out of file, but still had pattern left. - // this is ok if we're doing the match as part of - // a glob fs traversal. - return partial; - } else if (pi === pl) { - // ran out of pattern, still have file left. - // this is only acceptable if we're on the very last - // empty segment of a file with a trailing slash. - // a/* should match a/b/ - var emptyFileEnd = fi === fl - 1 && file[fi] === ''; - return emptyFileEnd; - } // should be unreachable. + const parentPath = parentModule(__filename); + const cwd = parentPath ? path.dirname(parentPath) : __dirname; + const filePath = resolveFrom(cwd, moduleId); + const oldModule = __webpack_require__.c[filePath]; // Delete itself from module parent + if (oldModule && oldModule.parent) { + let i = oldModule.parent.children.length; - throw new Error('wtf?'); -}; // replace stuff like \* with * + while (i--) { + if (oldModule.parent.children[i].id === filePath) { + oldModule.parent.children.splice(i, 1); + } + } + } + delete __webpack_require__.c[filePath]; // Delete module from cache -function globUnescape(s) { - return s.replace(/\\(.)/g, '$1'); -} + const parent = __webpack_require__.c[parentPath]; // If `filePath` and `parentPath` are the same, cache will already be deleted so we won't get a memory leak in next step -function regExpEscape(s) { - return s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&'); -} + return parent === undefined ? __webpack_require__(889)(filePath) : parent.require(filePath); // In case cache doesn't have parent, fall back to normal require +}; /***/ }), -/* 872 */ +/* 885 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var concatMap = __webpack_require__(873); - -var balanced = __webpack_require__(874); +"use strict"; -module.exports = expandTop; -var escSlash = '\0SLASH' + Math.random() + '\0'; -var escOpen = '\0OPEN' + Math.random() + '\0'; -var escClose = '\0CLOSE' + Math.random() + '\0'; -var escComma = '\0COMMA' + Math.random() + '\0'; -var escPeriod = '\0PERIOD' + Math.random() + '\0'; -function numeric(str) { - return parseInt(str, 10) == str ? parseInt(str, 10) : str.charCodeAt(0); -} +const path = __webpack_require__(429); -function escapeBraces(str) { - return str.split('\\\\').join(escSlash).split('\\{').join(escOpen).split('\\}').join(escClose).split('\\,').join(escComma).split('\\.').join(escPeriod); -} +const Module = __webpack_require__(886); -function unescapeBraces(str) { - return str.split(escSlash).join('\\').split(escOpen).join('{').split(escClose).join('}').split(escComma).join(',').split(escPeriod).join('.'); -} // Basically just str.split(","), but handling cases -// where we have nested braced sections, which should be -// treated as individual members, like {a,{b,c},d} +const fs = __webpack_require__(880); +const resolveFrom = (fromDir, moduleId, silent) => { + if (typeof fromDir !== 'string') { + throw new TypeError("Expected `fromDir` to be of type `string`, got `".concat(typeof fromDir, "`")); + } -function parseCommaParts(str) { - if (!str) return ['']; - var parts = []; - var m = balanced('{', '}', str); - if (!m) return str.split(','); - var pre = m.pre; - var body = m.body; - var post = m.post; - var p = pre.split(','); - p[p.length - 1] += '{' + body + '}'; - var postParts = parseCommaParts(post); + if (typeof moduleId !== 'string') { + throw new TypeError("Expected `moduleId` to be of type `string`, got `".concat(typeof moduleId, "`")); + } - if (post.length) { - p[p.length - 1] += postParts.shift(); - p.push.apply(p, postParts); + try { + fromDir = fs.realpathSync(fromDir); + } catch (err) { + if (err.code === 'ENOENT') { + fromDir = path.resolve(fromDir); + } else if (silent) { + return null; + } else { + throw err; + } } - parts.push.apply(parts, p); - return parts; -} + const fromFile = path.join(fromDir, 'noop.js'); -function expandTop(str) { - if (!str) return []; // I don't know why Bash 4.3 does this, but it does. - // Anything starting with {} will have the first two bytes preserved - // but *only* at the top level, so {},a}b will not expand to anything, - // but a{},b}c will be expanded to [a}c,abc]. - // One could argue that this is a bug in Bash, but since the goal of - // this module is to match Bash's rules, we escape a leading {} + const resolveFileName = () => Module._resolveFilename(moduleId, { + id: fromFile, + filename: fromFile, + paths: Module._nodeModulePaths(fromDir) + }); - if (str.substr(0, 2) === '{}') { - str = '\\{\\}' + str.substr(2); + if (silent) { + try { + return resolveFileName(); + } catch (err) { + return null; + } } - return expand(escapeBraces(str), true).map(unescapeBraces); -} + return resolveFileName(); +}; -function identity(e) { - return e; -} +module.exports = (fromDir, moduleId) => resolveFrom(fromDir, moduleId); -function embrace(str) { - return '{' + str + '}'; -} +module.exports.silent = (fromDir, moduleId) => resolveFrom(fromDir, moduleId, true); -function isPadded(el) { - return /^-?0\d/.test(el); -} +/***/ }), +/* 886 */ +/***/ ((module) => { -function lte(i, y) { - return i <= y; -} +"use strict"; +module.exports = require("module"); -function gte(i, y) { - return i >= y; -} +/***/ }), +/* 887 */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -function expand(str, isTop) { - var expansions = []; - var m = balanced('{', '}', str); - if (!m || /\$$/.test(m.pre)) return [str]; - var isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body); - var isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body); - var isSequence = isNumericSequence || isAlphaSequence; - var isOptions = m.body.indexOf(',') >= 0; +"use strict"; - if (!isSequence && !isOptions) { - // {a},b} - if (m.post.match(/,.*\}/)) { - str = m.pre + '{' + m.body + escClose + m.post; - return expand(str); - } - return [str]; +const callsites = __webpack_require__(888); + +module.exports = filepath => { + const stacks = callsites(); + + if (!filepath) { + return stacks[2].getFileName(); } - var n; + let seenVal = false; // Skip the first stack as it's this function - if (isSequence) { - n = m.body.split(/\.\./); - } else { - n = parseCommaParts(m.body); + stacks.shift(); - if (n.length === 1) { - // x{{a,b}}y ==> x{a}y x{b}y - n = expand(n[0], false).map(embrace); + for (const stack of stacks) { + const parentFilepath = stack.getFileName(); - if (n.length === 1) { - var post = m.post.length ? expand(m.post, false) : ['']; - return post.map(function (p) { - return m.pre + n[0] + p; - }); - } + if (typeof parentFilepath !== 'string') { + continue; } - } // at this point, n is the parts, and we know it's not a comma set - // with a single entry. - // no need to expand pre, since it is guaranteed to be free of brace-sets + if (parentFilepath === filepath) { + seenVal = true; + continue; + } // Skip native modules - var pre = m.pre; - var post = m.post.length ? expand(m.post, false) : ['']; - var N; - if (isSequence) { - var x = numeric(n[0]); - var y = numeric(n[1]); - var width = Math.max(n[0].length, n[1].length); - var incr = n.length == 3 ? Math.abs(numeric(n[2])) : 1; - var test = lte; - var reverse = y < x; + if (parentFilepath === 'module.js') { + continue; + } - if (reverse) { - incr *= -1; - test = gte; + if (seenVal && parentFilepath !== filepath) { + return parentFilepath; } + } +}; - var pad = n.some(isPadded); - N = []; +/***/ }), +/* 888 */ +/***/ ((module) => { - for (var i = x; test(i, y); i += incr) { - var c; +"use strict"; - if (isAlphaSequence) { - c = String.fromCharCode(i); - if (c === '\\') c = ''; - } else { - c = String(i); - if (pad) { - var need = width - c.length; +const callsites = () => { + const _prepareStackTrace = Error.prepareStackTrace; - if (need > 0) { - var z = new Array(need + 1).join('0'); - if (i < 0) c = '-' + z + c.slice(1);else c = z + c; - } - } - } + Error.prepareStackTrace = (_, stack) => stack; - N.push(c); - } - } else { - N = concatMap(n, function (el) { - return expand(el, false); - }); - } + const stack = new Error().stack.slice(1); + Error.prepareStackTrace = _prepareStackTrace; + return stack; +}; - for (var j = 0; j < N.length; j++) { - for (var k = 0; k < post.length; k++) { - var expansion = pre + N[j] + post[k]; - if (!isTop || isSequence || expansion) expansions.push(expansion); - } - } +module.exports = callsites; // TODO: Remove this for the next major release - return expansions; -} +module.exports["default"] = callsites; /***/ }), -/* 873 */ +/* 889 */ /***/ ((module) => { -module.exports = function (xs, fn) { - var res = []; - - for (var i = 0; i < xs.length; i++) { - var x = fn(xs[i], i); - if (isArray(x)) res.push.apply(res, x);else res.push(x); - } - - return res; -}; - -var isArray = Array.isArray || function (xs) { - return Object.prototype.toString.call(xs) === '[object Array]'; -}; +function webpackEmptyContext(req) { + var e = new Error("Cannot find module '" + req + "'"); + e.code = 'MODULE_NOT_FOUND'; + throw e; +} +webpackEmptyContext.keys = () => ([]); +webpackEmptyContext.resolve = webpackEmptyContext; +webpackEmptyContext.id = 889; +module.exports = webpackEmptyContext; /***/ }), -/* 874 */ +/* 890 */ /***/ ((module) => { "use strict"; -module.exports = balanced; +const singleComment = Symbol('singleComment'); +const multiComment = Symbol('multiComment'); -function balanced(a, b, str) { - if (a instanceof RegExp) a = maybeMatch(a, str); - if (b instanceof RegExp) b = maybeMatch(b, str); - var r = range(a, b, str); - return r && { - start: r[0], - end: r[1], - pre: str.slice(0, r[0]), - body: str.slice(r[0] + a.length, r[1]), - post: str.slice(r[1] + b.length) - }; -} +const stripWithoutWhitespace = () => ''; -function maybeMatch(reg, str) { - var m = str.match(reg); - return m ? m[0] : null; -} +const stripWithWhitespace = (string, start, end) => string.slice(start, end).replace(/\S/g, ' '); -balanced.range = range; +const isEscaped = (jsonString, quotePosition) => { + let index = quotePosition - 1; + let backslashCount = 0; -function range(a, b, str) { - var begs, beg, left, right, result; - var ai = str.indexOf(a); - var bi = str.indexOf(b, ai + 1); - var i = ai; + while (jsonString[index] === '\\') { + index -= 1; + backslashCount += 1; + } - if (ai >= 0 && bi > 0) { - if (a === b) { - return [ai, bi]; - } + return Boolean(backslashCount % 2); +}; - begs = []; - left = str.length; +module.exports = function (jsonString) { + let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - while (i >= 0 && !result) { - if (i == ai) { - begs.push(i); - ai = str.indexOf(a, i + 1); - } else if (begs.length == 1) { - result = [begs.pop(), bi]; - } else { - beg = begs.pop(); + if (typeof jsonString !== 'string') { + throw new TypeError("Expected argument `jsonString` to be a `string`, got `".concat(typeof jsonString, "`")); + } - if (beg < left) { - left = beg; - right = bi; - } + const strip = options.whitespace === false ? stripWithoutWhitespace : stripWithWhitespace; + let insideString = false; + let insideComment = false; + let offset = 0; + let result = ''; - bi = str.indexOf(b, i + 1); + for (let i = 0; i < jsonString.length; i++) { + const currentCharacter = jsonString[i]; + const nextCharacter = jsonString[i + 1]; + + if (!insideComment && currentCharacter === '"') { + const escaped = isEscaped(jsonString, i); + + if (!escaped) { + insideString = !insideString; } + } - i = ai < bi && ai >= 0 ? ai : bi; + if (insideString) { + continue; } - if (begs.length) { - result = [left, right]; + if (!insideComment && currentCharacter + nextCharacter === '//') { + result += jsonString.slice(offset, i); + offset = i; + insideComment = singleComment; + i++; + } else if (insideComment === singleComment && currentCharacter + nextCharacter === '\r\n') { + i++; + insideComment = false; + result += strip(jsonString, offset, i); + offset = i; + continue; + } else if (insideComment === singleComment && currentCharacter === '\n') { + insideComment = false; + result += strip(jsonString, offset, i); + offset = i; + } else if (!insideComment && currentCharacter + nextCharacter === '/*') { + result += jsonString.slice(offset, i); + offset = i; + insideComment = multiComment; + i++; + continue; + } else if (insideComment === multiComment && currentCharacter + nextCharacter === '*/') { + i++; + insideComment = false; + result += strip(jsonString, offset, i + 1); + offset = i + 1; + continue; } } - return result; -} + return result + (insideComment ? strip(jsonString.slice(offset)) : jsonString.slice(offset)); +}; /***/ }), -/* 875 */ +/* 891 */ /***/ ((module) => { "use strict"; module.exports = require("os"); /***/ }), -/* 876 */ +/* 892 */ /***/ ((module) => { "use strict"; module.exports = require("url"); /***/ }), -/* 877 */ +/* 893 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; @@ -126460,26 +130538,26 @@ module.exports = require("url"); // Requirements //------------------------------------------------------------------------------ -const fs = __webpack_require__(861); +const fs = __webpack_require__(880); const path = __webpack_require__(429); -const getGlobParent = __webpack_require__(878); +const getGlobParent = __webpack_require__(894); -const isGlob = __webpack_require__(879); +const isGlob = __webpack_require__(895); const escapeRegExp = __webpack_require__(525); const { Minimatch -} = __webpack_require__(871); +} = __webpack_require__(862); const { Legacy: { IgnorePattern, CascadingConfigArrayFactory } -} = __webpack_require__(863); +} = __webpack_require__(883); const debug = __webpack_require__(496)("eslint:file-enumerator"); //------------------------------------------------------------------------------ // Helpers @@ -126998,17 +131076,17 @@ module.exports = { }; /***/ }), -/* 878 */ +/* 894 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; -var isGlob = __webpack_require__(879); +var isGlob = __webpack_require__(895); var pathPosixDirname = (__webpack_require__(429).posix.dirname); -var isWin32 = (__webpack_require__(875).platform)() === 'win32'; +var isWin32 = (__webpack_require__(891).platform)() === 'win32'; var slash = '/'; var backslash = /\\/g; var escaped = /\\([!*?|[\](){}])/g; @@ -127086,7 +131164,7 @@ function isGlobby(str) { } /***/ }), -/* 879 */ +/* 895 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { /*! @@ -127095,7 +131173,7 @@ function isGlobby(str) { * Copyright (c) 2014-2017, Jon Schlinkert. * Released under the MIT License. */ -var isExtglob = __webpack_require__(880); +var isExtglob = __webpack_require__(896); var chars = { '{': '}', @@ -127263,7 +131341,7 @@ module.exports = function isGlob(str, options) { }; /***/ }), -/* 880 */ +/* 896 */ /***/ ((module) => { /*! @@ -127288,7 +131366,7 @@ module.exports = function isExtglob(str) { }; /***/ }), -/* 881 */ +/* 897 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; @@ -127310,7 +131388,7 @@ module.exports = { }; /***/ }), -/* 882 */ +/* 898 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; @@ -127322,7 +131400,7 @@ module.exports = { // Requirements //------------------------------------------------------------------------------ -const fs = __webpack_require__(861), +const fs = __webpack_require__(880), path = __webpack_require__(429); const rulesDirCache = {}; //------------------------------------------------------------------------------ @@ -127349,14 +131427,14 @@ module.exports = function (relativeRulesDir, cwd) { return; } - rules[file.slice(0, -3)] = __webpack_require__(883)(path.join(rulesDir, file)); + rules[file.slice(0, -3)] = __webpack_require__(899)(path.join(rulesDir, file)); }); rulesDirCache[rulesDir] = rules; return rules; }; /***/ }), -/* 883 */ +/* 899 */ /***/ ((module) => { function webpackEmptyContext(req) { @@ -127366,11 +131444,11 @@ function webpackEmptyContext(req) { } webpackEmptyContext.keys = () => ([]); webpackEmptyContext.resolve = webpackEmptyContext; -webpackEmptyContext.id = 883; +webpackEmptyContext.id = 899; module.exports = webpackEmptyContext; /***/ }), -/* 884 */ +/* 900 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; @@ -127382,7 +131460,7 @@ module.exports = webpackEmptyContext; // Requirements //------------------------------------------------------------------------------ -const murmur = __webpack_require__(885); //------------------------------------------------------------------------------ +const murmur = __webpack_require__(901); //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ @@ -127406,7 +131484,7 @@ function hash(str) { module.exports = hash; /***/ }), -/* 885 */ +/* 901 */ /***/ ((module) => { /** @@ -127555,7 +131633,7 @@ module.exports = hash; })(); /***/ }), -/* 886 */ +/* 902 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; @@ -127570,15 +131648,15 @@ module.exports = hash; const assert = __webpack_require__(431); -const fs = __webpack_require__(861); +const fs = __webpack_require__(880); -const fileEntryCache = __webpack_require__(887); +const fileEntryCache = __webpack_require__(903); -const stringify = __webpack_require__(905); +const stringify = __webpack_require__(921); const pkg = __webpack_require__(443); -const hash = __webpack_require__(884); +const hash = __webpack_require__(900); const debug = __webpack_require__(496)("eslint:lint-result-cache"); //----------------------------------------------------------------------------- // Helpers @@ -127734,12 +131812,12 @@ class LintResultCache { module.exports = LintResultCache; /***/ }), -/* 887 */ +/* 903 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { var path = __webpack_require__(429); -var crypto = __webpack_require__(888); +var crypto = __webpack_require__(904); module.exports = { createFromFile: function (filePath, useChecksum) { @@ -127748,9 +131826,9 @@ module.exports = { return this.create(fname, dir, useChecksum); }, create: function (cacheId, _path, useChecksum) { - var fs = __webpack_require__(861); + var fs = __webpack_require__(880); - var flatCache = __webpack_require__(889); + var flatCache = __webpack_require__(905); var cache = flatCache.load(cacheId, _path); var normalizedEntries = {}; @@ -128021,23 +132099,23 @@ module.exports = { }; /***/ }), -/* 888 */ +/* 904 */ /***/ ((module) => { "use strict"; module.exports = require("crypto"); /***/ }), -/* 889 */ +/* 905 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { var path = __webpack_require__(429); -var fs = __webpack_require__(861); +var fs = __webpack_require__(880); -var utils = __webpack_require__(890); +var utils = __webpack_require__(906); -var del = __webpack_require__(892); +var del = __webpack_require__(908); var writeJSON = utils.writeJSON; var cache = { @@ -128230,14 +132308,14 @@ module.exports = { }; /***/ }), -/* 890 */ +/* 906 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var fs = __webpack_require__(861); +var fs = __webpack_require__(880); var path = __webpack_require__(429); -var flatted = __webpack_require__(891); +var flatted = __webpack_require__(907); module.exports = { tryParse: function (filePath, defaultValue) { @@ -128281,7 +132359,7 @@ module.exports = { }; /***/ }), -/* 891 */ +/* 907 */ /***/ ((__unused_webpack_module, exports) => { "use strict"; @@ -128410,12 +132488,12 @@ const fromJSON = any => parse($stringify(any)); exports.fromJSON = fromJSON; /***/ }), -/* 892 */ +/* 908 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var rimraf = (__webpack_require__(893).sync); +var rimraf = (__webpack_require__(909).sync); -var fs = __webpack_require__(861); +var fs = __webpack_require__(880); module.exports = function del(file) { if (fs.existsSync(file)) { @@ -128430,7 +132508,7 @@ module.exports = function del(file) { }; /***/ }), -/* 893 */ +/* 909 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { /* provided dependency */ var process = __webpack_require__(494); @@ -128438,12 +132516,12 @@ const assert = __webpack_require__(431); const path = __webpack_require__(429); -const fs = __webpack_require__(861); +const fs = __webpack_require__(880); let glob = undefined; try { - glob = __webpack_require__(894); + glob = __webpack_require__(910); } catch (_err) {// treat glob as optional. } @@ -128724,7 +132802,7 @@ module.exports = rimraf; rimraf.sync = rimrafSync; /***/ }), -/* 894 */ +/* 910 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { /* provided dependency */ var process = __webpack_require__(494); @@ -128770,37 +132848,37 @@ rimraf.sync = rimrafSync; // things that don't exist. module.exports = glob; -var rp = __webpack_require__(895); +var rp = __webpack_require__(911); -var minimatch = __webpack_require__(871); +var minimatch = __webpack_require__(862); var Minimatch = minimatch.Minimatch; -var inherits = __webpack_require__(897); +var inherits = __webpack_require__(913); -var EE = (__webpack_require__(898).EventEmitter); +var EE = (__webpack_require__(914).EventEmitter); var path = __webpack_require__(429); var assert = __webpack_require__(431); -var isAbsolute = __webpack_require__(899); +var isAbsolute = __webpack_require__(915); -var globSync = __webpack_require__(900); +var globSync = __webpack_require__(916); -var common = __webpack_require__(901); +var common = __webpack_require__(917); var setopts = common.setopts; var ownProp = common.ownProp; -var inflight = __webpack_require__(902); +var inflight = __webpack_require__(918); var util = __webpack_require__(439); var childrenIgnored = common.childrenIgnored; var isIgnored = common.isIgnored; -var once = __webpack_require__(904); +var once = __webpack_require__(920); function glob(pattern, options, cb) { if (typeof options === 'function') cb = options, options = {}; @@ -129426,7 +133504,7 @@ Glob.prototype._stat2 = function (f, abs, er, stat, cb) { }; /***/ }), -/* 895 */ +/* 911 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { /* provided dependency */ var process = __webpack_require__(494); @@ -129437,14 +133515,14 @@ realpath.realpathSync = realpathSync; realpath.monkeypatch = monkeypatch; realpath.unmonkeypatch = unmonkeypatch; -var fs = __webpack_require__(861); +var fs = __webpack_require__(880); var origRealpath = fs.realpath; var origRealpathSync = fs.realpathSync; var version = process.version; var ok = /^v[0-5]\./.test(version); -var old = __webpack_require__(896); +var old = __webpack_require__(912); function newError(er) { return er && er.syscall === 'realpath' && (er.code === 'ELOOP' || er.code === 'ENOMEM' || er.code === 'ENAMETOOLONG'); @@ -129496,7 +133574,7 @@ function unmonkeypatch() { } /***/ }), -/* 896 */ +/* 912 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => { /* provided dependency */ var process = __webpack_require__(494); @@ -129525,7 +133603,7 @@ var pathModule = __webpack_require__(429); var isWindows = process.platform === 'win32'; -var fs = __webpack_require__(861); // JavaScript implementation of realpath, ported from node pre-v6 +var fs = __webpack_require__(880); // JavaScript implementation of realpath, ported from node pre-v6 var DEBUG = process.env.NODE_DEBUG && /fs/.test(process.env.NODE_DEBUG); @@ -129796,7 +133874,7 @@ exports.realpath = function realpath(p, cache, cb) { }; /***/ }), -/* 897 */ +/* 913 */ /***/ ((module) => { if (typeof Object.create === 'function') { @@ -129830,14 +133908,14 @@ if (typeof Object.create === 'function') { } /***/ }), -/* 898 */ +/* 914 */ /***/ ((module) => { "use strict"; module.exports = require("events"); /***/ }), -/* 899 */ +/* 915 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; @@ -129863,7 +133941,7 @@ module.exports.posix = posix; module.exports.win32 = win32; /***/ }), -/* 900 */ +/* 916 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { /* provided dependency */ var console = __webpack_require__(438); @@ -129871,13 +133949,13 @@ module.exports.win32 = win32; module.exports = globSync; globSync.GlobSync = GlobSync; -var rp = __webpack_require__(895); +var rp = __webpack_require__(911); -var minimatch = __webpack_require__(871); +var minimatch = __webpack_require__(862); var Minimatch = minimatch.Minimatch; -var Glob = (__webpack_require__(894).Glob); +var Glob = (__webpack_require__(910).Glob); var util = __webpack_require__(439); @@ -129885,9 +133963,9 @@ var path = __webpack_require__(429); var assert = __webpack_require__(431); -var isAbsolute = __webpack_require__(899); +var isAbsolute = __webpack_require__(915); -var common = __webpack_require__(901); +var common = __webpack_require__(917); var setopts = common.setopts; var ownProp = common.ownProp; @@ -130295,7 +134373,7 @@ GlobSync.prototype._makeAbs = function (f) { }; /***/ }), -/* 901 */ +/* 917 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => { /* provided dependency */ var process = __webpack_require__(494); @@ -130311,13 +134389,13 @@ function ownProp(obj, field) { return Object.prototype.hasOwnProperty.call(obj, field); } -var fs = __webpack_require__(861); +var fs = __webpack_require__(880); var path = __webpack_require__(429); -var minimatch = __webpack_require__(871); +var minimatch = __webpack_require__(862); -var isAbsolute = __webpack_require__(899); +var isAbsolute = __webpack_require__(915); var Minimatch = minimatch.Minimatch; @@ -130511,15 +134589,15 @@ function childrenIgnored(self, path) { } /***/ }), -/* 902 */ +/* 918 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { /* provided dependency */ var process = __webpack_require__(494); -var wrappy = __webpack_require__(903); +var wrappy = __webpack_require__(919); var reqs = Object.create(null); -var once = __webpack_require__(904); +var once = __webpack_require__(920); module.exports = wrappy(inflight); @@ -130573,7 +134651,7 @@ function slice(args) { } /***/ }), -/* 903 */ +/* 919 */ /***/ ((module) => { // Returns a wrapper function that returns a wrapped callback @@ -130612,10 +134690,10 @@ function wrappy(fn, cb) { } /***/ }), -/* 904 */ +/* 920 */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var wrappy = __webpack_require__(903); +var wrappy = __webpack_require__(919); module.exports = wrappy(once); module.exports.strict = wrappy(onceStrict); @@ -130659,7 +134737,7 @@ function onceStrict(fn) { } /***/ }), -/* 905 */ +/* 921 */ /***/ ((module) => { module.exports = function (obj, opts) { @@ -130819,7 +134897,7 @@ var objectKeys = Object.keys || function (obj) { /******/ __webpack_require__(0); /******/ __webpack_require__(427); /******/ __webpack_require__(428); -/******/ var __webpack_exports__ = __webpack_require__(859); +/******/ var __webpack_exports__ = __webpack_require__(878); /******/ /******/ return __webpack_exports__; /******/ })()