eslint 10.1.0 → 10.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -218,6 +218,8 @@ Packages that are controlled by the ESLint team and have no external dependencie
218
218
 
219
219
  For external packages, we don't use `require(esm)` because a package could add a top-level `await` and thus break ESLint. We can use an external ESM-only package only in case it is needed only in asynchronous code, in which case it can be loaded using dynamic `import()`.
220
220
 
221
+ These policies don't apply to packages intended for our own usage only, such as `eslint-config-eslint`.
222
+
221
223
  ## License
222
224
 
223
225
  MIT License
@@ -358,7 +360,7 @@ to get your logo on our READMEs and [website](https://eslint.org/sponsors).
358
360
  <p><a href="https://automattic.com"><img src="https://images.opencollective.com/automattic/d0ef3e1/logo.png" alt="Automattic" height="128"></a></p><h3>Gold Sponsors</h3>
359
361
  <p><a href="https://qlty.sh/"><img src="https://images.opencollective.com/qltysh/33d157d/logo.png" alt="Qlty Software" height="96"></a></p><h3>Silver Sponsors</h3>
360
362
  <p><a href="https://vite.dev/"><img src="https://images.opencollective.com/vite/d472863/logo.png" alt="Vite" height="64"></a> <a href="https://liftoff.io/"><img src="https://images.opencollective.com/liftoff/2d6c3b6/logo.png" alt="Liftoff" height="64"></a> <a href="https://stackblitz.com"><img src="https://avatars.githubusercontent.com/u/28635252" alt="StackBlitz" height="64"></a></p><h3>Bronze Sponsors</h3>
361
- <p><a href="https://syntax.fm"><img src="https://github.com/syntaxfm.png" alt="Syntax" height="32"></a> <a href="https://cybozu.co.jp/"><img src="https://images.opencollective.com/cybozu/933e46d/logo.png" alt="Cybozu" height="32"></a> <a href="https://opensource.sap.com"><img src="https://avatars.githubusercontent.com/u/2531208" alt="SAP" height="32"></a> <a href="https://www.crawljobs.com/"><img src="https://images.opencollective.com/crawljobs-poland/fa43a17/logo.png" alt="CrawlJobs" height="32"></a> <a href="https://depot.dev"><img src="https://images.opencollective.com/depot/39125a1/logo.png" alt="Depot" height="32"></a> <a href="https://www.n-ix.com/"><img src="https://images.opencollective.com/n-ix-ltd/575a7a5/logo.png" alt="N-iX Ltd" 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://www.gitbook.com"><img src="https://avatars.githubusercontent.com/u/7111340" alt="GitBook" height="32"></a> <a href="https://herocoders.com"><img src="https://avatars.githubusercontent.com/u/37549774" alt="HeroCoders" height="32"></a> <a href="https://www.lambdatest.com"><img src="https://avatars.githubusercontent.com/u/171592363" alt="TestMu AI Open Source Office (Formerly LambdaTest)" height="32"></a></p>
363
+ <p><a href="https://cybozu.co.jp/"><img src="https://images.opencollective.com/cybozu/933e46d/logo.png" alt="Cybozu" height="32"></a> <a href="https://opensource.sap.com"><img src="https://avatars.githubusercontent.com/u/2531208" alt="SAP" height="32"></a> <a href="https://www.crawljobs.com/"><img src="https://images.opencollective.com/crawljobs-poland/fa43a17/logo.png" alt="CrawlJobs" height="32"></a> <a href="https://depot.dev"><img src="https://images.opencollective.com/depot/39125a1/logo.png" alt="Depot" 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://www.gitbook.com"><img src="https://avatars.githubusercontent.com/u/7111340" alt="GitBook" height="32"></a> <a href="https://herocoders.com"><img src="https://avatars.githubusercontent.com/u/37549774" alt="HeroCoders" height="32"></a> <a href="https://www.lambdatest.com"><img src="https://avatars.githubusercontent.com/u/171592363" alt="TestMu AI Open Source Office (Formerly LambdaTest)" height="32"></a></p>
362
364
  <h3>Technology Sponsors</h3>
363
365
  Technology sponsors allow us to use their products and services for free as part of a contribution to the open source ecosystem and our work.
364
366
  <p><a href="https://netlify.com"><img src="https://raw.githubusercontent.com/eslint/eslint.org/main/src/assets/images/techsponsors/netlify-icon.svg" alt="Netlify" height="32"></a> <a href="https://algolia.com"><img src="https://raw.githubusercontent.com/eslint/eslint.org/main/src/assets/images/techsponsors/algolia-icon.svg" alt="Algolia" height="32"></a> <a href="https://1password.com"><img src="https://raw.githubusercontent.com/eslint/eslint.org/main/src/assets/images/techsponsors/1password-icon.svg" alt="1Password" height="32"></a></p>
package/conf/globals.js CHANGED
@@ -144,6 +144,7 @@ const es2026 = {
144
144
  AsyncDisposableStack: false,
145
145
  DisposableStack: false,
146
146
  SuppressedError: false,
147
+ Temporal: false,
147
148
  };
148
149
 
149
150
  //-----------------------------------------------------------------------------
@@ -228,6 +228,76 @@ function splitPluginIdentifier(identifier) {
228
228
  };
229
229
  }
