Socket
Socket
Sign inDemoInstall

eslint

Package Overview
Dependencies
99
Maintainers
4
Versions
357
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 8.52.0 to 8.56.0

lib/shared/severity.js

26

bin/eslint.js

@@ -100,6 +100,11 @@ #!/usr/bin/env node

*/
const displayedErrors = new Set();
/**
* Tracks whether an unexpected error was caught
* @type {boolean}
*/
let hadFatalError = false;
/**
* Catch and report unexpected error.

@@ -111,2 +116,3 @@ * @param {any} error The thrown error object.

process.exitCode = 2;
hadFatalError = true;

@@ -148,3 +154,3 @@ const { version } = require("../package.json");

// Otherwise, call the CLI.
process.exitCode = await require("../lib/cli").execute(
const exitCode = await require("../lib/cli").execute(
process.argv,

@@ -154,2 +160,18 @@ process.argv.includes("--stdin") ? await readStdin() : null,

);
/*
* If an uncaught exception or unhandled rejection was detected in the meantime,
* keep the fatal exit code 2 that is already assigned to `process.exitCode`.
* Without this condition, exit code 2 (unsuccessful execution) could be overwritten with
* 1 (successful execution, lint problems found) or even 0 (successful execution, no lint problems found).
* This ensures that unexpected errors that seemingly don't affect the success
* of the execution will still cause a non-zero exit code, as it's a common
* practice and the default behavior of Node.js to exit with non-zero
* in case of an uncaught exception or unhandled rejection.
*
* Otherwise, assign the exit code returned from CLI.
*/
if (!hadFatalError) {
process.exitCode = exitCode;
}
}()).catch(onFatalError);

4

lib/cli-engine/cli-engine.js

@@ -86,3 +86,3 @@ /**

* @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|string} [reportUnusedDisableDirectives] `true`, `"error"` or '"warn"' 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.

@@ -228,3 +228,3 @@ * @property {string} [resolvePluginsRelativeTo] The folder where plugins should be resolved from, defaulting to the CWD

* @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 {boolean|string} config.reportUnusedDisableDirectives If `true`, `"error"` or '"warn"', then it reports unused `eslint-disable` comments.
* @param {FileEnumerator} config.fileEnumerator The file enumerator to check if a path is a target or not.

@@ -231,0 +231,0 @@ * @param {Linter} config.linter The linter instance to verify.

@@ -131,12 +131,24 @@ /**

const cachedResults = fileDescriptor.meta.results;
// Just in case, not sure if this can ever happen.
if (!cachedResults) {
return cachedResults;
}
/*
* Shallow clone the object to ensure that any properties added or modified afterwards
* will not be accidentally stored in the cache file when `reconcile()` is called.
* https://github.com/eslint/eslint/issues/13507
* All intentional changes to the cache file must be done through `setCachedLintResults()`.
*/
const results = { ...cachedResults };
// If source is present but null, need to reread the file from the filesystem.
if (
fileDescriptor.meta.results &&
fileDescriptor.meta.results.source === null
) {
if (results.source === null) {
debug(`Rereading cached result source from filesystem: ${filePath}`);
fileDescriptor.meta.results.source = fs.readFileSync(filePath, "utf-8");
results.source = fs.readFileSync(filePath, "utf-8");
}
return fileDescriptor.meta.results;
return results;
}

@@ -143,0 +155,0 @@

@@ -25,3 +25,4 @@ /**

log = require("./shared/logging"),
RuntimeInfo = require("./shared/runtime-info");
RuntimeInfo = require("./shared/runtime-info"),
{ normalizeSeverityToString } = require("./shared/severity");
const { Legacy: { naming } } = require("@eslint/eslintrc");

@@ -93,2 +94,3 @@ const { ModuleImporter } = require("@humanwhocodes/module-importer");

reportUnusedDisableDirectives,
reportUnusedDisableDirectivesSeverity,
resolvePluginsRelativeTo,

@@ -130,2 +132,10 @@ rule,

if (reportUnusedDisableDirectives || reportUnusedDisableDirectivesSeverity !== void 0) {
overrideConfig[0].linterOptions = {
reportUnusedDisableDirectives: reportUnusedDisableDirectives
? "error"
: normalizeSeverityToString(reportUnusedDisableDirectivesSeverity)
};
}
if (parser) {

@@ -183,4 +193,3 @@ overrideConfig[0].languageOptions.parser = await importer.import(parser);

overrideConfig,
overrideConfigFile,
reportUnusedDisableDirectives: reportUnusedDisableDirectives ? "error" : void 0
overrideConfigFile
};

@@ -197,2 +206,7 @@

options.ignorePath = ignorePath;
if (reportUnusedDisableDirectives || reportUnusedDisableDirectivesSeverity !== void 0) {
options.reportUnusedDisableDirectives = reportUnusedDisableDirectives
? "error"
: normalizeSeverityToString(reportUnusedDisableDirectivesSeverity);
}
}

@@ -394,2 +408,7 @@

if (options.reportUnusedDisableDirectives && options.reportUnusedDisableDirectivesSeverity !== void 0) {
log.error("The --report-unused-disable-directives option and the --report-unused-disable-directives-severity option cannot be used together.");
return 2;
}
const ActiveESLint = usingFlatConfig ? FlatESLint : ESLint;

@@ -396,0 +415,0 @@

@@ -17,2 +17,3 @@ /**

const structuredClone = require("@ungap/structured-clone").default;
const { normalizeSeverityToNumber } = require("../shared/severity");

@@ -266,3 +267,23 @@ //-----------------------------------------------------------------------------

const ALLOWED_SEVERITIES = new Set(["error", "warn", "off", 2, 1, 0]);
/** @type {ObjectPropertySchema} */
const disableDirectiveSeveritySchema = {
merge(first, second) {
const value = second === void 0 ? first : second;
if (typeof value === "boolean") {
return value ? "warn" : "off";
}
return normalizeSeverityToNumber(value);
},
validate(value) {
if (!(ALLOWED_SEVERITIES.has(value) || typeof value === "boolean")) {
throw new TypeError("Expected one of: \"error\", \"warn\", \"off\", 0, 1, 2, or a boolean.");
}
}
};
/** @type {ObjectPropertySchema} */
const deepObjectAssignSchema = {

@@ -539,3 +560,3 @@ merge(first = {}, second = {}) {

noInlineConfig: booleanSchema,
reportUnusedDisableDirectives: booleanSchema
reportUnusedDisableDirectives: disableDirectiveSeveritySchema
}

@@ -542,0 +563,0 @@ },

@@ -678,3 +678,2 @@ /**

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.
warnIgnored = true,

@@ -724,2 +723,5 @@ ...unknownOptions

}
if (unknownOptionKeys.includes("reportUnusedDisableDirectives")) {
errors.push("'reportUnusedDisableDirectives' has been removed. Please use the 'overrideConfig.linterOptions.reportUnusedDisableDirectives' option instead.");
}
}

@@ -779,10 +781,2 @@ if (typeof allowInlineConfig !== "boolean") {

}
if (
reportUnusedDisableDirectives !== "error" &&
reportUnusedDisableDirectives !== "warn" &&
reportUnusedDisableDirectives !== "off" &&
reportUnusedDisableDirectives !== null
) {
errors.push("'reportUnusedDisableDirectives' must be any of \"error\", \"warn\", \"off\", and null.");
}
if (typeof warnIgnored !== "boolean") {

@@ -812,3 +806,2 @@ errors.push("'warnIgnored' must be a boolean.");

ignorePatterns,
reportUnusedDisableDirectives,
warnIgnored

@@ -815,0 +808,0 @@ };

@@ -14,2 +14,3 @@ /**

const fs = require("fs").promises;
const { existsSync } = require("fs");
const path = require("path");

@@ -87,3 +88,2 @@ const findUp = require("find-up");

* @property {Record<string,Plugin>} [plugins] An array of plugin implementations.
* @property {"error" | "warn" | "off"} [reportUnusedDisableDirectives] the severity to report unused eslint-disable directives.
* @property {boolean} warnIgnored Show warnings when the file list includes ignored files

@@ -453,3 +453,2 @@ */

* @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 {Linter} config.linter The linter instance to verify.

