Socket
Socket
Sign inDemoInstall

eslint

Package Overview
Dependencies
Maintainers
4
Versions
366
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

eslint - npm Package Compare versions

Comparing version 8.51.0 to 8.53.0

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);

58

conf/rule-type-list.json
{
"types": [
{ "name": "problem", "displayName": "Possible Problems", "description": "These rules relate to possible logic errors in code:" },
{ "name": "suggestion", "displayName": "Suggestions", "description": "These rules suggest alternate ways of doing things:" },
{ "name": "layout", "displayName": "Layout & Formatting", "description": "These rules care about how the code looks rather than how it executes:" }
],
"deprecated": {
"name": "Deprecated",
"description": "These rules have been deprecated in accordance with the <a href=\"{{ '/use/rule-deprecation' | url }}\">deprecation policy</a>, and replaced by newer rules:",
"rules": []
"types": {
"problem": [],
"suggestion": [],
"layout": []
},
"removed": {
"name": "Removed",
"description": "These rules from older versions of ESLint (before the <a href=\"{{ '/use/rule-deprecation' | url }}\">deprecation policy</a> existed) have been replaced by newer rules:",
"rules": [
{ "removed": "generator-star", "replacedBy": ["generator-star-spacing"] },
{ "removed": "global-strict", "replacedBy": ["strict"] },
{ "removed": "no-arrow-condition", "replacedBy": ["no-confusing-arrow", "no-constant-condition"] },
{ "removed": "no-comma-dangle", "replacedBy": ["comma-dangle"] },
{ "removed": "no-empty-class", "replacedBy": ["no-empty-character-class"] },
{ "removed": "no-empty-label", "replacedBy": ["no-labels"] },
{ "removed": "no-extra-strict", "replacedBy": ["strict"] },
{ "removed": "no-reserved-keys", "replacedBy": ["quote-props"] },
{ "removed": "no-space-before-semi", "replacedBy": ["semi-spacing"] },
{ "removed": "no-wrap-func", "replacedBy": ["no-extra-parens"] },
{ "removed": "space-after-function-name", "replacedBy": ["space-before-function-paren"] },
{ "removed": "space-after-keywords", "replacedBy": ["keyword-spacing"] },
{ "removed": "space-before-function-parentheses", "replacedBy": ["space-before-function-paren"] },
{ "removed": "space-before-keywords", "replacedBy": ["keyword-spacing"] },
{ "removed": "space-in-brackets", "replacedBy": ["object-curly-spacing", "array-bracket-spacing"] },
{ "removed": "space-return-throw-case", "replacedBy": ["keyword-spacing"] },
{ "removed": "space-unary-word-ops", "replacedBy": ["space-unary-ops"] },
{ "removed": "spaced-line-comment", "replacedBy": ["spaced-comment"] }
]
}
"deprecated": [],
"removed": [
{ "removed": "generator-star", "replacedBy": ["generator-star-spacing"] },
{ "removed": "global-strict", "replacedBy": ["strict"] },
{ "removed": "no-arrow-condition", "replacedBy": ["no-confusing-arrow", "no-constant-condition"] },
{ "removed": "no-comma-dangle", "replacedBy": ["comma-dangle"] },
{ "removed": "no-empty-class", "replacedBy": ["no-empty-character-class"] },
{ "removed": "no-empty-label", "replacedBy": ["no-labels"] },
{ "removed": "no-extra-strict", "replacedBy": ["strict"] },
{ "removed": "no-reserved-keys", "replacedBy": ["quote-props"] },
{ "removed": "no-space-before-semi", "replacedBy": ["semi-spacing"] },
{ "removed": "no-wrap-func", "replacedBy": ["no-extra-parens"] },
{ "removed": "space-after-function-name", "replacedBy": ["space-before-function-paren"] },
{ "removed": "space-after-keywords", "replacedBy": ["keyword-spacing"] },
{ "removed": "space-before-function-parentheses", "replacedBy": ["space-before-function-paren"] },
{ "removed": "space-before-keywords", "replacedBy": ["keyword-spacing"] },
{ "removed": "space-in-brackets", "replacedBy": ["object-curly-spacing", "array-bracket-spacing"] },
{ "removed": "space-return-throw-case", "replacedBy": ["keyword-spacing"] },
{ "removed": "space-unary-word-ops", "replacedBy": ["space-unary-ops"] },
{ "removed": "spaced-line-comment", "replacedBy": ["spaced-comment"] }
]
}

@@ -321,3 +321,10 @@ /**

debug("Error parsing CLI options:", error.message);
log.error(error.message);
let errorMessage = error.message;
if (usingFlatConfig) {
errorMessage += "\nYou're using eslint.config.js, some command line flags are no longer available. Please see https://eslint.org/docs/latest/use/command-line-interface for details.";
}
log.error(errorMessage);
return 2;

@@ -324,0 +331,0 @@ }

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

//-----------------------------------------------------------------------------
// Requirements
//-----------------------------------------------------------------------------
/*
* Note: This can be removed in ESLint v9 because structuredClone is available globally
* starting in Node.js v17.
*/
const structuredClone = require("@ungap/structured-clone").default;
//-----------------------------------------------------------------------------
// Type Definitions

@@ -123,3 +133,3 @@ //-----------------------------------------------------------------------------

finalOptions[0] = ruleSeverities.get(finalOptions[0]);
return finalOptions;
return structuredClone(finalOptions);
}

