From bc82f31a850218f6ef9cca3b00ac7fa9889b2cb6 Mon Sep 17 00:00:00 2001 From: sushichan044 <71284054+sushichan044@users.noreply.github.com> Date: Sat, 12 Apr 2025 15:24:51 +0900 Subject: [PATCH 01/16] init --- designs/2025-bulk-suppressions-api/README.md | 104 +++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 designs/2025-bulk-suppressions-api/README.md diff --git a/designs/2025-bulk-suppressions-api/README.md b/designs/2025-bulk-suppressions-api/README.md new file mode 100644 index 00000000..6a80ca41 --- /dev/null +++ b/designs/2025-bulk-suppressions-api/README.md @@ -0,0 +1,104 @@ +- Repo: eslint/eslint +- Start Date: 2025-04-11 +- RFC PR: (leave this empty, to be filled in later) +- Authors: [Kentaro Suzuki](https://github.com/sushichan044) + +# Add support for bulk suppressions in `ESLint` and `LegacyESLint` classes + +## Summary + + + +## Motivation + + + +## Detailed Design + + + +## Documentation + + + +## Drawbacks + + + +## Backwards Compatibility Analysis + + + +## Alternatives + + + +## Open Questions + + + +## Help Needed + + + +## Frequently Asked Questions + + + +## Related Discussions + + From f63e63ff66c01b922ac8379b0e60701f7055031c Mon Sep 17 00:00:00 2001 From: sushichan044 <71284054+sushichan044@users.noreply.github.com> Date: Tue, 6 May 2025 02:34:31 +0900 Subject: [PATCH 02/16] feat: add support for bulk suppressions in `ESLint` and `LegacyESLint` classes --- designs/2025-bulk-suppressions-api/README.md | 199 ++++++++++++++++++- 1 file changed, 198 insertions(+), 1 deletion(-) diff --git a/designs/2025-bulk-suppressions-api/README.md b/designs/2025-bulk-suppressions-api/README.md index 6a80ca41..8c4bda91 100644 --- a/designs/2025-bulk-suppressions-api/README.md +++ b/designs/2025-bulk-suppressions-api/README.md @@ -1,5 +1,5 @@ - Repo: eslint/eslint -- Start Date: 2025-04-11 +- Start Date: 2025-05-06 - RFC PR: (leave this empty, to be filled in later) - Authors: [Kentaro Suzuki](https://github.com/sushichan044) @@ -9,11 +9,20 @@ +This RFC proposes extending the bulk suppressions feature, introduced in ESLint 9.24.0 for CLI usage, to be available through the Node.js API via the `ESLint` and `LegacyESLint` classes. + ## Motivation +Currently, the bulk suppression feature introduced in ESLint 9.24.0 is only available via the CLI. +This leads to inconsistencies when ESLint is used programmatically via its Node.js API, such as in IDE integrations. + +This leads to inconsistencies when ESLint is used programmatically. Violations suppressed using `eslint-suppressions.json` (especially when using a custom location via the CLI) might not be recognized when using the Node.js API, leading to incorrect error reporting in environments like IDEs. + +This RFC aims to resolve this discrepancy by adding support for bulk suppressions to the `ESLint` and `LegacyESLint` Node.js APIs, ensuring consistent linting results and configuration capabilities across both interfaces. + ## Detailed Design used. Be sure to define any new terms in this section. --> +This proposal integrates the existing bulk suppression functionality into the `ESLint` and `LegacyESLint` Node.js API classes by leveraging the internal `SuppressionsService`. A new `suppressionsLocation` option is introduced in the constructors. + +1. New Constructor Option (`suppressionsLocation`) + - Both `ESLintOptions` and `LegacyESLintOptions` will accept a new optional property: `suppressionsLocation`. + - `suppressionsLocation: string | undefined`: Specifies the path to the suppressions file (`eslint-suppressions.json`). This path can be absolute or relative to the `cwd`. + - If `suppressionsLocation` is provided, ESLint will attempt to load suppressions from that specific file path. + - If `suppressionsLocation` is not provided (or is `undefined`), ESLint will default to looking for `eslint-suppressions.json` in the `cwd`. + +2. Service Instantiation and Configuration + - Upon instantiation, the `ESLint` and `LegacyESLint` constructors will create an instance of `SuppressionsService`. + - A new constructor option, `suppressionsLocation` (string, optional), will be added to both classes. + - If provided, this path (relative to `cwd`) specifies the suppression file. + - If not provided, ESLint defaults to searching for `eslint-suppressions.json` in the `cwd`. + - The constructor will resolve the final absolute path to the suppression file (using `suppressionsLocation` or the default) and pass it to the `SuppressionsService` constructor. + +3. Applying Suppressions + - Within the `lintFiles()` and `lintText()` methods of both classes, *after* the initial linting results are obtained, the `applySuppressions` method of the instantiated `SuppressionsService` will be called. + - This method takes the raw linting results and the loaded suppressions (from the resolved file path) and returns the results with suppressions applied, along with any unused suppressions. + - The final, suppression-applied results will be returned to the user. + +### Example code of `lib/eslint/eslint.js` + +```javascript +import fs from "node:fs"; +import { getCacheFile } from "./eslint-helpers.js"; +import { SuppressionsService } from "../services/suppressions-service.js"; + +class ESLint { + constructor(options = {}) { + const processedOptions = processOptions(options); + + // ... existing constructor logic to initialize options, linter, cache, configLoader ... + + const suppressionsFilePath = getCacheFile( + processedOptions.suppressionsLocation, + processedOptions.cwd, + { prefix: "suppressions_" } + ); + + privateMembers.set(this, { + options: processedOptions, + linter: /* ... */, + lintResultCache: /* ... */, + configLoader: /* ... */ + suppressionsFilePath, + }); + } + + async lintFiles(patterns) { + const { options, suppressionsFilePath, lintResultCache, /* ... other needed members */ } = privateMembers.get(this); + let suppressionResults = null; + + // Existing lint logic to get initial `results` (LintResult[]) + const results = /* LintResult[] */ + + // Persist the cache to disk before applying suppressions. + if (lintResultCache) { + lintResultCache.reconcile(); + } + + const finalResults = results.filter(result => !!result); + + if (!fs.existsSync(suppressionsFilePath)) { + return finalResults; + } + + const suppressions = new SuppressionsService({ + filePath: suppressionsFilePath, + cwd: options.cwd, + }); + + return suppressions.applySuppressions( + finalResults, + await suppressions.load(), + ); + } + + async lintText(code, options = {}) { + const { + options: eslintOptions, // Renamed to avoid conflict with method options + suppressionsFilePath, + linter, + configLoader + } = privateMembers.get(this); + + const { filePath: providedFilePath, warnIgnored, ...otherOptions } = options || {}; + + const results = []; + + // --- Existing lintText logic to determine config, etc. --- + + // Do lint. + results.push( + verifyText({ + text: code, + filePath: resolvedFilename.endsWith("__placeholder__.js") + ? "" + : resolvedFilename, + configs, + cwd, + fix: fixer, + allowInlineConfig, + ruleFilter, + stats, + linter, + }), + ); + + if (!fs.existsSync(suppressionsFilePath)) { + return processLintReport(this, { results }); + } + + const suppressions = new SuppressionsService({ + filePath: suppressionsFilePath, + cwd: eslintOptions.cwd, + }); + + const suppressedResults = suppressions.applySuppressions( + results, + await suppressions.load(), + ); + + // Return the suppression-applied results + return processLintReport(this, { results: suppressedResults }); + } +} +``` + ## Documentation on the ESLint blog to explain the motivation? --> +The documentation updates will reflect that this change aligns the Node.js API behavior with the existing CLI functionality. + +1. API Documentation (`ESLint`/`LegacyESLint` classes): + - Add the new `suppressionsLocation` option to the constructor options documentation for both `ESLint` and `LegacyESLint`, explaining its purpose (specifying the suppression file path) and behavior (relative to `cwd`, default lookup). + - Add a note to the descriptions of `lintText()` and `lintFiles()` methods stating that suppressions are automatically applied based on the resolved suppression file path (either from `suppressionsLocation` or the default `eslint-suppressions.json` in `cwd`). Example: "Applies suppressions from the resolved suppression file (`suppressionsLocation` option or `eslint-suppressions.json` in `cwd`), if found." + +2. Bulk Suppressions User Guide Page: + - Update the existing user guide page for Bulk Suppressions. + - Add a section or note clarifying that the feature is now also available when using the `ESLint` and `LegacyESLint` Node.js APIs. + - Explicitly mention how the suppression file is located when using the API: "Note: When using the Node.js API, ESLint searches for the suppression file specified by the `suppressionsLocation` constructor option. If this option is not provided, it defaults to looking for `eslint-suppressions.json` in the `cwd` (current working directory)." + +3. Release Notes: + - Include an entry in the release notes announcing the availability of bulk suppressions in the Node.js API, **highlighting the new `suppressionsLocation` option**. + ## Drawbacks implementing this RFC as possible. --> +- API Complexity: Introduces a new option (`suppressionsLocation`) to the constructor API surface for both `ESLint` and `LegacyESLint`, slightly increasing complexity compared to only supporting the default file location. +- Performance: The overhead of potentially resolving `suppressionsLocation` and then searching for/parsing the suppression file is introduced. However, this aligns the API\'s behavior and capabilities with the CLI. +- Complexity: Introduces `SuppressionsService` interaction into `ESLint`/`LegacyESLint`, but reuses existing internal logic. + ## Backwards Compatibility Analysis to existing users? --> +This change is designed to be backward-compatible. + +- New Option is Optional: The new `suppressionsLocation` option is optional. Existing code that does not provide this option will continue to work, defaulting to the behavior of looking for `eslint-suppressions.json` in the `cwd`. +- Automatic Application: By integrating bulk suppression handling directly into the existing `lintText()` and `lintFiles()` methods, users who utilize a suppression file (either at the default location or specified via the new option) will automatically benefit simply by updating their ESLint version. +- Alignment with CLI: This approach aligns the Node.js API behavior *and configuration options* more closely with the established CLI behavior. +- Non-Breaking: Since the core change only alters behavior when a suppression file is found (based on the new option or default location), it is considered a non-breaking change for existing API consumers. + ## Alternatives projects have already implemented a similar feature. --> +- No `suppressionsLocation` API Option: The initial consideration was to *not* add the `suppressionsLocation` option to the API, only implementing the default lookup in `cwd`. This was simpler but rejected because it lacked full consistency with the CLI\'s `--suppressions-location` flag, preventing API users from specifying a custom file path. Adding the option provides greater flexibility and closer parity with the CLI. +- Separate API Method for Applying Suppressions: Introducing new methods like `lintTextWithSuppressions()` was rejected as inconsistent and burdensome for users compared to automatic application within existing methods. +- Including Suppression File Manipulation Options in `lintText`/`lintFiles`: The CLI includes flags like `--suppress-all`, `--suppress-rule `, and `--prune-suppressions` which generate, update, or prune the suppression file based on lint results. Adding corresponding options to the `lintText` and `lintFiles` API methods was considered. However, this approach was rejected because: + - It would introduce file-writing side effects into API methods primarily designed for linting (reading and analyzing code). This could lead to unexpected behavior for API consumers. + - It blurs the responsibility of the `lintText`/`lintFiles` methods. + ## Open Questions you can remove this section. --> +- Specific implementation examples for the `LegacyESLint` class. +- Should functionality equivalent to CLI flags like `--suppress-all` or `--suppress-rule` be supported via separate API methods in the future? + ## Help Needed of help would you need from the team? --> +I intend to implement this feature. + ## Frequently Asked Questions in this section. --> +Potential questions regarding alternative design approaches are addressed in the `Alternatives` section. + ## Related Discussions If there is an issue, pull request, or other URL that provides useful context for this proposal, please include those links here. --> + +### Current Usage of ESLint Node.js API + +While improving IDE support is not the primary goal of this RFC, the following investigation provides context on how various tools integrate with ESLint\'s Node.js API. + +#### IDE Integrations + +- VSCode: Uses [`ESLint.lintText()` / `LegacyESLint.lintText()`](https://github.com/microsoft/vscode-eslint/blob/c0e753713ea9935667e849d91e549adbff213e7e/server/src/eslint.ts#L1192-L1243) for validation. + +- Zed: Interacts with the `vscode-eslint` server via `--stdio`. No specific changes needed beyond updating `vscode-eslint`. + - + - + +- JetBrains IDEs: Implementation details are unknown (closed-source). + +- Neovim: Integrations like [nvim-eslint](https://github.com/esmuellert/nvim-eslint) typically use `vscode-eslint`. No specific changes needed beyond updating `vscode-eslint`. + +#### ESLint Wrappers / Utilities + +- xo: Uses [`ESLint.lintFiles()` / `ESLint.lintText()`](https://github.com/xojs/xo/blob/529e6c4ac75f6165044f7ea87bad0b9831803efd/lib/xo.ts#L333-L395) for linting. + +- eslint-interactive: Uses [`ESLint.lintFiles()`](https://github.com/mizdra/eslint-interactive/blob/96f3fa34eb6fa150056aa48c0bc2c3e322ef3549/src/core.ts#L85-L93) for linting. From c5b4134d87d0250bdbcf0298e848834c992881f5 Mon Sep 17 00:00:00 2001 From: sushichan044 <71284054+sushichan044@users.noreply.github.com> Date: Wed, 7 May 2025 00:42:01 +0900 Subject: [PATCH 03/16] add changes to cli --- designs/2025-bulk-suppressions-api/README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/designs/2025-bulk-suppressions-api/README.md b/designs/2025-bulk-suppressions-api/README.md index 8c4bda91..d9392d7c 100644 --- a/designs/2025-bulk-suppressions-api/README.md +++ b/designs/2025-bulk-suppressions-api/README.md @@ -54,6 +54,10 @@ This proposal integrates the existing bulk suppression functionality into the `E - This method takes the raw linting results and the loaded suppressions (from the resolved file path) and returns the results with suppressions applied, along with any unused suppressions. - The final, suppression-applied results will be returned to the user. +4. Changes to ESLint CLI + - With the integration of suppression handling into the `ESLint` and `LegacyESLint` APIs, the ESLint CLI (`lib/cli.js`) will be updated. + - Specifically, direct calls to `SuppressionsService` within the CLI will be removed. The CLI will now leverage the updated API methods to handle bulk suppressions, ensuring that the CLI's behavior is consistent with the API's new capabilities. This change simplifies the CLI's implementation by delegating suppression logic to the core API. + ### Example code of `lib/eslint/eslint.js` ```javascript From 8b6e9734a1b02b128d751449bf335bf968f8fe3f Mon Sep 17 00:00:00 2001 From: Kentaro Suzuki <71284054+sushichan044@users.noreply.github.com> Date: Thu, 8 May 2025 23:22:36 +0900 Subject: [PATCH 04/16] fill PR Co-authored-by: Nicholas C. Zakas --- designs/2025-bulk-suppressions-api/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/designs/2025-bulk-suppressions-api/README.md b/designs/2025-bulk-suppressions-api/README.md index d9392d7c..7437509c 100644 --- a/designs/2025-bulk-suppressions-api/README.md +++ b/designs/2025-bulk-suppressions-api/README.md @@ -1,6 +1,6 @@ - Repo: eslint/eslint - Start Date: 2025-05-06 -- RFC PR: (leave this empty, to be filled in later) +- RFC PR: https://github.com/eslint/rfcs/pull/133 - Authors: [Kentaro Suzuki](https://github.com/sushichan044) # Add support for bulk suppressions in `ESLint` and `LegacyESLint` classes From fa25623767c24c22f0aafd4bae2236103111e728 Mon Sep 17 00:00:00 2001 From: sushichan044 <71284054+sushichan044@users.noreply.github.com> Date: Wed, 28 May 2025 19:59:16 +0900 Subject: [PATCH 05/16] perf: instantiate SuppressionsService once in constructor --- designs/2025-bulk-suppressions-api/README.md | 29 ++++++++++---------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/designs/2025-bulk-suppressions-api/README.md b/designs/2025-bulk-suppressions-api/README.md index 7437509c..ddca1ed9 100644 --- a/designs/2025-bulk-suppressions-api/README.md +++ b/designs/2025-bulk-suppressions-api/README.md @@ -66,6 +66,12 @@ import { getCacheFile } from "./eslint-helpers.js"; import { SuppressionsService } from "../services/suppressions-service.js"; class ESLint { + /** + * The suppressions service to use for suppressing messages. + * @type {SuppressionsService} + */ + #suppressionsService; + constructor(options = {}) { const processedOptions = processOptions(options); @@ -77,17 +83,21 @@ class ESLint { { prefix: "suppressions_" } ); + this.#suppressionsService = new SuppressionsService({ + filepath: suppressionsFilePath, + cwd: processedOptions.cwd, + }) + privateMembers.set(this, { options: processedOptions, linter: /* ... */, lintResultCache: /* ... */, configLoader: /* ... */ - suppressionsFilePath, }); } async lintFiles(patterns) { - const { options, suppressionsFilePath, lintResultCache, /* ... other needed members */ } = privateMembers.get(this); + const { option, lintResultCache, /* ... other needed members */ } = privateMembers.get(this); let suppressionResults = null; // Existing lint logic to get initial `results` (LintResult[]) @@ -104,12 +114,7 @@ class ESLint { return finalResults; } - const suppressions = new SuppressionsService({ - filePath: suppressionsFilePath, - cwd: options.cwd, - }); - - return suppressions.applySuppressions( + return this.#suppressionsService.applySuppressions( finalResults, await suppressions.load(), ); @@ -118,7 +123,6 @@ class ESLint { async lintText(code, options = {}) { const { options: eslintOptions, // Renamed to avoid conflict with method options - suppressionsFilePath, linter, configLoader } = privateMembers.get(this); @@ -150,12 +154,7 @@ class ESLint { return processLintReport(this, { results }); } - const suppressions = new SuppressionsService({ - filePath: suppressionsFilePath, - cwd: eslintOptions.cwd, - }); - - const suppressedResults = suppressions.applySuppressions( + const suppressedResults = this.#suppressionsService.applySuppressions( results, await suppressions.load(), ); From 00ba3e9e6c7d9dc232908841b6c056a7c8ce4601 Mon Sep 17 00:00:00 2001 From: sushichan044 <71284054+sushichan044@users.noreply.github.com> Date: Wed, 28 May 2025 20:25:23 +0900 Subject: [PATCH 06/16] docs: explicitly show scope --- designs/2025-bulk-suppressions-api/README.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/designs/2025-bulk-suppressions-api/README.md b/designs/2025-bulk-suppressions-api/README.md index ddca1ed9..8ade59c2 100644 --- a/designs/2025-bulk-suppressions-api/README.md +++ b/designs/2025-bulk-suppressions-api/README.md @@ -1,15 +1,17 @@ - Repo: eslint/eslint - Start Date: 2025-05-06 -- RFC PR: https://github.com/eslint/rfcs/pull/133 +- RFC PR: - Authors: [Kentaro Suzuki](https://github.com/sushichan044) -# Add support for bulk suppressions in `ESLint` and `LegacyESLint` classes +# Consider bulk suppressions when running Lint via the Node.js API ## Summary -This RFC proposes extending the bulk suppressions feature, introduced in ESLint 9.24.0 for CLI usage, to be available through the Node.js API via the `ESLint` and `LegacyESLint` classes. +This RFC proposes integrating bulk suppressions support into the Node.js API via the `ESLint` and `LegacyESLint` classes, specifically focusing on considering existing bulk suppressions when linting files or text through the API. This change ensures that suppression files (`eslint-suppressions.json`) created via CLI commands are automatically respected when using the programmatic API, maintaining consistency between CLI and API behavior. + +The scope is limited to applying existing suppressions during linting and does not include suppression file manipulation features (such as `--suppress-all`, `--suppress-rule`, or `--prune-suppressions`), which remain CLI-exclusive functionalities. ## Motivation From 40473fd3ba2991c20222505c167d8516aa5cd3f9 Mon Sep 17 00:00:00 2001 From: sushichan044 <71284054+sushichan044@users.noreply.github.com> Date: Tue, 17 Jun 2025 10:48:58 +0900 Subject: [PATCH 07/16] we don't need to focus on privateMembers in ESLint class --- designs/2025-bulk-suppressions-api/README.md | 7 ------- 1 file changed, 7 deletions(-) diff --git a/designs/2025-bulk-suppressions-api/README.md b/designs/2025-bulk-suppressions-api/README.md index 8ade59c2..7714878b 100644 --- a/designs/2025-bulk-suppressions-api/README.md +++ b/designs/2025-bulk-suppressions-api/README.md @@ -89,13 +89,6 @@ class ESLint { filepath: suppressionsFilePath, cwd: processedOptions.cwd, }) - - privateMembers.set(this, { - options: processedOptions, - linter: /* ... */, - lintResultCache: /* ... */, - configLoader: /* ... */ - }); } async lintFiles(patterns) { From 88564b2d57b425df9831a4288c03518fe28d2edf Mon Sep 17 00:00:00 2001 From: Blake Sager Date: Tue, 23 Dec 2025 12:38:33 -0600 Subject: [PATCH 08/16] Tweak wording for clarity --- designs/2025-bulk-suppressions-api/README.md | 88 ++------------------ 1 file changed, 5 insertions(+), 83 deletions(-) diff --git a/designs/2025-bulk-suppressions-api/README.md b/designs/2025-bulk-suppressions-api/README.md index 7714878b..90e9538f 100644 --- a/designs/2025-bulk-suppressions-api/README.md +++ b/designs/2025-bulk-suppressions-api/README.md @@ -1,41 +1,26 @@ - Repo: eslint/eslint - Start Date: 2025-05-06 - RFC PR: -- Authors: [Kentaro Suzuki](https://github.com/sushichan044) +- Authors: [Kentaro Suzuki](https://github.com/sushichan044) [Blake Sager](https://github.com/adf0nt3s) # Consider bulk suppressions when running Lint via the Node.js API ## Summary - - This RFC proposes integrating bulk suppressions support into the Node.js API via the `ESLint` and `LegacyESLint` classes, specifically focusing on considering existing bulk suppressions when linting files or text through the API. This change ensures that suppression files (`eslint-suppressions.json`) created via CLI commands are automatically respected when using the programmatic API, maintaining consistency between CLI and API behavior. The scope is limited to applying existing suppressions during linting and does not include suppression file manipulation features (such as `--suppress-all`, `--suppress-rule`, or `--prune-suppressions`), which remain CLI-exclusive functionalities. ## Motivation - - Currently, the bulk suppression feature introduced in ESLint 9.24.0 is only available via the CLI. -This leads to inconsistencies when ESLint is used programmatically via its Node.js API, such as in IDE integrations. -This leads to inconsistencies when ESLint is used programmatically. Violations suppressed using `eslint-suppressions.json` (especially when using a custom location via the CLI) might not be recognized when using the Node.js API, leading to incorrect error reporting in environments like IDEs. +This leads to inconsistencies when ESLint is used programmatically via its Node.js API, such as in IDE integrations. Violations suppressed using `eslint-suppressions.json` (especially when using a custom location via the CLI) might not be recognized when using the Node.js API, leading to incorrect error reporting in environments like IDEs. This RFC aims to resolve this discrepancy by adding support for bulk suppressions to the `ESLint` and `LegacyESLint` Node.js APIs, ensuring consistent linting results and configuration capabilities across both interfaces. ## Detailed Design - - This proposal integrates the existing bulk suppression functionality into the `ESLint` and `LegacyESLint` Node.js API classes by leveraging the internal `SuppressionsService`. A new `suppressionsLocation` option is introduced in the constructors. 1. New Constructor Option (`suppressionsLocation`) @@ -47,7 +32,8 @@ This proposal integrates the existing bulk suppression functionality into the `E 2. Service Instantiation and Configuration - Upon instantiation, the `ESLint` and `LegacyESLint` constructors will create an instance of `SuppressionsService`. - A new constructor option, `suppressionsLocation` (string, optional), will be added to both classes. - - If provided, this path (relative to `cwd`) specifies the suppression file. + - If provided and relative, this path (relative to `cwd`) specifies the suppression file. + - If provided and absolute, this path (relative to `/`) specifies the suppression file. - If not provided, ESLint defaults to searching for `eslint-suppressions.json` in the `cwd`. - The constructor will resolve the final absolute path to the suppression file (using `suppressionsLocation` or the default) and pass it to the `SuppressionsService` constructor. @@ -162,11 +148,6 @@ class ESLint { ## Documentation - - The documentation updates will reflect that this change aligns the Node.js API behavior with the existing CLI functionality. 1. API Documentation (`ESLint`/`LegacyESLint` classes): @@ -183,29 +164,12 @@ The documentation updates will reflect that this change aligns the Node.js API b ## Drawbacks - - - API Complexity: Introduces a new option (`suppressionsLocation`) to the constructor API surface for both `ESLint` and `LegacyESLint`, slightly increasing complexity compared to only supporting the default file location. - Performance: The overhead of potentially resolving `suppressionsLocation` and then searching for/parsing the suppression file is introduced. However, this aligns the API\'s behavior and capabilities with the CLI. - Complexity: Introduces `SuppressionsService` interaction into `ESLint`/`LegacyESLint`, but reuses existing internal logic. ## Backwards Compatibility Analysis - - This change is designed to be backward-compatible. - New Option is Optional: The new `suppressionsLocation` option is optional. Existing code that does not provide this option will continue to work, defaulting to the behavior of looking for `eslint-suppressions.json` in the `cwd`. @@ -215,13 +179,6 @@ This change is designed to be backward-compatible. ## Alternatives - - - No `suppressionsLocation` API Option: The initial consideration was to *not* add the `suppressionsLocation` option to the API, only implementing the default lookup in `cwd`. This was simpler but rejected because it lacked full consistency with the CLI\'s `--suppressions-location` flag, preventing API users from specifying a custom file path. Adding the option provides greater flexibility and closer parity with the CLI. - Separate API Method for Applying Suppressions: Introducing new methods like `lintTextWithSuppressions()` was rejected as inconsistent and burdensome for users compared to automatic application within existing methods. - Including Suppression File Manipulation Options in `lintText`/`lintFiles`: The CLI includes flags like `--suppress-all`, `--suppress-rule `, and `--prune-suppressions` which generate, update, or prune the suppression file based on lint results. Adding corresponding options to the `lintText` and `lintFiles` API methods was considered. However, this approach was rejected because: @@ -230,51 +187,16 @@ This change is designed to be backward-compatible. ## Open Questions - - - Specific implementation examples for the `LegacyESLint` class. - Should functionality equivalent to CLI flags like `--suppress-all` or `--suppress-rule` be supported via separate API methods in the future? ## Help Needed - - I intend to implement this feature. -## Frequently Asked Questions - - - -Potential questions regarding alternative design approaches are addressed in the `Alternatives` section. - ## Related Discussions - +* Original RFC PR: https://github.com/eslint/rfcs/pull/133/files ### Current Usage of ESLint Node.js API From 680fd223f17dc1c6bd56a926f9744d8a896dac44 Mon Sep 17 00:00:00 2001 From: Blake Sager Date: Sat, 17 Jan 2026 01:39:01 -0600 Subject: [PATCH 09/16] Add new constructor variable --- designs/2025-bulk-suppressions-api/README.md | 69 ++++++++++++-------- 1 file changed, 41 insertions(+), 28 deletions(-) diff --git a/designs/2025-bulk-suppressions-api/README.md b/designs/2025-bulk-suppressions-api/README.md index 90e9538f..1257107f 100644 --- a/designs/2025-bulk-suppressions-api/README.md +++ b/designs/2025-bulk-suppressions-api/README.md @@ -23,28 +23,40 @@ This RFC aims to resolve this discrepancy by adding support for bulk suppression This proposal integrates the existing bulk suppression functionality into the `ESLint` and `LegacyESLint` Node.js API classes by leveraging the internal `SuppressionsService`. A new `suppressionsLocation` option is introduced in the constructors. -1. New Constructor Option (`suppressionsLocation`) - - Both `ESLintOptions` and `LegacyESLintOptions` will accept a new optional property: `suppressionsLocation`. - - `suppressionsLocation: string | undefined`: Specifies the path to the suppressions file (`eslint-suppressions.json`). This path can be absolute or relative to the `cwd`. - - If `suppressionsLocation` is provided, ESLint will attempt to load suppressions from that specific file path. - - If `suppressionsLocation` is not provided (or is `undefined`), ESLint will default to looking for `eslint-suppressions.json` in the `cwd`. +1. New Constructor Options + - `suppressionsLocation` + - Both `ESLintOptions` and `LegacyESLintOptions` will accept a new optional property: `suppressionsLocation`. + - `suppressionsLocation: string | undefined`: Specifies the path to the suppressions file (`eslint-suppressions.json`). This path can be absolute or relative to the `cwd`. + - If `suppressionsLocation` is provided, ESLint will attempt to load suppressions from that specific file path. + - If `suppressionsLocation` is not provided (or is `undefined`), ESLint will default to looking for `eslint-suppressions.json` in the `cwd`. + - `applySuppressions` + - Controls whether suppressions are automatically applied to results from `lintText()` and `lintFiles()`. + - If `true`, suppressions are automatically applied to lint results before returning. + - If `false`, results are returned as-is without applying suppressions. + - If not provided (or is `undefined`), defaults to `true`. 2. Service Instantiation and Configuration - Upon instantiation, the `ESLint` and `LegacyESLint` constructors will create an instance of `SuppressionsService`. - - A new constructor option, `suppressionsLocation` (string, optional), will be added to both classes. - - If provided and relative, this path (relative to `cwd`) specifies the suppression file. - - If provided and absolute, this path (relative to `/`) specifies the suppression file. - - If not provided, ESLint defaults to searching for `eslint-suppressions.json` in the `cwd`. - - The constructor will resolve the final absolute path to the suppression file (using `suppressionsLocation` or the default) and pass it to the `SuppressionsService` constructor. + - 2 new constructor options will be added to both classes. + - `suppressionsLocation` (string, optional) + - If provided and relative, this path (relative to `cwd`) specifies the suppression file. + - If provided and absolute, this path (relative to `/`) specifies the suppression file. + - If not provided, ESLint defaults to searching for `eslint-suppressions.json` in the `cwd`. + - The constructor will resolve the final absolute path to the suppression file (using `suppressionsLocation` or the default) and pass it to the `SuppressionsService` constructor. + - `applySuppressions` (boolean, optional) + - If `true`, suppressions will be applied automatically in `lintText()` and `lintFiles()`. + - If `false`, suppressions will not be applied. + - If not provided, defaults to `true`. 3. Applying Suppressions - - Within the `lintFiles()` and `lintText()` methods of both classes, *after* the initial linting results are obtained, the `applySuppressions` method of the instantiated `SuppressionsService` will be called. - - This method takes the raw linting results and the loaded suppressions (from the resolved file path) and returns the results with suppressions applied, along with any unused suppressions. - - The final, suppression-applied results will be returned to the user. + - When `applySuppressions` is `true` (the default), the `lintFiles()` and `lintText()` methods will automatically apply suppressions to results before returning. + - Within these methods, *after* the initial linting results are obtained, the `applySuppressions` method of the instantiated `SuppressionsService` will be called. + - This method takes the raw linting results and the loaded suppressions (from the resolved file path) and returns the results with suppressions applied. + - When `applySuppressions` is `false`, the raw linting results are returned without applying suppressions, allowing consumers to handle suppressions themselves. 4. Changes to ESLint CLI - - With the integration of suppression handling into the `ESLint` and `LegacyESLint` APIs, the ESLint CLI (`lib/cli.js`) will be updated. - - Specifically, direct calls to `SuppressionsService` within the CLI will be removed. The CLI will now leverage the updated API methods to handle bulk suppressions, ensuring that the CLI's behavior is consistent with the API's new capabilities. This change simplifies the CLI's implementation by delegating suppression logic to the core API. + - The CLI will instantiate `ESLint` with `applySuppressions: false` to receive raw linting results. + - The CLI will continue to call `SuppressionsService` directly to handle suppression-related flags (`--suppress-all`, `--suppress-rule`, `--prune-suppressions`) and to apply suppressions before output. ### Example code of `lib/eslint/eslint.js` @@ -61,6 +73,7 @@ class ESLint { #suppressionsService; constructor(options = {}) { + // options includes: suppressionsLocation, applySuppressions, cwd, ... const processedOptions = processOptions(options); // ... existing constructor logic to initialize options, linter, cache, configLoader ... @@ -78,8 +91,7 @@ class ESLint { } async lintFiles(patterns) { - const { option, lintResultCache, /* ... other needed members */ } = privateMembers.get(this); - let suppressionResults = null; + const { options, lintResultCache, /* ... other needed members */ } = privateMembers.get(this); // Existing lint logic to get initial `results` (LintResult[]) const results = /* LintResult[] */ @@ -91,13 +103,13 @@ class ESLint { const finalResults = results.filter(result => !!result); - if (!fs.existsSync(suppressionsFilePath)) { + if (!fs.existsSync(suppressionsFilePath) || options.applySuppressions === false) { return finalResults; - } + } return this.#suppressionsService.applySuppressions( finalResults, - await suppressions.load(), + await this.#suppressionsService.load(), ); } @@ -131,16 +143,15 @@ class ESLint { }), ); - if (!fs.existsSync(suppressionsFilePath)) { + if (!fs.existsSync(suppressionsFilePath) || eslintOptions.applySuppressions === false) { return processLintReport(this, { results }); } const suppressedResults = this.#suppressionsService.applySuppressions( results, - await suppressions.load(), + await this.#suppressionsService.load(), ); - // Return the suppression-applied results return processLintReport(this, { results: suppressedResults }); } } @@ -151,8 +162,10 @@ class ESLint { The documentation updates will reflect that this change aligns the Node.js API behavior with the existing CLI functionality. 1. API Documentation (`ESLint`/`LegacyESLint` classes): - - Add the new `suppressionsLocation` option to the constructor options documentation for both `ESLint` and `LegacyESLint`, explaining its purpose (specifying the suppression file path) and behavior (relative to `cwd`, default lookup). - - Add a note to the descriptions of `lintText()` and `lintFiles()` methods stating that suppressions are automatically applied based on the resolved suppression file path (either from `suppressionsLocation` or the default `eslint-suppressions.json` in `cwd`). Example: "Applies suppressions from the resolved suppression file (`suppressionsLocation` option or `eslint-suppressions.json` in `cwd`), if found." + - Add the new `suppressionsLocation` and `applySuppressions` options to the constructor options documentation for both `ESLint` and `LegacyESLint`. + - Document `suppressionsLocation`: its purpose (specifying the suppression file path) and behavior (relative to `cwd`, default lookup). + - Document `applySuppressions`: controls whether suppressions are automatically applied (defaults to `true`). + - Add a note to the descriptions of `lintText()` and `lintFiles()` methods stating that suppressions are automatically applied when `applySuppressions` is `true` (the default), based on the resolved suppression file path. 2. Bulk Suppressions User Guide Page: - Update the existing user guide page for Bulk Suppressions. @@ -160,11 +173,11 @@ The documentation updates will reflect that this change aligns the Node.js API b - Explicitly mention how the suppression file is located when using the API: "Note: When using the Node.js API, ESLint searches for the suppression file specified by the `suppressionsLocation` constructor option. If this option is not provided, it defaults to looking for `eslint-suppressions.json` in the `cwd` (current working directory)." 3. Release Notes: - - Include an entry in the release notes announcing the availability of bulk suppressions in the Node.js API, **highlighting the new `suppressionsLocation` option**. + - Include an entry in the release notes announcing the availability of bulk suppressions in the Node.js API, **highlighting the new `suppressionsLocation` and `applySuppressions` options**. ## Drawbacks -- API Complexity: Introduces a new option (`suppressionsLocation`) to the constructor API surface for both `ESLint` and `LegacyESLint`, slightly increasing complexity compared to only supporting the default file location. +- API Complexity: Introduces two new options (`suppressionsLocation` and `applySuppressions`) to the constructor API surface for both `ESLint` and `LegacyESLint`, slightly increasing complexity. - Performance: The overhead of potentially resolving `suppressionsLocation` and then searching for/parsing the suppression file is introduced. However, this aligns the API\'s behavior and capabilities with the CLI. - Complexity: Introduces `SuppressionsService` interaction into `ESLint`/`LegacyESLint`, but reuses existing internal logic. @@ -172,7 +185,7 @@ The documentation updates will reflect that this change aligns the Node.js API b This change is designed to be backward-compatible. -- New Option is Optional: The new `suppressionsLocation` option is optional. Existing code that does not provide this option will continue to work, defaulting to the behavior of looking for `eslint-suppressions.json` in the `cwd`. +- New Options are Optional: The new `suppressionsLocation` and `applySuppressions` options are optional. Existing code that does not provide these options will continue to work, with `applySuppressions` defaulting to `true` and `suppressionsLocation` defaulting to looking for `eslint-suppressions.json` in the `cwd`. - Automatic Application: By integrating bulk suppression handling directly into the existing `lintText()` and `lintFiles()` methods, users who utilize a suppression file (either at the default location or specified via the new option) will automatically benefit simply by updating their ESLint version. - Alignment with CLI: This approach aligns the Node.js API behavior *and configuration options* more closely with the established CLI behavior. - Non-Breaking: Since the core change only alters behavior when a suppression file is found (based on the new option or default location), it is considered a non-breaking change for existing API consumers. From 17936f430a323929997430b8af10127ea0d6386b Mon Sep 17 00:00:00 2001 From: Blake Sager Date: Fri, 23 Jan 2026 20:00:42 -0600 Subject: [PATCH 10/16] Remove mention of LegacyESLint from rfc --- designs/2025-bulk-suppressions-api/README.md | 25 ++++++++++---------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/designs/2025-bulk-suppressions-api/README.md b/designs/2025-bulk-suppressions-api/README.md index 1257107f..2f8a844d 100644 --- a/designs/2025-bulk-suppressions-api/README.md +++ b/designs/2025-bulk-suppressions-api/README.md @@ -7,7 +7,7 @@ ## Summary -This RFC proposes integrating bulk suppressions support into the Node.js API via the `ESLint` and `LegacyESLint` classes, specifically focusing on considering existing bulk suppressions when linting files or text through the API. This change ensures that suppression files (`eslint-suppressions.json`) created via CLI commands are automatically respected when using the programmatic API, maintaining consistency between CLI and API behavior. +This RFC proposes integrating bulk suppressions support into the Node.js API via the `ESLint` class, specifically focusing on considering existing bulk suppressions when linting files or text through the API. This change ensures that suppression files (`eslint-suppressions.json`) created via CLI commands are automatically respected when using the programmatic API, maintaining consistency between CLI and API behavior. The scope is limited to applying existing suppressions during linting and does not include suppression file manipulation features (such as `--suppress-all`, `--suppress-rule`, or `--prune-suppressions`), which remain CLI-exclusive functionalities. @@ -17,15 +17,15 @@ Currently, the bulk suppression feature introduced in ESLint 9.24.0 is only avai This leads to inconsistencies when ESLint is used programmatically via its Node.js API, such as in IDE integrations. Violations suppressed using `eslint-suppressions.json` (especially when using a custom location via the CLI) might not be recognized when using the Node.js API, leading to incorrect error reporting in environments like IDEs. -This RFC aims to resolve this discrepancy by adding support for bulk suppressions to the `ESLint` and `LegacyESLint` Node.js APIs, ensuring consistent linting results and configuration capabilities across both interfaces. +This RFC aims to resolve this discrepancy by adding support for bulk suppressions to the `ESLint` Node.js API, ensuring consistent linting results and configuration capabilities across both interfaces. ## Detailed Design -This proposal integrates the existing bulk suppression functionality into the `ESLint` and `LegacyESLint` Node.js API classes by leveraging the internal `SuppressionsService`. A new `suppressionsLocation` option is introduced in the constructors. +This proposal integrates the existing bulk suppression functionality into the `ESLint` Node.js API class by leveraging the internal `SuppressionsService`. A new `suppressionsLocation` option is introduced in the constructor. 1. New Constructor Options - `suppressionsLocation` - - Both `ESLintOptions` and `LegacyESLintOptions` will accept a new optional property: `suppressionsLocation`. + - `ESLintOptions` will accept a new optional property: `suppressionsLocation`. - `suppressionsLocation: string | undefined`: Specifies the path to the suppressions file (`eslint-suppressions.json`). This path can be absolute or relative to the `cwd`. - If `suppressionsLocation` is provided, ESLint will attempt to load suppressions from that specific file path. - If `suppressionsLocation` is not provided (or is `undefined`), ESLint will default to looking for `eslint-suppressions.json` in the `cwd`. @@ -36,8 +36,8 @@ This proposal integrates the existing bulk suppression functionality into the `E - If not provided (or is `undefined`), defaults to `true`. 2. Service Instantiation and Configuration - - Upon instantiation, the `ESLint` and `LegacyESLint` constructors will create an instance of `SuppressionsService`. - - 2 new constructor options will be added to both classes. + - Upon instantiation, the `ESLint` constructor will create an instance of `SuppressionsService`. + - 2 new constructor options will be added to the `ESLint` class. - `suppressionsLocation` (string, optional) - If provided and relative, this path (relative to `cwd`) specifies the suppression file. - If provided and absolute, this path (relative to `/`) specifies the suppression file. @@ -161,15 +161,15 @@ class ESLint { The documentation updates will reflect that this change aligns the Node.js API behavior with the existing CLI functionality. -1. API Documentation (`ESLint`/`LegacyESLint` classes): - - Add the new `suppressionsLocation` and `applySuppressions` options to the constructor options documentation for both `ESLint` and `LegacyESLint`. +1. API Documentation (`ESLint` class): + - Add the new `suppressionsLocation` and `applySuppressions` options to the constructor options documentation for `ESLint`. - Document `suppressionsLocation`: its purpose (specifying the suppression file path) and behavior (relative to `cwd`, default lookup). - Document `applySuppressions`: controls whether suppressions are automatically applied (defaults to `true`). - Add a note to the descriptions of `lintText()` and `lintFiles()` methods stating that suppressions are automatically applied when `applySuppressions` is `true` (the default), based on the resolved suppression file path. 2. Bulk Suppressions User Guide Page: - Update the existing user guide page for Bulk Suppressions. - - Add a section or note clarifying that the feature is now also available when using the `ESLint` and `LegacyESLint` Node.js APIs. + - Add a section or note clarifying that the feature is now also available when using the `ESLint` Node.js API. - Explicitly mention how the suppression file is located when using the API: "Note: When using the Node.js API, ESLint searches for the suppression file specified by the `suppressionsLocation` constructor option. If this option is not provided, it defaults to looking for `eslint-suppressions.json` in the `cwd` (current working directory)." 3. Release Notes: @@ -177,9 +177,9 @@ The documentation updates will reflect that this change aligns the Node.js API b ## Drawbacks -- API Complexity: Introduces two new options (`suppressionsLocation` and `applySuppressions`) to the constructor API surface for both `ESLint` and `LegacyESLint`, slightly increasing complexity. +- API Complexity: Introduces two new options (`suppressionsLocation` and `applySuppressions`) to the constructor API surface for `ESLint`, slightly increasing complexity. - Performance: The overhead of potentially resolving `suppressionsLocation` and then searching for/parsing the suppression file is introduced. However, this aligns the API\'s behavior and capabilities with the CLI. -- Complexity: Introduces `SuppressionsService` interaction into `ESLint`/`LegacyESLint`, but reuses existing internal logic. +- Complexity: Introduces `SuppressionsService` interaction into `ESLint`, but reuses existing internal logic. ## Backwards Compatibility Analysis @@ -200,7 +200,6 @@ This change is designed to be backward-compatible. ## Open Questions -- Specific implementation examples for the `LegacyESLint` class. - Should functionality equivalent to CLI flags like `--suppress-all` or `--suppress-rule` be supported via separate API methods in the future? ## Help Needed @@ -217,7 +216,7 @@ While improving IDE support is not the primary goal of this RFC, the following i #### IDE Integrations -- VSCode: Uses [`ESLint.lintText()` / `LegacyESLint.lintText()`](https://github.com/microsoft/vscode-eslint/blob/c0e753713ea9935667e849d91e549adbff213e7e/server/src/eslint.ts#L1192-L1243) for validation. +- VSCode: Uses [`ESLint.lintText()`](https://github.com/microsoft/vscode-eslint/blob/c0e753713ea9935667e849d91e549adbff213e7e/server/src/eslint.ts#L1192-L1243) for validation. - Zed: Interacts with the `vscode-eslint` server via `--stdio`. No specific changes needed beyond updating `vscode-eslint`. - From 3e7a38661ef7da8d560e7244e0cf70c57482d3d9 Mon Sep 17 00:00:00 2001 From: Blake Sager <134943191+adf0nt3s@users.noreply.github.com> Date: Fri, 23 Jan 2026 20:01:16 -0600 Subject: [PATCH 11/16] Update designs/2025-bulk-suppressions-api/README.md Co-authored-by: Milos Djermanovic --- designs/2025-bulk-suppressions-api/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/designs/2025-bulk-suppressions-api/README.md b/designs/2025-bulk-suppressions-api/README.md index 2f8a844d..167bdd16 100644 --- a/designs/2025-bulk-suppressions-api/README.md +++ b/designs/2025-bulk-suppressions-api/README.md @@ -1,6 +1,6 @@ - Repo: eslint/eslint - Start Date: 2025-05-06 -- RFC PR: +- RFC PR: - Authors: [Kentaro Suzuki](https://github.com/sushichan044) [Blake Sager](https://github.com/adf0nt3s) # Consider bulk suppressions when running Lint via the Node.js API From 2009171a6ab6fd34167d41701fb26a79cf1fac90 Mon Sep 17 00:00:00 2001 From: Blake Sager Date: Fri, 23 Jan 2026 20:30:37 -0600 Subject: [PATCH 12/16] Clarify caching behavior when applySuppressions is true --- designs/2025-bulk-suppressions-api/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/designs/2025-bulk-suppressions-api/README.md b/designs/2025-bulk-suppressions-api/README.md index 167bdd16..763c0539 100644 --- a/designs/2025-bulk-suppressions-api/README.md +++ b/designs/2025-bulk-suppressions-api/README.md @@ -52,6 +52,7 @@ This proposal integrates the existing bulk suppression functionality into the `E - When `applySuppressions` is `true` (the default), the `lintFiles()` and `lintText()` methods will automatically apply suppressions to results before returning. - Within these methods, *after* the initial linting results are obtained, the `applySuppressions` method of the instantiated `SuppressionsService` will be called. - This method takes the raw linting results and the loaded suppressions (from the resolved file path) and returns the results with suppressions applied. + - When caching is enabled, the **original lint results** are stored in the cache. Suppressions are applied after cache retrieval, so that changes to the suppression file take effect without needing to bust the cache. - When `applySuppressions` is `false`, the raw linting results are returned without applying suppressions, allowing consumers to handle suppressions themselves. 4. Changes to ESLint CLI From ab726a85f19ab276cf0db2ece71dd7b62172a226 Mon Sep 17 00:00:00 2001 From: Blake Sager Date: Sat, 31 Jan 2026 16:32:13 -0600 Subject: [PATCH 13/16] Default applySuppressions for backwards-compat CYA --- designs/2025-bulk-suppressions-api/README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/designs/2025-bulk-suppressions-api/README.md b/designs/2025-bulk-suppressions-api/README.md index 763c0539..2fa2b899 100644 --- a/designs/2025-bulk-suppressions-api/README.md +++ b/designs/2025-bulk-suppressions-api/README.md @@ -33,7 +33,7 @@ This proposal integrates the existing bulk suppression functionality into the `E - Controls whether suppressions are automatically applied to results from `lintText()` and `lintFiles()`. - If `true`, suppressions are automatically applied to lint results before returning. - If `false`, results are returned as-is without applying suppressions. - - If not provided (or is `undefined`), defaults to `true`. + - If not provided (or is `undefined`), defaults to `false`. (This is to preserve backwards compatibility for existing API users who may not expect suppressions to be applied automatically. We may consider changing this default to `true` in a future major release.) 2. Service Instantiation and Configuration - Upon instantiation, the `ESLint` constructor will create an instance of `SuppressionsService`. @@ -46,10 +46,10 @@ This proposal integrates the existing bulk suppression functionality into the `E - `applySuppressions` (boolean, optional) - If `true`, suppressions will be applied automatically in `lintText()` and `lintFiles()`. - If `false`, suppressions will not be applied. - - If not provided, defaults to `true`. + - If not provided, defaults to `false`. 3. Applying Suppressions - - When `applySuppressions` is `true` (the default), the `lintFiles()` and `lintText()` methods will automatically apply suppressions to results before returning. + - When `applySuppressions` is `true`, the `lintFiles()` and `lintText()` methods will automatically apply suppressions to results before returning. - Within these methods, *after* the initial linting results are obtained, the `applySuppressions` method of the instantiated `SuppressionsService` will be called. - This method takes the raw linting results and the loaded suppressions (from the resolved file path) and returns the results with suppressions applied. - When caching is enabled, the **original lint results** are stored in the cache. Suppressions are applied after cache retrieval, so that changes to the suppression file take effect without needing to bust the cache. @@ -165,8 +165,8 @@ The documentation updates will reflect that this change aligns the Node.js API b 1. API Documentation (`ESLint` class): - Add the new `suppressionsLocation` and `applySuppressions` options to the constructor options documentation for `ESLint`. - Document `suppressionsLocation`: its purpose (specifying the suppression file path) and behavior (relative to `cwd`, default lookup). - - Document `applySuppressions`: controls whether suppressions are automatically applied (defaults to `true`). - - Add a note to the descriptions of `lintText()` and `lintFiles()` methods stating that suppressions are automatically applied when `applySuppressions` is `true` (the default), based on the resolved suppression file path. + - Document `applySuppressions`: controls whether suppressions are automatically applied (defaults to `false`). + - Add a note to the descriptions of `lintText()` and `lintFiles()` methods stating that suppressions are automatically applied when `applySuppressions` is `true`, based on the resolved suppression file path. 2. Bulk Suppressions User Guide Page: - Update the existing user guide page for Bulk Suppressions. @@ -186,8 +186,8 @@ The documentation updates will reflect that this change aligns the Node.js API b This change is designed to be backward-compatible. -- New Options are Optional: The new `suppressionsLocation` and `applySuppressions` options are optional. Existing code that does not provide these options will continue to work, with `applySuppressions` defaulting to `true` and `suppressionsLocation` defaulting to looking for `eslint-suppressions.json` in the `cwd`. -- Automatic Application: By integrating bulk suppression handling directly into the existing `lintText()` and `lintFiles()` methods, users who utilize a suppression file (either at the default location or specified via the new option) will automatically benefit simply by updating their ESLint version. +- New Options are Optional: The new `suppressionsLocation` and `applySuppressions` options are optional. Existing code that does not provide these options will continue to work, with `applySuppressions` defaulting to `false` and `suppressionsLocation` defaulting to looking for `eslint-suppressions.json` in the `cwd`. +- Opt-in Application: Bulk suppression handling is integrated directly into the existing `lintText()` and `lintFiles()` methods but is opt-in. Users who utilize a suppression file must set `applySuppressions: true` to have suppressions applied automatically. This preserves backwards compatibility for existing API consumers. - Alignment with CLI: This approach aligns the Node.js API behavior *and configuration options* more closely with the established CLI behavior. - Non-Breaking: Since the core change only alters behavior when a suppression file is found (based on the new option or default location), it is considered a non-breaking change for existing API consumers. From 788997c539c2762290e37cb02cae660cb6bf9115 Mon Sep 17 00:00:00 2001 From: Blake Sager Date: Sun, 1 Feb 2026 14:44:51 -0600 Subject: [PATCH 14/16] Update missed default change and drop fs check for suppressions file --- designs/2025-bulk-suppressions-api/README.md | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/designs/2025-bulk-suppressions-api/README.md b/designs/2025-bulk-suppressions-api/README.md index 2fa2b899..a08139ab 100644 --- a/designs/2025-bulk-suppressions-api/README.md +++ b/designs/2025-bulk-suppressions-api/README.md @@ -94,6 +94,8 @@ class ESLint { async lintFiles(patterns) { const { options, lintResultCache, /* ... other needed members */ } = privateMembers.get(this); + const { filePath...otherOptions } = options || {}; + // Existing lint logic to get initial `results` (LintResult[]) const results = /* LintResult[] */ @@ -121,7 +123,7 @@ class ESLint { configLoader } = privateMembers.get(this); - const { filePath: providedFilePath, warnIgnored, ...otherOptions } = options || {}; + const { filePath, warnIgnored, ...otherOptions } = options || {}; const results = []; @@ -144,7 +146,7 @@ class ESLint { }), ); - if (!fs.existsSync(suppressionsFilePath) || eslintOptions.applySuppressions === false) { + if (!filePath || eslintOptions.applySuppressions === false) { return processLintReport(this, { results }); } @@ -165,8 +167,8 @@ The documentation updates will reflect that this change aligns the Node.js API b 1. API Documentation (`ESLint` class): - Add the new `suppressionsLocation` and `applySuppressions` options to the constructor options documentation for `ESLint`. - Document `suppressionsLocation`: its purpose (specifying the suppression file path) and behavior (relative to `cwd`, default lookup). - - Document `applySuppressions`: controls whether suppressions are automatically applied (defaults to `false`). - - Add a note to the descriptions of `lintText()` and `lintFiles()` methods stating that suppressions are automatically applied when `applySuppressions` is `true`, based on the resolved suppression file path. + - Document `applySuppressions`: controls whether suppressions are automatically applied (defaults to `true`). + - Add a note to the descriptions of `lintText()` and `lintFiles()` methods stating that suppressions are automatically applied when `applySuppressions` is `true` (the default), based on the resolved suppression file path. 2. Bulk Suppressions User Guide Page: - Update the existing user guide page for Bulk Suppressions. @@ -186,8 +188,8 @@ The documentation updates will reflect that this change aligns the Node.js API b This change is designed to be backward-compatible. -- New Options are Optional: The new `suppressionsLocation` and `applySuppressions` options are optional. Existing code that does not provide these options will continue to work, with `applySuppressions` defaulting to `false` and `suppressionsLocation` defaulting to looking for `eslint-suppressions.json` in the `cwd`. -- Opt-in Application: Bulk suppression handling is integrated directly into the existing `lintText()` and `lintFiles()` methods but is opt-in. Users who utilize a suppression file must set `applySuppressions: true` to have suppressions applied automatically. This preserves backwards compatibility for existing API consumers. +- New Options are Optional: The new `suppressionsLocation` and `applySuppressions` options are optional. Existing code that does not provide these options will continue to work, with `applySuppressions` defaulting to `true` and `suppressionsLocation` defaulting to looking for `eslint-suppressions.json` in the `cwd`. +- Automatic Application: By integrating bulk suppression handling directly into the existing `lintText()` and `lintFiles()` methods, users who utilize a suppression file (either at the default location or specified via the new option) will automatically benefit simply by updating their ESLint version. - Alignment with CLI: This approach aligns the Node.js API behavior *and configuration options* more closely with the established CLI behavior. - Non-Breaking: Since the core change only alters behavior when a suppression file is found (based on the new option or default location), it is considered a non-breaking change for existing API consumers. From 1cf84238dbd1eda7de445b409bdda5291cc37d5e Mon Sep 17 00:00:00 2001 From: Blake Sager Date: Sun, 1 Feb 2026 20:19:31 -0600 Subject: [PATCH 15/16] Fix lingering default: true reference --- designs/2025-bulk-suppressions-api/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/designs/2025-bulk-suppressions-api/README.md b/designs/2025-bulk-suppressions-api/README.md index a08139ab..4560aece 100644 --- a/designs/2025-bulk-suppressions-api/README.md +++ b/designs/2025-bulk-suppressions-api/README.md @@ -188,7 +188,7 @@ The documentation updates will reflect that this change aligns the Node.js API b This change is designed to be backward-compatible. -- New Options are Optional: The new `suppressionsLocation` and `applySuppressions` options are optional. Existing code that does not provide these options will continue to work, with `applySuppressions` defaulting to `true` and `suppressionsLocation` defaulting to looking for `eslint-suppressions.json` in the `cwd`. +- New Options are Optional: The new `suppressionsLocation` and `applySuppressions` options are optional. Existing code that does not provide these options will continue to work, with `applySuppressions` defaulting to `false` and `suppressionsLocation` defaulting to looking for `eslint-suppressions.json` in the `cwd`. - Automatic Application: By integrating bulk suppression handling directly into the existing `lintText()` and `lintFiles()` methods, users who utilize a suppression file (either at the default location or specified via the new option) will automatically benefit simply by updating their ESLint version. - Alignment with CLI: This approach aligns the Node.js API behavior *and configuration options* more closely with the established CLI behavior. - Non-Breaking: Since the core change only alters behavior when a suppression file is found (based on the new option or default location), it is considered a non-breaking change for existing API consumers. From 9217c6a60d0d1be24c53b8fdd9fc661c5d533a3f Mon Sep 17 00:00:00 2001 From: Blake Sager Date: Sun, 1 Feb 2026 21:09:42 -0600 Subject: [PATCH 16/16] Remove unnecessary check from lintFiles spec --- designs/2025-bulk-suppressions-api/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/designs/2025-bulk-suppressions-api/README.md b/designs/2025-bulk-suppressions-api/README.md index 4560aece..3d19127c 100644 --- a/designs/2025-bulk-suppressions-api/README.md +++ b/designs/2025-bulk-suppressions-api/README.md @@ -106,7 +106,7 @@ class ESLint { const finalResults = results.filter(result => !!result); - if (!fs.existsSync(suppressionsFilePath) || options.applySuppressions === false) { + if (options.applySuppressions === false) { return finalResults; }