Skip to content

feat(graphql_analyze): implement useSortedSelectionSet#9853

Merged
Netail merged 3 commits intobiomejs:nextfrom
Netail:feat/use-sorted-selection-set
Apr 11, 2026
Merged

feat(graphql_analyze): implement useSortedSelectionSet#9853
Netail merged 3 commits intobiomejs:nextfrom
Netail:feat/use-sorted-selection-set

Conversation

@Netail
Copy link
Copy Markdown
Member

@Netail Netail commented Apr 7, 2026

AI disclosure: base by myself, from selection_group by our good friend co-pilot

Summary

Implement SelectionSet sorting for graphql, based on Eslint Graphql's alphabetize

Related #9137

Test Plan

Unit tests

Docs

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Apr 7, 2026

🦋 Changeset detected

Latest commit: dc24c3a

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 14 packages
Name Type
@biomejs/biome Minor
@biomejs/cli-win32-x64 Minor
@biomejs/cli-win32-arm64 Minor
@biomejs/cli-darwin-x64 Minor
@biomejs/cli-darwin-arm64 Minor
@biomejs/cli-linux-x64 Minor
@biomejs/cli-linux-arm64 Minor
@biomejs/cli-linux-x64-musl Minor
@biomejs/cli-linux-arm64-musl Minor
@biomejs/wasm-web Minor
@biomejs/wasm-bundler Minor
@biomejs/wasm-nodejs Minor
@biomejs/backend-jsonrpc Patch
@biomejs/js-api Major

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions github-actions Bot added A-Project Area: project A-Linter Area: linter A-Diagnostic Area: diagnostocis labels Apr 7, 2026
@Netail Netail marked this pull request as draft April 7, 2026 21:40
@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented Apr 7, 2026

Merging this PR will not alter performance

✅ 9 untouched benchmarks
⏩ 219 skipped benchmarks1


Comparing Netail:feat/use-sorted-selection-set (dc24c3a) with next (5a594fb)

Open in CodSpeed

Footnotes

  1. 219 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 7, 2026

Walkthrough

Adds a new GraphQL assist action useSortedSelectionSet: extends ActionName with UseSortedSelectionSet, registers a new source rule that detects unsorted GraphQL selection sets and offers an unsafe fix to replace them with a sorted selection list, exports a new use_sorted_selection_set options module and an empty UseSortedSelectionSetOptions struct, and adds valid/invalid GraphQL test fixtures plus a changeset entry documenting the assist.

Possibly related PRs

Suggested labels

A-Tooling

Suggested reviewers

  • dyc3
🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately reflects the main change: implementing a new GraphQL assist action useSortedSelectionSet for selection set sorting.
Description check ✅ Passed The description relates to the changeset, mentioning SelectionSet sorting implementation for GraphQL based on ESLint's alphabetize rule with a test plan.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.changeset/new-bikes-buy.md:
- Around line 1-3: The changeset currently lists "@biomejs/biome": patch which
understates the release; update the changeset to use "minor" instead of "patch"
for the "@biomejs/biome" entry so the new user-facing assist on next is released
as a minor version.

In `@crates/biome_graphql_analyze/src/assist/source/use_sorted_selection_set.rs`:
- Around line 218-275: Add a test fixture pair under
tests/specs/source/useSortedSelectionSet/ that exercises the underscore, digit,
and mixed-case branches of the comparator so regressions in
locale_compare/compare_primary/primary_char_key/compare_tertiary are caught:
create one "invalid" input where fields are intentionally ordered to trigger
ordering differences between '_' vs digits vs letters and mixed-case
tie-breakers (e.g., names with leading '_' , names starting with digits, and
same letters with differing case), and a corresponding "valid" file with the
correct order per the comparator; ensure the spec asserts the rule flags the
invalid file and accepts the valid one.
- Around line 45-52: The rule metadata declares UseSortedSelectionSet with
FixKind::Safe but reordering selection fields is observable under GraphQL, so
change the metadata on UseSortedSelectionSet from FixKind::Safe to
FixKind::Unsafe; also add/expand unit tests for the comparator logic (exercise
underscores, digits, and mixed-case tie-breakers) to the existing test suite
that validates the selection ordering comparator to ensure those cases are
covered.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: a6077ffb-fbdd-403d-aa3d-23a866574972