@@ -466,3 +465,2 @@ * @returns {LintResult} The result of linting.

allowInlineConfig,
reportUnusedDisableDirectives,
linter

@@ -487,3 +485,2 @@ }) {

fix,
reportUnusedDisableDirectives,

@@ -756,3 +753,2 @@ /**

fixTypes,
reportUnusedDisableDirectives,
globInputPaths,

@@ -775,3 +771,3 @@ errorOnUnmatchedPattern,

// Ignore errors when no such file exists or file system is read only (and cache file does not exist)
if (errorCode !== "ENOENT" && !(errorCode === "EROFS" && !(await fs.exists(cacheFilePath)))) {
if (errorCode !== "ENOENT" && !(errorCode === "EROFS" && !existsSync(cacheFilePath))) {
throw error;

@@ -868,3 +864,2 @@ }

allowInlineConfig,
reportUnusedDisableDirectives,
linter

@@ -954,3 +949,2 @@ });

fix,
reportUnusedDisableDirectives,
warnIgnored: constructorWarnIgnored

@@ -979,3 +973,2 @@ } = eslintOptions;

allowInlineConfig,
reportUnusedDisableDirectives,
linter

@@ -982,0 +975,0 @@ }));

@@ -18,3 +18,6 @@ /**

}
} = require("@eslint/eslintrc/universal");
} = require("@eslint/eslintrc/universal"),
{
directivesPattern
} = require("../shared/directives");

@@ -152,2 +155,33 @@ const debug = require("debug")("eslint:config-comment-parser");

/**
* Extract the directive and the justification from a given directive comment and trim them.
* @param {string} value The comment text to extract.
* @returns {{directivePart: string, justificationPart: string}} The extracted directive and justification.
*/
extractDirectiveComment(value) {
const match = /\s-{2,}\s/u.exec(value);
if (!match) {
return { directivePart: value.trim(), justificationPart: "" };
}
const directive = value.slice(0, match.index).trim();
const justification = value.slice(match.index + match[0].length).trim();
return { directivePart: directive, justificationPart: justification };
}
/**
* Parses a directive comment into directive text and value.
* @param {Comment} comment The comment node with the directive to be parsed.
* @returns {{directiveText: string, directiveValue: string}} The directive text and value.
*/
parseDirective(comment) {
const { directivePart } = this.extractDirectiveComment(comment.value);
const match = directivesPattern.exec(directivePart);
const directiveText = match[1];
const directiveValue = directivePart.slice(match.index + directiveText.length);
return { directiveText, directiveValue };
}
};

@@ -51,2 +51,3 @@ /**

* @property {boolean | undefined} reportUnusedDisableDirectives Adds reported errors for unused eslint-disable and eslint-enable directives
* @property {string | undefined} reportUnusedDisableDirectivesSeverity A severity string indicating if and how unused disable and enable directives should be tracked and reported.
* @property {string} [resolvePluginsRelativeTo] A folder where plugins should be resolved from, CWD by default

@@ -311,2 +312,9 @@ * @property {Object} [rule] Specify rules

{
option: "report-unused-disable-directives-severity",
type: "String",
default: void 0,
description: "Chooses severity level for reporting unused eslint-disable and eslint-enable directives",
enum: ["off", "warn", "error", "0", "1", "2"]
},
{
heading: "Caching"

@@ -313,0 +321,0 @@ },

/**
* @fileoverview Rule to enforce linebreaks after open and before close array brackets
* @author Jan Peer Stöcklmair <https://github.com/JPeer264>
* @deprecated in ESLint v8.53.0
*/

@@ -17,2 +18,4 @@

