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.45.0 to 8.46.0

messages/eslintrc-incompat.js

70

lib/config/flat-config-schema.js

@@ -215,2 +215,34 @@ /**

/**
* The error type when there's an eslintrc-style options in a flat config.
*/
class IncompatibleKeyError extends Error {
/**
* @param {string} key The invalid key.
*/
constructor(key) {
super("This appears to be in eslintrc format rather than flat config format.");
this.messageTemplate = "eslintrc-incompat";
this.messageData = { key };
}
}
/**
* The error type when there's an eslintrc-style plugins array found.
*/
class IncompatiblePluginsError extends Error {
/**
* Creates a new instance.
* @param {Array<string>} plugins The plugins array.
*/
constructor(plugins) {
super("This appears to be in eslintrc format (array of strings) rather than flat config format (object).");
this.messageTemplate = "eslintrc-plugins";
this.messageData = { plugins };
}
}
//-----------------------------------------------------------------------------

@@ -307,2 +339,7 @@ // Low-Level Schemas

// make sure it's not an array, which would mean eslintrc-style is used
if (Array.isArray(value)) {
throw new IncompatiblePluginsError(value);
}
// second check the keys to make sure they are objects

@@ -443,2 +480,30 @@ for (const key of Object.keys(value)) {

/**
* Creates a schema that always throws an error. Useful for warning
* about eslintrc-style keys.
* @param {string} key The eslintrc key to create a schema for.
* @returns {ObjectPropertySchema} The schema.
*/
function createEslintrcErrorSchema(key) {
return {
merge: "replace",
validate() {
throw new IncompatibleKeyError(key);
}
};
}
const eslintrcKeys = [
"env",
"extends",
"globals",
"ignorePatterns",
"noInlineConfig",
"overrides",
"parser",
"parserOptions",
"reportUnusedDisableDirectives",
"root"
];
//-----------------------------------------------------------------------------

@@ -449,2 +514,7 @@ // Full schema

exports.flatConfigSchema = {
// eslintrc-style keys that should always error
...Object.fromEntries(eslintrcKeys.map(key => [key, createEslintrcErrorSchema(key)])),
// flat config keys
settings: deepObjectAssignSchema,

@@ -451,0 +521,0 @@ linterOptions: {

8

lib/eslint/flat-eslint.js

@@ -717,8 +717,6 @@ /**

// ensure the rule exists
if (!rule) {
throw new TypeError(`Could not find the rule "${ruleId}".`);
// ignore unknown rules
if (rule) {
resultRules.set(ruleId, rule);
}
resultRules.set(ruleId, rule);
}

@@ -725,0 +723,0 @@ }

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

onPatternEnter() {
/*
* `RegExpValidator` may parse the pattern twice in one `validatePattern`.
* So `this._controlChars` should be cleared here as well.
*
* For example, the `/(?<a>\x1f)/` regex will parse the pattern twice.
* This is based on the content described in Annex B.
* If the regex contains a `GroupName` and the `u` flag is not used, `ParseText` will be called twice.
* See https://tc39.es/ecma262/2023/multipage/additional-ecmascript-features-for-web-browsers.html#sec-parsepattern-annexb
*/
this._controlChars = [];

@@ -36,6 +46,9 @@ }

const uFlag = typeof flags === "string" && flags.includes("u");
const vFlag = typeof flags === "string" && flags.includes("v");
this._controlChars = [];
this._source = regexpStr;
try {
this._source = regexpStr;
this._validator.validatePattern(regexpStr, void 0, void 0, uFlag); // Call onCharacter hook
this._validator.validatePattern(regexpStr, void 0, void 0, { unicode: uFlag, unicodeSets: vFlag }); // Call onCharacter hook
} catch {

@@ -42,0 +55,0 @@

@@ -9,15 +9,13 @@ /**

//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
const { RegExpParser, visitRegExpAST } = require("@eslint-community/regexpp");
//------------------------------------------------------------------------------
// Helpers
//------------------------------------------------------------------------------
/*
* plain-English description of the following regexp:
* 0. `^` fix the match at the beginning of the string
* 1. `([^\\[]|\\.|\[([^\\\]]|\\.)+\])*`: regexp contents; 0 or more of the following
* 1.0. `[^\\[]`: any character that's not a `\` or a `[` (anything but escape sequences and character classes)
* 1.1. `\\.`: an escape sequence
* 1.2. `\[([^\\\]]|\\.)+\]`: a character class that isn't empty
* 2. `$`: fix the match at the end of the string
*/
const regex = /^([^\\[]|\\.|\[([^\\\]]|\\.)+\])*$/u;
const parser = new RegExpParser();
const QUICK_TEST_REGEX = /\[\]/u;

@@ -49,5 +47,28 @@ //------------------------------------------------------------------------------

"Literal[regex]"(node) {
if (!regex.test(node.regex.pattern)) {
context.report({ node, messageId: "unexpected" });
const { pattern, flags } = node.regex;
if (!QUICK_TEST_REGEX.test(pattern)) {
return;
}
let regExpAST;
try {
regExpAST = parser.parsePattern(pattern, 0, pattern.length, {
unicode: flags.includes("u"),
unicodeSets: flags.includes("v")
});
} catch {
// Ignore regular expressions that regexpp cannot parse
return;
}
visitRegExpAST(regExpAST, {
onCharacterClassEnter(characterClass) {
if (!characterClass.negate && characterClass.elements.length === 0) {
context.report({ node, messageId: "unexpected" });
}
}
});
}

@@ -54,0 +75,0 @@ };

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

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

@@ -23,3 +25,14 @@ // Rule Definition

schema: [],
schema: [
{
type: "object",
properties: {
allowObjectPatternsAsParameters: {
type: "boolean",
default: false
}
},
additionalProperties: false
}
],

@@ -32,7 +45,29 @@ messages: {

create(context) {
const options = context.options[0] || {},
allowObjectPatternsAsParameters = options.allowObjectPatternsAsParameters || false;
return {
ObjectPattern(node) {
if (node.properties.length === 0) {
context.report({ node, messageId: "unexpected", data: { type: "object" } });
if (node.properties.length > 0) {
return;
}
// Allow {} and {} = {} empty object patterns as parameters when allowObjectPatternsAsParameters is true
if (
allowObjectPatternsAsParameters &&
(
astUtils.isFunction(node.parent) ||
(
node.parent.type === "AssignmentPattern" &&
astUtils.isFunction(node.parent.parent) &&
node.parent.right.type === "ObjectExpression" &&
node.parent.right.properties.length === 0
)
)
) {
return;
}
context.report({ node, messageId: "unexpected", data: { type: "object" } });
},

@@ -39,0 +74,0 @@ ArrayPattern(node) {

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

const validator = new RegExpValidator();
const validFlags = /[dgimsuy]/gu;
const validFlags = /[dgimsuvy]/gu;
const undefined1 = void 0;

@@ -112,8 +112,10 @@

* @param {string} pattern The RegExp pattern to validate.
* @param {boolean} uFlag The Unicode flag.
* @param {Object} flags The RegExp flags to validate.
* @param {boolean} [flags.unicode] The Unicode flag.
* @param {boolean} [flags.unicodeSets] The UnicodeSets flag.
* @returns {string|null} The syntax error.
*/
function validateRegExpPattern(pattern, uFlag) {
function validateRegExpPattern(pattern, flags) {
try {
validator.validatePattern(pattern, undefined1, undefined1, uFlag);
validator.validatePattern(pattern, undefined1, undefined1, flags);
return null;

@@ -136,6 +138,15 @@ } catch (err) {

validator.validateFlags(flags);
return null;
} catch {
return `Invalid flags supplied to RegExp constructor '${flags}'`;
}
/*
* `regexpp` checks the combination of `u` and `v` flags when parsing `Pattern` according to `ecma262`,
* but this rule may check only the flag when the pattern is unidentifiable, so check it here.
* https://tc39.es/ecma262/multipage/text-processing.html#sec-parsepattern
*/
if (flags.includes("u") && flags.includes("v")) {
return "Regex 'u' and 'v' flags cannot be used together";
}
return null;
}

@@ -172,4 +183,8 @@

flags === null
? validateRegExpPattern(pattern, true) && validateRegExpPattern(pattern, false)
: validateRegExpPattern(pattern, flags.includes("u"))
? (
validateRegExpPattern(pattern, { unicode: true, unicodeSets: false }) &&
validateRegExpPattern(pattern, { unicode: false, unicodeSets: true }) &&
validateRegExpPattern(pattern, { unicode: false, unicodeSets: false })
)
: validateRegExpPattern(pattern, { unicode: flags.includes("u"), unicodeSets: flags.includes("v") })
);

@@ -176,0 +191,0 @@

@@ -189,3 +189,3 @@ /**

const references = sourceCode.getScope(node).through;
const unsafeRefs = references.filter(r => !isSafe(loopNode, r)).map(r => r.identifier.name);
const unsafeRefs = references.filter(r => r.resolved && !isSafe(loopNode, r)).map(r => r.identifier.name);

@@ -192,0 +192,0 @@ if (unsafeRefs.length > 0) {

@@ -21,3 +21,3 @@ /**

* so this function reverts CharacterClassRange syntax and restore the sequence.
* @param {regexpp.AST.CharacterClassElement[]} nodes The node list to iterate character sequences.
* @param {import('@eslint-community/regexpp').AST.CharacterClassElement[]} nodes The node list to iterate character sequences.
* @returns {IterableIterator<number[]>} The list of character sequences.

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

case "CharacterSet":
case "CharacterClass": // [[]] nesting character class
case "ClassStringDisjunction": // \q{...}
case "ExpressionCharacterClass": // [A--B]
if (seq.length > 0) {

@@ -149,3 +152,6 @@ yield seq;

pattern.length,
flags.includes("u")
{
unicode: flags.includes("u"),
unicodeSets: flags.includes("v")
}
);

@@ -152,0 +158,0 @@ } catch {

@@ -80,3 +80,3 @@ /**

try {
regExpAST = regExpParser.parsePattern(pattern, 0, pattern.length, flags.includes("u"));
regExpAST = regExpParser.parsePattern(pattern, 0, pattern.length, { unicode: flags.includes("u"), unicodeSets: flags.includes("v") });
} catch {

@@ -159,3 +159,2 @@

const patternNode = node.arguments[0];
const flagsNode = node.arguments[1];

@@ -166,4 +165,20 @@ if (node.callee.type === "Identifier" && node.callee.name === "RegExp" && isString(patternNode) && !shadowed) {

const rawPatternStartRange = patternNode.range[0] + 1;
const flags = isString(flagsNode) ? flagsNode.value : "";
let flags;
if (node.arguments.length < 2) {
// It has no flags.
flags = "";
} else {
const flagsNode = node.arguments[1];
if (isString(flagsNode)) {
flags = flagsNode.value;
} else {
// The flags cannot be determined.
return;
}
}
checkRegex(

@@ -170,0 +185,0 @@ node,

/**
* @fileoverview Disallows unnecessary `return await`
* @author Jordan Harband
* @deprecated in ESLint v8.46.0
*/

@@ -29,2 +30,6 @@ "use strict";

deprecated: true,
replacedBy: [],
schema: [

@@ -31,0 +36,0 @@ ],

@@ -98,3 +98,3 @@ /**

try {
regExpAST = parser.parsePattern(pattern, 0, pattern.length, flags.includes("u"));
regExpAST = parser.parsePattern(pattern, 0, pattern.length, { unicode: flags.includes("u"), unicodeSets: flags.includes("v") });
} catch {

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

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

const astUtils = require("./utils/ast-utils");
const { RegExpParser, visitRegExpAST } = require("@eslint-community/regexpp");
/**
* @typedef {import('@eslint-community/regexpp').AST.CharacterClass} CharacterClass
* @typedef {import('@eslint-community/regexpp').AST.ExpressionCharacterClass} ExpressionCharacterClass
*/
//------------------------------------------------------------------------------

@@ -32,52 +37,14 @@ // Rule Definition

/**
* Parses a regular expression into a list of characters with character class info.
* @param {string} regExpText The raw text used to create the regular expression
* @returns {Object[]} A list of characters, each with info on escaping and whether they're in a character class.
* @example
*
* parseRegExp("a\\b[cd-]");
*
* // returns:
* [
* { text: "a", index: 0, escaped: false, inCharClass: false, startsCharClass: false, endsCharClass: false },
* { text: "b", index: 2, escaped: true, inCharClass: false, startsCharClass: false, endsCharClass: false },
* { text: "c", index: 4, escaped: false, inCharClass: true, startsCharClass: true, endsCharClass: false },
* { text: "d", index: 5, escaped: false, inCharClass: true, startsCharClass: false, endsCharClass: false },
* { text: "-", index: 6, escaped: false, inCharClass: true, startsCharClass: false, endsCharClass: false }
* ];
*
/*
* Set of characters that require escaping in character classes in `unicodeSets` mode.
* ( ) [ ] { } / - \ | are ClassSetSyntaxCharacter
*/
function parseRegExp(regExpText) {
const charList = [];
const REGEX_CLASSSET_CHARACTER_ESCAPES = union(REGEX_GENERAL_ESCAPES, new Set("q/[{}|()-"));
regExpText.split("").reduce((state, char, index) => {
if (!state.escapeNextChar) {
if (char === "\\") {
return Object.assign(state, { escapeNextChar: true });
}
if (char === "[" && !state.inCharClass) {
return Object.assign(state, { inCharClass: true, startingCharClass: true });
}
if (char === "]" && state.inCharClass) {
if (charList.length && charList[charList.length - 1].inCharClass) {
charList[charList.length - 1].endsCharClass = true;
}
return Object.assign(state, { inCharClass: false, startingCharClass: false });
}
}
charList.push({
text: char,
index,
escaped: state.escapeNextChar,
inCharClass: state.inCharClass,
startsCharClass: state.startingCharClass,
endsCharClass: false
});
return Object.assign(state, { escapeNextChar: false, startingCharClass: false });
}, { escapeNextChar: false, inCharClass: false, startingCharClass: false });
/*
* A single character set of ClassSetReservedDoublePunctuator.
* && !! ## $$ %% ** ++ ,, .. :: ;; << == >> ?? @@ ^^ `` ~~ are ClassSetReservedDoublePunctuator
*/
const REGEX_CLASS_SET_RESERVED_DOUBLE_PUNCTUATOR = new Set("!#$%&*+,.:;<=>?@^`~");
return charList;
}
/** @type {import('../shared/types').Rule} */

@@ -108,2 +75,3 @@ module.exports = {

const sourceCode = context.sourceCode;
const parser = new RegExpParser();

@@ -115,5 +83,6 @@ /**

* @param {string} character The uselessly escaped character (not including the backslash)
* @param {boolean} [disableEscapeBackslashSuggest] `true` if escapeBackslash suggestion should be turned off.
* @returns {void}
*/
function report(node, startOffset, character) {
function report(node, startOffset, character, disableEscapeBackslashSuggest) {
const rangeStart = node.range[0] + startOffset;

@@ -141,8 +110,12 @@ const range = [rangeStart, rangeStart + 1];

},
{
messageId: "escapeBackslash",
fix(fixer) {
return fixer.insertTextBeforeRange(range, "\\");
}
}
...disableEscapeBackslashSuggest
? []
: [
{
messageId: "escapeBackslash",
fix(fixer) {
return fixer.insertTextBeforeRange(range, "\\");
}
}
]
]

@@ -191,2 +164,129 @@ });

/**
* Checks if the escape character in given regexp is unnecessary.
* @private
* @param {ASTNode} node node to validate.
* @returns {void}
*/
function validateRegExp(node) {
const { pattern, flags } = node.regex;
let patternNode;
const unicode = flags.includes("u");
const unicodeSets = flags.includes("v");
try {
patternNode = parser.parsePattern(pattern, 0, pattern.length, { unicode, unicodeSets });
} catch {
// Ignore regular expressions with syntax errors
return;
}
/** @type {(CharacterClass | ExpressionCharacterClass)[]} */
const characterClassStack = [];
visitRegExpAST(patternNode, {
onCharacterClassEnter: characterClassNode => characterClassStack.unshift(characterClassNode),
onCharacterClassLeave: () => characterClassStack.shift(),
onExpressionCharacterClassEnter: characterClassNode => characterClassStack.unshift(characterClassNode),
onExpressionCharacterClassLeave: () => characterClassStack.shift(),
onCharacterEnter(characterNode) {
if (!characterNode.raw.startsWith("\\")) {
// It's not an escaped character.
return;
}
const escapedChar = characterNode.raw.slice(1);
if (escapedChar !== String.fromCodePoint(characterNode.value)) {
// It's a valid escape.
return;
}
let allowedEscapes;
if (characterClassStack.length) {
allowedEscapes = unicodeSets ? REGEX_CLASSSET_CHARACTER_ESCAPES : REGEX_GENERAL_ESCAPES;
} else {
allowedEscapes = REGEX_NON_CHARCLASS_ESCAPES;
}
if (allowedEscapes.has(escapedChar)) {
return;
}
const reportedIndex = characterNode.start + 1;
let disableEscapeBackslashSuggest = false;
if (characterClassStack.length) {
const characterClassNode = characterClassStack[0];
if (escapedChar === "^") {
/*
* The '^' character is also a special case; it must always be escaped outside of character classes, but
* it only needs to be escaped in character classes if it's at the beginning of the character class. To
* account for this, consider it to be a valid escape character outside of character classes, and filter
* out '^' characters that appear at the start of a character class.
*/
if (characterClassNode.start + 1 === characterNode.start) {
return;
}
}
if (!unicodeSets) {
if (escapedChar === "-") {
/*
* The '-' character is a special case, because it's only valid to escape it if it's in a character
* class, and is not at either edge of the character class. To account for this, don't consider '-'
* characters to be valid in general, and filter out '-' characters that appear in the middle of a
* character class.
*/
if (characterClassNode.start + 1 !== characterNode.start && characterNode.end !== characterClassNode.end - 1) {
return;
}
}
} else { // unicodeSets mode
if (REGEX_CLASS_SET_RESERVED_DOUBLE_PUNCTUATOR.has(escapedChar)) {
// Escaping is valid if it is a ClassSetReservedDoublePunctuator.
if (pattern[characterNode.end] === escapedChar) {
return;
}
if (pattern[characterNode.start - 1] === escapedChar) {
if (escapedChar !== "^") {
return;
}
// If the previous character is a `negate` caret(`^`), escape to caret is unnecessary.
if (!characterClassNode.negate) {
return;
}
const negateCaretIndex = characterClassNode.start + 1;
if (negateCaretIndex < characterNode.start - 1) {
return;
}
}
}
if (characterNode.parent.type === "ClassIntersection" || characterNode.parent.type === "ClassSubtraction") {
disableEscapeBackslashSuggest = true;
}
}
}
report(
node,
reportedIndex,
escapedChar,
disableEscapeBackslashSuggest
);
}
});
}
/**
* Checks if a node has an escape.

@@ -229,28 +329,3 @@ * @param {ASTNode} node node to check.

} else if (node.regex) {
parseRegExp(node.regex.pattern)
/*
* The '-' character is a special case, because it's only valid to escape it if it's in a character
* class, and is not at either edge of the character class. To account for this, don't consider '-'
* characters to be valid in general, and filter out '-' characters that appear in the middle of a
* character class.
*/
.filter(charInfo => !(charInfo.text === "-" && charInfo.inCharClass && !charInfo.startsCharClass && !charInfo.endsCharClass))
/*
* The '^' character is also a special case; it must always be escaped outside of character classes, but
* it only needs to be escaped in character classes if it's at the beginning of the character class. To
* account for this, consider it to be a valid escape character outside of character classes, and filter
* out '^' characters that appear at the start of a character class.
*/
.filter(charInfo => !(charInfo.text === "^" && charInfo.startsCharClass))
// Filter out characters that aren't escaped.
.filter(charInfo => charInfo.escaped)
// Filter out characters that are valid to escape, based on their position in the regular expression.
.filter(charInfo => !(charInfo.inCharClass ? REGEX_GENERAL_ESCAPES : REGEX_NON_CHARCLASS_ESCAPES).has(charInfo.text))
// Report all the remaining characters.
.forEach(charInfo => report(node, charInfo.index, charInfo.text));
validateRegExp(node);
}

@@ -257,0 +332,0 @@

@@ -115,10 +115,13 @@ /**

* @param {ASTNode} regexNode AST node which contains the regular expression.
* @param {boolean} uFlag Flag indicates whether unicode mode is enabled or not.
* @param {string|null} flags The regular expression flags to be checked.
* @returns {void}
*/
function checkRegex(pattern, node, regexNode, uFlag) {
function checkRegex(pattern, node, regexNode, flags) {
let ast;
try {
ast = parser.parsePattern(pattern, 0, pattern.length, uFlag);
ast = parser.parsePattern(pattern, 0, pattern.length, {
unicode: Boolean(flags && flags.includes("u")),
unicodeSets: Boolean(flags && flags.includes("v"))
});
} catch {

@@ -152,3 +155,3 @@

if (node.regex) {
checkRegex(node.regex.pattern, node, node, node.regex.flags.includes("u"));
checkRegex(node.regex.pattern, node, node, node.regex.flags);
}

@@ -171,3 +174,3 @@ },

if (regex) {
checkRegex(regex, refNode, refNode.arguments[0], flags && flags.includes("u"));
checkRegex(regex, refNode, refNode.arguments[0], flags);
}

@@ -174,0 +177,0 @@ }

@@ -244,3 +244,3 @@ /**

* @param {number} ecmaVersion The ecmaVersion to convert.
* @returns {import("regexpp/ecma-versions").EcmaVersion} The resulting ecmaVersion compatible for regexpp.
* @returns {import("@eslint-community/regexpp/ecma-versions").EcmaVersion} The resulting ecmaVersion compatible for regexpp.
*/

@@ -301,3 +301,6 @@ function getRegexppEcmaVersion(ecmaVersion) {

try {
validator.validatePattern(pattern, 0, pattern.length, flags ? flags.includes("u") : false);
validator.validatePattern(pattern, 0, pattern.length, {
unicode: flags ? flags.includes("u") : false,
unicodeSets: flags ? flags.includes("v") : false
});
if (flags) {

@@ -466,3 +469,6 @@ validator.validateFlags(flags);

const ast = new RegExpParser({ ecmaVersion: regexppEcmaVersion }).parsePattern(regexContent, 0, regexContent.length, flags ? flags.includes("u") : false);
const ast = new RegExpParser({ ecmaVersion: regexppEcmaVersion }).parsePattern(regexContent, 0, regexContent.length, {
unicode: flags ? flags.includes("u") : false,
unicodeSets: flags ? flags.includes("v") : false
});

@@ -469,0 +475,0 @@ visitRegExpAST(ast, {

@@ -31,3 +31,3 @@ /**

docs: {
description: "Enforce the use of `u` flag on RegExp",
description: "Enforce the use of `u` or `v` flag on RegExp",
recommended: false,

@@ -55,3 +55,3 @@ url: "https://eslint.org/docs/latest/rules/require-unicode-regexp"

if (!flags.includes("u")) {
if (!flags.includes("u") && !flags.includes("v")) {
context.report({

@@ -90,3 +90,3 @@ messageId: "requireUFlag",

if (!flagsNode || (typeof flags === "string" && !flags.includes("u"))) {
if (!flagsNode || (typeof flags === "string" && !flags.includes("u") && !flags.includes("v"))) {
context.report({

@@ -93,0 +93,0 @@ messageId: "requireUFlag",

@@ -11,3 +11,3 @@ /**

const REGEXPP_LATEST_ECMA_VERSION = 2022;
const REGEXPP_LATEST_ECMA_VERSION = 2024;

@@ -32,3 +32,3 @@ /**

try {
validator.validatePattern(pattern, void 0, void 0, /* uFlag = */ true);
validator.validatePattern(pattern, void 0, void 0, { unicode: /* uFlag = */ true });
} catch {

@@ -35,0 +35,0 @@ return false;

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

@@ -64,9 +64,9 @@ "description": "An AST-based pattern checker for JavaScript.",

"@eslint-community/eslint-utils": "^4.2.0",
"@eslint-community/regexpp": "^4.4.0",
"@eslint/eslintrc": "^2.1.0",
"@eslint/js": "8.44.0",
"@eslint-community/regexpp": "^4.6.1",
"@eslint/eslintrc": "^2.1.1",
"@eslint/js": "^8.46.0",
"@humanwhocodes/config-array": "^0.11.10",
"@humanwhocodes/module-importer": "^1.0.1",
"@nodelib/fs.walk": "^1.2.8",
"ajv": "^6.10.0",
"ajv": "^6.12.4",
"chalk": "^4.0.0",

@@ -77,5 +77,5 @@ "cross-spawn": "^7.0.2",

"escape-string-regexp": "^4.0.0",
"eslint-scope": "^7.2.0",
"eslint-visitor-keys": "^3.4.1",
"espree": "^9.6.0",
"eslint-scope": "^7.2.2",
"eslint-visitor-keys": "^3.4.2",
"espree": "^9.6.1",
"esquery": "^1.4.2",

@@ -82,0 +82,0 @@ "esutils": "^2.0.2",

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

<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://iboysoft.com/"><img src="https://images.opencollective.com/iboysoft-software/7f9d60e/avatar.png" alt="iBoysoft" height="32"></a> <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>
<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://iboysoft.com/"><img src="https://images.opencollective.com/iboysoft-software/7f9d60e/avatar.png" alt="iBoysoft" height="32"></a> <a href="https://www.bairesdev.com/sponsoring-open-source-projects/"><img src="https://images.opencollective.com/bairesdev/48bb773/logo.png" alt="BairesDev" height="32"></a> <a href="https://github.com/about"><img src="https://avatars.githubusercontent.com/u/9919?v=4" alt="GitHub" 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>
<!--sponsorsend-->

@@ -290,0 +290,0 @@

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