230
230
 
231
+ /**
232
+ * Normalizes a language name by replacing the built-in `@/` plugin prefix with `js/`.
233
+ * @param {string} languageName The language name to normalize.
234
+ * @returns {string} The normalized language name.
235
+ */
236
+ function normalizeLanguageName(languageName) {
237
+ return languageName.startsWith("@/")
238
+ ? `js/${languageName.slice(2)}`
239
+ : languageName;
240
+ }
241
+
242
+ /**
243
+ * Checks if a rule's `meta.languages` supports the given language.
244
+ * @param {Array<string>|undefined} ruleLangs The rule's `meta.languages` array.
245
+ * @param {string} configLanguageName The normalized language name from the config (e.g., "js/js").
246
+ * @param {Array<string>} validPluginNames The valid plugin name aliases for the config's plugin
247
+ * (normalized plugin name plus its `meta.namespace` if defined).
248
+ * @returns {boolean} True if the rule supports the language, false otherwise.
249
+ */
250
+ function doesRuleSupportLanguage(
251
+ ruleLangs,
252
+ configLanguageName,
253
+ validPluginNames,
254
+ ) {
255
+ // If no languages specified, works with all languages (backward compatible)
256
+ if (!ruleLangs) {
257
+ return true;
258
+ }
259
+
260
+ const { objectName: configLangPart } =
261
+ splitPluginIdentifier(configLanguageName);
262
+
263
+ for (const langEntry of ruleLangs) {
264
+ // Skip non-string entries
265
+ if (typeof langEntry !== "string") {
266
+ continue;
267
+ }
268
+
269
+ // "*" matches any language
270
+ if (langEntry === "*") {
271
+ return true;
272
+ }
273
+
274
+ // Direct match
275
+ if (langEntry === configLanguageName) {
276
+ return true;
277
+ }
278
+
279
+ const { pluginName: rulePluginPart, objectName: ruleLangPart } =
280
+ splitPluginIdentifier(langEntry);
281
+
282
+ // "plugin/*" wildcard - matches any language from that plugin (by name or namespace)
283
+ if (ruleLangPart === "*") {
284
+ if (validPluginNames.includes(rulePluginPart)) {
285
+ return true;
286
+ }
287
+ } else {
288
+ // Match by plugin name or namespace, with exact language part
289
+ if (
290
+ validPluginNames.includes(rulePluginPart) &&
291
+ ruleLangPart === configLangPart
292
+ ) {
293
+ return true;
294
+ }
295
+ }
296
+ }
297
+
298
+ return false;
299
+ }
300
+
231
301
  /**
232
302
  * Returns the name of an object in the config by reading its `meta` key.
233
303
  * @param {Object} object The object to check.
@@ -572,12 +642,30 @@ class Config {
572
642
  * @throws {TypeError} If the rulesConfig is not provided or is invalid.
573
643
  * @throws {InvalidRuleOptionsSchemaError} If a rule's `meta.schema` is invalid.
574
644
  * @throws {TypeError} If a rule is not found in the plugins.
645
+ * @throws {TypeError} If a rule does not support the current language.
575
646
  */
576
647
  validateRulesConfig(rulesConfig) {
577
648
  if (!rulesConfig) {
578
649
  throw new TypeError("Config is required for validation.");
579
650
  }
580
651
 
652
+ // Normalize "@/" prefix to "js/" for matching and user-facing messages
653
+ const normalizedLanguageName = normalizeLanguageName(
654
+ this.#languageName,
655
+ );
656
+
657
+ // Compute valid plugin name aliases for the config's language plugin once
658
+ const { pluginName: configPluginName } = splitPluginIdentifier(
659
+ normalizedLanguageName,
660
+ );
661
+ const configPlugin =
662
+ this.plugins[configPluginName] ??
663
+ (configPluginName === "js" ? this.plugins["@"] : void 0);
664
+ const validPluginNames = configPlugin?.meta?.namespace
665
+ ? [configPluginName, configPlugin.meta.namespace]
666
+ : [configPluginName];
667
+ const unsupportedLanguageRules = [];
668
+
581
669
  for (const [ruleId, ruleOptions] of Object.entries(rulesConfig)) {
582
670
  // check for edge case
583
671
  if (ruleId === "__proto__") {
@@ -603,6 +691,34 @@ class Config {
603
691
  throwRuleNotFoundError(parseRuleId(ruleId), this);
604
692
  }
605
693
 
694
+ // Validate meta.languages structure if present (only for enabled rules)
695
+ if (rule.meta?.languages !== void 0) {
696
+ if (!Array.isArray(rule.meta.languages)) {
697
+ throw new TypeError(
698
+ `Key "rules": Key "${ruleId}": Key "meta": Key "languages": Expected an array.`,
699
+ );
700
+ }
701
+
702
+ for (const lang of rule.meta.languages) {
703
+ if (typeof lang !== "string") {
704
+ throw new TypeError(
705
+ `Key "rules": Key "${ruleId}": Key "meta": Key "languages": Expected each element to be a string.`,
706
+ );
707
+ }
708
+ }
709
+ }
710
+
711
+ // Check if the rule supports the current language
712
+ if (
713
+ !doesRuleSupportLanguage(
714
+ rule.meta?.languages,
715
+ normalizedLanguageName,
716
+ validPluginNames,
717
+ )
718
+ ) {
719
+ unsupportedLanguageRules.push(ruleId);
720
+ }
721
+
606
722
  const validateRule = getOrCreateValidator(rule, ruleId);
607
723
 
608
724
  if (validateRule) {
@@ -634,6 +750,19 @@ class Config {
634
750
  }
635
751
  }
636
752
  }
753
+
754
+ if (unsupportedLanguageRules.length > 0) {
755
+ const error = new TypeError(
756
+ `Key "rules": The following rules do not support the language "${normalizedLanguageName}":\n${unsupportedLanguageRules.map(ruleId => `\t- "${ruleId}"`).join("\n")}`,
757
+ );
758
+
759
+ error.messageTemplate = "rule-unsupported-language";
760
+ error.messageData = {
761
+ ruleIds: unsupportedLanguageRules,
762
+ language: normalizedLanguageName,
763
+ };
764
+ throw error;
765
+ }
637
766
  }
638
767
 
639
768
  /**
@@ -224,15 +224,16 @@ function assertIsRuleSeverity(ruleId, value) {
224
224
  }
225
225
 
226
226
  /**
227
- * Validates that a given string is the form pluginName/objectName.
227
+ * Validates that a given string matches the "pluginName/memberPlaceholder" pattern.
228
228
  * @param {string} value The string to check.
229
+ * @param {string} memberPlaceholder The placeholder for the member portion of the expected format in the error message.
229
230
  * @returns {void}
230
- * @throws {TypeError} If the string isn't in the correct format.
231
+ * @throws {TypeError} If the string doesn't match the expected pattern.
231
232
  */
232
- function assertIsPluginMemberName(value) {
233
+ function assertIsPluginMemberName(value, memberPlaceholder) {
233
234
  if (!/[\w\-@$]+(?:\/[\w\-$]+)+$/iu.test(value)) {
234
235
  throw new TypeError(
235
- `Expected string in the form "pluginName/objectName" but found "${value}".`,
236
+ `Expected string in the form "pluginName/${memberPlaceholder}" but found "${value}".`,
236
237
  );
237
238
  }
238
239
  }
@@ -375,7 +376,9 @@ const languageOptionsSchema = {
375
376
  /** @type {ObjectPropertySchema} */
376
377
  const languageSchema = {
377
378
  merge: "replace",
378
- validate: assertIsPluginMemberName,
379
+ validate(value) {
380
+ assertIsPluginMemberName(value, "languageName");
381
+ },
379
382
  };
380
383
 
381
384
  /** @type {ObjectPropertySchema} */
@@ -430,7 +433,7 @@ const processorSchema = {
430
433
  merge: "replace",
431
434
  validate(value) {
432
435
  if (typeof value === "string") {
433
- assertIsPluginMemberName(value);
436
+ assertIsPluginMemberName(value, "processorName");
434
437
  } else if (value && typeof value === "object") {
435
438
  if (
436
439
  typeof value.preprocess !== "function" ||
@@ -31,7 +31,7 @@ function isCaseNode(node) {
31
31
 
32
32
  /**
33
33
  * Checks if a given node appears as the value of a PropertyDefinition node.
34
- * @param {ASTNode} node THe node to check.
34
+ * @param {ASTNode} node The node to check.
35
35
  * @returns {boolean} `true` if the node is a PropertyDefinition value,
36
36
  * false if not.
37
37
  */
@@ -504,7 +504,7 @@ function processCodePathToEnter(analyzer, node) {
504
504
 
505
505
  case "SwitchCase":
506
506
  /*
507
- * Fork if this node is after the 2st node in `cases`.
507
+ * Fork if this node is after the 1st node in `cases`.
508
508
  * It's similar to `else` blocks.
509
509
  * The next `test` node is processed in this path.
510
510
  */
@@ -626,10 +626,13 @@ function processCodePathToExit(analyzer, node) {
626
626
  case "ImportExpression":
627
627
  case "MemberExpression":
628
628
  case "NewExpression":
629
- case "YieldExpression":
630
629
  state.makeFirstThrowablePathInTryBlock();
631
630
  break;
632
631
 
632
+ case "YieldExpression":
633
+ state.makeYield();
634
+ break;
635
+
633
636
  case "WhileStatement":
634
637
  case "DoWhileStatement":
635
638
  case "ForStatement":
@@ -569,11 +569,10 @@ class TryContext {
569
569
  this.position = "try";
570
570
 
571
571
  /**
572
- * If the `try` statement has a `finally` block, this affects how a
573
- * `return` statement behaves in the `try` block. Without `finally`,
574
- * `return` behaves as usual and doesn't require a fork; with `finally`,
575
- * `return` forks into the `finally` block, so we need a fork context
576
- * to track it.
572
+ * If the `try` statement has a `finally` block, this affects how return-like
573
+ * leaving paths behave in the `try` block. Without `finally`, they behave as
574
+ * usual and don't require a fork; with `finally`, they fork into the
575
+ * `finally` block, so we need a fork context to track them.
577
576
  * @type {ForkContext|null}
578
577
  */
579
578
  this.returnedForkContext = hasFinalizer
@@ -1755,6 +1754,23 @@ class CodePathState {
1755
1754
  this.forkContext.add(segments);
1756
1755
  }
1757
1756
 
1757
+ /**
1758
+ * Records abrupt resumption paths from a suspended `yield` expression,
1759
+ * then splits normal post-`yield` continuation into a fresh segment.
1760
+ * @returns {void}
1761
+ */
1762
+ makeYield() {
1763
+ const forkContext = this.forkContext;
1764
+ const leavingSegments = forkContext.head;
1765
+
1766
+ if (forkContext.reachable) {
1767
+ getReturnContext(this).returnedForkContext.add(leavingSegments);
1768
+ getThrowContext(this).thrownForkContext.add(leavingSegments);
1769
+
1770
+ forkContext.replaceHead(forkContext.makeNext(-1, -1));
1771
+ }
1772
+ }
1773
+
1758
1774
  /**
1759
1775
  * Makes a code path segment from the first throwable node to the `catch`
1760
1776
  * block or the `finally` block.
@@ -100,9 +100,10 @@ class CodePath {
100
100
  * Final code path segments that represent normal completion of the code path.
101
101
  * For functions, this means both explicit `return` statements and implicit returns,
102
102
  * such as the last reachable segment in a function that does not have an
103
- * explicit `return` as this implicitly returns `undefined`. For scripts,
104
- * modules, class field initializers, and class static blocks, this means
105
- * all lines of code have been executed.
103
+ * explicit `return` as this implicitly returns `undefined`, as well as
104
+ * return-like exits from suspended `yield` expressions. For scripts, modules,
105
+ * class field initializers, and class static blocks, this means all lines of
106
+ * code have been executed.
106
107
  * These segments are also present in `finalSegments`.
107
108
  * This is a passthrough to the underlying `CodePathState`.
108
109
  * @type {CodePathSegment[]}
@@ -112,7 +113,8 @@ class CodePath {
112
113
  }
113
114
 
114
115
  /**
115
- * Final code path segments that represent `throw` statements.
116
+ * Final code path segments that represent `throw` statements and throw-like
117
+ * exits from suspended `yield` expressions.
116
118
  * This is a passthrough to the underlying `CodePathState`.
117
119
  * These segments are also present in `finalSegments`.
118
120
  * @type {CodePathSegment[]}
@@ -1202,6 +1202,22 @@ class Linter {
1202
1202
  throw err;
1203
1203
  }
1204
1204
 
1205
+ /*
1206
+ * If the rule does not support the current language, report a
1207
+ * specific, actionable error message.
1208
+ */
1209
+ if (
1210
+ err.messageTemplate ===
1211
+ "rule-unsupported-language"
1212
+ ) {
1213
+ report.addError({
1214
+ ruleId,
1215
+ message: `Inline configuration for rule "${ruleId}" is invalid:\n\tRule does not support the language "${err.messageData.language}". Use a config block with "files" to apply the rule only to supported files, or disable it.\n`,
1216
+ loc,
1217
+ });
1218
+ return;
1219
+ }
1220
+
1205
1221
  let baseMessage = err.message
1206
1222
  .slice(
1207
1223
  err.message.startsWith('Key "rules":')
@@ -28,12 +28,18 @@ module.exports = {
28
28
  },
29
29
 
30
30
  create(context) {
31
+ const sourceCode = context.sourceCode;
32
+
31
33
  return {
32
34
  "NewExpression[callee.name='Promise'][arguments.0.async=true]"(
33
35
  node,
34
36
  ) {
37
+ if (!sourceCode.isGlobalReference(node.callee)) {
38
+ return;
39
+ }
40
+
35
41
  context.report({
36
- node: context.sourceCode.getFirstToken(
42
+ node: sourceCode.getFirstToken(
37
43
  node.arguments[0],
38
44
  token => token.value === "async",
39
45
  ),
@@ -20,7 +20,14 @@ const getPropertyName = require("./utils/ast-utils").getStaticPropertyName;
20
20
  // Helpers
21
21
  //------------------------------------------------------------------------------
22
22
 
23
- const nonCallableGlobals = ["Atomics", "JSON", "Math", "Reflect", "Intl"];
23
+ const nonCallableGlobals = [
24
+ "Atomics",
25
+ "JSON",
26
+ "Math",
27
+ "Reflect",
28
+ "Intl",
29
+ "Temporal",
30
+ ];
24
31
 
25
32
  /**
26
33
  * Returns the name of the node to report
@@ -612,7 +612,7 @@ module.exports = {
612
612
 
613
613
  /**
614
614
  * Checks the current context for shadowed variables.
615
- * @param {Scope} scope Fixme
615
+ * @param {Scope} scope The scope to check for shadowed variables.
616
616
  * @returns {void}
617
617
  */
618
618
  function checkForShadows(scope) {
@@ -128,6 +128,35 @@ function getEncloseFunctionDeclaration(reference) {
128
128
  return null;
129
129
  }
130
130
 
131
+ /**
132
+ * Checks whether a given modifier is in a loop.
133
+ *
134
+ * Besides checking for the condition being in the loop, this also checks
135
+ * whether the function that this modifier is belonging to is called
136
+ * in the loop.
137
+ * @param {LoopConditionInfo} condition The condition to check.
138
+ * @param {Reference} modifier The modifier to check.
139
+ * @returns {boolean} `true` if the modifier is in a loop.
140
+ */
141
+ function hasModifierInLoop(condition, modifier) {
142
+ if (condition.isInLoop(modifier)) {
143
+ return true;
144
+ }
145
+
146
+ const funcNode = getEncloseFunctionDeclaration(modifier);
147
+
148
+ if (!funcNode) {
149
+ return false;
150
+ }
151
+
152
+ const funcVar = astUtils.getVariableByName(
153
+ modifier.from.upper,
154
+ funcNode.id.name,
155
+ );
156
+
157
+ return Boolean(funcVar && funcVar.references.some(condition.isInLoop));
158
+ }
159
+
131
160
  /**
132
161
  * Updates the "modified" flags of given loop conditions with given modifiers.
133
162
  * @param {LoopConditionInfo[]} conditions The loop conditions to be updated.
@@ -140,26 +169,8 @@ function updateModifiedFlag(conditions, modifiers) {
140
169
 
141
170
  for (let j = 0; !condition.modified && j < modifiers.length; ++j) {
142
171
  const modifier = modifiers[j];
143
- let funcNode, funcVar;
144
172
 
145
- /*
146
- * Besides checking for the condition being in the loop, we want to
147
- * check the function that this modifier is belonging to is called
148
- * in the loop.
149
- * FIXME: This should probably be extracted to a function.
150
- */
151
- const inLoop =
152
- condition.isInLoop(modifier) ||
153
- Boolean(
154
- (funcNode = getEncloseFunctionDeclaration(modifier)) &&
155
- (funcVar = astUtils.getVariableByName(
156
- modifier.from.upper,
157
- funcNode.id.name,
158
- )) &&
159
- funcVar.references.some(condition.isInLoop),
160
- );
161
-
162
- condition.modified = inLoop;
173
+ condition.modified = hasModifierInLoop(condition, modifier);
163
174
  }
164
175
  }
165
176
  }
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+
3
+ module.exports = function ({ ruleIds, language }) {
4
+ return `
5
+ The following rules do not support the language "${language}":
6
+ ${ruleIds.map(id => `\t- "${id}"`).join("\n")}
7
+
8
+ To fix this error, either:
9
+ - Remove the rule from your configuration, or set its severity to "off".
10
+ - Use the "files" option to apply the rule only to files of the supported language, for example:
11
+ {
12
+ files: ["**/*.js"],
13
+ rules: { "${ruleIds[0]}": "error" }
14
+ }
15
+
16
+ See https://eslint.org/docs/latest/use/configure/rules for more information.
17
+ `.trimStart();
18
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint",
3
- "version": "10.1.0",
3
+ "version": "10.2.1",
4
4
  "author": "Nicholas C. Zakas <nicholas+npm@nczconsulting.com>",
5
5
  "description": "An AST-based pattern checker for JavaScript.",
6
6
  "type": "commonjs",
@@ -119,10 +119,10 @@
119
119
  "dependencies": {
120
120
  "@eslint-community/eslint-utils": "^4.8.0",
121
121
  "@eslint-community/regexpp": "^4.12.2",
122
- "@eslint/config-array": "^0.23.3",
123
- "@eslint/config-helpers": "^0.5.3",
124
- "@eslint/core": "^1.1.1",
125
- "@eslint/plugin-kit": "^0.6.1",
122
+ "@eslint/config-array": "^0.23.5",
123
+ "@eslint/config-helpers": "^0.5.5",
124
+ "@eslint/core": "^1.2.1",
125
+ "@eslint/plugin-kit": "^0.7.1",
126
126
  "@humanfs/node": "^0.16.6",
127
127
  "@humanwhocodes/module-importer": "^1.0.1",
128
128
  "@humanwhocodes/retry": "^0.4.2",
@@ -168,7 +168,7 @@
168
168
  "ejs": "^3.0.2",
169
169
  "eslint": "file:.",
170
170
  "eslint-config-eslint": "file:packages/eslint-config-eslint",
171
- "eslint-plugin-eslint-plugin": "^6.0.0",
171
+ "eslint-plugin-eslint-plugin": "^7.3.2",
172
172
  "eslint-plugin-expect-type": "^0.6.0",
173
173
  "eslint-plugin-yml": "^1.14.0",
174
174
  "eslint-release": "^3.3.0",
@@ -185,7 +185,7 @@
185
185
  "lint-staged": "^11.0.0",
186
186
  "markdown-it": "^12.2.0",
187
187
  "markdown-it-container": "^3.0.0",
188
- "markdownlint-cli2": "^0.21.0",
188
+ "markdownlint-cli2": "^0.22.0",
189
189
  "marked": "^4.0.8",
190
190
  "metascraper": "^5.25.7",
191
191
  "metascraper-description": "^5.25.7",
@@ -196,7 +196,7 @@
196
196
  "mocha": "^11.7.1",
197
197
  "node-polyfill-webpack-plugin": "^1.0.3",
198
198
  "npm-license": "^0.3.3",
199
- "prettier": "3.8.1",
199
+ "prettier": "3.8.2",
200
200
  "progress": "^2.0.3",
201
201
  "proxyquire": "^2.0.1",
202
202
  "recast": "^0.23.0",