📥 Commits

Reviewing files that changed from the base of the PR and between c54e8c2 and 9356234.

⛔ Files ignored due to path filters (5)
  • crates/biome_diagnostics_categories/src/categories.rs is excluded by !**/categories.rs and included by **
  • crates/biome_graphql_analyze/tests/specs/source/useSortedSelectionSet/invalid.graphql.snap is excluded by !**/*.snap and included by **
  • crates/biome_graphql_analyze/tests/specs/source/useSortedSelectionSet/valid.graphql.snap is excluded by !**/*.snap and included by **
  • packages/@biomejs/backend-jsonrpc/src/workspace.ts is excluded by !**/backend-jsonrpc/src/workspace.ts and included by **
  • packages/@biomejs/biome/configuration_schema.json is excluded by !**/configuration_schema.json and included by **
📒 Files selected for processing (7)
  • .changeset/new-bikes-buy.md
  • crates/biome_configuration/src/analyzer/assist/actions.rs
  • crates/biome_graphql_analyze/src/assist/source/use_sorted_selection_set.rs
  • crates/biome_graphql_analyze/tests/specs/source/useSortedSelectionSet/invalid.graphql
  • crates/biome_graphql_analyze/tests/specs/source/useSortedSelectionSet/valid.graphql
  • crates/biome_rule_options/src/lib.rs
  • crates/biome_rule_options/src/use_sorted_selection_set.rs

Comment thread .changeset/new-bikes-buy.md
Comment thread crates/biome_graphql_analyze/src/assist/source/use_sorted_selection_set.rs Outdated
@Netail Netail force-pushed the feat/use-sorted-selection-set branch 2 times, most recently from 37e0ee4 to 810c10b Compare April 8, 2026 21:45
@Netail Netail marked this pull request as ready for review April 8, 2026 22:02
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
crates/biome_graphql_analyze/src/assist/source/use_sorted_selection_set.rs (1)

100-102: Tiny tidy-up: inline the one-line comparator helper.

comparator currently just forwards to ComparableToken::ascii_nat_cmp; inlining would reduce indirection without changing behaviour.

♻️ Minimal refactor
-fn comparator(a: &ComparableToken, b: &ComparableToken) -> std::cmp::Ordering {
-    ComparableToken::ascii_nat_cmp(a, b)
-}
@@
-            comparator(&a, &b)
+            ComparableToken::ascii_nat_cmp(&a, &b)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/biome_graphql_analyze/src/assist/source/use_sorted_selection_set.rs`
around lines 100 - 102, The helper function comparator that simply calls
ComparableToken::ascii_nat_cmp should be inlined: replace uses of comparator
(e.g., sort_by(comparator) or any place passing comparator) with a direct
closure or function pointer calling ComparableToken::ascii_nat_cmp (for example
sort_by(|a, b| ComparableToken::ascii_nat_cmp(a, b))) and then remove the
now-unused fn comparator definition to eliminate the trivial indirection while
preserving behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@crates/biome_graphql_analyze/src/assist/source/use_sorted_selection_set.rs`:
- Around line 100-102: The helper function comparator that simply calls
ComparableToken::ascii_nat_cmp should be inlined: replace uses of comparator
(e.g., sort_by(comparator) or any place passing comparator) with a direct
closure or function pointer calling ComparableToken::ascii_nat_cmp (for example
sort_by(|a, b| ComparableToken::ascii_nat_cmp(a, b))) and then remove the
now-unused fn comparator definition to eliminate the trivial indirection while
preserving behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 9a83176d-5da0-4db3-8de8-23390fe94265

📥 Commits

Reviewing files that changed from the base of the PR and between 9356234 and 810c10b.

