Skip to content

feat(assist): use sorted type fields 9137#9275

Merged
Netail merged 6 commits intobiomejs:nextfrom
ff1451:feat/use-sorted-type-fields-9137
Apr 6, 2026
Merged

feat(assist): use sorted type fields 9137#9275
Netail merged 6 commits intobiomejs:nextfrom
ff1451:feat/use-sorted-type-fields-9137

Conversation

@ff1451
Copy link
Copy Markdown
Contributor

@ff1451 ff1451 commented Feb 28, 2026

I used Claude Code to assist with generating test cases and documentation.

Summary

Implements the useSortedTypeFields assist action for GraphQL as part of #9137.

This action alphabetically sorts fields of:

  • ObjectTypeDefinition
  • InterfaceTypeDefinition
  • InputObjectTypeDefinition
  • and their corresponding extensions

The ordering matches JavaScript’s localeCompare() behavior for GraphQL identifiers ([_A-Za-z0-9]):

  • Primary order: _ < digits < letters (case-insensitive)
  • Tiebreaker: lowercase before uppercase (e.g. aField before AField)

This PR also introduces the assist category infrastructure for biome_graphql_analyze, which previously only supported lint rules.


Why this is implemented as an assist

Sorting fields is a non-semantic, style-only transformation with a clear and safe auto-fix. It does not indicate a bug or problematic pattern — it only improves structural consistency and readability.

For that reason, I implemented it as an assist action rather than a lint rule. If this classification is incorrect (for example, if it should follow thenursery rule policy or be modeled as a lint rule instead), please let me know. I’m happy to adjust the implementation accordingly.


Branch Target

This PR currently targets next, since adding a new assist action is a user-facing feature (minor change).

If new assist actions are expected to target main instead (e.g. if they follow the same release policy as nursery rules), I’m happy to retarget the branch.


Test Plan

Snapshot tests cover:

  • Unsorted ObjectTypeDefinition
  • Unsorted InterfaceTypeDefinition
  • Unsorted InputObjectTypeDefinition
  • Unsorted ObjectTypeExtension
  • Unsorted InterfaceTypeExtension
  • Unsorted InputObjectTypeExtension
  • Mixed-case ordering (apple before Zoo)
  • Case tiebreaker (aField before AField)
  • localeCompare character class ordering (a_ before a1)

Documentation

Inline rustdoc documentation is provided in use_sorted_type_fields.rs,
including expect_diff examples demonstrating the before/after transformation.


@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Feb 28, 2026

🦋 Changeset detected

Latest commit: c24a3d5

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-Tooling Area: internal tools A-Diagnostic Area: diagnostocis labels Feb 28, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Feb 28, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 16af1509-c740-4b8b-8f1f-52a92edbd8f7

📥 Commits

Reviewing files that changed from the base of the PR and between b9a73d9 and c24a3d5.

📒 Files selected for processing (1)
  • .changeset/afraid-humans-worry.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • .changeset/afraid-humans-worry.md

Walkthrough

Adds a new GraphQL assist useSortedTypeFields that detects unsorted fields in object, interface and input object definitions (including extensions) and can auto-fix by replacing them with a locale-aware alphabetically sorted list. Changes include a new ActionName variant, analyzer Assist category and group registration, the rule implementation and state/query types, options struct, codegen updates, build/watch group update, and new test fixtures for valid/invalid cases.

Possibly related PRs

Suggested reviewers

  • dyc3
🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the main change: implementing a new assist action for sorting GraphQL type fields, with reference to the issue number.
Description check ✅ Passed The description is comprehensive and directly related to the changeset, explaining the assist action's purpose, sorting behaviour, and implementation rationale.

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

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

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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.

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

79-131: Consider extracting common pattern.

The six match arms follow identical structure. A helper method could reduce duplication, though current readability is fine.

♻️ Optional: Extract helper for common pattern
fn check_fields<T, F>(fields: Option<T>, check_sorted: F) -> Option<UseSortedTypeFieldsState>
where
    F: FnOnce(&T) -> bool,
    T: Into<UseSortedTypeFieldsState>,
{
    let fields = fields?;
    if check_sorted(&fields) {
        None
    } else {
        Some(fields.into())
    }
}

This would require implementing Into<UseSortedTypeFieldsState> for the field types, which may be more boilerplate than it's worth.

🤖 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_type_fields.rs`
around lines 79 - 131, The six match arms in run (handling
UseSortedTypeFieldsQuery::{GraphqlObjectTypeDefinition,
GraphqlObjectTypeExtension, GraphqlInterfaceTypeDefinition,
GraphqlInterfaceTypeExtension, GraphqlInputObjectTypeDefinition,
GraphqlInputObjectTypeExtension}) duplicate the same pattern; extract a helper
like check_fields that takes the optional fields, a predicate
(is_field_definition_list_sorted or is_input_field_list_sorted) and a closure or
an Into/From conversion to produce the appropriate UseSortedTypeFieldsState
(UseSortedTypeFieldsState::TypeFields or ::InputFields) so each arm reduces to
calling check_fields(fields_option, predicate, state_mapper). Ensure helper
handles the Option early-return (fields?) and returns Some(state) or None
matching current behavior; reference functions is_field_definition_list_sorted,
is_input_field_list_sorted and enum UseSortedTypeFieldsState for integration.
🤖 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_type_fields.rs`:
- Around line 79-131: The six match arms in run (handling
UseSortedTypeFieldsQuery::{GraphqlObjectTypeDefinition,
GraphqlObjectTypeExtension, GraphqlInterfaceTypeDefinition,
GraphqlInterfaceTypeExtension, GraphqlInputObjectTypeDefinition,
GraphqlInputObjectTypeExtension}) duplicate the same pattern; extract a helper
like check_fields that takes the optional fields, a predicate
(is_field_definition_list_sorted or is_input_field_list_sorted) and a closure or
an Into/From conversion to produce the appropriate UseSortedTypeFieldsState
(UseSortedTypeFieldsState::TypeFields or ::InputFields) so each arm reduces to
calling check_fields(fields_option, predicate, state_mapper). Ensure helper
handles the Option early-return (fields?) and returns Some(state) or None
matching current behavior; reference functions is_field_definition_list_sorted,
is_input_field_list_sorted and enum UseSortedTypeFieldsState for integration.

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8cd3da1 and b9a73d9.

⛔ Files ignored due to path filters (3)
  • crates/biome_diagnostics_categories/src/categories.rs is excluded by !**/categories.rs and included by **
  • crates/biome_graphql_analyze/tests/specs/source/useSortedTypeFields/invalid.graphql.snap is excluded by !**/*.snap and included by **
  • crates/biome_graphql_analyze/tests/specs/source/useSortedTypeFields/valid.graphql.snap is excluded by !**/*.snap and included by **
📒 Files selected for processing (13)
  • .changeset/afraid-humans-worry.md
  • crates/biome_configuration/src/analyzer/assist/actions.rs
  • crates/biome_graphql_analyze/build.rs
  • crates/biome_graphql_analyze/src/assist.rs
  • crates/biome_graphql_analyze/src/assist/source.rs
  • crates/biome_graphql_analyze/src/assist/source/use_sorted_type_fields.rs
  • crates/biome_graphql_analyze/src/lib.rs
  • crates/biome_graphql_analyze/src/registry.rs
  • crates/biome_graphql_analyze/tests/specs/source/useSortedTypeFields/invalid.graphql
  • crates/biome_graphql_analyze/tests/specs/source/useSortedTypeFields/valid.graphql
  • crates/biome_rule_options/src/lib.rs
  • crates/biome_rule_options/src/use_sorted_type_fields.rs
  • xtask/codegen/src/generate_analyzer.rs

@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented Feb 28, 2026

Merging this PR will not alter performance

✅ 9 untouched benchmarks
⏩ 219 skipped benchmarks1


Comparing ff1451:feat/use-sorted-type-fields-9137 (c24a3d5) with next (01f8473)

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.

@ff1451 ff1451 changed the title feat(lint): use sorted type fields 9137 feat(assist): use sorted type fields 9137 Feb 28, 2026
Comment thread .changeset/afraid-humans-worry.md Outdated
@Netail
Copy link
Copy Markdown
Member

Netail commented Mar 31, 2026

Sorry for the long wait, looks good :)

Copy link
Copy Markdown
Member

@Netail Netail left a comment

Choose a reason for hiding this comment

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

Perhaps some comments around some fields in tests, so we make sure that comments are moved with the memebers

Comment thread crates/biome_graphql_analyze/src/assist/source/use_sorted_type_fields.rs Outdated
Comment thread crates/biome_graphql_analyze/src/assist/source/use_sorted_type_fields.rs Outdated
@Netail Netail requested a review from a team March 31, 2026 17:44
@Netail Netail force-pushed the feat/use-sorted-type-fields-9137 branch from 35917ef to c24a3d5 Compare April 6, 2026 15:23
@Netail Netail merged commit 1fdbcee into biomejs:next Apr 6, 2026
17 checks passed
@coderabbitai coderabbitai Bot mentioned this pull request Apr 6, 2026
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 A-Tooling Area: internal tools

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants