Socket
Socket
Sign inDemoInstall

eslint-plugin-unicorn

Package Overview
Dependencies
Maintainers
2
Versions
105
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

eslint-plugin-unicorn - npm Package Compare versions

Comparing version 48.0.1 to 49.0.0

rules/utils/get-ancestor.js

43

package.json
{
"name": "eslint-plugin-unicorn",
"version": "48.0.1",
"version": "49.0.0",
"description": "More than 100 powerful ESLint rules",

@@ -29,2 +29,3 @@ "license": "MIT",

"run-rules-on-codebase": "node ./test/run-rules-on-codebase/lint.mjs",
"bundle-lodash": "echo \"export {defaultsDeep, camelCase, kebabCase, snakeCase, upperFirst, lowerFirst} from 'lodash-es';\" | npx esbuild --bundle --outfile=rules/utils/lodash.js --format=cjs",
"smoke": "eslint-remote-tester --config ./test/smoke/eslint-remote-tester.config.js",

@@ -50,3 +51,3 @@ "test": "npm-run-all --continue-on-error lint test:*",

"dependencies": {
"@babel/helper-validator-identifier": "^7.22.5",
"@babel/helper-validator-identifier": "^7.22.20",
"@eslint-community/eslint-utils": "^4.4.0",

@@ -59,3 +60,2 @@ "ci-info": "^3.8.0",

"jsesc": "^3.0.2",
"lodash": "^4.17.21",
"pluralize": "^8.0.0",

@@ -69,33 +69,33 @@ "read-pkg-up": "^7.0.1",

"devDependencies": {
"@babel/code-frame": "^7.22.5",
"@babel/core": "^7.22.8",
"@babel/eslint-parser": "^7.22.7",
"@babel/code-frame": "^7.22.13",
"@babel/core": "^7.23.2",
"@babel/eslint-parser": "^7.22.15",
"@lubien/fixture-beta-package": "^1.0.0-beta.1",
"@typescript-eslint/parser": "^6.2.0",
"@typescript-eslint/parser": "^6.9.0",
"ava": "^3.15.0",
"c8": "^8.0.0",
"c8": "^8.0.1",
"chalk": "^5.3.0",
"enquirer": "^2.3.6",
"eslint": "^8.44.0",
"enquirer": "^2.4.1",
"eslint": "^8.52.0",
"eslint-ava-rule-tester": "^4.0.0",
"eslint-doc-generator": "^1.4.3",
"eslint-plugin-eslint-plugin": "^5.1.0",
"eslint-doc-generator": "^1.5.2",
"eslint-plugin-eslint-plugin": "^5.1.1",
"eslint-plugin-internal-rules": "file:./scripts/internal-rules/",
"eslint-remote-tester": "^3.0.0",
"eslint-remote-tester": "^3.0.1",
"eslint-remote-tester-repositories": "^1.0.1",
"execa": "^7.1.1",
"execa": "^8.0.1",
"listr": "^0.14.3",
"lodash-es": "^4.17.21",
"markdownlint-cli": "^0.35.0",
"markdownlint-cli": "^0.37.0",
"mem": "^9.0.2",
"npm-package-json-lint": "^7.0.0",
"npm-run-all": "^4.1.5",
"npm-run-all2": "^6.1.1",
"outdent": "^0.8.0",
"typescript": "^5.1.6",
"vue-eslint-parser": "^9.3.1",
"xo": "^0.54.2",
"yaml": "^2.3.1"
"typescript": "^5.2.2",
"vue-eslint-parser": "^9.3.2",
"xo": "^0.56.0",
"yaml": "^2.3.3"
},
"peerDependencies": {
"eslint": ">=8.44.0"
"eslint": ">=8.52.0"
},

@@ -121,2 +121,3 @@ "ava": {

"eslint-remote-tester-results",
"rules/utils/lodash.js",
"test/integration/{fixtures,fixtures-local}/**"

@@ -123,0 +124,0 @@ ],

'use strict';
const {pick} = require('lodash');
const isMemberExpression = require('./is-member-expression.js');

@@ -49,7 +48,12 @@ const {isCallExpression} = require('./call-or-new-expression.js');

isCallExpression(node, {
...pick(options, ['argumentsLength', 'minimumArguments', 'maximumArguments', 'allowSpreadElement']),
argumentsLength: options.argumentsLength,
minimumArguments: options.minimumArguments,
maximumArguments: options.maximumArguments,
allowSpreadElement: options.allowSpreadElement,
optional: optionalCall,
})
&& isMemberExpression(node.callee, {
...pick(options, ['object', 'objects', 'computed']),
object: options.object,
objects: options.objects,
computed: options.computed,
property: method,

@@ -56,0 +60,0 @@ properties: methods,

@@ -118,2 +118,12 @@ 'use strict';

// `type Foo = { [Identifier: string]: string }`
case 'TSIndexSignature': {
return parent.parameters.includes(node);
}
// `type Identifier = Foo`
case 'TSTypeAliasDeclaration': {
return parent.id === node;
}
case 'TSPropertySignature': {

@@ -120,0 +130,0 @@ return parent.key === node;

@@ -31,6 +31,5 @@ 'use strict';

const {raw: original, regex} = node;
// Regular Expressions with `u` flag are not well handled by `regexp-tree`
// Regular Expressions with `u` and `v` flag are not well handled by `regexp-tree`
// https://github.com/DmitrySoshnikov/regexp-tree/issues/162
if (regex.flags.includes('u')) {
if (regex.flags.includes('u') || regex.flags.includes('v')) {
return;

@@ -37,0 +36,0 @@ }

@@ -65,3 +65,3 @@ 'use strict';

isNameAllowed(originalName)
|| isNameAllowed(originalName.replace(/_+$/g, ''))
|| isNameAllowed(originalName.replaceAll(/_+$/g, ''))
) {

@@ -68,0 +68,0 @@ return;

@@ -92,3 +92,3 @@ 'use strict';

);
const lastProperty = objectPattern.properties[objectPattern.properties.length - 1];
const lastProperty = objectPattern.properties.at(-1);

@@ -138,3 +138,3 @@ const hasRest = lastProperty && lastProperty.type === 'RestElement';

const {properties} = objectPattern;
const lastProperty = properties[properties.length - 1];
const lastProperty = properties.at(-1);

@@ -141,0 +141,0 @@ yield fixer.replaceText(node, newMember);

'use strict';
const {upperFirst} = require('lodash');
const {upperFirst} = require('./utils/lodash.js');

@@ -4,0 +4,0 @@ const MESSAGE_ID_INVALID_EXPORT = 'invalidExport';

'use strict';
const path = require('node:path');
const readPkgUp = require('read-pkg-up');

@@ -50,90 +51,67 @@ const semver = require('semver');

// We don't need to normalize the package.json data, because we are only using 2 properties and those 2 properties
// aren't validated by the normalization. But when this plugin is used in a monorepo, the name field in the
// package.json is invalid and would make this plugin throw an error. See also #1871
const packageResult = readPkgUp.sync({normalize: false});
const hasPackage = Boolean(packageResult);
const packageJson = hasPackage ? packageResult.packageJson : {};
const packageDependencies = {
...packageJson.dependencies,
...packageJson.devDependencies,
};
const DEPENDENCY_INCLUSION_RE = /^[+-]\s*@?\S+\/?\S+/;
const VERSION_COMPARISON_RE = /^(?<name>@?\S\/?\S+)@(?<condition>>|>=)(?<version>\d+(?:\.\d+){0,2}(?:-[\da-z-]+(?:\.[\da-z-]+)*)?(?:\+[\da-z-]+(?:\.[\da-z-]+)*)?)/i;
const PKG_VERSION_RE = /^(?<condition>>|>=)(?<version>\d+(?:\.\d+){0,2}(?:-[\da-z-]+(?:\.[\da-z-]+)*)?(?:\+[\da-z-]+(?:\.[\da-z-]+)*)?)\s*$/;
const ISO8601_DATE = /\d{4}-\d{2}-\d{2}/;
function parseTodoWithArguments(string, {terms}) {
const lowerCaseString = string.toLowerCase();
const lowerCaseTerms = terms.map(term => term.toLowerCase());
const hasTerm = lowerCaseTerms.some(term => lowerCaseString.includes(term));
if (!hasTerm) {
return false;
/** @param {string} dirname */
function getPackageHelpers(dirname) {
// We don't need to normalize the package.json data, because we are only using 2 properties and those 2 properties
// aren't validated by the normalization. But when this plugin is used in a monorepo, the name field in the
// package.json can be invalid and would make this plugin throw an error. See also #1871
/** @type {readPkgUp.ReadResult | undefined} */
let packageResult;
try {
packageResult = readPkgUp.sync({normalize: false, cwd: dirname});
} catch {
// This can happen if package.json files have comments in them etc.
packageResult = undefined;
}
const TODO_ARGUMENT_RE = /\[(?<rawArguments>[^}]+)]/i;
const result = TODO_ARGUMENT_RE.exec(string);
const hasPackage = Boolean(packageResult);
const packageJson = packageResult ? packageResult.packageJson : {};
if (!result) {
return false;
}
const packageDependencies = {
...packageJson.dependencies,
...packageJson.devDependencies,
};
const {rawArguments} = result.groups;
function parseTodoWithArguments(string, {terms}) {
const lowerCaseString = string.toLowerCase();
const lowerCaseTerms = terms.map(term => term.toLowerCase());
const hasTerm = lowerCaseTerms.some(term => lowerCaseString.includes(term));
const parsedArguments = rawArguments
.split(',')
.map(argument => parseArgument(argument.trim()));
if (!hasTerm) {
return false;
}
return createArgumentGroup(parsedArguments);
}
const TODO_ARGUMENT_RE = /\[(?<rawArguments>[^}]+)]/i;
const result = TODO_ARGUMENT_RE.exec(string);
function createArgumentGroup(arguments_) {
const groups = {};
for (const {value, type} of arguments_) {
groups[type] = groups[type] || [];
groups[type].push(value);
}
if (!result) {
return false;
}
return groups;
}
const {rawArguments} = result.groups;
function parseArgument(argumentString) {
if (ISO8601_DATE.test(argumentString)) {
return {
type: 'dates',
value: argumentString,
};
}
const parsedArguments = rawArguments
.split(',')
.map(argument => parseArgument(argument.trim()));
if (hasPackage && DEPENDENCY_INCLUSION_RE.test(argumentString)) {
const condition = argumentString[0] === '+' ? 'in' : 'out';
const name = argumentString.slice(1).trim();
return {
type: 'dependencies',
value: {
name,
condition,
},
};
return createArgumentGroup(parsedArguments);
}
if (hasPackage && VERSION_COMPARISON_RE.test(argumentString)) {
const {groups} = VERSION_COMPARISON_RE.exec(argumentString);
const name = groups.name.trim();
const condition = groups.condition.trim();
const version = groups.version.trim();
function parseArgument(argumentString, dirname) {
const {hasPackage} = getPackageHelpers(dirname);
if (ISO8601_DATE.test(argumentString)) {
return {
type: 'dates',
value: argumentString,
};
}
const hasEngineKeyword = name.indexOf('engine:') === 0;
const isNodeEngine = hasEngineKeyword && name === 'engine:node';
if (hasPackage && DEPENDENCY_INCLUSION_RE.test(argumentString)) {
const condition = argumentString[0] === '+' ? 'in' : 'out';
const name = argumentString.slice(1).trim();
if (hasEngineKeyword && isNodeEngine) {
return {
type: 'engines',
type: 'dependencies',
value: {
name,
condition,
version,
},

@@ -143,52 +121,89 @@ };

if (!hasEngineKeyword) {
if (hasPackage && VERSION_COMPARISON_RE.test(argumentString)) {
const {groups} = VERSION_COMPARISON_RE.exec(argumentString);
const name = groups.name.trim();
const condition = groups.condition.trim();
const version = groups.version.trim();
const hasEngineKeyword = name.indexOf('engine:') === 0;
const isNodeEngine = hasEngineKeyword && name === 'engine:node';
if (hasEngineKeyword && isNodeEngine) {
return {
type: 'engines',
value: {
condition,
version,
},
};
}
if (!hasEngineKeyword) {
return {
type: 'dependencies',
value: {
name,
condition,
version,
},
};
}
}
if (hasPackage && PKG_VERSION_RE.test(argumentString)) {
const result = PKG_VERSION_RE.exec(argumentString);
const {condition, version} = result.groups;
return {
type: 'dependencies',
type: 'packageVersions',
value: {
name,
condition,
version,
condition: condition.trim(),
version: version.trim(),
},
};
}
}
if (hasPackage && PKG_VERSION_RE.test(argumentString)) {
const result = PKG_VERSION_RE.exec(argumentString);
const {condition, version} = result.groups;
// Currently being ignored as integration tests pointed
// some TODO comments have `[random data like this]`
return {
type: 'packageVersions',
value: {
condition: condition.trim(),
version: version.trim(),
},
type: 'unknowns',
value: argumentString,
};
}
// Currently being ignored as integration tests pointed
// some TODO comments have `[random data like this]`
return {
type: 'unknowns',
value: argumentString,
};
}
function parseTodoMessage(todoString) {
// @example "TODO [...]: message here"
// @example "TODO [...] message here"
const argumentsEnd = todoString.indexOf(']');
function parseTodoMessage(todoString) {
// @example "TODO [...]: message here"
// @example "TODO [...] message here"
const argumentsEnd = todoString.indexOf(']');
const afterArguments = todoString.slice(argumentsEnd + 1).trim();
const afterArguments = todoString.slice(argumentsEnd + 1).trim();
// Check if have to skip colon
// @example "TODO [...]: message here"
const dropColon = afterArguments[0] === ':';
if (dropColon) {
return afterArguments.slice(1).trim();
}
// Check if have to skip colon
// @example "TODO [...]: message here"
const dropColon = afterArguments[0] === ':';
if (dropColon) {
return afterArguments.slice(1).trim();
return afterArguments;
}
return afterArguments;
return {packageResult, hasPackage, packageJson, packageDependencies, parseArgument, parseTodoMessage, parseTodoWithArguments};
}
const DEPENDENCY_INCLUSION_RE = /^[+-]\s*@?\S+\/?\S+/;
const VERSION_COMPARISON_RE = /^(?<name>@?\S\/?\S+)@(?<condition>>|>=)(?<version>\d+(?:\.\d+){0,2}(?:-[\da-z-]+(?:\.[\da-z-]+)*)?(?:\+[\da-z-]+(?:\.[\da-z-]+)*)?)/i;
const PKG_VERSION_RE = /^(?<condition>>|>=)(?<version>\d+(?:\.\d+){0,2}(?:-[\da-z-]+(?:\.[\da-z-]+)*)?(?:\+[\da-z-]+(?:\.[\da-z-]+)*)?)\s*$/;
const ISO8601_DATE = /\d{4}-\d{2}-\d{2}/;
function createArgumentGroup(arguments_) {
const groups = {};
for (const {value, type} of arguments_) {
groups[type] = groups[type] || [];
groups[type].push(value);
}
return groups;
}
function reachedDate(past, now) {

@@ -268,2 +283,5 @@ return Date.parse(past) < Date.parse(now);

const dirname = path.dirname(context.filename);
const {packageJson, packageDependencies, parseArgument, parseTodoMessage, parseTodoWithArguments} = getPackageHelpers(dirname);
const {sourceCode} = context;

@@ -290,9 +308,14 @@ const comments = sourceCode.getAllComments();

// Since we have priority, we leave only the comments that we didn't use.
const fakeContext = {
...context,
sourceCode: {
...sourceCode,
getAllComments: () => options.allowWarningComments ? [] : unusedComments,
const fakeContext = new Proxy(context, {
get(target, property, receiver) {
if (property === 'sourceCode') {
return {
...sourceCode,
getAllComments: () => options.allowWarningComments ? [] : unusedComments,
};
}
return Reflect.get(target, property, receiver);
},
};
});
const rules = baseRule.create(fakeContext);

@@ -492,3 +515,3 @@

const withoutWhitespace = unknown.replace(/ /g, '');
const withoutWhitespace = unknown.replaceAll(' ', '');

@@ -495,0 +518,0 @@ if (parseArgument(withoutWhitespace).type !== 'unknowns') {

'use strict';
const path = require('node:path');
const {camelCase, kebabCase, snakeCase, upperFirst} = require('lodash');
const {camelCase, kebabCase, snakeCase, upperFirst} = require('./utils/lodash.js');
const cartesianProductSamples = require('./utils/cartesian-product-samples.js');

@@ -5,0 +5,0 @@

@@ -10,3 +10,3 @@ 'use strict';

const firstToken = parentheses[0] || node;
const lastToken = parentheses[parentheses.length - 1] || node;
const lastToken = parentheses.at(-1) || node;

@@ -13,0 +13,0 @@ let [start] = firstToken.range;

'use strict';
const {defaultsDeep} = require('lodash');
const {defaultsDeep} = require('./utils/lodash.js');
const {getStringIfConstant} = require('@eslint-community/eslint-utils');

@@ -4,0 +4,0 @@ const {isCallExpression} = require('./ast/index.js');

@@ -403,3 +403,3 @@ 'use strict';

context.on('ReturnStatement', node => {
const currentFunction = functionStack[functionStack.length - 1];
const currentFunction = functionStack.at(-1);
if (!currentFunction) {

@@ -406,0 +406,0 @@ return;

@@ -86,3 +86,3 @@ 'use strict';

const callbackLastToken = isParenthesized
? callbackParentheses[callbackParentheses.length - 1]
? callbackParentheses.at(-1)
: callback;

@@ -89,0 +89,0 @@ if (

@@ -14,3 +14,3 @@ 'use strict';

// Find exactly one trailing space, allow exactly one space
const hasTrailingSpace = value => value.length > 1 && value.charAt(value.length - 1) === ' ' && value.charAt(value.length - 2) !== ' ';
const hasTrailingSpace = value => value.length > 1 && value.at(-1) === ' ' && value.at(-2) !== ' ';

@@ -17,0 +17,0 @@ /** @param {import('eslint').Rule.RuleContext} context */

@@ -11,3 +11,3 @@ 'use strict';

function checkEscape(context, node, value) {
const fixedValue = value.replace(/(?<=(?:^|[^\\])(?:\\\\)*\\)x/g, 'u00');
const fixedValue = value.replaceAll(/(?<=(?:^|[^\\])(?:\\\\)*\\)x/g, 'u00');

@@ -14,0 +14,0 @@ if (value !== fixedValue) {

@@ -33,3 +33,3 @@ 'use strict';

case 'SequenceExpression': {
return notPromise(node.expressions[node.expressions.length - 1]);
return notPromise(node.expressions.at(-1));
}

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

@@ -28,3 +28,3 @@ 'use strict';

// We only check cases where the last case is the `default` case
if (defaultCase !== cases[cases.length - 1]) {
if (defaultCase !== cases.at(-1)) {
return;

@@ -31,0 +31,0 @@ }

@@ -239,3 +239,3 @@ 'use strict';

const firstUndefined = undefinedArguments[0];
const lastUndefined = undefinedArguments[undefinedArguments.length - 1];
const lastUndefined = undefinedArguments.at(-1);

@@ -242,0 +242,0 @@ return {

@@ -31,3 +31,3 @@ 'use strict';

const {before, dotAndFractions, after} = match.groups;
const fixedDotAndFractions = dotAndFractions.replace(/[.0_]+$/g, '');
const fixedDotAndFractions = dotAndFractions.replaceAll(/[.0_]+$/g, '');
const formatted = ((before + fixedDotAndFractions) || '0') + after;

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

@@ -114,3 +114,3 @@ 'use strict';

const strippedNumber = number.replace(/_/g, '');
const strippedNumber = number.replaceAll('_', '');
const {prefix, data} = numeric.getPrefix(strippedNumber);

@@ -117,0 +117,0 @@

@@ -75,3 +75,3 @@ 'use strict';

const isLastParameter = (parameters, parameter) => {
const lastParameter = parameters[parameters.length - 1];
const lastParameter = parameters.at(-1);

@@ -126,3 +126,3 @@ // See 'default-param-last' rule

const checkExpression = (node, left, right, assignment) => {
const currentFunction = functionStack[functionStack.length - 1];
const currentFunction = functionStack.at(-1);

@@ -129,0 +129,0 @@ if (!currentFunction || !isDefaultExpression(left, right)) {

@@ -15,3 +15,3 @@ 'use strict';

const dashToCamelCase = string => string.replace(/-[a-z]/g, s => s[1].toUpperCase());
const dashToCamelCase = string => string.replaceAll(/-[a-z]/g, s => s[1].toUpperCase());

@@ -18,0 +18,0 @@ function getFix(callExpression, context) {

'use strict';
const {findVariable} = require('@eslint-community/eslint-utils');
const {getAncestor} = require('./utils/index.js');
const {isStaticRequire, isStringLiteral, isMemberExpression} = require('./ast/index.js');

@@ -8,4 +11,71 @@ const MESSAGE_ID = 'prefer-event-target';

const packagesShouldBeIgnored = new Set([
'@angular/core',
'eventemitter3',
]);
const isConstVariableDeclarationId = node =>
node.parent.type === 'VariableDeclarator'
&& node.parent.id === node
&& node.parent.parent.type === 'VariableDeclaration'
&& node.parent.parent.kind === 'const'
&& node.parent.parent.declarations.includes(node.parent);
function isAwaitImportOrRequireFromIgnoredPackages(node) {
if (!node) {
return false;
}
let source;
if (isStaticRequire(node)) {
[source] = node.arguments;
} else if (node.type === 'AwaitExpression' && node.argument.type === 'ImportExpression') {
({source} = node.argument);
}
if (isStringLiteral(source) && packagesShouldBeIgnored.has(source.value)) {
return true;
}
return false;
}
function isFromIgnoredPackage(node) {
if (!node) {
return false;
}
const importDeclaration = getAncestor(node, 'ImportDeclaration');
if (packagesShouldBeIgnored.has(importDeclaration?.source.value)) {
return true;
}
// `const {EventEmitter} = ...`
if (
node.parent.type === 'Property'
&& node.parent.value === node
&& node.parent.key.type === 'Identifier'
&& node.parent.key.name === 'EventEmitter'
&& node.parent.parent.type === 'ObjectPattern'
&& node.parent.parent.properties.includes(node.parent)
&& isConstVariableDeclarationId(node.parent.parent)
&& isAwaitImportOrRequireFromIgnoredPackages(node.parent.parent.parent.init)
) {
return true;
}
// `const EventEmitter = (...).EventEmitter`
if (
isConstVariableDeclarationId(node)
&& isMemberExpression(node.parent.init, {property: 'EventEmitter', optional: false, computed: false})
&& isAwaitImportOrRequireFromIgnoredPackages(node.parent.init.object)
) {
return true;
}
return false;
}
/** @param {import('eslint').Rule.RuleContext} context */
const create = () => ({
const create = context => ({
Identifier(node) {

@@ -25,2 +95,8 @@ if (!(

const scope = context.sourceCode.getScope(node);
const variableNode = findVariable(scope, node)?.defs[0]?.name;
if (isFromIgnoredPackage(variableNode)) {
return;
}
return {

@@ -27,0 +103,0 @@ node,

@@ -151,3 +151,3 @@ 'use strict';

if (exportDeclaration) {
const lastSpecifier = exportDeclaration.specifiers[exportDeclaration.specifiers.length - 1];
const lastSpecifier = exportDeclaration.specifiers.at(-1);

@@ -154,0 +154,0 @@ // `export {} from 'foo';`

@@ -102,3 +102,3 @@ 'use strict';

const firstToken = parentheses[0] || initObject;
const lastToken = parentheses[parentheses.length - 1] || initObject;
const lastToken = parentheses.at(-1) || initObject;
const startToken = sourceCode.getTokenBefore(firstToken);

@@ -105,0 +105,0 @@ const [start] = startToken.range;

@@ -21,3 +21,3 @@ 'use strict';

const leftQuote = node.raw.charAt(0);
const rightQuote = node.raw.charAt(node.raw.length - 1);
const rightQuote = node.raw.at(-1);
return `${leftQuote}${value}${rightQuote}`;

@@ -24,0 +24,0 @@ };

@@ -80,2 +80,6 @@ 'use strict';

const isRegExpWithoutGlobalFlag = (node, scope) => {
if (isRegexLiteral(node)) {
return !node.regex.flags.includes('g');
}
const staticResult = getStaticValue(node, scope);

@@ -82,0 +86,0 @@

@@ -77,3 +77,3 @@ 'use strict';

.filter(({node, isArrayLiteral}) => (!isArrayLiteral || node.elements.length > 0));
const lastArgument = nonEmptyArguments[nonEmptyArguments.length - 1];
const lastArgument = nonEmptyArguments.at(-1);

@@ -80,0 +80,0 @@ let text = nonEmptyArguments

@@ -20,3 +20,3 @@ 'use strict';

const {pattern, flags} = node.regex;
if (flags.replace('u', '') !== 'g') {
if (flags.replace('u', '').replace('v', '') !== 'g') {
return;

@@ -29,3 +29,4 @@ }

tree = parseRegExp(pattern, flags, {
unicodePropertyEscape: true,
unicodePropertyEscape: flags.includes('u'),
unicodeSet: flags.includes('v'),
namedGroups: true,

@@ -32,0 +33,0 @@ lookbehind: true,

@@ -194,3 +194,3 @@ 'use strict';

const lastStatement = ifStatements[ifStatements.length - 1].statement;
const lastStatement = ifStatements.at(-1).statement;
if (lastStatement.alternate) {

@@ -197,0 +197,0 @@ const {alternate} = lastStatement;

'use strict';
const path = require('node:path');
const {defaultsDeep, upperFirst, lowerFirst} = require('lodash');
const {defaultsDeep, upperFirst, lowerFirst} = require('./utils/lodash.js');
const avoidCapture = require('./utils/avoid-capture.js');

@@ -5,0 +5,0 @@ const cartesianProductSamples = require('./utils/cartesian-product-samples.js');

@@ -82,3 +82,3 @@ 'use strict';

const dedented = stripIndent(joined);
const trimmed = dedented.replace(new RegExp(`^${eol}|${eol}[ \t]*$`, 'g'), '');
const trimmed = dedented.replaceAll(new RegExp(`^${eol}|${eol}[ \t]*$`, 'g'), '');

@@ -85,0 +85,0 @@ const fixed

'use strict';
module.exports = string => string.replace(
module.exports = string => string.replaceAll(
/(?<=(?:^|[^\\])(?:\\\\)*)(?<symbol>(?:`|\$(?={)))/g,
'\\$<symbol>',
);

@@ -51,3 +51,4 @@ 'use strict';

toLocation: require('./to-location.js'),
getAncestor: require('./get-ancestor.js'),
};

@@ -212,3 +212,3 @@ 'use strict';

case 'SequenceExpression': {
if (isNumber(node.expressions[node.expressions.length - 1], scope)) {
if (isNumber(node.expressions.at(-1), scope)) {
return true;

@@ -215,0 +215,0 @@ }

@@ -28,3 +28,3 @@ 'use strict';

return (
reference?.resolved
Boolean(reference?.resolved)
&& reference.resolved.defs.length > 0

@@ -31,0 +31,0 @@ );

@@ -51,3 +51,3 @@ 'use strict';

const [start] = (parentheses[0] || node).range;
const [, end] = (parentheses[parentheses.length - 1] || node).range;
const [, end] = (parentheses.at(-1) || node).range;
return [start, end];

@@ -54,0 +54,0 @@ }

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