⛔ Files ignored due to path filters (5)
  • crates/biome_diagnostics_categories/src/categories.rs is excluded by !**/categories.rs and included by **
  • crates/biome_graphql_analyze/tests/specs/source/useSortedSelectionSet/invalid.graphql.snap is excluded by !**/*.snap and included by **
  • crates/biome_graphql_analyze/tests/specs/source/useSortedSelectionSet/valid.graphql.snap is excluded by !**/*.snap and included by **
  • packages/@biomejs/backend-jsonrpc/src/workspace.ts is excluded by !**/backend-jsonrpc/src/workspace.ts and included by **
  • packages/@biomejs/biome/configuration_schema.json is excluded by !**/configuration_schema.json and included by **
📒 Files selected for processing (7)
  • .changeset/new-bikes-buy.md
  • crates/biome_configuration/src/analyzer/assist/actions.rs
  • crates/biome_graphql_analyze/src/assist/source/use_sorted_selection_set.rs
  • crates/biome_graphql_analyze/tests/specs/source/useSortedSelectionSet/invalid.graphql
  • crates/biome_graphql_analyze/tests/specs/source/useSortedSelectionSet/valid.graphql
  • crates/biome_rule_options/src/lib.rs
  • crates/biome_rule_options/src/use_sorted_selection_set.rs
✅ Files skipped from review due to trivial changes (3)
  • .changeset/new-bikes-buy.md
  • crates/biome_rule_options/src/lib.rs
  • crates/biome_rule_options/src/use_sorted_selection_set.rs
🚧 Files skipped from review as they are similar to previous changes (3)
  • crates/biome_graphql_analyze/tests/specs/source/useSortedSelectionSet/invalid.graphql
  • crates/biome_graphql_analyze/tests/specs/source/useSortedSelectionSet/valid.graphql
  • crates/biome_configuration/src/analyzer/assist/actions.rs

@Netail Netail force-pushed the feat/use-sorted-selection-set branch from 810c10b to ee4154c Compare April 9, 2026 19:39
@Netail Netail requested review from a team April 9, 2026 19:41
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
crates/biome_graphql_analyze/src/assist/source/use_sorted_selection_set.rs (1)

106-109: Tiny naming nit: fields is actually a selection list.

This reads cleaner if fields is renamed to selections (future-you will thank present-you).

💡 Suggested rename
-        let fields = node.selections();
+        let selections = node.selections();
         let mut mutation = ctx.root().begin();

-        sort_selection_list(&fields, &mut mutation)?;
+        sort_selection_list(&selections, &mut mutation)?;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/biome_graphql_analyze/src/assist/source/use_sorted_selection_set.rs`
around lines 106 - 109, In the action function (fn action) the local variable
named fields actually holds node.selections(); rename fields to selections to
make intent clear: change the declaration let fields = node.selections() to let
selections = node.selections() and update all subsequent uses in the function
(and any lambda/closure if present) to reference selections instead of fields
(e.g., where fields.iter() or fields.len() might be used); this is purely a
local rename inside action and requires no API changes.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@crates/biome_graphql_analyze/src/assist/source/use_sorted_selection_set.rs`:
- Around line 106-109: In the action function (fn action) the local variable
named fields actually holds node.selections(); rename fields to selections to
make intent clear: change the declaration let fields = node.selections() to let
selections = node.selections() and update all subsequent uses in the function
(and any lambda/closure if present) to reference selections instead of fields
(e.g., where fields.iter() or fields.len() might be used); this is purely a
local rename inside action and requires no API changes.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 920a7242-f24b-4ffd-9b76-a1d0ed0d433a

📥 Commits

Reviewing files that changed from the base of the PR and between 810c10b and ee4154c.

⛔ Files ignored due to path filters (5)
  • crates/biome_diagnostics_categories/src/categories.rs is excluded by !**/categories.rs and included by **
  • crates/biome_graphql_analyze/tests/specs/source/useSortedSelectionSet/invalid.graphql.snap is excluded by !**/*.snap and included by **
  • crates/biome_graphql_analyze/tests/specs/source/useSortedSelectionSet/valid.graphql.snap is excluded by !**/*.snap and included by **
  • packages/@biomejs/backend-jsonrpc/src/workspace.ts is excluded by !**/backend-jsonrpc/src/workspace.ts and included by **
  • packages/@biomejs/biome/configuration_schema.json is excluded by !**/configuration_schema.json and included by **
📒 Files selected for processing (7)
  • .changeset/new-bikes-buy.md
  • crates/biome_configuration/src/analyzer/assist/actions.rs
  • crates/biome_graphql_analyze/src/assist/source/use_sorted_selection_set.rs
  • crates/biome_graphql_analyze/tests/specs/source/useSortedSelectionSet/invalid.graphql
  • crates/biome_graphql_analyze/tests/specs/source/useSortedSelectionSet/valid.graphql
  • crates/biome_rule_options/src/lib.rs
  • crates/biome_rule_options/src/use_sorted_selection_set.rs
✅ Files skipped from review due to trivial changes (6)
  • .changeset/new-bikes-buy.md
  • crates/biome_rule_options/src/lib.rs
  • crates/biome_graphql_analyze/tests/specs/source/useSortedSelectionSet/valid.graphql
  • crates/biome_graphql_analyze/tests/specs/source/useSortedSelectionSet/invalid.graphql
  • crates/biome_configuration/src/analyzer/assist/actions.rs
  • crates/biome_rule_options/src/use_sorted_selection_set.rs

Comment thread crates/biome_graphql_analyze/src/assist/source/use_sorted_selection_set.rs Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
crates/biome_graphql_analyze/src/assist/source/use_sorted_selection_set.rs (1)

106-119: Nitpick: Variable naming.

Line 108 uses fields but it holds all selections (fields, spreads, and fragments). Consider renaming to selections for consistency with the rest of the file.

♻️ Suggested fix
 fn action(ctx: &RuleContext<Self>, _state: &Self::State) -> Option<GraphqlRuleAction> {
     let node = ctx.query();
-    let fields = node.selections();
+    let selections = node.selections();
     let mut mutation = ctx.root().begin();

-    sort_selection_list(&fields, &mut mutation)?;
+    sort_selection_list(&selections, &mut mutation)?;

     Some(RuleAction::new(
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/biome_graphql_analyze/src/assist/source/use_sorted_selection_set.rs`
around lines 106 - 119, In the action function, the local variable named
`fields` actually holds all selection items (fields, spreads, fragments); rename
`fields` to `selections` to match naming used elsewhere and improve clarity.
Update the declaration that assigns `node.selections()` and any subsequent
usages (e.g., the call to `sort_selection_list(&fields, &mut mutation)?;`) to
use `selections`, ensuring the function `action`, the `node.selections()` call,
and the `sort_selection_list` invocation are updated accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@crates/biome_graphql_analyze/src/assist/source/use_sorted_selection_set.rs`:
- Around line 106-119: In the action function, the local variable named `fields`
actually holds all selection items (fields, spreads, fragments); rename `fields`
to `selections` to match naming used elsewhere and improve clarity. Update the
declaration that assigns `node.selections()` and any subsequent usages (e.g.,
the call to `sort_selection_list(&fields, &mut mutation)?;`) to use
`selections`, ensuring the function `action`, the `node.selections()` call, and
the `sort_selection_list` invocation are updated accordingly.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: baddf7ef-0789-4612-b529-a3e964e28e3d

📥 Commits

Reviewing files that changed from the base of the PR and between ee4154c and dc24c3a.

⛔ Files ignored due to path filters (2)
  • crates/biome_diagnostics_categories/src/categories.rs is excluded by !**/categories.rs and included by **
  • packages/@biomejs/backend-jsonrpc/src/workspace.ts is excluded by !**/backend-jsonrpc/src/workspace.ts and included by **
📒 Files selected for processing (1)
  • crates/biome_graphql_analyze/src/assist/source/use_sorted_selection_set.rs

@Netail Netail merged commit 816302f into biomejs:next Apr 11, 2026
17 checks passed
@Netail Netail deleted the feat/use-sorted-selection-set branch April 11, 2026 15:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-Diagnostic Area: diagnostocis A-Linter Area: linter A-Project Area: project

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants