Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: eslint/eslint
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v9.10.0
Choose a base ref
...
head repository: eslint/eslint
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v9.11.0
Choose a head ref

Commits on Sep 7, 2024

  1. docs: Update README

    GitHub Actions Bot committed Sep 7, 2024
    Copy the full SHA
    4edac1a View commit details

Commits on Sep 8, 2024

  1. docs: Update README

    GitHub Actions Bot committed Sep 8, 2024
    Copy the full SHA
    adcc50d View commit details

Commits on Sep 10, 2024

  1. chore: enable $ExpectType comments in .ts files (#18869)

    * chore: enable `$ExpectType` comments in .ts files
    
    * Update eslint.config.js
    
    Co-authored-by: Nicholas C. Zakas <nicholas@humanwhocodes.com>
    
    * ignore .ts files in lib/types
    
    ---------
    
    Co-authored-by: Nicholas C. Zakas <nicholas@humanwhocodes.com>
    fasttime and nzakas authored Sep 10, 2024
    Copy the full SHA
    a416f0a View commit details
  2. chore: Update change.yml (#18882)

    nzakas authored Sep 10, 2024
    Copy the full SHA
    78b2421 View commit details

Commits on Sep 11, 2024

  1. docs: clarify resultsMeta in LoadedFormatter type (#18881)

    Refs #18821
    mdjermanovic authored Sep 11, 2024

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    59cfc0f View commit details
  2. chore: update dependency @eslint/core to ^0.6.0 (#18863)

    Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
    renovate[bot] authored Sep 11, 2024

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    d594ddd View commit details
  3. feat: add type FormatterFunction, update LoadedFormatter (#18872)

    * feat: add type `FormatterFunction`, update `LoadedFormatter`
    
    * add TypeDoc for `FormatterFunction`
    
    * mark second argument of `FormatterFunction` as required, update TypeDoc
    fasttime authored Sep 11, 2024

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    a48f8c2 View commit details
  4. refactor: use Directive class from @eslint/plugin-kit (#18884)

    mdjermanovic authored Sep 11, 2024

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    7b852ce View commit details

Commits on Sep 12, 2024

  1. chore: Add PR note to all templates (#18892)

    nzakas authored Sep 12, 2024

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    2c2805f View commit details

Commits on Sep 13, 2024

  1. refactor: use optional chaining when validating config rules (#18893)

    * refactor: use optional chaining when validating config rules
    
    This change reduces the number of "&&" while still keeping the same behavior
    
    * refactor: use optional chaining when validating config rules
    
    * refactor: use optional chaining when validating config rules
    lucasrmendonca authored Sep 13, 2024

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    71f37c5 View commit details

Commits on Sep 16, 2024

  1. fix: add missing types for camelcase options (#18897)

    kripod authored Sep 16, 2024

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    a0deed1 View commit details
  2. fix: add missing types for no-empty-function options (#18901)

    kripod authored Sep 16, 2024

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    fa11b2e View commit details
  3. feat: Add no-useless-constructor suggestion (#18799)

    * feat: add fixer for `no-useless-constructor` & tests
    
    * docs: updated docs
    
    * changed to suggestion
    
    * added suggestion messageId
    
    * support automatic semi insertion
    
    * added deleted test
    
    * add failing test
    
    * altered logic
    
    * using `unIndent`
    imjordanxd authored Sep 16, 2024

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    19c6856 View commit details
  4. fix: add missing types for no-implicit-coercion options (#18903)

    kripod authored Sep 16, 2024

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    c153084 View commit details
  5. fix: add missing types for no-misleading-character-class options (#…

    kripod authored Sep 16, 2024

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    2de5742 View commit details
  6. feat: limit the name given to ImportSpecifier in id-length (#18861)

    * feat: report name given to ImportSpecifier
    
    * update code
    
    * no error on same local name
    
    * add more tests
    Tanujkanti4441 authored Sep 16, 2024

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    492eb8f View commit details
  7. chore: updates for v8.57.1 release

    Jenkins committed Sep 16, 2024
    Copy the full SHA
    6d4484d View commit details
  8. build: Support updates to previous major versions (#18871)

    * build: Support updates to previous major versions
    
    * fix options name
    
    * add docs about release parameters
    
    * upgrade eslint-release
    
    * update tables
    
    * Fix typo
    
    Co-authored-by: Nitin Kumar <snitin315@gmail.com>
    
    ---------
    
    Co-authored-by: Nitin Kumar <snitin315@gmail.com>
    mdjermanovic and snitin315 authored Sep 16, 2024
    Copy the full SHA
    959d360 View commit details

Commits on Sep 17, 2024

  1. docs: add unicode abbreviations in no-irregular-whitespace rule (#18894)

    * docs: add unicode abbreviations in no-irregular-whitespace rule
    
    * docs: add more abbreviations
    
    Co-authored-by: Milos Djermanovic <milos.djermanovic@gmail.com>
    
    ---------
    
    Co-authored-by: Milos Djermanovic <milos.djermanovic@gmail.com>
    alixroyere and mdjermanovic authored Sep 17, 2024
    Copy the full SHA
    91cbd18 View commit details

Commits on Sep 18, 2024

  1. feat: Add language to types (#18917)

    nzakas authored Sep 18, 2024
    Copy the full SHA
    c591da6 View commit details
  2. feat: add "eslint/universal" to export Linter (#18883)

    * feat: add "eslint/universal" to export `Linter`
    
    fixes #18715
    
    * fix: add lib/universal.js
    
    * feat: add typings
    
    * chore: add tests for "eslint/universal" types
    
    * Update lib/types/universal.d.ts
    
    Co-authored-by: Francesco Trotta <github@fasttime.org>
    
    * chore: update types tests
    
    ---------
    
    Co-authored-by: Francesco Trotta <github@fasttime.org>
    aladdin-add and fasttime authored Sep 18, 2024
    Copy the full SHA
    ec30c73 View commit details

Commits on Sep 19, 2024

  1. refactor: Extract processor logic into ProcessorService (#18818)

    * refactor: Extract processor logic into ProcessorService
    
    * Remove .only
    
    * Fix failing tests
    
    * Remove extra file
    
    * Add test for BOM
    
    * Update lib/linter/vfile.js
    
    Co-authored-by: Milos Djermanovic <milos.djermanovic@gmail.com>
    
    * Apply feedback and add tests
    
    ---------
    
    Co-authored-by: Milos Djermanovic <milos.djermanovic@gmail.com>
    nzakas and mdjermanovic authored Sep 19, 2024
    Copy the full SHA
    e4e02cc View commit details
  2. fix: add missing types for no-extra-boolean-cast options (#18902)

    kripod authored Sep 19, 2024
    Copy the full SHA
    d715781 View commit details
  3. fix: add missing types for no-param-reassign options (#18906)

    * fix: add missing types for `no-param-reassign` options
    
    * refactor: improve types for `no-param-reassign`
    kripod authored Sep 19, 2024
    Copy the full SHA
    8f630eb View commit details
  4. docs: correct prefer-object-has-own type definition comment (#18924)

    snitin315 authored Sep 19, 2024
    Copy the full SHA
    e4e5709 View commit details

Commits on Sep 20, 2024

  1. fix: add missing types for no-restricted-exports rule (#18914)

    kripod authored Sep 20, 2024
    Copy the full SHA
    5e5f39b View commit details
  2. chore: package.json update for @eslint/js release

    Jenkins committed Sep 20, 2024
    Copy the full SHA
    a10f90a View commit details
  3. chore: upgrade @eslint/js@9.11.0 (#18927)

    mdjermanovic authored Sep 20, 2024
    Copy the full SHA
    ca21a64 View commit details
  4. Build: changelog update for 9.11.0

    Jenkins committed Sep 20, 2024
    Copy the full SHA
    4cc6637 View commit details
  5. 9.11.0

    Jenkins committed Sep 20, 2024
    Copy the full SHA
    26baf40 View commit details
Showing with 924 additions and 266 deletions.
  1. +8 −5 .github/ISSUE_TEMPLATE/bug-report.yml
  2. +3 −0 .github/ISSUE_TEMPLATE/change.yml
  3. +3 −0 .github/ISSUE_TEMPLATE/docs.yml
  4. +3 −0 .github/ISSUE_TEMPLATE/new-rule.yml
  5. +3 −0 .github/ISSUE_TEMPLATE/new-syntax.yml
  6. +3 −0 .github/ISSUE_TEMPLATE/rule-change.yml
  7. +51 −0 CHANGELOG.md
  8. +48 −15 Makefile.js
  9. +2 −2 README.md
  10. +1 −1 docs/package.json
  11. +1 −1 docs/src/_data/rules.json
  12. +2 −1 docs/src/_data/rules_meta.json
  13. +2 −2 docs/src/_data/versions.json
  14. +2 −2 docs/src/integrate/nodejs-api.md
  15. +41 −0 docs/src/maintain/manage-releases.md
  16. +15 −15 docs/src/rules/no-irregular-whitespace.md
  17. +1 −1 docs/src/use/formatters/html-formatter-example.html
  18. +22 −4 eslint.config.js
  19. +1 −5 lib/config/flat-config-helpers.js
  20. +1 −52 lib/languages/js/source-code/source-code.js
  21. +145 −108 lib/linter/linter.js
  22. +8 −1 lib/linter/vfile.js
  23. +7 −0 lib/rules/id-length.js
  24. +18 −2 lib/rules/no-useless-constructor.js
  25. +109 −0 lib/services/processor-service.js
  26. +1 −1 lib/shared/types.js
  27. +38 −5 lib/types/index.d.ts
  28. +20 −12 lib/types/rules/best-practices.d.ts
  29. +46 −0 lib/types/rules/ecmascript-6.d.ts
  30. +35 −2 lib/types/rules/possible-errors.d.ts
  31. +10 −0 lib/types/rules/stylistic-issues.d.ts
  32. +6 −0 lib/types/universal.d.ts
  33. +10 −0 lib/universal.js
  34. +13 −6 package.json
  35. +1 −1 packages/js/package.json
  36. +30 −0 tests/lib/eslint/eslint.js
  37. +41 −0 tests/lib/linter/linter.js
  38. +5 −0 tests/lib/linter/vfile.js
  39. +13 −0 tests/lib/rules/id-length.js
  40. +85 −9 tests/lib/rules/no-useless-constructor.js
  41. +49 −13 tests/lib/types/types.test.ts
  42. +21 −0 tests/lib/universal.js
13 changes: 8 additions & 5 deletions .github/ISSUE_TEMPLATE/bug-report.yml
Original file line number Diff line number Diff line change
@@ -15,11 +15,11 @@ body:
description: |
Please tell us about how you're running ESLint (Run `npx eslint --env-info`.)
value: |
Node version:
npm version:
Local ESLint version:
Global ESLint version:
Operating System:
Node version:
npm version:
Local ESLint version:
Global ESLint version:
Operating System:
validations:
required: true
- type: dropdown
@@ -87,6 +87,9 @@ body:
options:
- label: I am willing to submit a pull request for this issue.
required: false
- type: markdown
attributes:
value: Please **do not** open a pull request until this issue has been accepted by the team.
- type: textarea
id: comments
attributes:
3 changes: 3 additions & 0 deletions .github/ISSUE_TEMPLATE/change.yml
Original file line number Diff line number Diff line change
@@ -41,6 +41,9 @@ body:
options:
- label: I am willing to submit a pull request for this change.
required: false
- type: markdown
attributes:
value: Please **do not** open a pull request until this issue has been accepted by the team.
- type: textarea
attributes:
label: Additional comments
3 changes: 3 additions & 0 deletions .github/ISSUE_TEMPLATE/docs.yml
Original file line number Diff line number Diff line change
@@ -40,6 +40,9 @@ body:
options:
- label: I am willing to submit a pull request for this change.
required: false
- type: markdown
attributes:
value: Please **do not** open a pull request until this issue has been accepted by the team.
- type: textarea
attributes:
label: Additional comments
3 changes: 3 additions & 0 deletions .github/ISSUE_TEMPLATE/new-rule.yml
Original file line number Diff line number Diff line change
@@ -47,6 +47,9 @@ body:
options:
- label: I am willing to submit a pull request to implement this rule.
required: false
- type: markdown
attributes:
value: Please **do not** open a pull request until this issue has been accepted by the team.
- type: textarea
attributes:
label: Additional comments
3 changes: 3 additions & 0 deletions .github/ISSUE_TEMPLATE/new-syntax.yml
Original file line number Diff line number Diff line change
@@ -54,6 +54,9 @@ body:
options:
- label: I am willing to submit a pull request for this change.
required: false
- type: markdown
attributes:
value: Please **do not** open a pull request until this issue has been accepted by the team.
- type: textarea
attributes:
label: Additional comments
3 changes: 3 additions & 0 deletions .github/ISSUE_TEMPLATE/rule-change.yml
Original file line number Diff line number Diff line change
@@ -55,6 +55,9 @@ body:
options:
- label: I am willing to submit a pull request to implement this change.
required: false
- type: markdown
attributes:
value: Please **do not** open a pull request until this issue has been accepted by the team.
- type: textarea
attributes:
label: Additional comments
51 changes: 51 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,54 @@
v9.11.0 - September 20, 2024

* [`ca21a64`](https://github.com/eslint/eslint/commit/ca21a64ed0f59adb9dadcef2fc8f7248879edbd3) chore: upgrade @eslint/js@9.11.0 (#18927) (Milos Djermanovic)
* [`a10f90a`](https://github.com/eslint/eslint/commit/a10f90af35aea9ac555b1f33106fbba1027d774e) chore: package.json update for @eslint/js release (Jenkins)
* [`5e5f39b`](https://github.com/eslint/eslint/commit/5e5f39b82535f59780ce4be56d01fd1466029c25) fix: add missing types for `no-restricted-exports` rule (#18914) (Kristóf Poduszló)
* [`e4e5709`](https://github.com/eslint/eslint/commit/e4e570952249d1c4fde59c79a0f49a38490b72c9) docs: correct `prefer-object-has-own` type definition comment (#18924) (Nitin Kumar)
* [`8f630eb`](https://github.com/eslint/eslint/commit/8f630eb5794ef9fe38e0b8f034287650def634bd) fix: add missing types for `no-param-reassign` options (#18906) (Kristóf Poduszló)
* [`d715781`](https://github.com/eslint/eslint/commit/d71578124f14d6da3fa5ab5cc391bb6c9ac3ffcf) fix: add missing types for `no-extra-boolean-cast` options (#18902) (Kristóf Poduszló)
* [`e4e02cc`](https://github.com/eslint/eslint/commit/e4e02cc6938f38ad5028bb8ad82f52460a18dea5) refactor: Extract processor logic into ProcessorService (#18818) (Nicholas C. Zakas)
* [`ec30c73`](https://github.com/eslint/eslint/commit/ec30c7349e0bc2c37465a036e8c7ea3318ac2328) feat: add "eslint/universal" to export `Linter` (#18883) (唯然)
* [`c591da6`](https://github.com/eslint/eslint/commit/c591da68d4a96aa28df68f4eff7641f42af82b15) feat: Add language to types (#18917) (Nicholas C. Zakas)
* [`91cbd18`](https://github.com/eslint/eslint/commit/91cbd18c70dee2ef73de8d8e43f2c744fd173934) docs: add unicode abbreviations in no-irregular-whitespace rule (#18894) (Alix Royere)
* [`959d360`](https://github.com/eslint/eslint/commit/959d360be597d3112b10590018cd52f1d98712d6) build: Support updates to previous major versions (#18871) (Milos Djermanovic)
* [`6d4484d`](https://github.com/eslint/eslint/commit/6d4484d9c19e4132f3dee948174a543dbbb5d30f) chore: updates for v8.57.1 release (Jenkins)
* [`492eb8f`](https://github.com/eslint/eslint/commit/492eb8f34ebbc5c9d1dbfcf4dd06b8dde8d1df74) feat: limit the name given to `ImportSpecifier` in `id-length` (#18861) (Tanuj Kanti)
* [`2de5742`](https://github.com/eslint/eslint/commit/2de5742682ec45e24dca9ca7faaa45330497fca9) fix: add missing types for `no-misleading-character-class` options (#18905) (Kristóf Poduszló)
* [`c153084`](https://github.com/eslint/eslint/commit/c153084250673b31bed46e3fe6af7a65b4ce8d6f) fix: add missing types for `no-implicit-coercion` options (#18903) (Kristóf Poduszló)
* [`19c6856`](https://github.com/eslint/eslint/commit/19c685608d134d9120a129cc80c0ba7f8f016aa3) feat: Add `no-useless-constructor` suggestion (#18799) (Jordan Thomson)
* [`fa11b2e`](https://github.com/eslint/eslint/commit/fa11b2ede6e5dc1f55dfe4b9b65d9760828900e8) fix: add missing types for `no-empty-function` options (#18901) (Kristóf Poduszló)
* [`a0deed1`](https://github.com/eslint/eslint/commit/a0deed122a9676fab07b903c8d16fbf60b92eadf) fix: add missing types for `camelcase` options (#18897) (Kristóf Poduszló)
* [`71f37c5`](https://github.com/eslint/eslint/commit/71f37c5bf04afb704232d312cc6c72c957d1c14e) refactor: use optional chaining when validating config rules (#18893) (lucasrmendonca)
* [`2c2805f`](https://github.com/eslint/eslint/commit/2c2805f8ee0fb1f27f3e442de248f45e5a98a067) chore: Add PR note to all templates (#18892) (Nicholas C. Zakas)
* [`7b852ce`](https://github.com/eslint/eslint/commit/7b852ce59e6ed56931c080aa46ab548fa57feffc) refactor: use `Directive` class from `@eslint/plugin-kit` (#18884) (Milos Djermanovic)
* [`a48f8c2`](https://github.com/eslint/eslint/commit/a48f8c29b58c27d87dbf202d55a5770d678d37d6) feat: add type `FormatterFunction`, update `LoadedFormatter` (#18872) (Francesco Trotta)
* [`d594ddd`](https://github.com/eslint/eslint/commit/d594ddd2cc9b0c251291ea12fbd14ccd2ee32ac7) chore: update dependency @eslint/core to ^0.6.0 (#18863) (renovate[bot])
* [`59cfc0f`](https://github.com/eslint/eslint/commit/59cfc0f1b3bbb62260602579f79bd1c36ab5a00f) docs: clarify `resultsMeta` in `LoadedFormatter` type (#18881) (Milos Djermanovic)
* [`78b2421`](https://github.com/eslint/eslint/commit/78b2421e28f29206fe120ae1b03804b1b79e6324) chore: Update change.yml (#18882) (Nicholas C. Zakas)
* [`a416f0a`](https://github.com/eslint/eslint/commit/a416f0a270e922c86e8571e94a30fc87d72fa873) chore: enable `$ExpectType` comments in .ts files (#18869) (Francesco Trotta)
* [`adcc50d`](https://github.com/eslint/eslint/commit/adcc50dbf1fb98c0884f841e2a627796a4490373) docs: Update README (GitHub Actions Bot)
* [`4edac1a`](https://github.com/eslint/eslint/commit/4edac1a325a832804f76602736a86217b40f69ac) docs: Update README (GitHub Actions Bot)

v8.57.1 - September 16, 2024

* [`140ec45`](https://github.com/eslint/eslint/commit/140ec4569fda5a974b6964242b0b2991828a5567) chore: upgrade @eslint/js@8.57.1 (#18913) (Milos Djermanovic)
* [`bcdfc04`](https://github.com/eslint/eslint/commit/bcdfc04a69c53dbf1fc3d38603fe0a796bf2274d) chore: package.json update for @eslint/js release (Jenkins)
* [`3f6ce8d`](https://github.com/eslint/eslint/commit/3f6ce8d6b74aba0d645448e898f271825eeb9630) chore: pin vite-plugin-commonjs@0.10.1 (#18910) (Milos Djermanovic)
* [`a19072f`](https://github.com/eslint/eslint/commit/a19072f9f17ea8266bc66193e5f8a4bf1368835d) fix: add logic to handle fixTypes in the lintText() method (#18900) (Francesco Trotta)
* [`04c7188`](https://github.com/eslint/eslint/commit/04c718865b75a95ebfc4d429b8c9fad773228624) fix: Don't lint same file multiple times (#18899) (Francesco Trotta)
* [`87ec3c4`](https://github.com/eslint/eslint/commit/87ec3c49dd23ab8892bc19aae711292d03a73483) fix: do not throw when defining a global named `__defineSetter__` (#18898) (Francesco Trotta)
* [`60a1267`](https://github.com/eslint/eslint/commit/60a12676878c3fe0623c3b93e7565f003daac5f0) fix: Provide helpful error message for nullish configs (#18889) (Milos Djermanovic)
* [`35d366a`](https://github.com/eslint/eslint/commit/35d366aed6e8ab0cfa8f9c9bac4656e3784c11f6) build: Support updates to previous major versions (#18870) (Milos Djermanovic)
* [`a0dea8e`](https://github.com/eslint/eslint/commit/a0dea8ee01cc4c1b65927562afd3a46418573a02) fix: allow `name` in global ignores, fix `--no-ignore` for non-global (#18875) (Milos Djermanovic)
* [`3836bb4`](https://github.com/eslint/eslint/commit/3836bb48d3f12058ec36c2edf2ca1b50eb1c923b) fix: do not crash on error in `fs.walk` filter (#18886) (Milos Djermanovic)
* [`2dec349`](https://github.com/eslint/eslint/commit/2dec349199df4cba1554172ad38163cc09ad0a52) fix: skip processor code blocks that match only universal patterns (#18880) (Milos Djermanovic)
* [`6a5add4`](https://github.com/eslint/eslint/commit/6a5add41e80941c7253b56b02815ac316e583006) docs: v8.x Add EOL banner (#18744) (Amaresh S M)
* [`b034575`](https://github.com/eslint/eslint/commit/b034575978e3bb57e2edca0d2dc547c7a3abc928) docs: v8.x add version support page to the dropdown (#18731) (Amaresh S M)
* [`760ef7d`](https://github.com/eslint/eslint/commit/760ef7d9dbd7b615ccbdc20f02cbc05dbabbada8) docs: v8.x add version support page in the side navbar (#18740) (Amaresh S M)
* [`428b7ea`](https://github.com/eslint/eslint/commit/428b7ea0a9c086b7d8afa0adb629b09d7347d41d) docs: Add Powered by Algolia label to the search (#18658) (Amaresh S M)
* [`9f07549`](https://github.com/eslint/eslint/commit/9f0754979527d05cd0abb2ea7ab1c3563fb4a361) chore: ignore `/docs/v8.x` in link checker (#18660) (Milos Djermanovic)
* [`c68c07f`](https://github.com/eslint/eslint/commit/c68c07ff44c180952e93c6f2c860079db6291b29) docs: version selectors synchronization (#18265) (Milos Djermanovic)

v9.10.0 - September 6, 2024

* [`24c3ff7`](https://github.com/eslint/eslint/commit/24c3ff7d0c0bd8b98994e04f0870cbec94c5801d) chore: upgrade to @eslint/js@9.10.0 (#18866) (Francesco Trotta)
63 changes: 48 additions & 15 deletions Makefile.js
Original file line number Diff line number Diff line change
@@ -50,6 +50,8 @@ const OPEN_SOURCE_LICENSES = [
/Public Domain/u, /LGPL/u, /Python/u, /BlueOak/u
];

const MAIN_GIT_BRANCH = "main";

//------------------------------------------------------------------------------
// Data
//------------------------------------------------------------------------------
@@ -74,6 +76,8 @@ const NODE = "node ", // intentional extra space
TEST_FILES = "\"tests/{bin,conf,lib,tools}/**/*.js\"",
PERF_ESLINTRC = path.join(PERF_TMP_DIR, "eslint.config.js"),
PERF_MULTIFILES_TARGET_DIR = path.join(PERF_TMP_DIR, "eslint"),
CHANGELOG_FILE = "./CHANGELOG.md",
VERSIONS_FILE = "./docs/src/_data/versions.json",

/*
* glob arguments with Windows separator `\` don't work:
@@ -97,6 +101,14 @@ function execSilent(cmd) {
return exec(cmd, { silent: true }).stdout;
}

/**
* Gets name of the currently checked out Git branch.
* @returns {string} Name of the currently checked out Git branch.
*/
function getCurrentGitBranch() {
return execSilent("git branch --show-current").trim();
}

/**
* Generates a release blog post for eslint.org
* @param {Object} releaseInfo The release metadata.
@@ -313,14 +325,18 @@ function updateVersions(oldVersion, newVersion) {
/**
* Updates the changelog, bumps the version number in package.json, creates a local git commit and tag,
* and generates the site in an adjacent `website` folder.
* @param {string} [prereleaseId] The prerelease identifier (alpha, beta, etc.). If `undefined`, this is
* @param {Object} options Release options.
* @param {string} [options.prereleaseId] The prerelease identifier (alpha, beta, etc.). If `undefined`, this is
* a regular release.
* @param {string} options.packageTag Tag that should be added to the package submitted to the npm registry.
* @returns {void}
*/
function generateRelease(prereleaseId) {
function generateRelease({ prereleaseId, packageTag }) {
echo(`Current Git branch: ${getCurrentGitBranch()}`);

const oldVersion = require("./package.json").version;

ReleaseOps.generateRelease(prereleaseId);
ReleaseOps.generateRelease(prereleaseId, packageTag);
const releaseInfo = JSON.parse(cat(".eslint-release-info.json"));

echo("Generating site");
@@ -335,7 +351,9 @@ function generateRelease(prereleaseId) {
docsPackage.version = releaseInfo.version;
fs.writeFileSync(docsPackagePath, `${JSON.stringify(docsPackage, null, 4)}\n`);

updateVersions(oldVersion, releaseInfo.version);
if (getCurrentGitBranch() === MAIN_GIT_BRANCH) {
updateVersions(oldVersion, releaseInfo.version);
}

echo("Updating commit with docs data");
exec("git add docs/ && git commit --amend --no-edit");
@@ -351,17 +369,32 @@ function publishRelease() {
ReleaseOps.publishRelease();
const releaseInfo = JSON.parse(cat(".eslint-release-info.json"));

/*
* for a pre-release, push to the "next" branch to trigger docs deploy
* for a release, push to the "latest" branch to trigger docs deploy
*/
if (isPreRelease(releaseInfo.version)) {
exec("git push origin HEAD:next -f");
} else {
exec("git push origin HEAD:latest -f");
}
const docsSiteBranch = releaseInfo.packageTag === "maintenance"
? `v${semver.major(releaseInfo.version)}.x`
: releaseInfo.packageTag; // "latest" or "next"

echo(`Updating docs site branch: ${docsSiteBranch}`);
exec(`git push origin HEAD:${docsSiteBranch} -f`);

publishSite();

// Update changelog and list of versions on the main branch
if (getCurrentGitBranch() !== MAIN_GIT_BRANCH) {
echo(`Updating changelog and versions on branch: ${MAIN_GIT_BRANCH}`);

exec(`git checkout ${MAIN_GIT_BRANCH} --force`);

fs.writeFileSync(CHANGELOG_FILE, `${releaseInfo.markdownChangelog}${cat(CHANGELOG_FILE)}`);

const versions = JSON.parse(cat(VERSIONS_FILE));

versions.items.find(({ branch }) => branch === docsSiteBranch).version = releaseInfo.version;
fs.writeFileSync(VERSIONS_FILE, `${JSON.stringify(versions, null, 4)}\n`);

exec(`git add ${CHANGELOG_FILE} ${VERSIONS_FILE}`);
exec(`git commit -m "chore: updates for v${releaseInfo.version} release"`);
exec("git push origin HEAD");
}
}

/**
@@ -1022,6 +1055,6 @@ target.perf = function() {
});
};

target.generateRelease = () => generateRelease();
target.generatePrerelease = ([prereleaseType]) => generateRelease(prereleaseType);
target.generateRelease = ([packageTag]) => generateRelease({ packageTag });
target.generatePrerelease = ([prereleaseId]) => generateRelease({ prereleaseId, packageTag: "next" });
target.publishRelease = publishRelease;
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -297,9 +297,9 @@ The following companies, organizations, and individuals support ESLint's ongoing
<!--sponsorsstart-->
<h3>Platinum Sponsors</h3>
<p><a href="https://automattic.com"><img src="https://images.opencollective.com/automattic/d0ef3e1/logo.png" alt="Automattic" height="128"></a> <a href="https://www.airbnb.com/"><img src="https://images.opencollective.com/airbnb/d327d66/logo.png" alt="Airbnb" height="128"></a></p><h3>Gold Sponsors</h3>
<p><a href="https://trunk.io/"><img src="https://images.opencollective.com/trunkio/fb92d60/avatar.png" alt="trunk.io" height="96"></a> <a href="https://opensource.siemens.com"><img src="https://avatars.githubusercontent.com/u/624020?v=4" alt="Siemens" height="96"></a></p><h3>Silver Sponsors</h3>
<p><a href="https://trunk.io/"><img src="https://images.opencollective.com/trunkio/fb92d60/avatar.png" alt="trunk.io" height="96"></a></p><h3>Silver Sponsors</h3>
<p><a href="https://www.jetbrains.com/"><img src="https://images.opencollective.com/jetbrains/fe76f99/logo.png" alt="JetBrains" 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> <a href="https://www.workleap.com"><img src="https://avatars.githubusercontent.com/u/53535748?u=d1e55d7661d724bf2281c1bfd33cb8f99fe2465f&v=4" alt="Workleap" height="64"></a></p><h3>Bronze Sponsors</h3>
<p><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://www.ignitionapp.com"><img src="https://avatars.githubusercontent.com/u/5753491?v=4" alt="Ignition" height="32"></a> <a href="https://nx.dev"><img src="https://avatars.githubusercontent.com/u/23692104?v=4" alt="Nx" 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://usenextbase.com"><img src="https://avatars.githubusercontent.com/u/145838380?v=4" alt="Nextbase Starter Kit" height="32"></a></p>
<p><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://nx.dev"><img src="https://avatars.githubusercontent.com/u/23692104?v=4" alt="Nx" 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://usenextbase.com"><img src="https://avatars.githubusercontent.com/u/145838380?v=4" alt="Nextbase Starter Kit" height="32"></a></p>
<!--sponsorsend-->

<!--techsponsorsstart-->
2 changes: 1 addition & 1 deletion docs/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "docs-eslint",
"private": true,
"version": "9.10.0",
"version": "9.11.0",
"description": "",
"main": "index.js",
"keywords": [],
2 changes: 1 addition & 1 deletion docs/src/_data/rules.json
Original file line number Diff line number Diff line change
@@ -1135,7 +1135,7 @@
"description": "Disallow unnecessary constructors",
"recommended": false,
"fixable": false,
"hasSuggestions": false
"hasSuggestions": true
},
{
"name": "no-useless-escape",
3 changes: 2 additions & 1 deletion docs/src/_data/rules_meta.json
Original file line number Diff line number Diff line change
@@ -2023,7 +2023,8 @@
"description": "Disallow unnecessary constructors",
"recommended": false,
"url": "https://eslint.org/docs/latest/rules/no-useless-constructor"
}
},
"hasSuggestions": true
},
"no-useless-escape": {
"type": "suggestion",
4 changes: 2 additions & 2 deletions docs/src/_data/versions.json
Original file line number Diff line number Diff line change
@@ -6,12 +6,12 @@
"path": "/docs/head/"
},
{
"version": "9.10.0",
"version": "9.11.0",
"branch": "latest",
"path": "/docs/latest/"
},
{
"version": "8.57.0",
"version": "8.57.1",
"branch": "v8.x",
"path": "/docs/v8.x/"
}
4 changes: 2 additions & 2 deletions docs/src/integrate/nodejs-api.md
Original file line number Diff line number Diff line change
@@ -466,8 +466,8 @@ This edit information means replacing the range of the `range` property by the `

The `LoadedFormatter` value is the object to convert the [LintResult] objects to text. The [eslint.loadFormatter()][eslint-loadformatter] method returns it. It has the following method:

* `format` (`(results: LintResult[], resultsMeta: ResultsMeta) => string | Promise<string>`)<br>
The method to convert the [LintResult] objects to text. `resultsMeta` is an object that will contain a `maxWarningsExceeded` object if `--max-warnings` was set and the number of warnings exceeded the limit. The `maxWarningsExceeded` object will contain two properties: `maxWarnings`, the value of the `--max-warnings` option, and `foundWarnings`, the number of lint warnings.
* `format` (`(results: LintResult[], resultsMeta?: ResultsMeta) => string | Promise<string>`)<br>
The method to convert the [LintResult] objects to text. `resultsMeta` is an optional parameter that is primarily intended for use by the ESLint CLI and can contain only a `maxWarningsExceeded` property that would be passed through the [`context`](../extend/custom-formatters#the-context-argument) object when this method calls the underlying formatter function. Note that ESLint automatically generates `cwd` and `rulesMeta` properties of the `context` object, so you typically don't need to pass in the second argument when calling this method.

---

41 changes: 41 additions & 0 deletions docs/src/maintain/manage-releases.md
Original file line number Diff line number Diff line change
@@ -49,6 +49,47 @@ In rare cases, a second patch release might be necessary if the release is known

After the patch release has been published (or no patch release is necessary), close the release issue and inform the team that they can start merging in semver-minor changes again.

### Release Parameters

The following tables show examples of the option to select as `RELEASE_TYPE` when starting `eslint-js Release` (the `@eslint/js` package release) and `eslint Release` (the `eslint` package release) jobs on Jenkins to release a new version with the latest features. In both jobs, `main` should be selected as `RELEASE_BRANCH`.

| **HEAD Version** | **Desired Next Version** | **`eslint-js Release`<br>`RELEASE_TYPE`** |
| :---: | :---: | :---: |
| `9.25.0` | `9.25.1` | `patch` |
| `9.25.0` | `9.26.0` | `minor` |
| `9.25.0` | `10.0.0-alpha.0` | `alpha.0` |
| `10.0.0-alpha.0` | `10.0.0-alpha.1` | `alpha` |
| `10.0.0-alpha.1` | `10.0.0-beta.0` | `beta` |
| `10.0.0-beta.0` | `10.0.0-beta.1` | `beta` |
| `10.0.0-beta.1` | `10.0.0-rc.0` | `rc` |
| `10.0.0-rc.0` | `10.0.0-rc.1` | `rc` |
| `10.0.0-rc.1` | `10.0.0` | `major` |

| **HEAD Version** | **Desired Next Version** | **`eslint Release`<br>`RELEASE_TYPE`** |
| :---: | :---: | :---: |
| `9.25.0` | `9.25.1` or `9.26.0` |`latest` |
| `9.25.0` | `10.0.0-alpha.0` | `alpha` |
| `10.0.0-alpha.0` | `10.0.0-alpha.1` | `alpha` |
| `10.0.0-alpha.1` | `10.0.0-beta.0` | `beta` |
| `10.0.0-beta.0` | `10.0.0-beta.1` | `beta` |
| `10.0.0-beta.1` | `10.0.0-rc.0` | `rc` |
| `10.0.0-rc.0` | `10.0.0-rc.1` | `rc` |
| `10.0.0-rc.1` | `10.0.0` | `latest` |

When releasing a new version of the previous major line, the option to select as `RELEASE_TYPE` depends on whether the HEAD version is a prerelease or not. In both jobs, the corresponding development branch (for example, `v9.x-dev`) should be selected as `RELEASE_BRANCH`.

| **HEAD Version** | **Previous Major Line Version** | **Desired Next Version** | **`eslint-js Release`<br>`RELEASE_TYPE`** |
| :---: | :---: | :---: | :---: |
| `10.0.0-alpha.0` | `9.25.0` | `9.25.1` | `patch` |
| `10.0.0-alpha.0` | `9.25.0` | `9.26.0` | `minor` |
| `10.0.0` | `9.25.0` | `9.25.1` | `maintenance.patch` |
| `10.0.0` | `9.25.0` | `9.26.0` | `maintenance.minor` |

| **HEAD Version** | **Previous Major Line Version** | **Desired Next Version** | **`eslint Release`<br>`RELEASE_TYPE`** |
| :---: | :---: | :---: | :---: |
| `10.0.0-alpha.0` | `9.25.0` | `9.25.1` or `9.26.0` | `latest` |
| `10.0.0` | `9.25.0` | `9.25.1` or `9.26.0` | `maintenance` |

## Emergency Releases

An emergency release is unplanned and isn't the regularly scheduled release or the anticipated patch release.
30 changes: 15 additions & 15 deletions docs/src/rules/no-irregular-whitespace.md
Original file line number Diff line number Diff line change
@@ -39,27 +39,27 @@ This rule disallows the following characters except where the options allow:
\u000B - Line Tabulation (\v) - <VT>
\u000C - Form Feed (\f) - <FF>
\u00A0 - No-Break Space - <NBSP>
\u0085 - Next Line
\u1680 - Ogham Space Mark
\u0085 - Next Line - <NEL>
\u1680 - Ogham Space Mark - <OGSP>
\u180E - Mongolian Vowel Separator - <MVS>
\ufeff - Zero Width No-Break Space - <BOM>
\u2000 - En Quad
\u2001 - Em Quad
\u2000 - En Quad - <NQSP>
\u2001 - Em Quad - <MQSP>
\u2002 - En Space - <ENSP>
\u2003 - Em Space - <EMSP>
\u2004 - Three-Per-Em
\u2005 - Four-Per-Em
\u2006 - Six-Per-Em
\u2007 - Figure Space
\u2004 - Three-Per-Em - <THPMSP> - <3/MSP>
\u2005 - Four-Per-Em - <FPMSP> - <4/MSP>
\u2006 - Six-Per-Em - <SPMSP> - <6/MSP>
\u2007 - Figure Space - <FSP>
\u2008 - Punctuation Space - <PUNCSP>
\u2009 - Thin Space
\u200A - Hair Space
\u2009 - Thin Space - <THSP>
\u200A - Hair Space - <HSP>
\u200B - Zero Width Space - <ZWSP>
\u2028 - Line Separator
\u2029 - Paragraph Separator
\u202F - Narrow No-Break Space
\u205f - Medium Mathematical Space
\u3000 - Ideographic Space
\u2028 - Line Separator - <LS> - <LSEP>
\u2029 - Paragraph Separator - <PS> - <PSEP>
\u202F - Narrow No-Break Space - <NNBSP>
\u205f - Medium Mathematical Space - <MMSP>
\u3000 - Ideographic Space - <IDSP>
```

## Options
2 changes: 1 addition & 1 deletion docs/src/use/formatters/html-formatter-example.html
Original file line number Diff line number Diff line change
@@ -118,7 +118,7 @@
<div id="overview" class="bg-2">
<h1>ESLint Report</h1>
<div>
<span>8 problems (4 errors, 4 warnings)</span> - Generated on Fri Sep 06 2024 20:24:45 GMT+0000 (Coordinated Universal Time)
<span>8 problems (4 errors, 4 warnings)</span> - Generated on Fri Sep 20 2024 15:43:28 GMT+0000 (Coordinated Universal Time)
</div>
</div>
<table>
26 changes: 22 additions & 4 deletions eslint.config.js
Original file line number Diff line number Diff line change
@@ -18,6 +18,8 @@ const eslintConfigESLintCJS = require("eslint-config-eslint/cjs");
const eslintConfigESLintFormatting = require("eslint-config-eslint/formatting");
const eslintPluginYml = require("eslint-plugin-yml");
const json = require("@eslint/json").default;
const expectType = require("eslint-plugin-expect-type");
const tsParser = require("@typescript-eslint/parser");

//-----------------------------------------------------------------------------
// Helpers
@@ -87,14 +89,14 @@ module.exports = [
"docs/!(src|tools)/",
"docs/src/!(_data)",
"jsdoc/**",
"lib/types/**/*.ts",
"templates/**",
"tests/bench/**",
"tests/fixtures/**",
"tests/performance/**",
"tmp/**",
"**/test.js",
".vscode",
"**/*.ts"
".vscode"
]
},
{
@@ -198,7 +200,7 @@ module.exports = [
{
name: "eslint/lib",
files: ["lib/*.js"],
ignores: ["lib/unsupported-api.js"],
ignores: ["lib/unsupported-api.js", "lib/universal.js"],
rules: {
"n/no-restricted-require": ["error", [
...createInternalFilesPatterns()
@@ -279,5 +281,21 @@ module.exports = [
...eslintPluginYml.configs["flat/recommended"].map(config => ({
...config,
files: [ALL_YAML_FILES]
}))
})),
{
name: "eslint/ts-rules",
files: ["tests/lib/types/*.ts"],
languageOptions: {
parser: tsParser,
parserOptions: {
project: "tests/lib/types/tsconfig.json"
}
},
plugins: {
"expect-type": expectType
},
rules: {
"expect-type/expect": "error"
}
}
];
6 changes: 1 addition & 5 deletions lib/config/flat-config-helpers.js
Original file line number Diff line number Diff line change
@@ -65,13 +65,9 @@ function parseRuleId(ruleId) {
* or undefined if not.
*/
function getRuleFromConfig(ruleId, config) {

const { pluginName, ruleName } = parseRuleId(ruleId);

const plugin = config.plugins && config.plugins[pluginName];
const rule = plugin && plugin.rules && plugin.rules[ruleName];

return rule;
return config.plugins?.[pluginName]?.rules?.[ruleName];
}

/**
53 changes: 1 addition & 52 deletions lib/languages/js/source-code/source-code.js
Original file line number Diff line number Diff line change
@@ -20,7 +20,7 @@ const

CodePathAnalyzer = require("../../../linter/code-path-analysis/code-path-analyzer"),
createEmitter = require("../../../linter/safe-emitter"),
{ ConfigCommentParser, VisitNodeStep, CallMethodStep } = require("@eslint/plugin-kit"),
{ ConfigCommentParser, VisitNodeStep, CallMethodStep, Directive } = require("@eslint/plugin-kit"),

eslintScope = require("eslint-scope");

@@ -316,57 +316,6 @@ function markExportedVariables(globalScope, variables) {

}

/**
* A class to represent a directive comment.
* @implements {IDirective}
*/
class Directive {

/**
* The type of directive.
* @type {"disable"|"enable"|"disable-next-line"|"disable-line"}
* @readonly
*/
type;

/**
* The node representing the directive.
* @type {ASTNode|Comment}
* @readonly
*/
node;

/**
* Everything after the "eslint-disable" portion of the directive,
* but before the "--" that indicates the justification.
* @type {string}
* @readonly
*/
value;

/**
* The justification for the directive.
* @type {string}
* @readonly
*/
justification;

/**
* Creates a new instance.
* @param {Object} options The options for the directive.
* @param {"disable"|"enable"|"disable-next-line"|"disable-line"} options.type The type of directive.
* @param {ASTNode|Comment} options.node The node representing the directive.
* @param {string} options.value The value of the directive.
* @param {string} options.justification The justification for the directive.
*/
constructor({ type, node, value, justification }) {
this.type = type;
this.node = node;
this.value = value;
this.justification = justification;
}
}

//------------------------------------------------------------------------------
// Public Interface
//------------------------------------------------------------------------------
253 changes: 145 additions & 108 deletions lib/linter/linter.js

Large diffs are not rendered by default.

9 changes: 8 additions & 1 deletion lib/linter/vfile.js
Original file line number Diff line number Diff line change
@@ -85,6 +85,13 @@ class VFile {
*/
body;

/**
* The raw body of the file, including a BOM if present.
* @type {string|Uint8Array}
* @readonly
*/
rawBody;

/**
* Indicates whether the file has a byte order mark (BOM).
* @type {boolean}
@@ -104,8 +111,8 @@ class VFile {
this.physicalPath = physicalPath ?? path;
this.bom = hasUnicodeBOM(body);
this.body = stripUnicodeBOM(body);
this.rawBody = body;
}

}

module.exports = { VFile };
7 changes: 7 additions & 0 deletions lib/rules/id-length.js
Original file line number Diff line number Diff line change
@@ -11,6 +11,7 @@
//------------------------------------------------------------------------------

const { getGraphemeCount } = require("../shared/string-utils");
const { getModuleExportName } = require("./utils/ast-utils");

//------------------------------------------------------------------------------
// Rule Definition
@@ -116,6 +117,12 @@ module.exports = {
}
return properties && !parent.computed && parent.key.name === node.name;
},
ImportSpecifier(parent, node) {
return (
parent.local === node &&
getModuleExportName(parent.imported) !== getModuleExportName(parent.local)
);
},
ImportDefaultSpecifier: true,
ImportNamespaceSpecifier: true,
RestElement: true,
20 changes: 18 additions & 2 deletions lib/rules/no-useless-constructor.js
Original file line number Diff line number Diff line change
@@ -4,6 +4,8 @@
*/
"use strict";

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

//------------------------------------------------------------------------------
// Helpers
//------------------------------------------------------------------------------
@@ -143,10 +145,13 @@ module.exports = {
url: "https://eslint.org/docs/latest/rules/no-useless-constructor"
},

hasSuggestions: true,

schema: [],

messages: {
noUselessConstructor: "Useless constructor."
noUselessConstructor: "Useless constructor.",
removeConstructor: "Remove the constructor."
}
},

@@ -177,7 +182,18 @@ module.exports = {
if (superClass ? isRedundantSuperCall(body, ctorParams) : (body.length === 0)) {
context.report({
node,
messageId: "noUselessConstructor"
messageId: "noUselessConstructor",
suggest: [
{
messageId: "removeConstructor",
*fix(fixer) {
const nextToken = context.sourceCode.getTokenAfter(node);
const addSemiColon = nextToken.type === "Punctuator" && nextToken.value === "[" && astUtils.needsPrecedingSemicolon(context.sourceCode, node);

yield fixer.replaceText(node, addSemiColon ? ";" : "");
}
}
]
});
}
}
109 changes: 109 additions & 0 deletions lib/services/processor-service.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/**
* @fileoverview ESLint Processor Service
* @author Nicholas C. Zakas
*/
/* eslint class-methods-use-this: off -- Anticipate future constructor arguments. */

"use strict";

//-----------------------------------------------------------------------------
// Requirements
//-----------------------------------------------------------------------------

const path = require("node:path");
const { VFile } = require("../linter/vfile.js");

//-----------------------------------------------------------------------------
// Types
//-----------------------------------------------------------------------------

/** @typedef {import("../shared/types.js").LintMessage} LintMessage */
/** @typedef {import("../linter/vfile.js").VFile} VFile */
/** @typedef {import("@eslint/core").Language} Language */
/** @typedef {import("@eslint/core").LanguageOptions} LanguageOptions */
/** @typedef {import("eslint").Linter.Processor} Processor */

//-----------------------------------------------------------------------------
// Exports
//-----------------------------------------------------------------------------

/**
* The service that applies processors to files.
*/
class ProcessorService {

/**
* Preprocesses the given file synchronously.
* @param {VFile} file The file to preprocess.
* @param {{processor:Processor}} config The configuration to use.
* @returns {{ok:boolean, files?: Array<VFile>, errors?: Array<LintMessage>}} An array of preprocessed files or errors.
* @throws {Error} If the preprocessor returns a promise.
*/
preprocessSync(file, config) {

const { processor } = config;
let blocks;

try {
blocks = processor.preprocess(file.rawBody, file.path);
} catch (ex) {

// If the message includes a leading line number, strip it:
const message = `Preprocessing error: ${ex.message.replace(/^line \d+:/iu, "").trim()}`;

return {
ok: false,
errors: [
{
ruleId: null,
fatal: true,
severity: 2,
message,
line: ex.lineNumber,
column: ex.column,
nodeType: null
}
]
};
}

if (typeof blocks.then === "function") {
throw new Error("Unsupported: Preprocessor returned a promise.");
}

return {
ok: true,
files: blocks.map((block, i) => {

// Legacy behavior: return the block as a string
if (typeof block === "string") {
return block;
}

const filePath = path.join(file.path, `${i}_${block.filename}`);

return new VFile(filePath, block.text, {
physicalPath: file.physicalPath
});
})
};

}

/**
* Postprocesses the given messages synchronously.
* @param {VFile} file The file to postprocess.
* @param {LintMessage[][]} messages The messages to postprocess.
* @param {{processor:Processor}} config The configuration to use.
* @returns {LintMessage[]} The postprocessed messages.
*/
postprocessSync(file, messages, config) {

const { processor } = config;

return processor.postprocess(messages, file.path);
}

}

module.exports = { ProcessorService };
2 changes: 1 addition & 1 deletion lib/shared/types.js
Original file line number Diff line number Diff line change
@@ -245,6 +245,6 @@ module.exports = {};
* A formatter function.
* @callback FormatterFunction
* @param {LintResult[]} results The list of linting results.
* @param {{cwd: string, maxWarningsExceeded?: MaxWarningsExceeded, rulesMeta: Record<string, RuleMeta>}} [context] A context object.
* @param {{cwd: string, maxWarningsExceeded?: MaxWarningsExceeded, rulesMeta: Record<string, RuleMeta>}} context A context object.
* @returns {string | Promise<string>} Formatted text.
*/
43 changes: 38 additions & 5 deletions lib/types/index.d.ts
Original file line number Diff line number Diff line change
@@ -26,6 +26,7 @@
*/

import * as ESTree from "estree";
import { Language } from "@eslint/core";
import { JSONSchema4 } from "json-schema";
import { LegacyESLint } from "./use-at-your-own-risk.js";

@@ -1265,6 +1266,13 @@ export namespace Linter {
*/
ignores?: string[];

/**
* The name of the language used for linting. This is used to determine the
* parser and other language-specific settings.
* @since 9.7.0
*/
language?: string;

/**
* An object containing settings related to how JavaScript is configured for
* linting.
@@ -1411,7 +1419,7 @@ export class ESLint {

isPathIgnored(filePath: string): Promise<boolean>;

loadFormatter(nameOrPath?: string): Promise<ESLint.Formatter>;
loadFormatter(nameOrPath?: string): Promise<ESLint.LoadedFormatter>;
}

export namespace ESLint {
@@ -1441,6 +1449,7 @@ export namespace ESLint {
interface Plugin extends ObjectMetaProperties {
configs?: Record<string, Linter.LegacyConfig | Linter.Config | Linter.Config[]> | undefined;
environments?: Record<string, Environment> | undefined;
languages?: Record<string, Language> | undefined;
processors?: Record<string, Linter.Processor> | undefined;
rules?: Record<string, Rule.RuleModule> | undefined;
}
@@ -1555,14 +1564,38 @@ export namespace ESLint {
replacedBy: string[];
}

interface Formatter {
format(results: LintResult[], data?: LintResultData): string | Promise<string>;
interface ResultsMeta {
maxWarningsExceeded?: MaxWarningsExceeded | undefined;
}

/** The type of an object resolved by {@link ESLint.loadFormatter}. */
interface LoadedFormatter {

/**
* Used to call the underlying formatter.
* @param results An array of lint results to format.
* @param resultsMeta An object with an optional `maxWarningsExceeded` property that will be
* passed to the underlying formatter function along with other properties set by ESLint.
* This argument can be omitted if `maxWarningsExceeded` is not needed.
* @return The formatter output.
*/
format(results: LintResult[], resultsMeta?: ResultsMeta): string | Promise<string>;
}

// The documented type name is `LoadedFormatter`, but `Formatter` has been historically more used.
type Formatter = LoadedFormatter;

/**
* The expected signature of a custom formatter.
* @param results An array of lint results to format.
* @param context Additional information for the formatter.
* @return The formatter output.
*/
type FormatterFunction =
(results: LintResult[], context: LintResultData) => string | Promise<string>;

// Docs reference the types by those name
type EditInfo = Rule.Fix;
type LoadedFormatter = Formatter;
type ResultsMeta = LintResultData;
}

// #endregion
32 changes: 20 additions & 12 deletions lib/types/rules/best-practices.d.ts
Original file line number Diff line number Diff line change
@@ -324,6 +324,8 @@ export interface BestPractices extends Linter.RulesRecord {
| "getters"
| "setters"
| "constructors"
| "asyncFunctions"
| "asyncMethods"
>;
}>,
]
@@ -472,7 +474,7 @@ export interface BestPractices extends Linter.RulesRecord {
/**
* @default []
*/
allow: Array<"~" | "!!" | "+" | "*">;
allow: Array<"~" | "!!" | "+" | "- -" | "-" | "*">;
}>,
]
>;
@@ -683,16 +685,22 @@ export interface BestPractices extends Linter.RulesRecord {
*/
"no-param-reassign": Linter.RuleEntry<
[
Partial<{
/**
* @default false
*/
props: boolean;
/**
* @default []
*/
ignorePropertyModificationsFor: string[];
}>,
| {
props?: false;
}
| ({
props: true;
} & Partial<{
/**
* @default []
*/
ignorePropertyModificationsFor: string[];
/**
* @since 6.6.0
* @default []
*/
ignorePropertyModificationsForRegex: string[];
}>),
]
>;

@@ -966,7 +974,7 @@ export interface BestPractices extends Linter.RulesRecord {
/**
* Disallow use of `Object.prototype.hasOwnProperty.call()` and prefer use of `Object.hasOwn()`.
*
* @since 3.5.0
* @since 8.5.0
* @see https://eslint.org/docs/rules/prefer-object-has-own
*/
"prefer-object-has-own": Linter.RuleEntry<[]>;
46 changes: 46 additions & 0 deletions lib/types/rules/ecmascript-6.d.ts
Original file line number Diff line number Diff line change
@@ -231,6 +231,52 @@ export interface ECMAScript6 extends Linter.RulesRecord {
*/
"no-new-symbol": Linter.RuleEntry<[]>;

/**
* Rule to disallow specified names in exports.
*
* @since 7.0.0-alpha.0
* @see https://eslint.org/docs/rules/no-restricted-exports
*/
"no-restricted-exports": Linter.RuleEntry<
[
Partial<{
/**
* @default []
*/
restrictedNamedExports: string[];
/**
* @since 9.3.0
*/
restrictedNamedExportsPattern: string;
/**
* @since 8.33.0
*/
restrictDefaultExports: Partial<{
/**
* @default false
*/
direct: boolean;
/**
* @default false
*/
named: boolean;
/**
* @default false
*/
defaultFrom: boolean;
/**
* @default false
*/
namedFrom: boolean;
/**
* @default false
*/
namespaceFrom: boolean;
}>;
}>,
]
>;

/**
* Rule to disallow specified modules when loaded by `import`.
*
37 changes: 35 additions & 2 deletions lib/types/rules/possible-errors.d.ts
Original file line number Diff line number Diff line change
@@ -251,7 +251,30 @@ export interface PossibleErrors extends Linter.RulesRecord {
* @since 0.4.0
* @see https://eslint.org/docs/rules/no-extra-boolean-cast
*/
"no-extra-boolean-cast": Linter.RuleEntry<[]>;
"no-extra-boolean-cast": Linter.RuleEntry<
[
| Partial<{
/**
* @since 9.3.0
* @default false
*/
enforceForInnerExpressions: boolean;
/**
* @deprecated
*/
enforceForLogicalOperands: never;
}>
| Partial<{
/**
* @deprecated
* @since 7.0.0-alpha.2
* @default false
*/
enforceForLogicalOperands: boolean;
enforceForInnerExpressions: never;
}>,
]
>;

/**
* Rule to disallow unnecessary parentheses.
@@ -391,7 +414,17 @@ export interface PossibleErrors extends Linter.RulesRecord {
* @since 5.3.0
* @see https://eslint.org/docs/rules/no-misleading-character-class
*/
"no-misleading-character-class": Linter.RuleEntry<[]>;
"no-misleading-character-class": Linter.RuleEntry<
[
Partial<{
/**
* @since 9.3.0
* @default false
*/
allowEscape: boolean;
}>,
]
>;

/**
* Rule to disallow calling global object properties as functions.
10 changes: 10 additions & 0 deletions lib/types/rules/stylistic-issues.d.ts
Original file line number Diff line number Diff line change
@@ -165,6 +165,16 @@ export interface StylisticIssues extends Linter.RulesRecord {
* @default false
*/
ignoreDestructuring: boolean;
/**
* @since 6.7.0
* @default false
*/
ignoreImports: boolean;
/**
* @since 7.4.0
* @default false
*/
ignoreGlobals: boolean;
/**
* @remarks
* Also accept for regular expression patterns
6 changes: 6 additions & 0 deletions lib/types/universal.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/**
* @fileoverview typings for "eslint/universal" module
* @author 唯然<weiran.zsd@outlook.com>
*/

export { Linter } from "./index";
10 changes: 10 additions & 0 deletions lib/universal.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/**
* @fileoverview exports for browsers
* @author 唯然<weiran.zsd@outlook.com>
*/

"use strict";

const { Linter } = require("./linter/linter");

module.exports = { Linter };
19 changes: 13 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "eslint",
"version": "9.10.0",
"version": "9.11.0",
"author": "Nicholas C. Zakas <nicholas+npm@nczconsulting.com>",
"description": "An AST-based pattern checker for JavaScript.",
"bin": {
@@ -20,6 +20,10 @@
},
"./rules": {
"types": "./lib/types/rules/index.d.ts"
},
"./universal": {
"types": "./lib/types/universal.d.ts",
"default": "./lib/universal.js"
}
},
"scripts": {
@@ -36,7 +40,8 @@
"lint:fix:docs:js": "trunk check -y --ignore=** --ignore=!docs/**/*.js -a --flter=eslint && trunk check -y --ignore=** --ignore=!docs/**/*.js",
"release:generate:alpha": "node Makefile.js generatePrerelease -- alpha",
"release:generate:beta": "node Makefile.js generatePrerelease -- beta",
"release:generate:latest": "node Makefile.js generateRelease",
"release:generate:latest": "node Makefile.js generateRelease -- latest",
"release:generate:maintenance": "node Makefile.js generateRelease -- maintenance",
"release:generate:rc": "node Makefile.js generatePrerelease -- rc",
"release:publish": "node Makefile.js publishRelease",
"test": "node Makefile.js test",
@@ -81,8 +86,8 @@
"@eslint-community/regexpp": "^4.11.0",
"@eslint/config-array": "^0.18.0",
"@eslint/eslintrc": "^3.1.0",
"@eslint/js": "9.10.0",
"@eslint/plugin-kit": "^0.1.0",
"@eslint/js": "9.11.0",
"@eslint/plugin-kit": "^0.2.0",
"@humanwhocodes/module-importer": "^1.0.1",
"@humanwhocodes/retry": "^0.3.0",
"@nodelib/fs.walk": "^1.2.8",
@@ -115,12 +120,13 @@
"devDependencies": {
"@babel/core": "^7.4.3",
"@babel/preset-env": "^7.4.3",
"@eslint/core": "^0.5.0",
"@eslint/core": "^0.6.0",
"@eslint/json": "^0.4.0",
"@trunkio/launcher": "^1.3.0",
"@types/estree": "^1.0.5",
"@types/json-schema": "^7.0.15",
"@types/node": "^20.11.5",
"@typescript-eslint/parser": "^8.4.0",
"@wdio/browser-runner": "^9.0.5",
"@wdio/cli": "^9.0.5",
"@wdio/concise-reporter": "^9.0.4",
@@ -135,8 +141,9 @@
"eslint": "file:.",
"eslint-config-eslint": "file:packages/eslint-config-eslint",
"eslint-plugin-eslint-plugin": "^6.0.0",
"eslint-plugin-expect-type": "^0.4.0",
"eslint-plugin-yml": "^1.14.0",
"eslint-release": "^3.2.2",
"eslint-release": "^3.3.0",
"eslint-rule-composer": "^0.3.0",
"eslump": "^3.0.0",
"esprima": "^4.0.1",
2 changes: 1 addition & 1 deletion packages/js/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@eslint/js",
"version": "9.10.0",
"version": "9.11.0",
"description": "ESLint JavaScript language implementation",
"main": "./src/index.js",
"scripts": {},
30 changes: 30 additions & 0 deletions tests/lib/eslint/eslint.js
Original file line number Diff line number Diff line change
@@ -1246,6 +1246,36 @@ describe("ESLint", () => {
});

});

it("should pass BOM through processors", async () => {
eslint = new ESLint({
overrideConfigFile: true,
overrideConfig: [
{
files: ["**/*.myjs"],
processor: {
preprocess(text, filename) {
return [{ text, filename }];
},
postprocess(messages) {
return messages.flat();
},
supportsAutofix: true
},
rules: {
"unicode-bom": ["error", "never"]
}
}
],
cwd: path.join(fixtureDir)
});
const results = await eslint.lintText("\uFEFFvar foo = 'bar';", { filePath: "test.myjs" });

assert.strictEqual(results.length, 1);
assert.strictEqual(results[0].messages.length, 1);
assert.strictEqual(results[0].messages[0].severity, 2);
assert.strictEqual(results[0].messages[0].ruleId, "unicode-bom");
});
});

describe("lintFiles()", () => {
41 changes: 41 additions & 0 deletions tests/lib/linter/linter.js
Original file line number Diff line number Diff line change
@@ -16071,6 +16071,47 @@ var a = "test2";
assert.strictEqual(logs.length, 1, "preprocess() should only be called once.");
});

it("should pass the BOM to preprocess", () => {
const logs = [];
const code = "\uFEFFfoo";
const config = {
files: ["**/*.myjs"],
processor: {
preprocess(text, filenameForText) {
logs.push({
text,
filename: filenameForText
});

return [{ text, filename: filenameForText }];
},
postprocess(messages) {
return messages.flat();
}
},
rules: {
"unicode-bom": ["error", "never"]
}
};

const results = linter.verify(code, config, {
filename: "a.myjs",
filterCodeBlock() {
return true;
}
});

assert.deepStrictEqual(logs, [
{
text: code,
filename: "a.myjs"
}
]);

assert.strictEqual(results.length, 1);
assert.strictEqual(results[0].ruleId, "unicode-bom");
});

it("should apply a preprocessor to the code, and lint each code sample separately", () => {
const code = "foo bar baz";
const configs = createFlatConfigArray([
5 changes: 5 additions & 0 deletions tests/lib/linter/vfile.js
Original file line number Diff line number Diff line change
@@ -26,6 +26,7 @@ describe("VFile", () => {
assert.strictEqual(vfile.path, "foo.js");
assert.strictEqual(vfile.physicalPath, "foo.js");
assert.strictEqual(vfile.body, "var foo = bar;");
assert.strictEqual(vfile.rawBody, "var foo = bar;");
assert.isFalse(vfile.bom);
});

@@ -35,6 +36,7 @@ describe("VFile", () => {
assert.strictEqual(vfile.path, "foo.js");
assert.strictEqual(vfile.physicalPath, "foo.js");
assert.strictEqual(vfile.body, "var foo = bar;");
assert.strictEqual(vfile.rawBody, "\uFEFFvar foo = bar;");
assert.isTrue(vfile.bom);
});

@@ -44,6 +46,7 @@ describe("VFile", () => {
assert.strictEqual(vfile.path, "foo.js");
assert.strictEqual(vfile.physicalPath, "foo/bar");
assert.strictEqual(vfile.body, "var foo = bar;");
assert.strictEqual(vfile.rawBody, "var foo = bar;");
assert.isFalse(vfile.bom);
});

@@ -55,6 +58,7 @@ describe("VFile", () => {
assert.strictEqual(vfile.path, "foo.js");
assert.strictEqual(vfile.physicalPath, "foo.js");
assert.deepStrictEqual(vfile.body, body);
assert.deepStrictEqual(vfile.rawBody, body);
assert.isFalse(vfile.bom);
});

@@ -66,6 +70,7 @@ describe("VFile", () => {
assert.strictEqual(vfile.path, "foo.js");
assert.strictEqual(vfile.physicalPath, "foo.js");
assert.deepStrictEqual(vfile.body, body.slice(3));
assert.deepStrictEqual(vfile.rawBody, body);
assert.isTrue(vfile.bom);
});

13 changes: 13 additions & 0 deletions tests/lib/rules/id-length.js
Original file line number Diff line number Diff line change
@@ -66,7 +66,11 @@ ruleTester.run("id-length", rule, {
{ code: "export var num = 0;", languageOptions: { ecmaVersion: 6, sourceType: "module" } },
{ code: "import * as something from 'y';", languageOptions: { ecmaVersion: 6, sourceType: "module" } },
{ code: "import { x } from 'y';", languageOptions: { ecmaVersion: 6, sourceType: "module" } },
{ code: "import { x as x } from 'y';", languageOptions: { ecmaVersion: 6, sourceType: "module" } },
{ code: "import { 'x' as x } from 'y';", languageOptions: { ecmaVersion: 2022, sourceType: "module" } },
{ code: "import { x as foo } from 'y';", languageOptions: { ecmaVersion: 6, sourceType: "module" } },
{ code: "import { longName } from 'y';", options: [{ max: 5 }], languageOptions: { ecmaVersion: 6, sourceType: "module" } },
{ code: "import { x as bar } from 'y';", options: [{ max: 5 }], languageOptions: { ecmaVersion: 6, sourceType: "module" } },
{ code: "({ prop: obj.x.y.something } = {});", languageOptions: { ecmaVersion: 6 } },
{ code: "({ prop: obj.longName } = {});", languageOptions: { ecmaVersion: 6 } },
{ code: "var obj = { a: 1, bc: 2 };", options: [{ properties: "never" }] },
@@ -250,6 +254,9 @@ ruleTester.run("id-length", rule, {
{ code: "var [,i,a] = arr;", languageOptions: { ecmaVersion: 6 }, errors: [tooShortError, tooShortError] },
{ code: "function foo([a]) {}", languageOptions: { ecmaVersion: 6 }, errors: [tooShortError] },
{ code: "import x from 'module';", languageOptions: { ecmaVersion: 6 }, errors: [tooShortError] },
{ code: "import { x as z } from 'module';", languageOptions: { ecmaVersion: 6 }, errors: [{ ...tooShortError, column: 15 }] },
{ code: "import { foo as z } from 'module';", languageOptions: { ecmaVersion: 6 }, errors: [{ ...tooShortError, column: 17 }] },
{ code: "import { 'foo' as z } from 'module';", languageOptions: { ecmaVersion: 2022 }, errors: [{ ...tooShortError, column: 19 }] },
{ code: "import * as x from 'module';", languageOptions: { ecmaVersion: 6 }, errors: [tooShortError] },
{
code: "import longName from 'module';",
@@ -263,6 +270,12 @@ ruleTester.run("id-length", rule, {
languageOptions: { ecmaVersion: 6 },
errors: [tooLongError]
},
{
code: "import { foo as longName } from 'module';",
options: [{ max: 5 }],
languageOptions: { ecmaVersion: 6 },
errors: [{ ...tooLongError, column: 17 }]
},
{
code: "var _$xt_$ = Foo(42)",
options: [{ min: 2, max: 4 }],
94 changes: 85 additions & 9 deletions tests/lib/rules/no-useless-constructor.js
Original file line number Diff line number Diff line change
@@ -11,6 +11,7 @@

const rule = require("../../../lib/rules/no-useless-constructor");
const RuleTester = require("../../../lib/rule-tester/rule-tester");
const { unIndent } = require("../../_utils");

//------------------------------------------------------------------------------
// Tests
@@ -47,39 +48,114 @@ ruleTester.run("no-useless-constructor", rule, {
invalid: [
{
code: "class A { constructor(){} }",
errors: [error]
errors: [{
...error,
suggestions: [{
messageId: "removeConstructor",
output: "class A { }"
}]
}]
},
{
code: "class A { 'constructor'(){} }",
errors: [error]
errors: [{
...error,
suggestions: [{
messageId: "removeConstructor",
output: "class A { }"
}]
}]
},
{
code: "class A extends B { constructor() { super(); } }",
errors: [error]
errors: [{
...error,
suggestions: [{
messageId: "removeConstructor",
output: "class A extends B { }"
}]
}]
},
{
code: "class A extends B { constructor(foo){ super(foo); } }",
errors: [error]
errors: [{
...error,
suggestions: [{
messageId: "removeConstructor",
output: "class A extends B { }"
}]
}]
},
{
code: "class A extends B { constructor(foo, bar){ super(foo, bar); } }",
errors: [error]
errors: [{
...error,
suggestions: [{
messageId: "removeConstructor",
output: "class A extends B { }"
}]
}]
},
{
code: "class A extends B { constructor(...args){ super(...args); } }",
errors: [error]
errors: [{
...error,
suggestions: [{
messageId: "removeConstructor",
output: "class A extends B { }"
}]
}]
},
{
code: "class A extends B.C { constructor() { super(...arguments); } }",
errors: [error]
errors: [{
...error,
suggestions: [{
messageId: "removeConstructor",
output: "class A extends B.C { }"
}]
}]
},
{
code: "class A extends B { constructor(a, b, ...c) { super(...arguments); } }",
errors: [error]
errors: [{
...error,
suggestions: [{
messageId: "removeConstructor",
output: "class A extends B { }"
}]
}]
},
{
code: "class A extends B { constructor(a, b, ...c) { super(a, b, ...c); } }",
errors: [error]
errors: [{
...error,
suggestions: [{
messageId: "removeConstructor",
output: "class A extends B { }"
}]
}]
},
{
code: unIndent`
class A {
foo = 'bar'
constructor() { }
[0]() { }
}`,
languageOptions: { ecmaVersion: 2022 },
errors: [{
...error,
suggestions: [{
messageId: "removeConstructor",
output: unIndent`
class A {
foo = 'bar'
;
[0]() { }
}`
}]
}]
}
]
});
62 changes: 49 additions & 13 deletions tests/lib/types/types.test.ts
Original file line number Diff line number Diff line change
@@ -27,6 +27,7 @@

import { AST, ESLint, Linter, loadESLint, Rule, RuleTester, Scope, SourceCode } from "eslint";
import { ESLintRules } from "eslint/rules";
import { Linter as ESLinter } from "eslint/universal";
import {
builtinRules,
FileEnumerator,
@@ -35,6 +36,7 @@ import {
shouldUseFlatConfig,
} from "eslint/use-at-your-own-risk";
import { Comment, PrivateIdentifier, PropertyDefinition, StaticBlock, WhileStatement } from "estree";
import { Language } from "@eslint/core";

const SOURCE = `var foo = bar;`;

@@ -105,17 +107,17 @@ loc.column; // $ExpectType number
sourceCode.getIndexFromLoc({ line: 0, column: 0 });

sourceCode.getTokenByRangeStart(0); // $ExpectType Token | null
sourceCode.getTokenByRangeStart(0, { includeComments: true }); // $ExpectType Comment | Token | null || Token | Comment | null
sourceCode.getTokenByRangeStart(0, { includeComments: true }); // $ExpectType Comment | Token | null
sourceCode.getTokenByRangeStart(0, { includeComments: false }); // $ExpectType Token | null
sourceCode.getTokenByRangeStart(0, { includeComments: false as boolean }); // $ExpectType Comment | Token | null || Token | Comment | null
sourceCode.getTokenByRangeStart(0, { includeComments: false as boolean }); // $ExpectType Comment | Token | null

sourceCode.getFirstToken(AST); // $ExpectType Token | null
sourceCode.getFirstToken(AST, 0);
sourceCode.getFirstToken(AST, { skip: 0 });
sourceCode.getFirstToken(AST, (t): t is AST.Token & { type: "Identifier" } => t.type === "Identifier"); // $ExpectType (Token & { type: "Identifier"; }) | null
sourceCode.getFirstToken(AST, { filter: (t): t is AST.Token & { type: "Identifier" } => t.type === "Identifier" }); // $ExpectType (Token & { type: "Identifier"; }) | null
sourceCode.getFirstToken(AST, { skip: 0, filter: t => t.type === "Identifier" });
sourceCode.getFirstToken(AST, { includeComments: true }); // $ExpectType Comment | Token | null || Token | Comment | null
sourceCode.getFirstToken(AST, { includeComments: true }); // $ExpectType Comment | Token | null
sourceCode.getFirstToken(AST, { includeComments: true, skip: 0 });
// prettier-ignore
sourceCode.getFirstToken(AST, { // $ExpectType (Token & { type: "Identifier"; }) | null
@@ -223,7 +225,7 @@ sourceCode.getFirstTokenBetween(AST, AST, {
skip: 0,
filter: (t): t is AST.Token & { type: "Identifier" } => t.type === "Identifier",
});
sourceCode.getFirstTokenBetween(AST, AST, { includeComments: true }); // $ExpectType Comment | Token | null || Token | Comment | null
sourceCode.getFirstTokenBetween(AST, AST, { includeComments: true }); // $ExpectType Comment | Token | null
sourceCode.getFirstTokenBetween(AST, AST, { includeComments: true, skip: 0 });
// prettier-ignore
sourceCode.getFirstTokenBetween(AST, AST, { // $ExpectType (Token & { type: "Identifier"; }) | null
@@ -241,7 +243,7 @@ sourceCode.getFirstTokensBetween(AST, AST, { // $ExpectType (Token & { type: "Id
filter: (t): t is AST.Token & { type: "Identifier" } => t.type === "Identifier",
});
sourceCode.getFirstTokensBetween(AST, AST, { count: 0, filter: t => t.type === "Identifier" });
sourceCode.getFirstTokensBetween(AST, AST, { includeComments: true }); // $ExpectType (Comment | Token)[] || (Token | Comment)[]
sourceCode.getFirstTokensBetween(AST, AST, { includeComments: true }); // $ExpectType (Comment | Token)[]
sourceCode.getFirstTokensBetween(AST, AST, { includeComments: true, count: 0 });
// prettier-ignore
sourceCode.getFirstTokensBetween(AST, AST, { // $ExpectType (Token & { type: "Identifier"; })[]
@@ -278,7 +280,7 @@ sourceCode.getTokens(AST, 0);
sourceCode.getTokens(AST, 0, 0);
sourceCode.getTokens(AST, (t): t is AST.Token & { type: "Identifier" } => t.type === "Identifier"); // $ExpectType (Token & { type: "Identifier"; })[]
sourceCode.getTokens(AST, { filter: (t): t is AST.Token & { type: "Identifier" } => t.type === "Identifier" }); // $ExpectType (Token & { type: "Identifier"; })[]
sourceCode.getTokens(AST, { includeComments: true }); // $ExpectType (Comment | Token)[] || (Token | Comment)[]
sourceCode.getTokens(AST, { includeComments: true }); // $ExpectType (Comment | Token)[]
// prettier-ignore
sourceCode.getTokens(AST, { // $ExpectType (Token & { type: "Identifier"; })[]
includeComments: true,
@@ -578,6 +580,7 @@ rule = {
// #region Linter

const linter = new Linter();
const eslinter = new ESLinter();

linter.version;

@@ -1003,7 +1006,7 @@ linterWithEslintrcConfig.getRules();
const customFormatter1: ESLint.Formatter = { format: () => "ok" };
const customFormatter2: ESLint.Formatter = { format: () => Promise.resolve("ok") };

let data: ESLint.LintResultData;
let resultsMeta: ESLint.ResultsMeta;
const meta: Rule.RuleMetaData = {
type: "suggestion",
docs: {
@@ -1019,15 +1022,15 @@ linterWithEslintrcConfig.getRules();
},
};

data = { cwd: "/foo/bar", rulesMeta: { "no-extra-semi": meta } };
resultsMeta = { maxWarningsExceeded: { maxWarnings: 42, foundWarnings: 43 } };

const version: string = ESLint.version;

(async () => {
const results: ESLint.LintResult[] = await resultsPromise;
const formatter = await formatterPromise;

const output: string = await formatter.format(results, data);
const output: string = await formatter.format(results, resultsMeta);

eslint.getRulesMetaForResults(results);

@@ -1131,7 +1134,7 @@ linterWithEslintrcConfig.getRules();
const customFormatter1: ESLint.Formatter = { format: () => "ok" };
const customFormatter2: ESLint.Formatter = { format: () => Promise.resolve("ok") };

let data: ESLint.LintResultData;
let resultsMeta: ESLint.ResultsMeta;
const meta: Rule.RuleMetaData = {
type: "suggestion",
docs: {
@@ -1147,15 +1150,15 @@ linterWithEslintrcConfig.getRules();
},
};

data = { cwd: "/foo/bar", rulesMeta: { "no-extra-semi": meta } };
resultsMeta = { maxWarningsExceeded: { maxWarnings: 42, foundWarnings: 43 } };

const version: string = LegacyESLint.version;

(async () => {
const results: ESLint.LintResult[] = await resultsPromise;
const formatter = await formatterPromise;

const output: string = await formatter.format(results, data);
const output: string = await formatter.format(results, resultsMeta);

eslint.getRulesMetaForResults(results);

@@ -1169,6 +1172,20 @@ linterWithEslintrcConfig.getRules();

// #endregion

// #region ESLint.Formatter

function jsonFormatter(results: ESLint.LintResult[]) {
return JSON.stringify(results, null, 2);
};

const customFormatter: ESLint.FormatterFunction = jsonFormatter;

function wrapperFormatter(results: ESLint.LintResult[], { cwd, maxWarningsExceeded, rulesMeta }: ESLint.LintResultData) {
customFormatter(results, { cwd, maxWarningsExceeded, rulesMeta });
}

// #endregion ESLint.Formatter

// #region ESLint.LintResult

let results!: ESLint.LintResult[];
@@ -1216,7 +1233,7 @@ for (const result of results) {
}
}

// #region ESLint.LintResult
// #endregion ESLint.LintResult

// #region ESLintRules

@@ -1340,6 +1357,15 @@ ruleTester.run("simple-valid-test", rule, {

// #region Config

((): Linter.Config => ({
language: "js/js"
}));

((): Linter.Config => ({
// @ts-expect-error
language: null
}));

((): Linter.Config => ({
languageOptions: {
parser: {
@@ -1482,6 +1508,16 @@ flatConfig = config;

// #endregion Config

// #region Plugins

((): ESLint.Plugin => ({
languages: {
"js": {} as Language
}
}));

// #endregion Plugins

(async (useFlatConfig?: boolean) => {
await loadESLint(); // $ExpectType typeof ESLint | typeof LegacyESLint
await loadESLint({}); // $ExpectType typeof ESLint | typeof LegacyESLint
21 changes: 21 additions & 0 deletions tests/lib/universal.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/**
* @fileoverview Tests for "eslint/universal".
* @author 唯然<weiran.zsd@outlook.com>
*/

"use strict";
const assert = require("node:assert/strict");

describe("universal", () => {
it("should have Linter exported", () => {
const { Linter } = require("eslint/universal");

assert.ok(Linter);
assert.ok(typeof Linter === "function");


const linter = new Linter();

assert.ok(linter);
});
});