@@ -383,44 +393,53 @@

for (const ruleId of Object.keys(result)) {
// avoid hairy edge case
if (ruleId === "__proto__") {
try {
/* eslint-disable-next-line no-proto -- Though deprecated, may still be present */
delete result.__proto__;
continue;
}
// avoid hairy edge case
if (ruleId === "__proto__") {
result[ruleId] = normalizeRuleOptions(result[ruleId]);
/* eslint-disable-next-line no-proto -- Though deprecated, may still be present */
delete result.__proto__;
continue;
}
/*
* 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;
}
result[ruleId] = normalizeRuleOptions(result[ruleId]);
const firstRuleOptions = normalizeRuleOptions(first[ruleId]);
const secondRuleOptions = normalizeRuleOptions(second[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;
}
/*
* 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;
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.
*/
} catch (ex) {
throw new Error(`Key "${ruleId}": ${ex.message}`, { cause: ex });
}
/*
* 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;
},

@@ -427,0 +446,0 @@

@@ -33,3 +33,3 @@ /**

* Groups a set of directives into sub-arrays by their parent comment.
* @param {Directive[]} directives Unused directives to be removed.
* @param {Iterable<Directive>} directives Unused directives to be removed.
* @returns {Directive[][]} Directives grouped by their parent comment.

@@ -181,6 +181,6 @@ */

* Parses details from directives to create output Problems.
* @param {Directive[]} allDirectives Unused directives to be removed.
* @param {Iterable<Directive>} allDirectives Unused directives to be removed.
* @returns {{ description, fix, unprocessedDirective }[]} Details for later creation of output Problems.
*/
function processUnusedDisableDirectives(allDirectives) {
function processUnusedDirectives(allDirectives) {
const directiveGroups = groupByParentComment(allDirectives);

@@ -205,2 +205,91 @@

/**
* Collect eslint-enable comments that are removing suppressions by eslint-disable comments.
* @param {Directive[]} directives The directives to check.
* @returns {Set<Directive>} The used eslint-enable comments
*/
function collectUsedEnableDirectives(directives) {
/**
* A Map of `eslint-enable` keyed by ruleIds that may be marked as used.
* If `eslint-enable` does not have a ruleId, the key will be `null`.
* @type {Map<string|null, Directive>}
*/
const enabledRules = new Map();
/**
* A Set of `eslint-enable` marked as used.
* It is also the return value of `collectUsedEnableDirectives` function.
* @type {Set<Directive>}
*/
const usedEnableDirectives = new Set();
/*
* Checks the directives backwards to see if the encountered `eslint-enable` is used by the previous `eslint-disable`,
* and if so, stores the `eslint-enable` in `usedEnableDirectives`.
*/
for (let index = directives.length - 1; index >= 0; index--) {
const directive = directives[index];
if (directive.type === "disable") {
if (enabledRules.size === 0) {
continue;
}
if (directive.ruleId === null) {
// If encounter `eslint-disable` without ruleId,
// mark all `eslint-enable` currently held in enabledRules as used.
// e.g.
// /* eslint-disable */ <- current directive
// /* eslint-enable rule-id1 */ <- used
// /* eslint-enable rule-id2 */ <- used
// /* eslint-enable */ <- used
for (const enableDirective of enabledRules.values()) {
usedEnableDirectives.add(enableDirective);
}
enabledRules.clear();
} else {
const enableDirective = enabledRules.get(directive.ruleId);
if (enableDirective) {
// If encounter `eslint-disable` with ruleId, and there is an `eslint-enable` with the same ruleId in enabledRules,
// mark `eslint-enable` with ruleId as used.
// e.g.
// /* eslint-disable rule-id */ <- current directive
// /* eslint-enable rule-id */ <- used
usedEnableDirectives.add(enableDirective);
} else {
const enabledDirectiveWithoutRuleId = enabledRules.get(null);
if (enabledDirectiveWithoutRuleId) {
// If encounter `eslint-disable` with ruleId, and there is no `eslint-enable` with the same ruleId in enabledRules,
// mark `eslint-enable` without ruleId as used.
// e.g.
// /* eslint-disable rule-id */ <- current directive
// /* eslint-enable */ <- used
usedEnableDirectives.add(enabledDirectiveWithoutRuleId);
}
}
}
} else if (directive.type === "enable") {
if (directive.ruleId === null) {
// If encounter `eslint-enable` without ruleId, the `eslint-enable` that follows it are unused.
// So clear enabledRules.
// e.g.
// /* eslint-enable */ <- current directive
// /* eslint-enable rule-id *// <- unused
// /* eslint-enable */ <- unused
enabledRules.clear();
enabledRules.set(null, directive);
} else {
enabledRules.set(directive.ruleId, directive);
}
}
}
return usedEnableDirectives;
}
/**
* This is the same as the exported function, except that it

@@ -212,3 +301,3 @@ * doesn't handle disable-line and disable-next-line directives, and it always reports unused

* (this function always reports unused disable directives).
* @returns {{problems: LintMessage[], unusedDisableDirectives: LintMessage[]}} An object with a list
* @returns {{problems: LintMessage[], unusedDirectives: LintMessage[]}} An object with a list
* of problems (including suppressed ones) and unused eslint-disable directives

@@ -265,13 +354,38 @@ */

const processed = processUnusedDisableDirectives(unusedDisableDirectivesToReport);
const unusedDisableDirectives = processed
const unusedEnableDirectivesToReport = new Set(
options.directives.filter(directive => directive.unprocessedDirective.type === "enable")
);
/*
* If directives has the eslint-enable directive,
* check whether the eslint-enable comment is used.
*/
if (unusedEnableDirectivesToReport.size > 0) {
for (const directive of collectUsedEnableDirectives(options.directives)) {
unusedEnableDirectivesToReport.delete(directive);
}
}
const processed = processUnusedDirectives(unusedDisableDirectivesToReport)
.concat(processUnusedDirectives(unusedEnableDirectivesToReport));
const unusedDirectives = processed
.map(({ description, fix, unprocessedDirective }) => {
const { parentComment, type, line, column } = unprocessedDirective;
let message;
if (type === "enable") {
message = description
? `Unused eslint-enable directive (no matching eslint-disable directives were found for ${description}).`
: "Unused eslint-enable directive (no matching eslint-disable directives were found).";
} else {
message = description
? `Unused eslint-disable directive (no problems were reported from ${description}).`
: "Unused eslint-disable directive (no problems were reported).";
}
return {
ruleId: null,
message: description
? `Unused eslint-disable directive (no problems were reported from ${description}).`
: "Unused eslint-disable directive (no problems were reported).",
message,
line: type === "disable-next-line" ? parentComment.commentToken.loc.start.line : line,

@@ -285,3 +399,3 @@ column: type === "disable-next-line" ? parentComment.commentToken.loc.start.column + 1 : column,

return { problems, unusedDisableDirectives };
return { problems, unusedDirectives };
}

@@ -353,6 +467,6 @@

? lineDirectivesResult.problems
.concat(blockDirectivesResult.unusedDisableDirectives)
.concat(lineDirectivesResult.unusedDisableDirectives)
.concat(blockDirectivesResult.unusedDirectives)
.concat(lineDirectivesResult.unusedDirectives)
.sort(compareLocations)
: lineDirectivesResult.problems;
};

@@ -50,3 +50,3 @@ /**

* @property {string} [printConfig] Print the configuration for the given file
* @property {boolean | undefined} reportUnusedDisableDirectives Adds reported errors for unused eslint-disable directives
* @property {boolean | undefined} reportUnusedDisableDirectives Adds reported errors for unused eslint-disable and eslint-enable directives
* @property {string} [resolvePluginsRelativeTo] A folder where plugins should be resolved from, CWD by default

@@ -308,3 +308,3 @@ * @property {Object} [rule] Specify rules

default: void 0,
description: "Adds reported errors for unused eslint-disable directives"
description: "Adds reported errors for unused eslint-disable and eslint-enable directives"
},

@@ -311,0 +311,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 @@

/**
* @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 @@

@@ -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 @@

/**
* @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 @@

/**
* @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,3 +12,3 @@ /**

const { getVariableByName, isArrowToken } = require("./utils/ast-utils");
const { getVariableByName, isArrowToken, isClosingBraceToken, isClosingParenToken } = require("./utils/ast-utils");

@@ -19,2 +19,41 @@ //------------------------------------------------------------------------------

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, 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"
]);
/**

@@ -58,3 +97,4 @@ * Tests if a node appears at the beginning of an ancestor ExpressionStatement node.

preferLiteral: "The object literal notation {} is preferable.",
useLiteral: "Replace with '{{replacement}}'."
useLiteral: "Replace with '{{replacement}}'.",
useLiteralAfterSemicolon: "Replace with '{{replacement}}', add preceding semicolon."
}

@@ -87,2 +127,46 @@ },

/**
* 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.

@@ -100,4 +184,18 @@ * @param {ASTNode} node The node to evaluate.

if (variable && variable.identifiers.length === 0) {
const replacement = needsParentheses(node) ? "({})" : "{}";
let replacement;
let fixText;
let messageId = "useLiteral";
if (needsParentheses(node)) {
replacement = "({})";
if (needsSemicolon(node)) {
fixText = ";({})";
messageId = "useLiteralAfterSemicolon";
} else {
fixText = "({})";
}
} else {
replacement = fixText = "{}";
}
context.report({

@@ -108,5 +206,5 @@ node,

{
messageId: "useLiteral",
messageId,
data: { replacement },
fix: fixer => fixer.replaceText(node, replacement)
fix: fixer => fixer.replaceText(node, fixText)
}

@@ -113,0 +211,0 @@ ]

@@ -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 @@ }

/**
* @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 @@

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

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

],
"docs/src/rules/*.md": [
"node tools/fetch-docs-links.js",
"git add docs/src/_data/further_reading_links.json"
],
"docs/**/*.svg": "npx svgo -r --multipass"

@@ -66,7 +62,8 @@ },

"@eslint-community/regexpp": "^4.6.1",
"@eslint/eslintrc": "^2.1.2",
"@eslint/js": "8.51.0",
"@humanwhocodes/config-array": "^0.11.11",
"@eslint/eslintrc": "^2.1.3",
"@eslint/js": "8.53.0",
"@humanwhocodes/config-array": "^0.11.13",
"@humanwhocodes/module-importer": "^1.0.1",
"@nodelib/fs.walk": "^1.2.8",
"@ungap/structured-clone": "^1.2.0",
"ajv": "^6.12.4",

@@ -140,8 +137,2 @@ "chalk": "^4.0.0",

"memfs": "^3.0.1",
"metascraper": "^5.25.7",
"metascraper-description": "^5.25.7",
"metascraper-image": "^5.29.3",
"metascraper-logo": "^5.25.7",
"metascraper-logo-favicon": "^5.25.7",
"metascraper-title": "^5.25.7",
"mocha": "^8.3.2",

@@ -148,0 +139,0 @@ "mocha-junit-reporter": "^2.0.0",

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

</a>
</td><td align="center" valign="top" width="11%">
<a href="https://github.com/Tanujkanti4441">
<img src="https://github.com/Tanujkanti4441.png?s=75" width="75" height="75"><br />
Tanuj Kanti
</a>
</td></tr></tbody></table>

@@ -292,4 +297,4 @@

<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://opensource.siemens.com"><img src="https://avatars.githubusercontent.com/u/624020?v=4" alt="Siemens" 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></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></p>
<!--sponsorsend-->

@@ -296,0 +301,0 @@

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

SocketSocket SOC 2 Logo

Product

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

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc