Bump the npm group with 11 updates (#1892)

* Bump the npm group with 11 updates

Bumps the npm group with 11 updates:

| Package | From | To |
| --- | --- | --- |
| [@actions/artifact](https://github.com/actions/toolkit/tree/HEAD/packages/artifact) | `1.1.1` | `1.1.2` |
| [@actions/core](https://github.com/actions/toolkit/tree/HEAD/packages/core) | `1.10.0` | `1.10.1` |
| [uuid](https://github.com/uuidjs/uuid) | `9.0.0` | `9.0.1` |
| [@types/uuid](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/uuid) | `9.0.3` | `9.0.4` |
| [@types/adm-zip](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/adm-zip) | `0.5.0` | `0.5.1` |
| [@types/js-yaml](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/js-yaml) | `4.0.5` | `4.0.6` |
| [@types/semver](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/semver) | `7.5.1` | `7.5.2` |
| [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) | `6.5.0` | `6.7.2` |
| [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) | `6.6.0` | `6.7.2` |
| [eslint](https://github.com/eslint/eslint) | `8.48.0` | `8.49.0` |
| [sinon](https://github.com/sinonjs/sinon) | `15.2.0` | `16.0.0` |


Updates `@actions/artifact` from 1.1.1 to 1.1.2
- [Changelog](https://github.com/actions/toolkit/blob/main/packages/artifact/RELEASES.md)
- [Commits](https://github.com/actions/toolkit/commits/HEAD/packages/artifact)

Updates `@actions/core` from 1.10.0 to 1.10.1
- [Changelog](https://github.com/actions/toolkit/blob/main/packages/core/RELEASES.md)
- [Commits](https://github.com/actions/toolkit/commits/HEAD/packages/core)

Updates `uuid` from 9.0.0 to 9.0.1
- [Changelog](https://github.com/uuidjs/uuid/blob/main/CHANGELOG.md)
- [Commits](https://github.com/uuidjs/uuid/compare/v9.0.0...v9.0.1)

Updates `@types/uuid` from 9.0.3 to 9.0.4
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/uuid)

Updates `@types/adm-zip` from 0.5.0 to 0.5.1
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/adm-zip)

Updates `@types/js-yaml` from 4.0.5 to 4.0.6
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/js-yaml)

Updates `@types/semver` from 7.5.1 to 7.5.2
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/semver)

Updates `@typescript-eslint/eslint-plugin` from 6.5.0 to 6.7.2
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.7.2/packages/eslint-plugin)

Updates `@typescript-eslint/parser` from 6.6.0 to 6.7.2
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.7.2/packages/parser)

Updates `eslint` from 8.48.0 to 8.49.0
- [Release notes](https://github.com/eslint/eslint/releases)
- [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md)
- [Commits](https://github.com/eslint/eslint/compare/v8.48.0...v8.49.0)

Updates `sinon` from 15.2.0 to 16.0.0
- [Release notes](https://github.com/sinonjs/sinon/releases)
- [Changelog](https://github.com/sinonjs/sinon/blob/main/docs/changelog.md)
- [Commits](https://github.com/sinonjs/sinon/compare/v15.2.0...v16.0.0)

---
updated-dependencies:
- dependency-name: "@actions/artifact"
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: npm
- dependency-name: "@actions/core"
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: npm
- dependency-name: uuid
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: npm
- dependency-name: "@types/uuid"
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: npm
- dependency-name: "@types/adm-zip"
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm
- dependency-name: "@types/js-yaml"
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm
- dependency-name: "@types/semver"
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: npm
- dependency-name: "@typescript-eslint/parser"
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: npm
- dependency-name: eslint
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: npm
- dependency-name: sinon
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: npm
...

Signed-off-by: dependabot[bot] <support@github.com>

* Update checked-in dependencies

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
This commit is contained in:
dependabot[bot] 2023-09-18 20:01:16 +00:00 committed by GitHub
parent f3a128e0fe
commit dd1128f4f1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
1127 changed files with 1819 additions and 19938 deletions

4
node_modules/eslint/README.md generated vendored
View file

@ -288,8 +288,8 @@ The following companies, organizations, and individuals support ESLint's ongoing
<h3>Platinum Sponsors</h3>
<p><a href="#"><img src="https://images.opencollective.com/2021-frameworks-fund/logo.png" alt="Chrome Frameworks Fund" height="undefined"></a> <a href="https://automattic.com"><img src="https://images.opencollective.com/automattic/d0ef3e1/logo.png" alt="Automattic" height="undefined"></a></p><h3>Gold Sponsors</h3>
<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://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://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>
<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://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://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" 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://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-->
## Technology Sponsors

View file

@ -9,7 +9,8 @@
// Requirements
//-----------------------------------------------------------------------------
const ajv = require("../shared/ajv")();
const ajvImport = require("../shared/ajv");
const ajv = ajvImport();
const {
parseRuleId,
getRuleFromConfig,

View file

@ -192,15 +192,18 @@ function forwardCurrentToHead(analyzer, node) {
headSegment = headSegments[i];
if (currentSegment !== headSegment && currentSegment) {
debug.dump(`onCodePathSegmentEnd ${currentSegment.id}`);
if (currentSegment.reachable) {
analyzer.emitter.emit(
"onCodePathSegmentEnd",
currentSegment,
node
);
}
const eventName = currentSegment.reachable
? "onCodePathSegmentEnd"
: "onUnreachableCodePathSegmentEnd";
debug.dump(`${eventName} ${currentSegment.id}`);
analyzer.emitter.emit(
eventName,
currentSegment,
node
);
}
}
@ -213,16 +216,19 @@ function forwardCurrentToHead(analyzer, node) {
headSegment = headSegments[i];
if (currentSegment !== headSegment && headSegment) {
debug.dump(`onCodePathSegmentStart ${headSegment.id}`);
const eventName = headSegment.reachable
? "onCodePathSegmentStart"
: "onUnreachableCodePathSegmentStart";
debug.dump(`${eventName} ${headSegment.id}`);
CodePathSegment.markUsed(headSegment);
if (headSegment.reachable) {
analyzer.emitter.emit(
"onCodePathSegmentStart",
headSegment,
node
);
}
analyzer.emitter.emit(
eventName,
headSegment,
node
);
}
}
@ -241,15 +247,17 @@ function leaveFromCurrentSegment(analyzer, node) {
for (let i = 0; i < currentSegments.length; ++i) {
const currentSegment = currentSegments[i];
const eventName = currentSegment.reachable
? "onCodePathSegmentEnd"
: "onUnreachableCodePathSegmentEnd";
debug.dump(`onCodePathSegmentEnd ${currentSegment.id}`);
if (currentSegment.reachable) {
analyzer.emitter.emit(
"onCodePathSegmentEnd",
currentSegment,
node
);
}
debug.dump(`${eventName} ${currentSegment.id}`);
analyzer.emitter.emit(
eventName,
currentSegment,
node
);
}
state.currentSegments = [];

View file

@ -117,6 +117,7 @@ class CodePath {
/**
* Current code path segments.
* @type {CodePathSegment[]}
* @deprecated
*/
get currentSegments() {
return this.internal.currentSegments;

View file

@ -898,6 +898,7 @@ const DEPRECATED_SOURCECODE_PASSTHROUGHS = {
getTokensBetween: "getTokensBetween"
};
const BASE_TRAVERSAL_CONTEXT = Object.freeze(
Object.keys(DEPRECATED_SOURCECODE_PASSTHROUGHS).reduce(
(contextInfo, methodName) =>

View file

@ -16,7 +16,9 @@ const
equal = require("fast-deep-equal"),
Traverser = require("../shared/traverser"),
{ getRuleOptionsSchema } = require("../config/flat-config-helpers"),
{ Linter, SourceCodeFixer, interpolate } = require("../linter");
{ Linter, SourceCodeFixer, interpolate } = require("../linter"),
CodePath = require("../linter/code-path-analysis/code-path");
const { FlatConfigArray } = require("../config/flat-config-array");
const { defaultConfig } = require("../config/default-config");
@ -274,6 +276,21 @@ function getCommentsDeprecation() {
);
}
/**
* Emit a deprecation warning if rule uses CodePath#currentSegments.
* @param {string} ruleName Name of the rule.
* @returns {void}
*/
function emitCodePathCurrentSegmentsWarning(ruleName) {
if (!emitCodePathCurrentSegmentsWarning[`warned-${ruleName}`]) {
emitCodePathCurrentSegmentsWarning[`warned-${ruleName}`] = true;
process.emitWarning(
`"${ruleName}" rule uses CodePath#currentSegments and will stop working in ESLint v9. Please read the documentation for how to update your code: https://eslint.org/docs/latest/extend/code-path-analysis#usage-examples`,
"DeprecationWarning"
);
}
}
//------------------------------------------------------------------------------
// Public Interface
//------------------------------------------------------------------------------
@ -664,6 +681,7 @@ class FlatRuleTester {
// Verify the code.
const { getComments } = SourceCode.prototype;
const originalCurrentSegments = Object.getOwnPropertyDescriptor(CodePath.prototype, "currentSegments");
let messages;
// check for validation errors
@ -677,11 +695,20 @@ class FlatRuleTester {
try {
SourceCode.prototype.getComments = getCommentsDeprecation;
Object.defineProperty(CodePath.prototype, "currentSegments", {
get() {
emitCodePathCurrentSegmentsWarning(ruleName);
return originalCurrentSegments.get.call(this);
}
});
messages = linter.verify(code, configs, filename);
} finally {
SourceCode.prototype.getComments = getComments;
Object.defineProperty(CodePath.prototype, "currentSegments", originalCurrentSegments);
}
const fatalErrorMessage = messages.find(m => m.fatal);
assert(!fatalErrorMessage, `A fatal parsing error occurred: ${fatalErrorMessage && fatalErrorMessage.message}`);

View file

@ -48,7 +48,8 @@ const
equal = require("fast-deep-equal"),
Traverser = require("../../lib/shared/traverser"),
{ getRuleOptionsSchema, validate } = require("../shared/config-validator"),
{ Linter, SourceCodeFixer, interpolate } = require("../linter");
{ Linter, SourceCodeFixer, interpolate } = require("../linter"),
CodePath = require("../linter/code-path-analysis/code-path");
const ajv = require("../shared/ajv")({ strictDefaults: true });
@ -164,6 +165,30 @@ const friendlySuggestionObjectParameterList = `[${[...suggestionObjectParameters
const hasOwnProperty = Function.call.bind(Object.hasOwnProperty);
const DEPRECATED_SOURCECODE_PASSTHROUGHS = {
getSource: "getText",
getSourceLines: "getLines",
getAllComments: "getAllComments",
getNodeByRangeIndex: "getNodeByRangeIndex",
// getComments: "getComments", -- already handled by a separate error
getCommentsBefore: "getCommentsBefore",
getCommentsAfter: "getCommentsAfter",
getCommentsInside: "getCommentsInside",
getJSDocComment: "getJSDocComment",
getFirstToken: "getFirstToken",
getFirstTokens: "getFirstTokens",
getLastToken: "getLastToken",
getLastTokens: "getLastTokens",
getTokenAfter: "getTokenAfter",
getTokenBefore: "getTokenBefore",
getTokenByRangeStart: "getTokenByRangeStart",
getTokens: "getTokens",
getTokensAfter: "getTokensAfter",
getTokensBefore: "getTokensBefore",
getTokensBetween: "getTokensBetween"
};
/**
* Clones a given value deeply.
* Note: This ignores `parent` property.
@ -335,6 +360,37 @@ function emitMissingSchemaWarning(ruleName) {
}
}
/**
* Emit a deprecation warning if a rule uses a deprecated `context` method.
* @param {string} ruleName Name of the rule.
* @param {string} methodName The name of the method on `context` that was used.
* @returns {void}
*/
function emitDeprecatedContextMethodWarning(ruleName, methodName) {
if (!emitDeprecatedContextMethodWarning[`warned-${ruleName}-${methodName}`]) {
emitDeprecatedContextMethodWarning[`warned-${ruleName}-${methodName}`] = true;
process.emitWarning(
`"${ruleName}" rule is using \`context.${methodName}()\`, which is deprecated and will be removed in ESLint v9. Please use \`sourceCode.${DEPRECATED_SOURCECODE_PASSTHROUGHS[methodName]}()\` instead.`,
"DeprecationWarning"
);
}
}
/**
* Emit a deprecation warning if rule uses CodePath#currentSegments.
* @param {string} ruleName Name of the rule.
* @returns {void}
*/
function emitCodePathCurrentSegmentsWarning(ruleName) {
if (!emitCodePathCurrentSegmentsWarning[`warned-${ruleName}`]) {
emitCodePathCurrentSegmentsWarning[`warned-${ruleName}`] = true;
process.emitWarning(
`"${ruleName}" rule uses CodePath#currentSegments and will stop working in ESLint v9. Please read the documentation for how to update your code: https://eslint.org/docs/latest/extend/code-path-analysis#usage-examples`,
"DeprecationWarning"
);
}
}
//------------------------------------------------------------------------------
// Public Interface
//------------------------------------------------------------------------------
@ -566,7 +622,27 @@ class RuleTester {
freezeDeeply(context.settings);
freezeDeeply(context.parserOptions);
return (typeof rule === "function" ? rule : rule.create)(context);
const newContext = Object.freeze(
Object.create(
context,
Object.fromEntries(Object.keys(DEPRECATED_SOURCECODE_PASSTHROUGHS).map(methodName => [
methodName,
{
value(...args) {
// emit deprecation warning
emitDeprecatedContextMethodWarning(ruleName, methodName);
// call the original method
return context[methodName].call(this, ...args);
},
enumerable: true
}
]))
)
);
return (typeof rule === "function" ? rule : rule.create)(newContext);
}
}));
@ -686,13 +762,22 @@ class RuleTester {
// Verify the code.
const { getComments } = SourceCode.prototype;
const originalCurrentSegments = Object.getOwnPropertyDescriptor(CodePath.prototype, "currentSegments");
let messages;
try {
SourceCode.prototype.getComments = getCommentsDeprecation;
Object.defineProperty(CodePath.prototype, "currentSegments", {
get() {
emitCodePathCurrentSegmentsWarning(ruleName);
return originalCurrentSegments.get.call(this);
}
});
messages = linter.verify(code, config, filename);
} finally {
SourceCode.prototype.getComments = getComments;
Object.defineProperty(CodePath.prototype, "currentSegments", originalCurrentSegments);
}
const fatalErrorMessage = messages.find(m => m.fatal);

View file

@ -18,15 +18,6 @@ const astUtils = require("./utils/ast-utils");
const TARGET_NODE_TYPE = /^(?:Arrow)?FunctionExpression$/u;
const TARGET_METHODS = /^(?:every|filter|find(?:Last)?(?:Index)?|flatMap|forEach|map|reduce(?:Right)?|some|sort|toSorted)$/u;
/**
* Checks a given code path segment is reachable.
* @param {CodePathSegment} segment A segment to check.
* @returns {boolean} `true` if the segment is reachable.
*/
function isReachable(segment) {
return segment.reachable;
}
/**
* Checks a given node is a member access which has the specified name's
* property.
@ -38,6 +29,22 @@ function isTargetMethod(node) {
return astUtils.isSpecificMemberAccess(node, null, TARGET_METHODS);
}
/**
* Checks all segments in a set and returns true if any are reachable.
* @param {Set<CodePathSegment>} segments The segments to check.
* @returns {boolean} True if any segment is reachable; false otherwise.
*/
function isAnySegmentReachable(segments) {
for (const segment of segments) {
if (segment.reachable) {
return true;
}
}
return false;
}
/**
* Returns a human-legible description of an array method
* @param {string} arrayMethodName A method name to fully qualify
@ -205,7 +212,7 @@ module.exports = {
messageId = "expectedNoReturnValue";
}
} else {
if (node.body.type === "BlockStatement" && funcInfo.codePath.currentSegments.some(isReachable)) {
if (node.body.type === "BlockStatement" && isAnySegmentReachable(funcInfo.currentSegments)) {
messageId = funcInfo.hasReturn ? "expectedAtEnd" : "expectedInside";
}
}
@ -242,7 +249,8 @@ module.exports = {
methodName &&
!node.async &&
!node.generator,
node
node,
currentSegments: new Set()
};
},
@ -251,6 +259,23 @@ module.exports = {
funcInfo = funcInfo.upper;
},
onUnreachableCodePathSegmentStart(segment) {
funcInfo.currentSegments.add(segment);
},
onUnreachableCodePathSegmentEnd(segment) {
funcInfo.currentSegments.delete(segment);
},
onCodePathSegmentStart(segment) {
funcInfo.currentSegments.add(segment);
},
onCodePathSegmentEnd(segment) {
funcInfo.currentSegments.delete(segment);
},
// Checks the return statement is valid.
ReturnStatement(node) {

View file

@ -16,12 +16,19 @@ const { upperCaseFirst } = require("../shared/string-utils");
//------------------------------------------------------------------------------
/**
* Checks whether or not a given code path segment is unreachable.
* @param {CodePathSegment} segment A CodePathSegment to check.
* @returns {boolean} `true` if the segment is unreachable.
* Checks all segments in a set and returns true if all are unreachable.
* @param {Set<CodePathSegment>} segments The segments to check.
* @returns {boolean} True if all segments are unreachable; false otherwise.
*/
function isUnreachable(segment) {
return !segment.reachable;
function areAllSegmentsUnreachable(segments) {
for (const segment of segments) {
if (segment.reachable) {
return false;
}
}
return true;
}
/**
@ -88,7 +95,7 @@ module.exports = {
* When unreachable, all paths are returned or thrown.
*/
if (!funcInfo.hasReturnValue ||
funcInfo.codePath.currentSegments.every(isUnreachable) ||
areAllSegmentsUnreachable(funcInfo.currentSegments) ||
astUtils.isES5Constructor(node) ||
isClassConstructor(node)
) {
@ -141,13 +148,31 @@ module.exports = {
hasReturn: false,
hasReturnValue: false,
messageId: "",
node
node,
currentSegments: new Set()
};
},
onCodePathEnd() {
funcInfo = funcInfo.upper;
},
onUnreachableCodePathSegmentStart(segment) {
funcInfo.currentSegments.add(segment);
},
onUnreachableCodePathSegmentEnd(segment) {
funcInfo.currentSegments.delete(segment);
},
onCodePathSegmentStart(segment) {
funcInfo.currentSegments.add(segment);
},
onCodePathSegmentEnd(segment) {
funcInfo.currentSegments.delete(segment);
},
// Reports a given return statement if it's inconsistent.
ReturnStatement(node) {
const argument = node.argument;

View file

@ -10,12 +10,19 @@
//------------------------------------------------------------------------------
/**
* Checks whether a given code path segment is reachable or not.
* @param {CodePathSegment} segment A code path segment to check.
* @returns {boolean} `true` if the segment is reachable.
* Checks all segments in a set and returns true if any are reachable.
* @param {Set<CodePathSegment>} segments The segments to check.
* @returns {boolean} True if any segment is reachable; false otherwise.
*/
function isReachable(segment) {
return segment.reachable;
function isAnySegmentReachable(segments) {
for (const segment of segments) {
if (segment.reachable) {
return true;
}
}
return false;
}
/**
@ -210,7 +217,8 @@ module.exports = {
isConstructor: true,
hasExtends: Boolean(superClass),
superIsConstructor: isPossibleConstructor(superClass),
codePath
codePath,
currentSegments: new Set()
};
} else {
funcInfo = {
@ -218,7 +226,8 @@ module.exports = {
isConstructor: false,
hasExtends: false,
superIsConstructor: false,
codePath
codePath,
currentSegments: new Set()
};
}
},
@ -261,6 +270,9 @@ module.exports = {
* @returns {void}
*/
onCodePathSegmentStart(segment) {
funcInfo.currentSegments.add(segment);
if (!(funcInfo && funcInfo.isConstructor && funcInfo.hasExtends)) {
return;
}
@ -281,6 +293,19 @@ module.exports = {
}
},
onUnreachableCodePathSegmentStart(segment) {
funcInfo.currentSegments.add(segment);
},
onUnreachableCodePathSegmentEnd(segment) {
funcInfo.currentSegments.delete(segment);
},
onCodePathSegmentEnd(segment) {
funcInfo.currentSegments.delete(segment);
},
/**
* Update information of the code path segment when a code path was
* looped.
@ -344,12 +369,11 @@ module.exports = {
// Reports if needed.
if (funcInfo.hasExtends) {
const segments = funcInfo.codePath.currentSegments;
const segments = funcInfo.currentSegments;
let duplicate = false;
let info = null;
for (let i = 0; i < segments.length; ++i) {
const segment = segments[i];
for (const segment of segments) {
if (segment.reachable) {
info = segInfoMap[segment.id];
@ -374,7 +398,7 @@ module.exports = {
info.validNodes.push(node);
}
}
} else if (funcInfo.codePath.currentSegments.some(isReachable)) {
} else if (isAnySegmentReachable(funcInfo.currentSegments)) {
context.report({
messageId: "unexpected",
node
@ -398,10 +422,9 @@ module.exports = {
}
// Returning argument is a substitute of 'super()'.
const segments = funcInfo.codePath.currentSegments;
const segments = funcInfo.currentSegments;
for (let i = 0; i < segments.length; ++i) {
const segment = segments[i];
for (const segment of segments) {
if (segment.reachable) {
const info = segInfoMap[segment.id];

View file

@ -14,15 +14,23 @@ const astUtils = require("./utils/ast-utils");
//------------------------------------------------------------------------------
// Helpers
//------------------------------------------------------------------------------
const TARGET_NODE_TYPE = /^(?:Arrow)?FunctionExpression$/u;
/**
* Checks a given code path segment is reachable.
* @param {CodePathSegment} segment A segment to check.
* @returns {boolean} `true` if the segment is reachable.
* Checks all segments in a set and returns true if any are reachable.
* @param {Set<CodePathSegment>} segments The segments to check.
* @returns {boolean} True if any segment is reachable; false otherwise.
*/
function isReachable(segment) {
return segment.reachable;
function isAnySegmentReachable(segments) {
for (const segment of segments) {
if (segment.reachable) {
return true;
}
}
return false;
}
//------------------------------------------------------------------------------
@ -71,7 +79,8 @@ module.exports = {
codePath: null,
hasReturn: false,
shouldCheck: false,
node: null
node: null,
currentSegments: []
};
/**
@ -85,7 +94,7 @@ module.exports = {
*/
function checkLastSegment(node) {
if (funcInfo.shouldCheck &&
funcInfo.codePath.currentSegments.some(isReachable)
isAnySegmentReachable(funcInfo.currentSegments)
) {
context.report({
node,
@ -144,7 +153,8 @@ module.exports = {
codePath,
hasReturn: false,
shouldCheck: isGetter(node),
node
node,
currentSegments: new Set()
};
},
@ -152,6 +162,21 @@ module.exports = {
onCodePathEnd() {
funcInfo = funcInfo.upper;
},
onUnreachableCodePathSegmentStart(segment) {
funcInfo.currentSegments.add(segment);
},
onUnreachableCodePathSegmentEnd(segment) {
funcInfo.currentSegments.delete(segment);
},
onCodePathSegmentStart(segment) {
funcInfo.currentSegments.add(segment);
},
onCodePathSegmentEnd(segment) {
funcInfo.currentSegments.delete(segment);
},
// Checks the return statement is valid.
ReturnStatement(node) {

View file

@ -10,6 +10,21 @@
const astUtils = require("./utils/ast-utils");
//------------------------------------------------------------------------------
// Helpers
//------------------------------------------------------------------------------
/**
* Types of class members.
* Those have `test` method to check it matches to the given class member.
* @private
*/
const ClassMemberTypes = {
"*": { test: () => true },
field: { test: node => node.type === "PropertyDefinition" },
method: { test: node => node.type === "MethodDefinition" }
};
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
@ -29,7 +44,32 @@ module.exports = {
schema: [
{
enum: ["always", "never"]
anyOf: [
{
type: "object",
properties: {
enforce: {
type: "array",
items: {
type: "object",
properties: {
blankLine: { enum: ["always", "never"] },
prev: { enum: ["method", "field", "*"] },
next: { enum: ["method", "field", "*"] }
},
additionalProperties: false,
required: ["blankLine", "prev", "next"]
},
minItems: 1
}
},
additionalProperties: false,
required: ["enforce"]
},
{
enum: ["always", "never"]
}
]
},
{
type: "object",
@ -55,6 +95,7 @@ module.exports = {
options[0] = context.options[0] || "always";
options[1] = context.options[1] || { exceptAfterSingleLine: false };
const configureList = typeof options[0] === "object" ? options[0].enforce : [{ blankLine: options[0], prev: "*", next: "*" }];
const sourceCode = context.sourceCode;
/**
@ -144,6 +185,38 @@ module.exports = {
return sourceCode.getTokensBetween(before, after, { includeComments: true }).length !== 0;
}
/**
* Checks whether the given node matches the given type.
* @param {ASTNode} node The class member node to check.
* @param {string} type The class member type to check.
* @returns {boolean} `true` if the class member node matched the type.
* @private
*/
function match(node, type) {
return ClassMemberTypes[type].test(node);
}
/**
* Finds the last matched configuration from the configureList.
* @param {ASTNode} prevNode The previous node to match.
* @param {ASTNode} nextNode The current node to match.
* @returns {string|null} Padding type or `null` if no matches were found.
* @private
*/
function getPaddingType(prevNode, nextNode) {
for (let i = configureList.length - 1; i >= 0; --i) {
const configure = configureList[i];
const matched =
match(prevNode, configure.prev) &&
match(nextNode, configure.next);
if (matched) {
return configure.blankLine;
}
}
return null;
}
return {
ClassBody(node) {
const body = node.body;
@ -158,22 +231,34 @@ module.exports = {
const isPadded = afterPadding.loc.start.line - beforePadding.loc.end.line > 1;
const hasTokenInPadding = hasTokenOrCommentBetween(beforePadding, afterPadding);
const curLineLastToken = findLastConsecutiveTokenAfter(curLast, nextFirst, 0);
const paddingType = getPaddingType(body[i], body[i + 1]);
if ((options[0] === "always" && !skip && !isPadded) ||
(options[0] === "never" && isPadded)) {
if (paddingType === "never" && isPadded) {
context.report({
node: body[i + 1],
messageId: isPadded ? "never" : "always",
messageId: "never",
fix(fixer) {
if (hasTokenInPadding) {
return null;
}
return isPadded
? fixer.replaceTextRange([beforePadding.range[1], afterPadding.range[0]], "\n")
: fixer.insertTextAfter(curLineLastToken, "\n");
return fixer.replaceTextRange([beforePadding.range[1], afterPadding.range[0]], "\n");
}
});
} else if (paddingType === "always" && !skip && !isPadded) {
context.report({
node: body[i + 1],
messageId: "always",
fix(fixer) {
if (hasTokenInPadding) {
return null;
}
return fixer.insertTextAfter(curLineLastToken, "\n");
}
});
}
}
}
};

View file

@ -16,6 +16,22 @@ const { directivesPattern } = require("../shared/directives");
const DEFAULT_FALLTHROUGH_COMMENT = /falls?\s?through/iu;
/**
* Checks all segments in a set and returns true if any are reachable.
* @param {Set<CodePathSegment>} segments The segments to check.
* @returns {boolean} True if any segment is reachable; false otherwise.
*/
function isAnySegmentReachable(segments) {
for (const segment of segments) {
if (segment.reachable) {
return true;
}
}
return false;
}
/**
* Checks whether or not a given comment string is really a fallthrough comment and not an ESLint directive.
* @param {string} comment The comment string to check.
@ -51,15 +67,6 @@ function hasFallthroughComment(caseWhichFallsThrough, subsequentCase, context, f
return Boolean(comment && isFallThroughComment(comment.value, fallthroughCommentPattern));
}
/**
* Checks whether or not a given code path segment is reachable.
* @param {CodePathSegment} segment A CodePathSegment to check.
* @returns {boolean} `true` if the segment is reachable.
*/
function isReachable(segment) {
return segment.reachable;
}
/**
* Checks whether a node and a token are separated by blank lines
* @param {ASTNode} node The node to check
@ -109,7 +116,8 @@ module.exports = {
create(context) {
const options = context.options[0] || {};
let currentCodePath = null;
const codePathSegments = [];
let currentCodePathSegments = new Set();
const sourceCode = context.sourceCode;
const allowEmptyCase = options.allowEmptyCase || false;
@ -126,13 +134,33 @@ module.exports = {
fallthroughCommentPattern = DEFAULT_FALLTHROUGH_COMMENT;
}
return {
onCodePathStart(codePath) {
currentCodePath = codePath;
onCodePathStart() {
codePathSegments.push(currentCodePathSegments);
currentCodePathSegments = new Set();
},
onCodePathEnd() {
currentCodePath = currentCodePath.upper;
currentCodePathSegments = codePathSegments.pop();
},
onUnreachableCodePathSegmentStart(segment) {
currentCodePathSegments.add(segment);
},
onUnreachableCodePathSegmentEnd(segment) {
currentCodePathSegments.delete(segment);
},
onCodePathSegmentStart(segment) {
currentCodePathSegments.add(segment);
},
onCodePathSegmentEnd(segment) {
currentCodePathSegments.delete(segment);
},
SwitchCase(node) {
/*
@ -157,7 +185,7 @@ module.exports = {
* `break`, `return`, or `throw` are unreachable.
* And allows empty cases and the last case.
*/
if (currentCodePath.currentSegments.some(isReachable) &&
if (isAnySegmentReachable(currentCodePathSegments) &&
(node.consequent.length > 0 || (!allowEmptyCase && hasBlankLinesBetween(node, nextToken))) &&
node.parent.cases[node.parent.cases.length - 1] !== node) {
fallthroughCase = node;

View file

@ -90,6 +90,21 @@ module.exports = {
return Boolean(funcInfo && funcInfo.isConstructor && funcInfo.hasExtends);
}
/**
* Determines if every segment in a set has been called.
* @param {Set<CodePathSegment>} segments The segments to search.
* @returns {boolean} True if every segment has been called; false otherwise.
*/
function isEverySegmentCalled(segments) {
for (const segment of segments) {
if (!isCalled(segment)) {
return false;
}
}
return true;
}
/**
* Checks whether or not this is before `super()` is called.
* @returns {boolean} `true` if this is before `super()` is called.
@ -97,7 +112,7 @@ module.exports = {
function isBeforeCallOfSuper() {
return (
isInConstructorOfDerivedClass() &&
!funcInfo.codePath.currentSegments.every(isCalled)
!isEverySegmentCalled(funcInfo.currentSegments)
);
}
@ -108,11 +123,9 @@ module.exports = {
* @returns {void}
*/
function setInvalid(node) {
const segments = funcInfo.codePath.currentSegments;
for (let i = 0; i < segments.length; ++i) {
const segment = segments[i];
const segments = funcInfo.currentSegments;
for (const segment of segments) {
if (segment.reachable) {
segInfoMap[segment.id].invalidNodes.push(node);
}
@ -124,11 +137,9 @@ module.exports = {
* @returns {void}
*/
function setSuperCalled() {
const segments = funcInfo.codePath.currentSegments;
for (let i = 0; i < segments.length; ++i) {
const segment = segments[i];
const segments = funcInfo.currentSegments;
for (const segment of segments) {
if (segment.reachable) {
segInfoMap[segment.id].superCalled = true;
}
@ -156,14 +167,16 @@ module.exports = {
classNode.superClass &&
!astUtils.isNullOrUndefined(classNode.superClass)
),
codePath
codePath,
currentSegments: new Set()
};
} else {
funcInfo = {
upper: funcInfo,
isConstructor: false,
hasExtends: false,
codePath
codePath,
currentSegments: new Set()
};
}
},
@ -211,6 +224,8 @@ module.exports = {
* @returns {void}
*/
onCodePathSegmentStart(segment) {
funcInfo.currentSegments.add(segment);
if (!isInConstructorOfDerivedClass()) {
return;
}
@ -225,6 +240,18 @@ module.exports = {
};
},
onUnreachableCodePathSegmentStart(segment) {
funcInfo.currentSegments.add(segment);
},
onUnreachableCodePathSegmentEnd(segment) {
funcInfo.currentSegments.delete(segment);
},
onCodePathSegmentEnd(segment) {
funcInfo.currentSegments.delete(segment);
},
/**
* Update information of the code path segment when a code path was
* looped.

View file

@ -11,6 +11,22 @@
const allLoopTypes = ["WhileStatement", "DoWhileStatement", "ForStatement", "ForInStatement", "ForOfStatement"];
/**
* Checks all segments in a set and returns true if any are reachable.
* @param {Set<CodePathSegment>} segments The segments to check.
* @returns {boolean} True if any segment is reachable; false otherwise.
*/
function isAnySegmentReachable(segments) {
for (const segment of segments) {
if (segment.reachable) {
return true;
}
}
return false;
}
/**
* Determines whether the given node is the first node in the code path to which a loop statement
* 'loops' for the next iteration.
@ -90,29 +106,36 @@ module.exports = {
loopsByTargetSegments = new Map(),
loopsToReport = new Set();
let currentCodePath = null;
const codePathSegments = [];
let currentCodePathSegments = new Set();
return {
onCodePathStart(codePath) {
currentCodePath = codePath;
onCodePathStart() {
codePathSegments.push(currentCodePathSegments);
currentCodePathSegments = new Set();
},
onCodePathEnd() {
currentCodePath = currentCodePath.upper;
currentCodePathSegments = codePathSegments.pop();
},
[loopSelector](node) {
onUnreachableCodePathSegmentStart(segment) {
currentCodePathSegments.add(segment);
},
/**
* Ignore unreachable loop statements to avoid unnecessary complexity in the implementation, or false positives otherwise.
* For unreachable segments, the code path analysis does not raise events required for this implementation.
*/
if (currentCodePath.currentSegments.some(segment => segment.reachable)) {
loopsToReport.add(node);
}
onUnreachableCodePathSegmentEnd(segment) {
currentCodePathSegments.delete(segment);
},
onCodePathSegmentEnd(segment) {
currentCodePathSegments.delete(segment);
},
onCodePathSegmentStart(segment, node) {
currentCodePathSegments.add(segment);
if (isLoopingTarget(node)) {
const loop = node.parent;
@ -140,6 +163,18 @@ module.exports = {
}
},
[loopSelector](node) {
/**
* Ignore unreachable loop statements to avoid unnecessary complexity in the implementation, or false positives otherwise.
* For unreachable segments, the code path analysis does not raise events required for this implementation.
*/
if (isAnySegmentReachable(currentCodePathSegments)) {
loopsToReport.add(node);
}
},
"Program:exit"() {
loopsToReport.forEach(
node => context.report({ node, messageId: "invalid" })

View file

@ -24,12 +24,19 @@ function isInitialized(node) {
}
/**
* Checks whether or not a given code path segment is unreachable.
* @param {CodePathSegment} segment A CodePathSegment to check.
* @returns {boolean} `true` if the segment is unreachable.
* Checks all segments in a set and returns true if all are unreachable.
* @param {Set<CodePathSegment>} segments The segments to check.
* @returns {boolean} True if all segments are unreachable; false otherwise.
*/
function isUnreachable(segment) {
return !segment.reachable;
function areAllSegmentsUnreachable(segments) {
for (const segment of segments) {
if (segment.reachable) {
return false;
}
}
return true;
}
/**
@ -124,7 +131,6 @@ module.exports = {
},
create(context) {
let currentCodePath = null;
/** @type {ConstructorInfo | null} */
let constructorInfo = null;
@ -132,6 +138,12 @@ module.exports = {
/** @type {ConsecutiveRange} */
const range = new ConsecutiveRange(context.sourceCode);
/** @type {Array<Set<CodePathSegment>>} */
const codePathSegments = [];
/** @type {Set<CodePathSegment>} */
let currentCodePathSegments = new Set();
/**
* Reports a given node if it's unreachable.
* @param {ASTNode} node A statement node to report.
@ -140,7 +152,7 @@ module.exports = {
function reportIfUnreachable(node) {
let nextNode = null;
if (node && (node.type === "PropertyDefinition" || currentCodePath.currentSegments.every(isUnreachable))) {
if (node && (node.type === "PropertyDefinition" || areAllSegmentsUnreachable(currentCodePathSegments))) {
// Store this statement to distinguish consecutive statements.
if (range.isEmpty) {
@ -181,12 +193,29 @@ module.exports = {
return {
// Manages the current code path.
onCodePathStart(codePath) {
currentCodePath = codePath;
onCodePathStart() {
codePathSegments.push(currentCodePathSegments);
currentCodePathSegments = new Set();
},
onCodePathEnd() {
currentCodePath = currentCodePath.upper;
currentCodePathSegments = codePathSegments.pop();
},
onUnreachableCodePathSegmentStart(segment) {
currentCodePathSegments.add(segment);
},
onUnreachableCodePathSegmentEnd(segment) {
currentCodePathSegments.delete(segment);
},
onCodePathSegmentEnd(segment) {
currentCodePathSegments.delete(segment);
},
onCodePathSegmentStart(segment) {
currentCodePathSegments.add(segment);
},
// Registers for all statement nodes (excludes FunctionDeclaration).

View file

@ -57,6 +57,22 @@ function isInFinally(node) {
return false;
}
/**
* Checks all segments in a set and returns true if any are reachable.
* @param {Set<CodePathSegment>} segments The segments to check.
* @returns {boolean} True if any segment is reachable; false otherwise.
*/
function isAnySegmentReachable(segments) {
for (const segment of segments) {
if (segment.reachable) {
return true;
}
}
return false;
}
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
@ -205,7 +221,6 @@ module.exports = {
*/
function markReturnStatementsOnCurrentSegmentsAsUsed() {
scopeInfo
.codePath
.currentSegments
.forEach(segment => markReturnStatementsOnSegmentAsUsed(segment, new Set()));
}
@ -222,7 +237,8 @@ module.exports = {
upper: scopeInfo,
uselessReturns: [],
traversedTryBlockStatements: [],
codePath
codePath,
currentSegments: new Set()
};
},
@ -259,6 +275,9 @@ module.exports = {
* NOTE: This event is notified for only reachable segments.
*/
onCodePathSegmentStart(segment) {
scopeInfo.currentSegments.add(segment);
const info = {
uselessReturns: getUselessReturns([], segment.allPrevSegments),
returned: false
@ -268,6 +287,18 @@ module.exports = {
segmentInfoMap.set(segment, info);
},
onUnreachableCodePathSegmentStart(segment) {
scopeInfo.currentSegments.add(segment);
},
onUnreachableCodePathSegmentEnd(segment) {
scopeInfo.currentSegments.delete(segment);
},
onCodePathSegmentEnd(segment) {
scopeInfo.currentSegments.delete(segment);
},
// Adds ReturnStatement node to check whether it's useless or not.
ReturnStatement(node) {
if (node.argument) {
@ -279,12 +310,12 @@ module.exports = {
isInFinally(node) ||
// Ignore `return` statements in unreachable places (https://github.com/eslint/eslint/issues/11647).
!scopeInfo.codePath.currentSegments.some(s => s.reachable)
!isAnySegmentReachable(scopeInfo.currentSegments)
) {
return;
}
for (const segment of scopeInfo.codePath.currentSegments) {
for (const segment of scopeInfo.currentSegments) {
const info = segmentInfoMap.get(segment);
if (info) {

View file

@ -213,7 +213,8 @@ module.exports = {
stack = {
upper: stack,
codePath,
referenceMap: shouldVerify ? createReferenceMap(scope) : null
referenceMap: shouldVerify ? createReferenceMap(scope) : null,
currentSegments: new Set()
};
},
onCodePathEnd() {
@ -223,11 +224,25 @@ module.exports = {
// Initialize the segment information.
onCodePathSegmentStart(segment) {
segmentInfo.initialize(segment);
stack.currentSegments.add(segment);
},
onUnreachableCodePathSegmentStart(segment) {
stack.currentSegments.add(segment);
},
onUnreachableCodePathSegmentEnd(segment) {
stack.currentSegments.delete(segment);
},
onCodePathSegmentEnd(segment) {
stack.currentSegments.delete(segment);
},
// Handle references to prepare verification.
Identifier(node) {
const { codePath, referenceMap } = stack;
const { referenceMap } = stack;
const reference = referenceMap && referenceMap.get(node);
// Ignore if this is not a valid variable reference.
@ -240,7 +255,7 @@ module.exports = {
// Add a fresh read variable.
if (reference.isRead() && !(writeExpr && writeExpr.parent.operator === "=")) {
segmentInfo.markAsRead(codePath.currentSegments, variable);
segmentInfo.markAsRead(stack.currentSegments, variable);
}
/*
@ -267,16 +282,15 @@ module.exports = {
* If the reference exists in `outdatedReadVariables` list, report it.
*/
":expression:exit"(node) {
const { codePath, referenceMap } = stack;
// referenceMap exists if this is in a resumable function scope.
if (!referenceMap) {
if (!stack.referenceMap) {
return;
}
// Mark the read variables on this code path as outdated.
if (node.type === "AwaitExpression" || node.type === "YieldExpression") {
segmentInfo.makeOutdated(codePath.currentSegments);
segmentInfo.makeOutdated(stack.currentSegments);
}
// Verify.
@ -288,7 +302,7 @@ module.exports = {
for (const reference of references) {
const variable = reference.resolved;
if (segmentInfo.isOutdated(codePath.currentSegments, variable)) {
if (segmentInfo.isOutdated(stack.currentSegments, variable)) {
if (node.parent.left === reference.identifier) {
context.report({
node: node.parent,

20
node_modules/eslint/package.json generated vendored
View file

@ -1,6 +1,6 @@
{
"name": "eslint",
"version": "8.48.0",
"version": "8.49.0",
"author": "Nicholas C. Zakas <nicholas+npm@nczconsulting.com>",
"description": "An AST-based pattern checker for JavaScript.",
"bin": {
@ -63,8 +63,8 @@
"@eslint-community/eslint-utils": "^4.2.0",
"@eslint-community/regexpp": "^4.6.1",
"@eslint/eslintrc": "^2.1.2",
"@eslint/js": "8.48.0",
"@humanwhocodes/config-array": "^0.11.10",
"@eslint/js": "8.49.0",
"@humanwhocodes/config-array": "^0.11.11",
"@humanwhocodes/module-importer": "^1.0.1",
"@nodelib/fs.walk": "^1.2.8",
"ajv": "^6.12.4",
@ -101,6 +101,11 @@
"devDependencies": {
"@babel/core": "^7.4.3",
"@babel/preset-env": "^7.4.3",
"@wdio/browser-runner": "^8.14.6",
"@wdio/cli": "^8.14.6",
"@wdio/concise-reporter": "^8.14.0",
"@wdio/globals": "^8.14.6",
"@wdio/mocha-framework": "^8.14.0",
"babel-loader": "^8.0.5",
"c8": "^7.12.0",
"chai": "^4.0.1",
@ -124,11 +129,6 @@
"glob": "^7.1.6",
"got": "^11.8.3",
"gray-matter": "^4.0.3",
"karma": "^6.1.1",
"karma-chrome-launcher": "^3.1.0",
"karma-mocha": "^2.0.1",
"karma-mocha-reporter": "^2.2.5",
"karma-webpack": "^5.0.0",
"lint-staged": "^11.0.0",
"load-perf": "^0.2.0",
"markdownlint": "^0.25.1",
@ -148,12 +148,14 @@
"pirates": "^4.0.5",
"progress": "^2.0.3",
"proxyquire": "^2.0.1",
"puppeteer": "^13.7.0",
"recast": "^0.20.4",
"regenerator-runtime": "^0.13.2",
"rollup-plugin-node-polyfills": "^0.2.1",
"semver": "^7.5.3",
"shelljs": "^0.8.2",
"sinon": "^11.0.0",
"vite-plugin-commonjs": "^0.8.2",
"webdriverio": "^8.14.6",
"webpack": "^5.23.0",
"webpack-cli": "^4.5.0",
"yorkie": "^2.0.0"