meta: {
deprecated: true,
replacedBy: [],
type: "layout",

@@ -19,0 +22,0 @@

/**
* @fileoverview Disallows or enforces spaces inside of array brackets.
* @author Jamund Ferguson
* @deprecated in ESLint v8.53.0
*/

@@ -16,2 +17,4 @@ "use strict";

meta: {
deprecated: true,
replacedBy: [],
type: "layout",

@@ -18,0 +21,0 @@

/**
* @fileoverview Rule to enforce line breaks after each array element
* @author Jan Peer Stöcklmair <https://github.com/JPeer264>
* @deprecated in ESLint v8.53.0
*/

@@ -17,2 +18,4 @@

meta: {
deprecated: true,
replacedBy: [],
type: "layout",

@@ -19,0 +22,0 @@

/**
* @fileoverview Rule to require parens in arrow function arguments.
* @author Jxck
* @deprecated in ESLint v8.53.0
*/

@@ -33,2 +34,4 @@ "use strict";

meta: {
deprecated: true,
replacedBy: [],
type: "layout",

@@ -35,0 +38,0 @@

/**
* @fileoverview Rule to define spacing before/after arrow function's arrow.
* @author Jxck
* @deprecated in ESLint v8.53.0
*/

@@ -20,2 +21,4 @@ "use strict";

meta: {
deprecated: true,
replacedBy: [],
type: "layout",

@@ -22,0 +25,0 @@

/**
* @fileoverview A rule to disallow or enforce spaces inside of single line blocks.
* @author Toru Nagashima
* @deprecated in ESLint v8.53.0
*/

@@ -17,2 +18,4 @@

meta: {
deprecated: true,
replacedBy: [],
type: "layout",

@@ -19,0 +22,0 @@

/**
* @fileoverview Rule to flag block statements that do not use the one true brace style
* @author Ian Christian Myers
* @deprecated in ESLint v8.53.0
*/

@@ -17,2 +18,4 @@

meta: {
deprecated: true,
replacedBy: [],
type: "layout",

@@ -19,0 +22,0 @@

/**
* @fileoverview Rule to forbid or enforce dangling commas.
* @author Ian Christian Myers
* @deprecated in ESLint v8.53.0
*/

@@ -76,2 +77,4 @@

meta: {
deprecated: true,
replacedBy: [],
type: "layout",

@@ -78,0 +81,0 @@

/**
* @fileoverview Comma spacing - validates spacing before and after comma
* @author Vignesh Anand aka vegetableman.
* @deprecated in ESLint v8.53.0
*/

@@ -16,2 +17,4 @@ "use strict";

meta: {
deprecated: true,
replacedBy: [],
type: "layout",

@@ -18,0 +21,0 @@

/**
* @fileoverview Comma style - enforces comma styles of two types: last and first
* @author Vignesh Anand aka vegetableman
* @deprecated in ESLint v8.53.0
*/

@@ -17,2 +18,4 @@

meta: {
deprecated: true,
replacedBy: [],
type: "layout",

@@ -19,0 +22,0 @@

/**
* @fileoverview Disallows or enforces spaces inside computed properties.
* @author Jamund Ferguson
* @deprecated in ESLint v8.53.0
*/

@@ -16,2 +17,4 @@ "use strict";

meta: {
deprecated: true,
replacedBy: [],
type: "layout",

@@ -18,0 +21,0 @@

/**
* @fileoverview Validates newlines before and after dots
* @author Greg Cochard
* @deprecated in ESLint v8.53.0
*/

@@ -17,2 +18,4 @@

meta: {
deprecated: true,
replacedBy: [],
type: "layout",

@@ -19,0 +22,0 @@

/**
* @fileoverview Require or disallow newline at the end of files
* @author Nodeca Team <https://github.com/nodeca>
* @deprecated in ESLint v8.53.0
*/

@@ -14,2 +15,4 @@ "use strict";

meta: {
deprecated: true,
replacedBy: [],
type: "layout",

@@ -16,0 +19,0 @@

@@ -104,26 +104,33 @@ /**

}
return {
ForStatement(node) {
if (node.test && node.test.type === "BinaryExpression" && node.test.left.type === "Identifier" && node.update) {
const counter = node.test.left.name;
const operator = node.test.operator;
const update = node.update;
if (node.test && node.test.type === "BinaryExpression" && node.update) {
for (const counterPosition of ["left", "right"]) {
if (node.test[counterPosition].type !== "Identifier") {
continue;
}
let wrongDirection;
const counter = node.test[counterPosition].name;
const operator = node.test.operator;
const update = node.update;
if (operator === "<" || operator === "<=") {
wrongDirection = -1;
} else if (operator === ">" || operator === ">=") {
wrongDirection = 1;
} else {
return;
}
let wrongDirection;
if (update.type === "UpdateExpression") {
if (getUpdateDirection(update, counter) === wrongDirection) {
if (operator === "<" || operator === "<=") {
wrongDirection = counterPosition === "left" ? -1 : 1;
} else if (operator === ">" || operator === ">=") {
wrongDirection = counterPosition === "left" ? 1 : -1;
} else {
return;
}
if (update.type === "UpdateExpression") {
if (getUpdateDirection(update, counter) === wrongDirection) {
report(node);
}
} else if (update.type === "AssignmentExpression" && getAssignmentDirection(update, counter) === wrongDirection) {
report(node);
}
} else if (update.type === "AssignmentExpression" && getAssignmentDirection(update, counter) === wrongDirection) {
report(node);
}

@@ -130,0 +137,0 @@ }

/**
* @fileoverview Rule to control spacing within function calls
* @author Matt DuVall <http://www.mattduvall.com>
* @deprecated in ESLint v8.53.0
*/

@@ -21,2 +22,4 @@

meta: {
deprecated: true,
replacedBy: [],
type: "layout",

@@ -23,0 +26,0 @@

/**
* @fileoverview Rule to enforce line breaks between arguments of a function call
* @author Alexey Gonchar <https://github.com/finico>
* @deprecated in ESLint v8.53.0
*/

@@ -15,2 +16,4 @@

meta: {
deprecated: true,
replacedBy: [],
type: "layout",

@@ -17,0 +20,0 @@

/**
* @fileoverview enforce consistent line breaks inside function parentheses
* @author Teddy Katz
* @deprecated in ESLint v8.53.0
*/

@@ -20,2 +21,4 @@ "use strict";

meta: {
deprecated: true,
replacedBy: [],
type: "layout",

@@ -22,0 +25,0 @@

/**
* @fileoverview Rule to check the spacing around the * in generator functions.
* @author Jamund Ferguson
* @deprecated in ESLint v8.53.0
*/

@@ -31,2 +32,4 @@

meta: {
deprecated: true,
replacedBy: [],
type: "layout",

@@ -33,0 +36,0 @@

/**
* @fileoverview enforce the location of arrow function bodies
* @author Sharmila Jesupaul
* @deprecated in ESLint v8.53.0
*/

@@ -15,2 +16,4 @@ "use strict";

meta: {
deprecated: true,
replacedBy: [],
type: "layout",

@@ -17,0 +20,0 @@

/**
* @fileoverview A rule to ensure consistent quotes used in jsx syntax.
* @author Mathias Schreck <https://github.com/lo1tuma>
* @deprecated in ESLint v8.53.0
*/

@@ -42,2 +43,4 @@

meta: {
deprecated: true,
replacedBy: [],
type: "layout",

@@ -44,0 +47,0 @@

/**
* @fileoverview Rule to specify spacing of object literal keys and values
* @author Brandon Mills
* @deprecated in ESLint v8.53.0
*/

@@ -136,2 +137,4 @@ "use strict";

meta: {
deprecated: true,
replacedBy: [],
type: "layout",

@@ -138,0 +141,0 @@

/**
* @fileoverview Rule to enforce spacing before and after keywords.
* @author Toru Nagashima
* @deprecated in ESLint v8.53.0
*/

@@ -67,2 +68,4 @@

meta: {
deprecated: true,
replacedBy: [],
type: "layout",

@@ -69,0 +72,0 @@

/**
* @fileoverview Rule to enforce a single linebreak style.
* @author Erik Mueller
* @deprecated in ESLint v8.53.0
*/

@@ -21,2 +22,4 @@

meta: {
deprecated: true,
replacedBy: [],
type: "layout",

@@ -23,0 +26,0 @@

/**
* @fileoverview Enforces empty lines around comments.
* @author Jamund Ferguson
* @deprecated in ESLint v8.53.0
*/

@@ -55,2 +56,4 @@ "use strict";

meta: {
deprecated: true,
replacedBy: [],
type: "layout",

@@ -57,0 +60,0 @@

/**
* @fileoverview Rule to check empty newline between class members
* @author 薛定谔的猫<hh_2013@foxmail.com>
* @deprecated in ESLint v8.53.0
*/

@@ -35,2 +36,4 @@ "use strict";

meta: {
deprecated: true,
replacedBy: [],
type: "layout",

@@ -37,0 +40,0 @@

/**
* @fileoverview Rule to check for max length on a line.
* @author Matt DuVall <http://www.mattduvall.com>
* @deprecated in ESLint v8.53.0
*/

@@ -69,2 +70,4 @@

meta: {
deprecated: true,
replacedBy: [],
type: "layout",

@@ -71,0 +74,0 @@

/**
* @fileoverview Specify the maximum number of statements allowed per line.
* @author Kenneth Williams
* @deprecated in ESLint v8.53.0
*/

@@ -20,2 +21,4 @@ "use strict";

meta: {
deprecated: true,
replacedBy: [],
type: "layout",

@@ -22,0 +25,0 @@

/**
* @fileoverview Enforce newlines between operands of ternary expressions
* @author Kai Cataldo
* @deprecated in ESLint v8.53.0
*/

@@ -17,2 +18,4 @@

meta: {
deprecated: true,
replacedBy: [],
type: "layout",

@@ -19,0 +22,0 @@

/**
* @fileoverview Rule to flag when using constructor without parentheses
* @author Ilya Volodin
* @deprecated in ESLint v8.53.0
*/

@@ -25,2 +26,4 @@

meta: {
deprecated: true,
replacedBy: [],
type: "layout",

@@ -27,0 +30,0 @@

@@ -5,2 +5,3 @@ /**

* @author Burak Yigit Kaya
* @deprecated in ESLint v8.53.0
*/

@@ -19,2 +20,4 @@

meta: {
deprecated: true,
replacedBy: [],
type: "layout",

@@ -21,0 +24,0 @@

@@ -9,2 +9,14 @@ /**

//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
const {
getVariableByName,
isClosingParenToken,
isOpeningParenToken,
isStartOfExpressionStatement,
needsPrecedingSemicolon
} = require("./utils/ast-utils");
//------------------------------------------------------------------------------
// Rule Definition

@@ -24,6 +36,10 @@ //------------------------------------------------------------------------------

hasSuggestions: true,
schema: [],
messages: {
preferLiteral: "The array literal notation [] is preferable."
preferLiteral: "The array literal notation [] is preferable.",
useLiteral: "Replace with an array literal.",
useLiteralAfterSemicolon: "Replace with an array literal, add preceding semicolon."
}

@@ -34,3 +50,29 @@ },

const sourceCode = context.sourceCode;
/**
* Gets the text between the calling parentheses of a CallExpression or NewExpression.
* @param {ASTNode} node A CallExpression or NewExpression node.
* @returns {string} The text between the calling parentheses, or an empty string if there are none.
*/
function getArgumentsText(node) {
const lastToken = sourceCode.getLastToken(node);
if (!isClosingParenToken(lastToken)) {
return "";
}
let firstToken = node.callee;
do {
firstToken = sourceCode.getTokenAfter(firstToken);
if (!firstToken || firstToken === lastToken) {
return "";
}
} while (!isOpeningParenToken(firstToken));
return sourceCode.text.slice(firstToken.range[1], lastToken.range[0]);
}
/**
* Disallow construction of dense arrays using the Array constructor

@@ -43,8 +85,45 @@ * @param {ASTNode} node node to evaluate

if (
node.arguments.length !== 1 &&
node.callee.type === "Identifier" &&
node.callee.name === "Array"
) {
context.report({ node, messageId: "preferLiteral" });
node.callee.type !== "Identifier" ||
node.callee.name !== "Array" ||
node.arguments.length === 1 &&
node.arguments[0].type !== "SpreadElement") {
return;
}
const variable = getVariableByName(sourceCode.getScope(node), "Array");
/*
* Check if `Array` is a predefined global variable: predefined globals have no declarations,
* meaning that the `identifiers` list of the variable object is empty.
*/
if (variable && variable.identifiers.length === 0) {
const argsText = getArgumentsText(node);
let fixText;
let messageId;
/*
* Check if the suggested change should include a preceding semicolon or not.
* Due to JavaScript's ASI rules, a missing semicolon may be inserted automatically
* before an expression like `Array()` or `new Array()`, but not when the expression
* is changed into an array literal like `[]`.
*/
if (isStartOfExpressionStatement(node) && needsPrecedingSemicolon(sourceCode, node)) {
fixText = `;[${argsText}]`;
messageId = "useLiteralAfterSemicolon";
} else {
fixText = `[${argsText}]`;
messageId = "useLiteral";
}
context.report({
node,
messageId: "preferLiteral",
suggest: [
{
messageId,
fix: fixer => fixer.replaceText(node, fixText)
}
]
});
}
}

@@ -51,0 +130,0 @@

@@ -5,2 +5,3 @@ /**

* @author Jxck <https://github.com/Jxck>
* @deprecated in ESLint v8.53.0
*/

@@ -32,2 +33,4 @@

meta: {
deprecated: true,
replacedBy: [],
type: "suggestion",

@@ -34,0 +37,0 @@

@@ -46,4 +46,7 @@ /**

hasSuggestions: true,
messages: {
unexpected: "Unexpected console statement."
unexpected: "Unexpected console statement.",
removeConsole: "Remove the console.{{ propertyName }}()."
}

@@ -99,2 +102,60 @@ },

/**
* Checks if removing the ExpressionStatement node will cause ASI to
* break.
* eg.
* foo()
* console.log();
* [1, 2, 3].forEach(a => doSomething(a))
*
* Removing the console.log(); statement should leave two statements, but
* here the two statements will become one because [ causes continuation after
* foo().
* @param {ASTNode} node The ExpressionStatement node to check.
* @returns {boolean} `true` if ASI will break after removing the ExpressionStatement
* node.
*/
function maybeAsiHazard(node) {
const SAFE_TOKENS_BEFORE = /^[:;{]$/u; // One of :;{
const UNSAFE_CHARS_AFTER = /^[-[(/+`]/u; // One of [(/+-`
const tokenBefore = sourceCode.getTokenBefore(node);
const tokenAfter = sourceCode.getTokenAfter(node);
return (
Boolean(tokenAfter) &&
UNSAFE_CHARS_AFTER.test(tokenAfter.value) &&
tokenAfter.value !== "++" &&
tokenAfter.value !== "--" &&
Boolean(tokenBefore) &&
!SAFE_TOKENS_BEFORE.test(tokenBefore.value)
);
}
/**
* Checks if the MemberExpression node's parent.parent.parent is a
* Program, BlockStatement, StaticBlock, or SwitchCase node. This check
* is necessary to avoid providing a suggestion that might cause a syntax error.
*
* eg. if (a) console.log(b), removing console.log() here will lead to a
* syntax error.
* if (a) { console.log(b) }, removing console.log() here is acceptable.
*
* Additionally, it checks if the callee of the CallExpression node is
* the node itself.
*
* eg. foo(console.log), cannot provide a suggestion here.
* @param {ASTNode} node The MemberExpression node to check.
* @returns {boolean} `true` if a suggestion can be provided for a node.
*/
function canProvideSuggestions(node) {
return (
node.parent.type === "CallExpression" &&
node.parent.callee === node &&
node.parent.parent.type === "ExpressionStatement" &&
astUtils.STATEMENT_LIST_PARENTS.has(node.parent.parent.parent.type) &&
!maybeAsiHazard(node.parent.parent)
);
}
/**
* Reports the given reference as a violation.

@@ -107,6 +168,17 @@ * @param {eslint-scope.Reference} reference The reference to report.

const propertyName = astUtils.getStaticPropertyName(node);
context.report({
node,
loc: node.loc,
messageId: "unexpected"
messageId: "unexpected",
suggest: canProvideSuggestions(node)
? [{
messageId: "removeConsole",
data: { propertyName },
fix(fixer) {
return fixer.remove(node.parent.parent);
}
}]
: []
});

@@ -113,0 +185,0 @@ }

/**
* @fileoverview Disallow parenthesising higher precedence subexpressions.
* @author Michael Ficarra
* @deprecated in ESLint v8.53.0
*/

@@ -17,2 +18,4 @@ "use strict";

meta: {
deprecated: true,
replacedBy: [],
type: "layout",

@@ -19,0 +22,0 @@

/**
* @fileoverview Rule to flag use of unnecessary semicolons
* @author Nicholas C. Zakas
* @deprecated in ESLint v8.53.0
*/

@@ -22,2 +23,4 @@

meta: {
deprecated: true,
replacedBy: [],
type: "suggestion",

@@ -24,0 +27,0 @@

/**
* @fileoverview Rule to flag use of a leading/trailing decimal point in a numeric literal
* @author James Allardice
* @deprecated in ESLint v8.53.0
*/

@@ -21,2 +22,4 @@

meta: {
deprecated: true,
replacedBy: [],
type: "suggestion",

@@ -23,0 +26,0 @@

@@ -99,3 +99,3 @@ /**

const scope = sourceCode.getScope(node);
const features = context.parserOptions.ecmaFeatures || {};
const features = context.languageOptions.parserOptions.ecmaFeatures || {};

@@ -102,0 +102,0 @@ // `this` at the top level of scripts always refers to the global object

/**
* @fileoverview Rule to disallow mixed binary operators.
* @author Toru Nagashima
* @deprecated in ESLint v8.53.0
*/

@@ -88,2 +89,4 @@

meta: {
deprecated: true,
replacedBy: [],
type: "suggestion",

@@ -90,0 +93,0 @@

/**
* @fileoverview Disallow mixed spaces and tabs for indentation
* @author Jary Niebur
* @deprecated in ESLint v8.53.0
*/

@@ -14,2 +15,4 @@ "use strict";

meta: {
deprecated: true,
replacedBy: [],
type: "layout",

@@ -16,0 +19,0 @@

/**
* @fileoverview Disallow use of multiple spaces.
* @author Nicholas C. Zakas
* @deprecated in ESLint v8.53.0
*/

@@ -17,2 +18,4 @@

meta: {
deprecated: true,
replacedBy: [],
type: "layout",

@@ -19,0 +22,0 @@

@@ -5,2 +5,3 @@ /**

* @author Greg Cochard
* @deprecated in ESLint v8.53.0
*/

@@ -16,2 +17,4 @@ "use strict";

meta: {
deprecated: true,
replacedBy: [],
type: "layout",

@@ -18,0 +21,0 @@

@@ -12,65 +12,10 @@ /**

const { getVariableByName, isArrowToken, isClosingBraceToken, isClosingParenToken } = require("./utils/ast-utils");
const {
getVariableByName,
isArrowToken,
isStartOfExpressionStatement,
needsPrecedingSemicolon
} = require("./utils/ast-utils");
//------------------------------------------------------------------------------
// Helpers
//------------------------------------------------------------------------------
const BREAK_OR_CONTINUE = new Set(["BreakStatement", "ContinueStatement"]);
// Declaration types that must contain a string Literal node at the end.
const DECLARATIONS = new Set(["ExportAllDeclaration", "ExportNamedDeclaration", "ImportDeclaration"]);
const IDENTIFIER_OR_KEYWORD = new Set(["Identifier", "Keyword"]);
// Keywords that can immediately precede an ExpressionStatement node, mapped to the their node types.
const NODE_TYPES_BY_KEYWORD = {
__proto__: null,
break: "BreakStatement",
continue: "ContinueStatement",
debugger: "DebuggerStatement",
do: "DoWhileStatement",
else: "IfStatement",
return: "ReturnStatement",
yield: "YieldExpression"
};
/*
* Before an opening parenthesis, `>` (for JSX), and postfix `++` and `--` always trigger ASI;
* the tokens `:`, `;`, `{` and `=>` don't expect a semicolon, as that would count as an empty statement.
*/
const PUNCTUATORS = new Set([":", ";", ">", "{", "=>", "++", "--"]);
/*
* Statements that can contain an `ExpressionStatement` after a closing parenthesis.
* DoWhileStatement is an exception in that it always triggers ASI after the closing parenthesis.
*/
const STATEMENTS = new Set([
"DoWhileStatement",
"ForInStatement",
"ForOfStatement",
"ForStatement",
"IfStatement",
"WhileStatement",
"WithStatement"
]);
/**
* Tests if a node appears at the beginning of an ancestor ExpressionStatement node.
* @param {ASTNode} node The node to check.
* @returns {boolean} Whether the node appears at the beginning of an ancestor ExpressionStatement node.
*/
function isStartOfExpressionStatement(node) {
const start = node.range[0];
let ancestor = node;
while ((ancestor = ancestor.parent) && ancestor.range[0] === start) {
if (ancestor.type === "ExpressionStatement") {
return true;
}
}
return false;
}
//------------------------------------------------------------------------------
// Rule Definition

@@ -125,46 +70,2 @@ //------------------------------------------------------------------------------

/**
* Determines whether a parenthesized object literal that replaces a specified node needs to be preceded by a semicolon.
* @param {ASTNode} node The node to be replaced. This node should be at the start of an `ExpressionStatement` or at the start of the body of an `ArrowFunctionExpression`.
* @returns {boolean} Whether a semicolon is required before the parenthesized object literal.
*/
function needsSemicolon(node) {
const prevToken = sourceCode.getTokenBefore(node);
if (!prevToken || prevToken.type === "Punctuator" && PUNCTUATORS.has(prevToken.value)) {
return false;
}
const prevNode = sourceCode.getNodeByRangeIndex(prevToken.range[0]);
if (isClosingParenToken(prevToken)) {
return !STATEMENTS.has(prevNode.type);
}
if (isClosingBraceToken(prevToken)) {
return (
prevNode.type === "BlockStatement" && prevNode.parent.type === "FunctionExpression" ||
prevNode.type === "ClassBody" && prevNode.parent.type === "ClassExpression" ||
prevNode.type === "ObjectExpression"
);
}
if (IDENTIFIER_OR_KEYWORD.has(prevToken.type)) {
if (BREAK_OR_CONTINUE.has(prevNode.parent.type)) {
return false;
}
const keyword = prevToken.value;
const nodeType = NODE_TYPES_BY_KEYWORD[keyword];
return prevNode.type !== nodeType;
}
if (prevToken.type === "String") {
return !DECLARATIONS.has(prevNode.parent.type);
}
return true;
}
/**
* Reports on nodes where the `Object` constructor is called without arguments.

@@ -188,3 +89,3 @@ * @param {ASTNode} node The node to evaluate.

replacement = "({})";
if (needsSemicolon(node)) {
if (needsPrecedingSemicolon(sourceCode, node)) {
fixText = ";({})";

@@ -191,0 +92,0 @@ messageId = "useLiteralAfterSemicolon";

@@ -212,8 +212,11 @@ /**

suggest.push({
messageId: "wrapBraces",
fix(fixer) {
return curlyWrapFixer(sourceCode, node, fixer);
}
});
// Do not suggest wrapping an unnamed FunctionExpression in braces as that would be invalid syntax.
if (!(node.body.type === "FunctionExpression" && !node.body.id)) {
suggest.push({
messageId: "wrapBraces",
fix(fixer) {
return curlyWrapFixer(sourceCode, node, fixer);
}
});
}

@@ -220,0 +223,0 @@ context.report({

@@ -14,2 +14,33 @@ /**

//------------------------------------------------------------------------------
// Helpers
//------------------------------------------------------------------------------
/**
* Returns true if the node or any of the objects
* to the left of it in the member/call chain is optional.
*
* e.g. `a?.b`, `a?.b.c`, `a?.()`, `a()?.()`
* @param {ASTNode} node The expression to check
* @returns {boolean} `true` if there is a short-circuiting optional `?.`
* in the same option chain to the left of this call or member expression,
* or the node itself is an optional call or member `?.`.
*/
function isAfterOptional(node) {
let leftNode;
if (node.type === "MemberExpression") {
leftNode = node.object;
} else if (node.type === "CallExpression") {
leftNode = node.callee;
} else {
return false;
}
if (node.optional) {
return true;
}
return isAfterOptional(leftNode);
}
//------------------------------------------------------------------------------
// Rule Definition

@@ -29,6 +60,9 @@ //------------------------------------------------------------------------------

hasSuggestions: true,
schema: [],
messages: {
prototypeBuildIn: "Do not access Object.prototype method '{{prop}}' from target object."
prototypeBuildIn: "Do not access Object.prototype method '{{prop}}' from target object.",
callObjectPrototype: "Call Object.prototype.{{prop}} explicitly."
}

@@ -64,3 +98,57 @@ },

data: { prop: propName },
node
node,
suggest: [
{
messageId: "callObjectPrototype",
data: { prop: propName },
fix(fixer) {
const sourceCode = context.sourceCode;
/*
* A call after an optional chain (e.g. a?.b.hasOwnProperty(c))
* must be fixed manually because the call can be short-circuited
*/
if (isAfterOptional(node)) {
return null;
}
/*
* A call on a ChainExpression (e.g. (a?.hasOwnProperty)(c)) will trigger
* no-unsafe-optional-chaining which should be fixed before this suggestion
*/
if (node.callee.type === "ChainExpression") {
return null;
}
const objectVariable = astUtils.getVariableByName(sourceCode.getScope(node), "Object");
/*
* We can't use Object if the global Object was shadowed,
* or Object does not exist in the global scope for some reason
*/
if (!objectVariable || objectVariable.scope.type !== "global" || objectVariable.defs.length > 0) {
return null;
}
let objectText = sourceCode.getText(callee.object);
if (astUtils.getPrecedence(callee.object) <= astUtils.getPrecedence({ type: "SequenceExpression" })) {
objectText = `(${objectText})`;
}
const openParenToken = sourceCode.getTokenAfter(
node.callee,
astUtils.isOpeningParenToken
);
const isEmptyParameters = node.arguments.length === 0;
const delim = isEmptyParameters ? "" : ", ";
const fixes = [
fixer.replaceText(callee, `Object.prototype.${propName}.call`),
fixer.insertTextAfter(openParenToken, objectText + delim)
];
return fixes;
}
}
]
});

@@ -67,0 +155,0 @@ }

@@ -77,2 +77,5 @@ /**

},
importNamePattern: {
type: "string"
},
message: {

@@ -119,4 +122,8 @@ type: "string",

patternAndEverything: "* import is invalid because '{{importNames}}' from '{{importSource}}' is restricted from being used by a pattern.",
patternAndEverythingWithRegexImportName: "* import is invalid because import name matching '{{importNames}}' pattern from '{{importSource}}' is restricted from being used.",
// eslint-disable-next-line eslint-plugin/report-message-format -- Custom message might not end in a period
patternAndEverythingWithCustomMessage: "* import is invalid because '{{importNames}}' from '{{importSource}}' is restricted from being used by a pattern. {{customMessage}}",
// eslint-disable-next-line eslint-plugin/report-message-format -- Custom message might not end in a period
patternAndEverythingWithRegexImportNameAndCustomMessage: "* import is invalid because import name matching '{{importNames}}' pattern from '{{importSource}}' is restricted from being used. {{customMessage}}",

@@ -180,6 +187,7 @@ everything: "* import is invalid because '{{importNames}}' from '{{importSource}}' is restricted.",

// relative paths are supported for this rule
const restrictedPatternGroups = restrictedPatterns.map(({ group, message, caseSensitive, importNames }) => ({
const restrictedPatternGroups = restrictedPatterns.map(({ group, message, caseSensitive, importNames, importNamePattern }) => ({
matcher: ignore({ allowRelativePaths: true, ignorecase: !caseSensitive }).add(group),
customMessage: message,
importNames
importNames,
importNamePattern
}));

@@ -268,2 +276,3 @@

const restrictedImportNames = group.importNames;
const restrictedImportNamePattern = group.importNamePattern ? new RegExp(group.importNamePattern, "u") : null;

@@ -274,3 +283,3 @@ /*

*/
if (!restrictedImportNames) {
if (!restrictedImportNames && !restrictedImportNamePattern) {
context.report({

@@ -287,36 +296,50 @@ node,

if (importNames.has("*")) {
const specifierData = importNames.get("*")[0];
importNames.forEach((specifiers, importName) => {
if (importName === "*") {
const [specifier] = specifiers;
context.report({
node,
messageId: customMessage ? "patternAndEverythingWithCustomMessage" : "patternAndEverything",
loc: specifierData.loc,
data: {
importSource,
importNames: restrictedImportNames,
customMessage
if (restrictedImportNames) {
context.report({
node,
messageId: customMessage ? "patternAndEverythingWithCustomMessage" : "patternAndEverything",
loc: specifier.loc,
data: {
importSource,
importNames: restrictedImportNames,
customMessage
}
});
} else {
context.report({
node,
messageId: customMessage ? "patternAndEverythingWithRegexImportNameAndCustomMessage" : "patternAndEverythingWithRegexImportName",
loc: specifier.loc,
data: {
importSource,
importNames: restrictedImportNamePattern,
customMessage
}
});
}
});
}
restrictedImportNames.forEach(importName => {
if (!importNames.has(importName)) {
return;
}
const specifiers = importNames.get(importName);
specifiers.forEach(specifier => {
context.report({
node,
messageId: customMessage ? "patternAndImportNameWithCustomMessage" : "patternAndImportName",
loc: specifier.loc,
data: {
importSource,
customMessage,
importName
}
if (
(restrictedImportNames && restrictedImportNames.includes(importName)) ||
(restrictedImportNamePattern && restrictedImportNamePattern.test(importName))
) {
specifiers.forEach(specifier => {
context.report({
node,
messageId: customMessage ? "patternAndImportNameWithCustomMessage" : "patternAndImportName",
loc: specifier.loc,
data: {
importSource,
customMessage,
importName
}
});
});
});
}
});

@@ -323,0 +346,0 @@ }

@@ -145,19 +145,2 @@ /**

/**
* Checks property accesses in a destructuring assignment expression, e.g. `var foo; ({foo} = bar);`
* @param {ASTNode} node An AssignmentExpression or AssignmentPattern node
* @returns {undefined}
*/
function checkDestructuringAssignment(node) {
if (node.right.type === "Identifier") {
const objectName = node.right.name;
if (node.left.type === "ObjectPattern") {
node.left.properties.forEach(property => {
checkPropertyAccess(node.left, objectName, astUtils.getStaticPropertyName(property));
});
}
}
}
return {

@@ -167,17 +150,21 @@ MemberExpression(node) {

},
VariableDeclarator(node) {
if (node.init && node.init.type === "Identifier") {
const objectName = node.init.name;
ObjectPattern(node) {
let objectName = null;
if (node.id.type === "ObjectPattern") {
node.id.properties.forEach(property => {
checkPropertyAccess(node.id, objectName, astUtils.getStaticPropertyName(property));
});
if (node.parent.type === "VariableDeclarator") {
if (node.parent.init && node.parent.init.type === "Identifier") {
objectName = node.parent.init.name;
}
} else if (node.parent.type === "AssignmentExpression" || node.parent.type === "AssignmentPattern") {
if (node.parent.right.type === "Identifier") {
objectName = node.parent.right.name;
}
}
},
AssignmentExpression: checkDestructuringAssignment,
AssignmentPattern: checkDestructuringAssignment
node.properties.forEach(property => {
checkPropertyAccess(node, objectName, astUtils.getStaticPropertyName(property));
});
}
};
}
};
/**
* @fileoverview Rule to check for tabs inside a file
* @author Gyandeep Singh
* @deprecated in ESLint v8.53.0
*/

@@ -22,2 +23,4 @@

meta: {
deprecated: true,
replacedBy: [],
type: "layout",

@@ -24,0 +27,0 @@

/**
* @fileoverview Disallow trailing spaces at the end of lines.
* @author Nodeca Team <https://github.com/nodeca>
* @deprecated in ESLint v8.53.0
*/

@@ -20,2 +21,4 @@ "use strict";

meta: {
deprecated: true,
replacedBy: [],
type: "layout",

@@ -22,0 +25,0 @@

/**
* @fileoverview Rule to disallow whitespace before properties
* @author Kai Cataldo
* @deprecated in ESLint v8.53.0
*/

@@ -20,2 +21,4 @@ "use strict";

meta: {
deprecated: true,
replacedBy: [],
type: "layout",

@@ -22,0 +25,0 @@

/**
* @fileoverview enforce the location of single-line statements
* @author Teddy Katz
* @deprecated in ESLint v8.53.0
*/

@@ -16,2 +17,4 @@ "use strict";

meta: {
deprecated: true,
replacedBy: [],
type: "layout",

@@ -18,0 +21,0 @@

/**
* @fileoverview Rule to require or disallow line breaks inside braces.
* @author Toru Nagashima
* @deprecated in ESLint v8.53.0
*/

@@ -150,2 +151,4 @@

meta: {
deprecated: true,
replacedBy: [],
type: "layout",

@@ -152,0 +155,0 @@

/**
* @fileoverview Disallows or enforces spaces inside of object literals.
* @author Jamund Ferguson
* @deprecated in ESLint v8.53.0
*/

@@ -16,2 +17,4 @@ "use strict";

meta: {
deprecated: true,
replacedBy: [],
type: "layout",

@@ -18,0 +21,0 @@

/**
* @fileoverview Rule to enforce placing object properties on separate lines.
* @author Vitor Balocco
* @deprecated in ESLint v8.53.0
*/

@@ -15,2 +16,4 @@

meta: {
deprecated: true,
replacedBy: [],
type: "layout",

@@ -17,0 +20,0 @@

/**
* @fileoverview Rule to check multiple var declarations per line
* @author Alberto Rodríguez
* @deprecated in ESLint v8.53.0
*/

@@ -14,2 +15,4 @@ "use strict";

meta: {
deprecated: true,
replacedBy: [],
type: "suggestion",

@@ -16,0 +19,0 @@

/**
* @fileoverview Operator linebreak - enforces operator linebreak style of two types: after and before
* @author Benoît Zugmeyer
* @deprecated in ESLint v8.53.0
*/

@@ -21,2 +22,4 @@

meta: {
deprecated: true,
replacedBy: [],
type: "layout",

@@ -23,0 +26,0 @@

/**
* @fileoverview A rule to ensure blank lines within blocks.
* @author Mathias Schreck <https://github.com/lo1tuma>
* @deprecated in ESLint v8.53.0
*/

@@ -21,2 +22,4 @@

meta: {
deprecated: true,
replacedBy: [],
type: "layout",

@@ -23,0 +26,0 @@

/**
* @fileoverview Rule to require or disallow newlines between statements
* @author Toru Nagashima
* @deprecated in ESLint v8.53.0
*/

@@ -386,2 +387,4 @@

meta: {
deprecated: true,
replacedBy: [],
type: "layout",

@@ -388,0 +391,0 @@

/**
* @fileoverview Rule to flag non-quoted property names in object literals.
* @author Mathias Bynens <http://mathiasbynens.be/>
* @deprecated in ESLint v8.53.0
*/

@@ -22,2 +23,4 @@ "use strict";

meta: {
deprecated: true,
replacedBy: [],
type: "suggestion",

@@ -24,0 +27,0 @@

/**
* @fileoverview A rule to choose between single and double quote marks
* @author Matt DuVall <http://www.mattduvall.com/>, Brandon Payton
* @deprecated in ESLint v8.53.0
*/

@@ -80,2 +81,4 @@

meta: {
deprecated: true,
replacedBy: [],
type: "layout",

@@ -82,0 +85,0 @@

/**
* @fileoverview Enforce spacing between rest and spread operators and their expressions.
* @author Kai Cataldo
* @deprecated in ESLint v8.53.0
*/

@@ -15,2 +16,4 @@

meta: {
deprecated: true,
replacedBy: [],
type: "layout",

@@ -17,0 +20,0 @@

/**
* @fileoverview Validates spacing before and after semicolon
* @author Mathias Schreck
* @deprecated in ESLint v8.53.0
*/

@@ -17,2 +18,4 @@

meta: {
deprecated: true,
replacedBy: [],
type: "layout",

@@ -19,0 +22,0 @@

/**
* @fileoverview Rule to enforce location of semicolons.
* @author Toru Nagashima
* @deprecated in ESLint v8.53.0
*/

@@ -73,2 +74,4 @@

meta: {
deprecated: true,
replacedBy: [],
type: "layout",

@@ -75,0 +78,0 @@

/**
* @fileoverview Rule to flag missing semicolons.
* @author Nicholas C. Zakas
* @deprecated in ESLint v8.53.0
*/

@@ -21,2 +22,4 @@ "use strict";

meta: {
deprecated: true,
replacedBy: [],
type: "layout",

@@ -23,0 +26,0 @@

/**
* @fileoverview A rule to ensure whitespace before blocks.
* @author Mathias Schreck <https://github.com/lo1tuma>
* @deprecated in ESLint v8.53.0
*/

@@ -40,2 +41,4 @@

meta: {
deprecated: true,
replacedBy: [],
type: "layout",

@@ -42,0 +45,0 @@

/**
* @fileoverview Rule to validate spacing before function paren.
* @author Mathias Schreck <https://github.com/lo1tuma>
* @deprecated in ESLint v8.53.0
*/

@@ -20,2 +21,4 @@ "use strict";

meta: {
deprecated: true,
replacedBy: [],
type: "layout",

@@ -22,0 +25,0 @@

/**
* @fileoverview Disallows or enforces spaces inside of parentheses.
* @author Jonathan Rajavuori
* @deprecated in ESLint v8.53.0
*/

@@ -16,2 +17,4 @@ "use strict";

meta: {
deprecated: true,
replacedBy: [],
type: "layout",

@@ -18,0 +21,0 @@

/**
* @fileoverview Require spaces around infix operators
* @author Michael Ficarra
* @deprecated in ESLint v8.53.0
*/

@@ -16,2 +17,4 @@ "use strict";

meta: {
deprecated: true,
replacedBy: [],
type: "layout",

@@ -18,0 +21,0 @@

/**
* @fileoverview This rule should require or disallow spaces before or after unary operations.
* @author Marcin Kumorek
* @deprecated in ESLint v8.53.0
*/

@@ -20,2 +21,4 @@ "use strict";

meta: {
deprecated: true,
replacedBy: [],
type: "layout",

@@ -22,0 +25,0 @@

/**
* @fileoverview Source code for spaced-comments rule
* @author Gyandeep Singh
* @deprecated in ESLint v8.53.0
*/

@@ -152,2 +153,4 @@ "use strict";

meta: {
deprecated: true,
replacedBy: [],
type: "suggestion",

@@ -154,0 +157,0 @@

/**
* @fileoverview Rule to enforce spacing around colons of switch statements.
* @author Toru Nagashima
* @deprecated in ESLint v8.53.0
*/

@@ -21,2 +22,4 @@

meta: {
deprecated: true,
replacedBy: [],
type: "layout",

@@ -23,0 +26,0 @@

/**
* @fileoverview Rule to enforce spacing around embedded expressions of template strings
* @author Toru Nagashima
* @deprecated in ESLint v8.53.0
*/

@@ -21,2 +22,4 @@

meta: {
deprecated: true,
replacedBy: [],
type: "layout",

@@ -23,0 +26,0 @@

/**
* @fileoverview Rule to check spacing between template tags and their literals
* @author Jonathan Wilsson
* @deprecated in ESLint v8.53.0
*/

@@ -15,2 +16,4 @@

meta: {
deprecated: true,
replacedBy: [],
type: "layout",

@@ -17,0 +20,0 @@

/**
* @fileoverview Rule to flag when IIFE is not wrapped in parens
* @author Ilya Volodin
* @deprecated in ESLint v8.53.0
*/

@@ -43,2 +44,4 @@

meta: {
deprecated: true,
replacedBy: [],
type: "layout",

@@ -45,0 +48,0 @@

/**
* @fileoverview Rule to flag when regex literals are not wrapped in parens
* @author Matt DuVall <http://www.mattduvall.com>
* @deprecated in ESLint v8.53.0
*/

@@ -15,2 +16,4 @@

meta: {
deprecated: true,
replacedBy: [],
type: "layout",

@@ -17,0 +20,0 @@

/**
* @fileoverview Rule to check the spacing around the * in yield* expressions.
* @author Bryan Smith
* @deprecated in ESLint v8.53.0
*/

@@ -15,2 +16,4 @@

meta: {
deprecated: true,
replacedBy: [],
type: "layout",

@@ -17,0 +20,0 @@

@@ -216,20 +216,2 @@ /**

/**
* Extract the directive and the justification from a given directive comment and trim them.
* @param {string} value The comment text to extract.
* @returns {{directivePart: string, justificationPart: string}} The extracted directive and justification.
*/
function extractDirectiveComment(value) {
const match = /\s-{2,}\s/u.exec(value);
if (!match) {
return { directivePart: value.trim(), justificationPart: "" };
}
const directive = value.slice(0, match.index).trim();
const justification = value.slice(match.index + match[0].length).trim();
return { directivePart: directive, justificationPart: justification };
}
/**
* Ensures that variables representing built-in properties of the Global Object,

@@ -925,3 +907,3 @@ * and any globals declared by special block comments, are present in the global

const { directivePart } = extractDirectiveComment(comment.value);
const { directivePart } = commentParser.extractDirectiveComment(comment.value);

@@ -982,6 +964,3 @@ const directiveMatch = directivesPattern.exec(directivePart);

const { directivePart } = extractDirectiveComment(comment.value);
const match = directivesPattern.exec(directivePart);
const directiveText = match[1];
const directiveValue = directivePart.slice(match.index + directiveText.length);
const { directiveText, directiveValue } = commentParser.parseDirective(comment);

@@ -988,0 +967,0 @@ switch (directiveText) {

{
"name": "eslint",
"version": "8.52.0",
"version": "8.56.0",
"author": "Nicholas C. Zakas <nicholas+npm@nczconsulting.com>",

@@ -22,2 +22,3 @@ "description": "An AST-based pattern checker for JavaScript.",

"lint:docs:js": "node Makefile.js lintDocsJS",
"lint:docs:rule-examples": "node Makefile.js checkRuleExamples",
"lint:fix": "node Makefile.js lint -- fix",

@@ -46,2 +47,3 @@ "lint:fix:docs:js": "node Makefile.js lintDocsJS -- fix",

"docs/src/rules/*.md": [
"node tools/check-rule-examples.js",
"node tools/fetch-docs-links.js",

@@ -67,4 +69,4 @@ "git add docs/src/_data/further_reading_links.json"

"@eslint-community/regexpp": "^4.6.1",
"@eslint/eslintrc": "^2.1.2",
"@eslint/js": "8.52.0",
"@eslint/eslintrc": "^2.1.4",
"@eslint/js": "8.56.0",
"@humanwhocodes/config-array": "^0.11.13",

@@ -123,7 +125,7 @@ "@humanwhocodes/module-importer": "^1.0.1",

"eslint-plugin-eslint-comments": "^3.2.0",
"eslint-plugin-eslint-plugin": "^5.1.0",
"eslint-plugin-eslint-plugin": "^5.2.1",
"eslint-plugin-internal-rules": "file:tools/internal-rules",
"eslint-plugin-jsdoc": "^46.2.5",
"eslint-plugin-n": "^16.0.0",
"eslint-plugin-unicorn": "^42.0.0",
"eslint-plugin-n": "^16.4.0",
"eslint-plugin-unicorn": "^49.0.0",
"eslint-release": "^3.2.0",

@@ -139,4 +141,6 @@ "eslump": "^3.0.0",

"load-perf": "^0.2.0",
"markdownlint": "^0.25.1",
"markdownlint-cli": "^0.31.1",
"markdown-it": "^12.2.0",
"markdown-it-container": "^3.0.0",
"markdownlint": "^0.32.0",
"markdownlint-cli": "^0.37.0",
"marked": "^4.0.8",

@@ -157,4 +161,4 @@ "memfs": "^3.0.1",

"proxyquire": "^2.0.1",
"recast": "^0.20.4",
"regenerator-runtime": "^0.13.2",
"recast": "^0.23.0",
"regenerator-runtime": "^0.14.0",
"rollup-plugin-node-polyfills": "^0.2.1",

@@ -164,3 +168,3 @@ "semver": "^7.5.3",

"sinon": "^11.0.0",
"vite-plugin-commonjs": "^0.8.2",
"vite-plugin-commonjs": "^0.10.0",
"webdriverio": "^8.14.6",

@@ -167,0 +171,0 @@ "webpack": "^5.23.0",

@@ -106,3 +106,3 @@ [![npm version](https://img.shields.io/npm/v/eslint.svg)](https://www.npmjs.com/package/eslint)

No, ESLint does both traditional linting (looking for problematic patterns) and style checking (enforcement of conventions). You can use ESLint for everything, or you can combine both using Prettier to format your code and ESLint to catch possible errors.
No, ESLint and Prettier have diffent jobs: ESLint is a linter (looking for problematic patterns) and Prettier is a code formatter. Using both tools is common, refer to [Prettier's documentation](https://prettier.io/docs/en/install#eslint-and-other-linters) to learn how to configure them to work well with each other.

@@ -213,3 +213,3 @@ ### Why can't ESLint find my plugins?

<a href="https://github.com/nzakas">
<img src="https://github.com/nzakas.png?s=75" width="75" height="75"><br />
<img src="https://github.com/nzakas.png?s=75" width="75" height="75" alt="Nicholas C. Zakas's Avatar"><br />
Nicholas C. Zakas

@@ -219,3 +219,3 @@ </a>

<a href="https://github.com/mdjermanovic">
<img src="https://github.com/mdjermanovic.png?s=75" width="75" height="75"><br />
<img src="https://github.com/mdjermanovic.png?s=75" width="75" height="75" alt="Milos Djermanovic's Avatar"><br />
Milos Djermanovic

@@ -231,3 +231,3 @@ </a>

<a href="https://github.com/aladdin-add">
<img src="https://github.com/aladdin-add.png?s=75" width="75" height="75"><br />
<img src="https://github.com/aladdin-add.png?s=75" width="75" height="75" alt="唯然's Avatar"><br />
唯然

@@ -237,3 +237,3 @@ </a>

<a href="https://github.com/snitin315">
<img src="https://github.com/snitin315.png?s=75" width="75" height="75"><br />
<img src="https://github.com/snitin315.png?s=75" width="75" height="75" alt="Nitin Kumar's Avatar"><br />
Nitin Kumar

@@ -249,3 +249,3 @@ </a>

<a href="https://github.com/bmish">
<img src="https://github.com/bmish.png?s=75" width="75" height="75"><br />
<img src="https://github.com/bmish.png?s=75" width="75" height="75" alt="Bryan Mishkin's Avatar"><br />
Bryan Mishkin

@@ -255,3 +255,3 @@ </a>

<a href="https://github.com/fasttime">
<img src="https://github.com/fasttime.png?s=75" width="75" height="75"><br />
<img src="https://github.com/fasttime.png?s=75" width="75" height="75" alt="Francesco Trotta's Avatar"><br />
Francesco Trotta

@@ -261,3 +261,3 @@ </a>

<a href="https://github.com/ota-meshi">
<img src="https://github.com/ota-meshi.png?s=75" width="75" height="75"><br />
<img src="https://github.com/ota-meshi.png?s=75" width="75" height="75" alt="Yosuke Ota's Avatar"><br />
Yosuke Ota

@@ -267,3 +267,3 @@ </a>

<a href="https://github.com/Tanujkanti4441">
<img src="https://github.com/Tanujkanti4441.png?s=75" width="75" height="75"><br />
<img src="https://github.com/Tanujkanti4441.png?s=75" width="75" height="75" alt="Tanuj Kanti's Avatar"><br />
Tanuj Kanti

@@ -279,3 +279,3 @@ </a>

<a href="https://github.com/amareshsm">
<img src="https://github.com/amareshsm.png?s=75" width="75" height="75"><br />
<img src="https://github.com/amareshsm.png?s=75" width="75" height="75" alt="Amaresh S M's Avatar"><br />
Amaresh S M

@@ -285,3 +285,3 @@ </a>

<a href="https://github.com/harish-sethuraman">
<img src="https://github.com/harish-sethuraman.png?s=75" width="75" height="75"><br />
<img src="https://github.com/harish-sethuraman.png?s=75" width="75" height="75" alt="Strek's Avatar"><br />
Strek

@@ -291,3 +291,3 @@ </a>

<a href="https://github.com/kecrily">
<img src="https://github.com/kecrily.png?s=75" width="75" height="75"><br />
<img src="https://github.com/kecrily.png?s=75" width="75" height="75" alt="Percy Ma's Avatar"><br />
Percy Ma

@@ -308,4 +308,4 @@ </a>

<p><a href="https://engineering.salesforce.com"><img src="https://images.opencollective.com/salesforce/ca8f997/logo.png" alt="Salesforce" height="96"></a> <a href="https://www.airbnb.com/"><img src="https://images.opencollective.com/airbnb/d327d66/logo.png" alt="Airbnb" height="96"></a></p><h3>Silver Sponsors</h3>
<p><a href="https://liftoff.io/"><img src="https://images.opencollective.com/liftoff/5c4fa84/logo.png" alt="Liftoff" height="64"></a> <a href="https://americanexpress.io"><img src="https://avatars.githubusercontent.com/u/3853301?v=4" alt="American Express" height="64"></a></p><h3>Bronze Sponsors</h3>
<p><a href="https://themeisle.com"><img src="https://images.opencollective.com/themeisle/d5592fe/logo.png" alt="ThemeIsle" height="32"></a> <a href="https://www.crosswordsolver.org/anagram-solver/"><img src="https://images.opencollective.com/anagram-solver/2666271/logo.png" alt="Anagram Solver" height="32"></a> <a href="https://icons8.com/"><img src="https://images.opencollective.com/icons8/7fa1641/logo.png" alt="Icons8" height="32"></a> <a href="https://discord.com"><img src="https://images.opencollective.com/discordapp/f9645d9/logo.png" alt="Discord" height="32"></a> <a href="https://transloadit.com/"><img src="https://avatars.githubusercontent.com/u/125754?v=4" alt="Transloadit" height="32"></a> <a href="https://www.ignitionapp.com"><img src="https://avatars.githubusercontent.com/u/5753491?v=4" alt="Ignition" height="32"></a> <a href="https://herocoders.com"><img src="https://avatars.githubusercontent.com/u/37549774?v=4" alt="HeroCoders" height="32"></a> <a href="https://quickbookstoolhub.com"><img src="https://avatars.githubusercontent.com/u/95090305?u=e5bc398ef775c9ed19f955c675cdc1fb6abf01df&v=4" alt="QuickBooks Tool hub" height="32"></a></p>
<p><a href="https://liftoff.io/"><img src="https://images.opencollective.com/liftoff/5c4fa84/logo.png" alt="Liftoff" height="64"></a> <a href="https://americanexpress.io"><img src="https://avatars.githubusercontent.com/u/3853301?v=4" alt="American Express" height="64"></a> <a href="https://www.workleap.com"><img src="https://avatars.githubusercontent.com/u/53535748?u=d1e55d7661d724bf2281c1bfd33cb8f99fe2465f&v=4" alt="Workleap" height="64"></a></p><h3>Bronze Sponsors</h3>
<p><a href="https://themeisle.com"><img src="https://images.opencollective.com/themeisle/d5592fe/logo.png" alt="ThemeIsle" height="32"></a> <a href="https://www.crosswordsolver.org/anagram-solver/"><img src="https://images.opencollective.com/anagram-solver/2666271/logo.png" alt="Anagram Solver" height="32"></a> <a href="https://icons8.com/"><img src="https://images.opencollective.com/icons8/7fa1641/logo.png" alt="Icons8" height="32"></a> <a href="https://discord.com"><img src="https://images.opencollective.com/discordapp/f9645d9/logo.png" alt="Discord" height="32"></a> <a href="https://transloadit.com/"><img src="https://avatars.githubusercontent.com/u/125754?v=4" alt="Transloadit" height="32"></a> <a href="https://www.ignitionapp.com"><img src="https://avatars.githubusercontent.com/u/5753491?v=4" alt="Ignition" height="32"></a> <a href="https://nx.dev"><img src="https://avatars.githubusercontent.com/u/23692104?v=4" alt="Nx" height="32"></a> <a href="https://herocoders.com"><img src="https://avatars.githubusercontent.com/u/37549774?v=4" alt="HeroCoders" height="32"></a></p>
<!--sponsorsend-->

@@ -312,0 +312,0 @@

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc