Socket
Socket
Sign inDemoInstall

eslint

Package Overview
Dependencies
98
Maintainers
4
Versions
357
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 8.43.0 to 8.44.0

7

conf/globals.js

@@ -131,3 +131,7 @@ /**

const es2024 = {
...es2023
};
//-----------------------------------------------------------------------------

@@ -149,3 +153,4 @@ // Exports

es2022,
es2023
es2023,
es2024
};

45

lib/cli-engine/cli-engine.js

@@ -161,3 +161,13 @@ /**

function calculateStatsPerFile(messages) {
return messages.reduce((stat, message) => {
const stat = {
errorCount: 0,
fatalErrorCount: 0,
warningCount: 0,
fixableErrorCount: 0,
fixableWarningCount: 0
};
for (let i = 0; i < messages.length; i++) {
const message = messages[i];
if (message.fatal || message.severity === 2) {

@@ -177,10 +187,4 @@ stat.errorCount++;

}
return stat;
}, {
errorCount: 0,
fatalErrorCount: 0,
warningCount: 0,
fixableErrorCount: 0,
fixableWarningCount: 0
});
}
return stat;
}

@@ -195,3 +199,13 @@

function calculateStatsPerRun(results) {
return results.reduce((stat, result) => {
const stat = {
errorCount: 0,
fatalErrorCount: 0,
warningCount: 0,
fixableErrorCount: 0,
fixableWarningCount: 0
};
for (let i = 0; i < results.length; i++) {
const result = results[i];
stat.errorCount += result.errorCount;

@@ -202,10 +216,5 @@ stat.fatalErrorCount += result.fatalErrorCount;

stat.fixableWarningCount += result.fixableWarningCount;
return stat;
}, {
errorCount: 0,
fatalErrorCount: 0,
warningCount: 0,
fixableErrorCount: 0,
fixableWarningCount: 0
});
}
return stat;
}

@@ -212,0 +221,0 @@

@@ -106,3 +106,13 @@ /**

function calculateStatsPerFile(messages) {
return messages.reduce((stat, message) => {
const stat = {
errorCount: 0,
fatalErrorCount: 0,
warningCount: 0,
fixableErrorCount: 0,
fixableWarningCount: 0
};
for (let i = 0; i < messages.length; i++) {
const message = messages[i];
if (message.fatal || message.severity === 2) {

@@ -122,36 +132,7 @@ stat.errorCount++;

}
return stat;
}, {
errorCount: 0,
fatalErrorCount: 0,
warningCount: 0,
fixableErrorCount: 0,
fixableWarningCount: 0
});
}
return stat;
}
/**
* It will calculate the error and warning count for collection of results from all files
* @param {LintResult[]} results Collection of messages from all the files
* @returns {Object} Contains the stats
* @private
*/
function calculateStatsPerRun(results) {
return results.reduce((stat, result) => {
stat.errorCount += result.errorCount;
stat.fatalErrorCount += result.fatalErrorCount;
stat.warningCount += result.warningCount;
stat.fixableErrorCount += result.fixableErrorCount;
stat.fixableWarningCount += result.fixableWarningCount;
return stat;
}, {
errorCount: 0,
fatalErrorCount: 0,
warningCount: 0,
fixableErrorCount: 0,
fixableWarningCount: 0
});
}
/**
* Create rulesMeta object.

@@ -556,39 +537,2 @@ * @param {Map<string,Rule>} rules a map of rules from which to generate the object.

/**
* Collect used deprecated rules.
* @param {Array<FlatConfig>} configs The configs to evaluate.
* @returns {IterableIterator<DeprecatedRuleInfo>} Used deprecated rules.
*/
function *iterateRuleDeprecationWarnings(configs) {
const processedRuleIds = new Set();
for (const config of configs) {
for (const [ruleId, ruleConfig] of Object.entries(config.rules)) {
// Skip if it was processed.
if (processedRuleIds.has(ruleId)) {
continue;
}
processedRuleIds.add(ruleId);
// Skip if it's not used.
if (!getRuleSeverity(ruleConfig)) {
continue;
}
const rule = getRuleFromConfig(ruleId, config);
// Skip if it's not deprecated.
if (!(rule && rule.meta && rule.meta.deprecated)) {
continue;
}
// This rule was used and deprecated.
yield {
ruleId,
replacedBy: rule.meta.replacedBy || []
};
}
}
}
/**
* Creates an error to be thrown when an array of results passed to `getRulesMetaForResults` was not created by the current engine.

@@ -817,3 +761,2 @@ * @returns {TypeError} An error object.

const startTime = Date.now();
const usedConfigs = [];
const fixTypesSet = fixTypes ? new Set(fixTypes) : null;

@@ -876,11 +819,2 @@

/*
* Store used configs for:
* - this method uses to collect used deprecated rules.
* - `--fix-type` option uses to get the loaded rule's meta data.
*/
if (!usedConfigs.includes(config)) {
usedConfigs.push(config);
}
// Skip if there is cached result.

@@ -954,18 +888,6 @@ if (lintResultCache) {

let usedDeprecatedRules;
const finalResults = results.filter(result => !!result);
return processLintReport(this, {
results: finalResults,
...calculateStatsPerRun(finalResults),
// Initialize it lazily because CLI and `ESLint` API don't use it.
get usedDeprecatedRules() {
if (!usedDeprecatedRules) {
usedDeprecatedRules = Array.from(
iterateRuleDeprecationWarnings(usedConfigs)
);
}
return usedDeprecatedRules;
}
results: finalResults
});

@@ -1032,3 +954,2 @@ }

const resolvedFilename = path.resolve(cwd, filePath || "__placeholder__.js");
let config;

@@ -1042,5 +963,2 @@ // Clear the last used config arrays.

// TODO: Needed?
config = configs.getConfig(resolvedFilename);
// Do lint.

@@ -1060,17 +978,5 @@ results.push(verifyText({

debug(`Linting complete in: ${Date.now() - startTime}ms`);
let usedDeprecatedRules;
return processLintReport(this, {
results,
...calculateStatsPerRun(results),
// Initialize it lazily because CLI and `ESLint` API don't use it.
get usedDeprecatedRules() {
if (!usedDeprecatedRules) {
usedDeprecatedRules = Array.from(
iterateRuleDeprecationWarnings(config)
);
}
return usedDeprecatedRules;
}
results
});

@@ -1077,0 +983,0 @@

@@ -36,3 +36,3 @@ /**

/* eslint-disable jsdoc/valid-types -- https://github.com/jsdoc-type-pratt-parser/jsdoc-type-pratt-parser/issues/4#issuecomment-778805577 */
/**

@@ -76,3 +76,2 @@ * A test case that is expected to pass lint.

*/
/* eslint-enable jsdoc/valid-types -- https://github.com/jsdoc-type-pratt-parser/jsdoc-type-pratt-parser/issues/4#issuecomment-778805577 */

@@ -79,0 +78,0 @@ //------------------------------------------------------------------------------

@@ -66,3 +66,3 @@ /**

/* eslint-disable jsdoc/valid-types -- https://github.com/jsdoc-type-pratt-parser/jsdoc-type-pratt-parser/issues/4#issuecomment-778805577 */
/**

@@ -112,3 +112,2 @@ * A test case that is expected to pass lint.

*/
/* eslint-enable jsdoc/valid-types -- https://github.com/jsdoc-type-pratt-parser/jsdoc-type-pratt-parser/issues/4#issuecomment-778805577 */

@@ -115,0 +114,0 @@ //------------------------------------------------------------------------------

@@ -227,49 +227,41 @@ /**

/**
* Creates a new `AccessorData` object for the given getter or setter node.
* @param {ASTNode} node A getter or setter node.
* @returns {AccessorData} New `AccessorData` object that contains the given node.
* Checks accessor pairs in the given list of nodes.
* @param {ASTNode[]} nodes The list to check.
* @returns {void}
* @private
*/
function createAccessorData(node) {
const name = astUtils.getStaticPropertyName(node);
const key = (name !== null) ? name : sourceCode.getTokens(node.key);
function checkList(nodes) {
const accessors = [];
let found = false;
return {
key,
getters: node.kind === "get" ? [node] : [],
setters: node.kind === "set" ? [node] : []
};
}
for (let i = 0; i < nodes.length; i++) {
const node = nodes[i];
/**
* Merges the given `AccessorData` object into the given accessors list.
* @param {AccessorData[]} accessors The list to merge into.
* @param {AccessorData} accessorData The object to merge.
* @returns {AccessorData[]} The same instance with the merged object.
* @private
*/
function mergeAccessorData(accessors, accessorData) {
const equalKeyElement = accessors.find(a => areEqualKeys(a.key, accessorData.key));
if (isAccessorKind(node)) {
if (equalKeyElement) {
equalKeyElement.getters.push(...accessorData.getters);
equalKeyElement.setters.push(...accessorData.setters);
} else {
accessors.push(accessorData);
}
// Creates a new `AccessorData` object for the given getter or setter node.
const name = astUtils.getStaticPropertyName(node);
const key = (name !== null) ? name : sourceCode.getTokens(node.key);
return accessors;
}
// Merges the given `AccessorData` object into the given accessors list.
for (let j = 0; j < accessors.length; j++) {
const accessor = accessors[j];
/**
* Checks accessor pairs in the given list of nodes.
* @param {ASTNode[]} nodes The list to check.
* @returns {void}
* @private
*/
function checkList(nodes) {
const accessors = nodes
.filter(isAccessorKind)
.map(createAccessorData)
.reduce(mergeAccessorData, []);
if (areEqualKeys(accessor.key, key)) {
accessor.getters.push(...node.kind === "get" ? [node] : []);
accessor.setters.push(...node.kind === "set" ? [node] : []);
found = true;
break;
}
}
if (!found) {
accessors.push({
key,
getters: node.kind === "get" ? [node] : [],
setters: node.kind === "set" ? [node] : []
});
}
found = false;
}
}

@@ -276,0 +268,0 @@ for (const { getters, setters } of accessors) {

@@ -243,7 +243,11 @@ /**

const linebreaksCount = node.elements.map((element, i) => {
let linebreaksCount = 0;
for (let i = 0; i < node.elements.length; i++) {
const element = node.elements[i];
const previousElement = elements[i - 1];
if (i === 0 || element === null || previousElement === null) {
return false;
continue;
}

@@ -255,4 +259,6 @@

return !astUtils.isTokenOnSameLine(lastTokenOfPreviousElement, firstTokenOfCurrentElement);
}).filter(isBreak => isBreak === true).length;
if (!astUtils.isTokenOnSameLine(lastTokenOfPreviousElement, firstTokenOfCurrentElement)) {
linebreaksCount++;
}
}

@@ -259,0 +265,0 @@ const needsLinebreaks = (

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

node.computed &&
node.property.type === "TemplateLiteral" &&
node.property.expressions.length === 0
astUtils.isStaticTemplateLiteral(node.property)
) {

@@ -140,0 +139,0 @@ checkComputedProperty(node, node.property.quasis[0].value.cooked);

@@ -141,39 +141,2 @@ /**

/**
* Creates a new `AccessorData` object for the given getter or setter node.
* @param {ASTNode} node A getter or setter node.
* @returns {AccessorData} New `AccessorData` object that contains the given node.
* @private
*/
function createAccessorData(node) {
const name = astUtils.getStaticPropertyName(node);
const key = (name !== null) ? name : sourceCode.getTokens(node.key);
return {
key,
getters: node.kind === "get" ? [node] : [],
setters: node.kind === "set" ? [node] : []
};
}
/**
* Merges the given `AccessorData` object into the given accessors list.
* @param {AccessorData[]} accessors The list to merge into.
* @param {AccessorData} accessorData The object to merge.
* @returns {AccessorData[]} The same instance with the merged object.
* @private
*/
function mergeAccessorData(accessors, accessorData) {
const equalKeyElement = accessors.find(a => areEqualKeys(a.key, accessorData.key));
if (equalKeyElement) {
equalKeyElement.getters.push(...accessorData.getters);
equalKeyElement.setters.push(...accessorData.setters);
} else {
accessors.push(accessorData);
}
return accessors;
}
/**
* Checks accessor pairs in the given list of nodes.

@@ -186,8 +149,36 @@ * @param {ASTNode[]} nodes The list to check.

function checkList(nodes, shouldCheck) {
const accessors = nodes
.filter(shouldCheck)
.filter(isAccessorKind)
.map(createAccessorData)
.reduce(mergeAccessorData, []);
const accessors = [];
let found = false;
for (let i = 0; i < nodes.length; i++) {
const node = nodes[i];
if (shouldCheck(node) && isAccessorKind(node)) {
// Creates a new `AccessorData` object for the given getter or setter node.
const name = astUtils.getStaticPropertyName(node);
const key = (name !== null) ? name : sourceCode.getTokens(node.key);
// Merges the given `AccessorData` object into the given accessors list.
for (let j = 0; j < accessors.length; j++) {
const accessor = accessors[j];
if (areEqualKeys(accessor.key, key)) {
accessor.getters.push(...node.kind === "get" ? [node] : []);
accessor.setters.push(...node.kind === "set" ? [node] : []);
found = true;
break;
}
}
if (!found) {
accessors.push({
key,
getters: node.kind === "get" ? [node] : [],
setters: node.kind === "set" ? [node] : []
});
}
found = false;
}
}
for (const { getters, setters } of accessors) {

@@ -194,0 +185,0 @@

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

const requiresOuterParenthesis = logical.parent.type !== "ExpressionStatement" &&
(astUtils.getPrecedence({ type: "AssignmentExpression" }) < astUtils.getPrecedence(logical.parent));
const parentPrecedence = astUtils.getPrecedence(logical.parent);
const requiresOuterParenthesis = logical.parent.type !== "ExpressionStatement" && (
parentPrecedence === -1 ||
astUtils.getPrecedence({ type: "AssignmentExpression" }) < parentPrecedence
);

@@ -377,0 +380,0 @@ if (!astUtils.isParenthesised(sourceCode, logical) && requiresOuterParenthesis) {

@@ -255,15 +255,19 @@ /**

/**
* A reducer to group an AST node by line number, both start and end.
* @param {Object} acc the accumulator
* @param {ASTNode} node the AST node in question
* @returns {Object} the modified accumulator
* @private
*
* reduce an array of AST nodes by line number, both start and end.
* @param {ASTNode[]} arr array of AST nodes
* @returns {Object} accululated AST nodes
*/
function groupByLineNumber(acc, node) {
for (let i = node.loc.start.line; i <= node.loc.end.line; ++i) {
ensureArrayAndPush(acc, i, node);
function groupArrayByLineNumber(arr) {
const obj = {};
for (let i = 0; i < arr.length; i++) {
const node = arr[i];
for (let j = node.loc.start.line; j <= node.loc.end.line; ++j) {
ensureArrayAndPush(obj, j, node);
}
}
return acc;
return obj;
}

@@ -316,9 +320,9 @@

const strings = getAllStrings();
const stringsByLine = strings.reduce(groupByLineNumber, {});
const stringsByLine = groupArrayByLineNumber(strings);
const templateLiterals = getAllTemplateLiterals();
const templateLiteralsByLine = templateLiterals.reduce(groupByLineNumber, {});
const templateLiteralsByLine = groupArrayByLineNumber(templateLiterals);
const regExpLiterals = getAllRegExpLiterals();
const regExpLiteralsByLine = regExpLiterals.reduce(groupByLineNumber, {});
const regExpLiteralsByLine = groupArrayByLineNumber(regExpLiterals);

@@ -325,0 +329,0 @@ lines.forEach((line, i) => {

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

conditionalAssign: { type: "boolean" },
ternaryOperandBinaryExpressions: { type: "boolean" },
nestedBinaryExpressions: { type: "boolean" },

@@ -80,2 +81,3 @@ returnAssign: { type: "boolean" },

const EXCEPT_COND_ASSIGN = ALL_NODES && context.options[1] && context.options[1].conditionalAssign === false;
const EXCEPT_COND_TERNARY = ALL_NODES && context.options[1] && context.options[1].ternaryOperandBinaryExpressions === false;
const NESTED_BINARY = ALL_NODES && context.options[1] && context.options[1].nestedBinaryExpressions === false;

@@ -891,3 +893,7 @@ const EXCEPT_RETURN_ASSIGN = ALL_NODES && context.options[1] && context.options[1].returnAssign === false;

}
const availableTypes = new Set(["BinaryExpression", "LogicalExpression"]);
if (
!(EXCEPT_COND_TERNARY && availableTypes.has(node.test.type)) &&
!isCondAssignException(node) &&

@@ -899,7 +905,11 @@ hasExcessParensWithPrecedence(node.test, precedence({ type: "LogicalExpression", operator: "||" }))

if (hasExcessParensWithPrecedence(node.consequent, PRECEDENCE_OF_ASSIGNMENT_EXPR)) {
if (
!(EXCEPT_COND_TERNARY && availableTypes.has(node.consequent.type)) &&
hasExcessParensWithPrecedence(node.consequent, PRECEDENCE_OF_ASSIGNMENT_EXPR)) {
report(node.consequent);
}
if (hasExcessParensWithPrecedence(node.alternate, PRECEDENCE_OF_ASSIGNMENT_EXPR)) {
if (
!(EXCEPT_COND_TERNARY && availableTypes.has(node.alternate.type)) &&
hasExcessParensWithPrecedence(node.alternate, PRECEDENCE_OF_ASSIGNMENT_EXPR)) {
report(node.alternate);

@@ -906,0 +916,0 @@ }

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

/**
* Checks if a node or token is fixable.
* A node is fixable if it can be removed without turning a subsequent statement into a directive after fixing other nodes.
* @param {Token} nodeOrToken The node or token to check.
* @returns {boolean} Whether or not the node is fixable.
*/
function isFixable(nodeOrToken) {
const nextToken = sourceCode.getTokenAfter(nodeOrToken);
if (!nextToken || nextToken.type !== "String") {
return true;
}
const stringNode = sourceCode.getNodeByRangeIndex(nextToken.range[0]);
return !astUtils.isTopLevelExpressionStatement(stringNode.parent);
}
/**
* Reports an unnecessary semicolon error.

@@ -51,13 +68,14 @@ * @param {Node|Token} nodeOrToken A node or a token to be reported.

messageId: "unexpected",
fix(fixer) {
fix: isFixable(nodeOrToken)
? fixer =>
/*
* Expand the replacement range to include the surrounding
* tokens to avoid conflicting with semi.
* https://github.com/eslint/eslint/issues/7928
*/
return new FixTracker(fixer, context.sourceCode)
.retainSurroundingTokens(nodeOrToken)
.remove(nodeOrToken);
}
/*
* Expand the replacement range to include the surrounding
* tokens to avoid conflicting with semi.
* https://github.com/eslint/eslint/issues/7928
*/
new FixTracker(fixer, context.sourceCode)
.retainSurroundingTokens(nodeOrToken)
.remove(nodeOrToken)
: null
});

@@ -64,0 +82,0 @@ }

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

function addDecimalPointToNumber(stringNumber) {
return `${stringNumber.slice(0, 1)}.${stringNumber.slice(1)}`;
return `${stringNumber[0]}.${stringNumber.slice(1)}`;
}

@@ -96,3 +96,8 @@

function removeLeadingZeros(numberAsString) {
return numberAsString.replace(/^0*/u, "");
for (let i = 0; i < numberAsString.length; i++) {
if (numberAsString[i] !== "0") {
return numberAsString.slice(i);
}
}
return numberAsString;
}

@@ -106,3 +111,8 @@

function removeTrailingZeros(numberAsString) {
return numberAsString.replace(/0*$/u, "");
for (let i = numberAsString.length - 1; i >= 0; i--) {
if (numberAsString[i] !== "0") {
return numberAsString.slice(0, i + 1);
}
}
return numberAsString;
}

@@ -134,3 +144,3 @@

if (trimmedFloat.startsWith(".")) {
const decimalDigits = trimmedFloat.split(".").pop();
const decimalDigits = trimmedFloat.slice(1);
const significantDigits = removeLeadingZeros(decimalDigits);

@@ -151,3 +161,2 @@

/**

@@ -168,3 +177,2 @@ * Converts a base ten number to proper scientific notation

return `${normalizedCoefficient}e${magnitude}`;
}

@@ -171,0 +179,0 @@

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

//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
const astUtils = require("./utils/ast-utils");
//------------------------------------------------------------------------------
// Rule Definition

@@ -121,11 +127,2 @@ //------------------------------------------------------------------------------

/**
* Function to check if a node is a static string template literal.
* @param {ASTNode} node The node to check.
* @returns {boolean} If the node is a string template literal.
*/
function isStaticTemplateLiteral(node) {
return node && node.type === "TemplateLiteral" && node.expressions.length === 0;
}
/**
* Function to check if a node is a require call.

@@ -149,3 +146,3 @@ * @param {ASTNode} node The node to check.

if (isStaticTemplateLiteral(node)) {
if (astUtils.isStaticTemplateLiteral(node)) {
return node.quasis[0].value.cooked.trim();

@@ -152,0 +149,0 @@ }

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

//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
const astUtils = require("./utils/ast-utils");
//------------------------------------------------------------------------------
// Rule Definition

@@ -51,2 +57,41 @@ //------------------------------------------------------------------------------

/**
* Checks if a `LabeledStatement` node is fixable.
* For a node to be fixable, there must be no comments between the label and the body.
* Furthermore, is must be possible to remove the label without turning the body statement into a
* directive after other fixes are applied.
* @param {ASTNode} node The node to evaluate.
* @returns {boolean} Whether or not the node is fixable.
*/
function isFixable(node) {
/*
* Only perform a fix if there are no comments between the label and the body. This will be the case
* when there is exactly one token/comment (the ":") between the label and the body.
*/
if (sourceCode.getTokenAfter(node.label, { includeComments: true }) !==
sourceCode.getTokenBefore(node.body, { includeComments: true })) {
return false;
}
// Looking for the node's deepest ancestor which is not a `LabeledStatement`.
let ancestor = node.parent;
while (ancestor.type === "LabeledStatement") {
ancestor = ancestor.parent;
}
if (ancestor.type === "Program" ||
(ancestor.type === "BlockStatement" && astUtils.isFunction(ancestor.parent))) {
const { body } = node;
if (body.type === "ExpressionStatement" &&
((body.expression.type === "Literal" && typeof body.expression.value === "string") ||
astUtils.isStaticTemplateLiteral(body.expression))) {
return false; // potential directive
}
}
return true;
}
/**
* Removes the top of the stack.

@@ -63,15 +108,3 @@ * At the same time, this reports the label if it's never used.

data: node.label,
fix(fixer) {
/*
* Only perform a fix if there are no comments between the label and the body. This will be the case
* when there is exactly one token/comment (the ":") between the label and the body.
*/
if (sourceCode.getTokenAfter(node.label, { includeComments: true }) ===
sourceCode.getTokenBefore(node.body, { includeComments: true })) {
return fixer.removeRange([node.range[0], node.body.range[0]]);
}
return null;
}
fix: isFixable(node) ? fixer => fixer.removeRange([node.range[0], node.body.range[0]]) : null
});

@@ -78,0 +111,0 @@ }

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

parent.left === id &&
isUnusedExpression(parent)
isUnusedExpression(parent) &&
!astUtils.isLogicalAssignmentOperator(parent.operator)
) ||

@@ -472,0 +473,0 @@ (

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

const parentPrecedence = astUtils.getPrecedence(parent);
const needsParens = (

@@ -63,3 +64,3 @@ parent.type === "ClassDeclaration" ||

parent.type.endsWith("Expression") &&
astUtils.getPrecedence(parent) >= PRECEDENCE_OF_EXPONENTIATION_EXPR &&
(parentPrecedence === -1 || parentPrecedence >= PRECEDENCE_OF_EXPONENTIATION_EXPR) &&
!(parent.type === "BinaryExpression" && parent.operator === "**" && parent.right === node) &&

@@ -66,0 +67,0 @@ !((parent.type === "CallExpression" || parent.type === "NewExpression") && parent.arguments.includes(node)) &&

@@ -40,11 +40,2 @@ /**

/**
* Determines whether the given node is a template literal without expressions.
* @param {ASTNode} node Node to check.
* @returns {boolean} True if the node is a template literal without expressions.
*/
function isStaticTemplateLiteral(node) {
return node.type === "TemplateLiteral" && node.expressions.length === 0;
}
const validPrecedingTokens = new Set([

@@ -182,3 +173,3 @@ "(",

isGlobalReference(astUtils.skipChainExpression(node.tag).object) &&
isStaticTemplateLiteral(node.quasi);
astUtils.isStaticTemplateLiteral(node.quasi);
}

@@ -196,3 +187,3 @@

if (isStaticTemplateLiteral(node)) {
if (astUtils.isStaticTemplateLiteral(node)) {
return node.quasis[0].value.cooked;

@@ -215,3 +206,3 @@ }

return isStringLiteral(node) ||
isStaticTemplateLiteral(node) ||
astUtils.isStaticTemplateLiteral(node) ||
isStringRawTaggedStaticTemplateLiteral(node);

@@ -218,0 +209,0 @@ }

@@ -8,2 +8,8 @@ /**

//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
const astUtils = require("./utils/ast-utils");
//------------------------------------------------------------------------------
// Rule Definition

@@ -92,3 +98,3 @@ //------------------------------------------------------------------------------

if (sibling.type === "Literal" || sibling.type === "TemplateLiteral" && !sibling.expressions.length) {
if (sibling.type === "Literal" || astUtils.isStaticTemplateLiteral(sibling)) {
const value = sibling.type === "Literal" ? sibling.value : sibling.quasis[0].value.cooked;

@@ -95,0 +101,0 @@

@@ -62,11 +62,2 @@ /**

/**
* Determines whether a node is a Template Literal which can be determined statically.
* @param {ASTNode} node Node to test
* @returns {boolean} True if the node is a Template Literal without expression.
*/
function isStaticTemplateLiteral(node) {
return node.type === "TemplateLiteral" && node.expressions.length === 0;
}
/**
* Determines whether a non-Literal node should be treated as a single Literal node.

@@ -77,3 +68,3 @@ * @param {ASTNode} node Node to test

function looksLikeLiteral(node) {
return isNegativeNumericLiteral(node) || isStaticTemplateLiteral(node);
return isNegativeNumericLiteral(node) || astUtils.isStaticTemplateLiteral(node);
}

@@ -105,3 +96,3 @@

if (isStaticTemplateLiteral(node)) {
if (astUtils.isStaticTemplateLiteral(node)) {
return {

@@ -108,0 +99,0 @@ type: "Literal",

@@ -24,3 +24,3 @@ /**

* @property {EcmaFeatures} [ecmaFeatures] The optional features.
* @property {3|5|6|7|8|9|10|11|12|13|14|2015|2016|2017|2018|2019|2020|2021|2022|2023} [ecmaVersion] The ECMAScript version (or revision number).
* @property {3|5|6|7|8|9|10|11|12|13|14|15|2015|2016|2017|2018|2019|2020|2021|2022|2023|2024} [ecmaVersion] The ECMAScript version (or revision number).
* @property {"script"|"module"} [sourceType] The source code type.

@@ -27,0 +27,0 @@ * @property {boolean} [allowReserved] Allowing the use of reserved words as identifiers in ES3.

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

@@ -65,4 +65,4 @@ "description": "An AST-based pattern checker for JavaScript.",

"@eslint-community/regexpp": "^4.4.0",
"@eslint/eslintrc": "^2.0.3",
"@eslint/js": "8.43.0",
"@eslint/eslintrc": "^2.1.0",
"@eslint/js": "8.44.0",
"@humanwhocodes/config-array": "^0.11.10",

@@ -79,3 +79,3 @@ "@humanwhocodes/module-importer": "^1.0.1",

"eslint-visitor-keys": "^3.4.1",
"espree": "^9.5.2",
"espree": "^9.6.0",
"esquery": "^1.4.2",

@@ -100,3 +100,3 @@ "esutils": "^2.0.2",

"natural-compare": "^1.4.0",
"optionator": "^0.9.1",
"optionator": "^0.9.3",
"strip-ansi": "^6.0.1",

@@ -121,4 +121,4 @@ "strip-json-comments": "^3.1.0",

"eslint-plugin-internal-rules": "file:tools/internal-rules",
"eslint-plugin-jsdoc": "^38.1.6",
"eslint-plugin-n": "^15.2.4",
"eslint-plugin-jsdoc": "^46.2.5",
"eslint-plugin-n": "^16.0.0",
"eslint-plugin-unicorn": "^42.0.0",

@@ -160,3 +160,3 @@ "eslint-release": "^3.2.0",

"regenerator-runtime": "^0.13.2",
"semver": "^7.3.5",
"semver": "^7.5.3",
"shelljs": "^0.8.2",

@@ -163,0 +163,0 @@ "sinon": "^11.0.0",

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

ESLint has full support for ECMAScript 3, 5 (default), 2015, 2016, 2017, 2018, 2019, 2020, 2021 and 2022. You can set your desired ECMAScript syntax (and other settings, like global variables or your target environments) through [configuration](https://eslint.org/docs/latest/use/configure).
ESLint has full support for ECMAScript 3, 5 (default), 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, and 2023. You can set your desired ECMAScript syntax (and other settings, like global variables or your target environments) through [configuration](https://eslint.org/docs/latest/use/configure).

@@ -288,3 +288,3 @@ ### What about experimental features?

<p><a href="https://sentry.io"><img src="https://avatars.githubusercontent.com/u/1396951?v=4" alt="Sentry" height="64"></a> <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://nx.dev"><img src="https://images.opencollective.com/nx/0efbe42/logo.png" alt="Nx (by Nrwl)" 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: free icons, photos, illustrations, and music" 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://themeisle.com"><img src="https://images.opencollective.com/themeisle/d5592fe/logo.png" alt="ThemeIsle" height="32"></a> <a href="https://nx.dev"><img src="https://images.opencollective.com/nx/0efbe42/logo.png" alt="Nx (by Nrwl)" 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: free icons, photos, illustrations, and music" 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://opensource.mercedes-benz.com/"><img src="https://avatars.githubusercontent.com/u/34240465?v=4" alt="Mercedes-Benz Group" 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>
<!--sponsorsend-->

@@ -291,0 +291,0 @@

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