Skip to content

feat: add quick fixes for GraphQL diagnostics#413

Open
JoviDeCroock wants to merge 1 commit into
mainfrom
feat/graphql-code-fixes
Open

feat: add quick fixes for GraphQL diagnostics#413
JoviDeCroock wants to merge 1 commit into
mainfrom
feat/graphql-code-fixes

Conversation

@JoviDeCroock

Copy link
Copy Markdown
Member

What/Why

Editors can request code fixes for the diagnostics GraphQLSP reports, but until now the plugin passed those requests straight through to TypeScript, which has nothing to offer inside a GraphQL document. This adds a getCodeFixesAtPosition proxy that turns three of the plugin's own diagnostics into one-click quick fixes:

  • "Did you mean" replacements (code 52001): graphql-js validation messages that end in Did you mean "a", "b", or "c"? produce one fix per suggestion, replacing just the misspelled token. Suggestions that aren't a plain rename ("Did you mean to use an inline fragment on ...") are skipped.
  • Replace deprecated field (code 52004): when a field's deprecation reason names a replacement — a backtick-quoted word or a single identifier after "use"/"replaced by"/"replaced with", case-insensitive — a fix replaces the deprecated field name. Reasons without a parseable replacement (e.g. "No longer supported") offer no fix.
  • Remove unused field (code 52005): the unused leaf paths listed in the diagnostic message are resolved back to their field nodes in the document and deleted, taking their line and indentation along when the field owns its line (a field with a selection set is deleted whole). When the removal would leave the parent selection set empty — which would be invalid GraphQL — no fix is offered.

Implementation notes

  • New module packages/graphqlsp/src/codeFixes.ts; the proxy in index.ts follows the existing guard() pattern and always merges with/falls back to info.languageService.getCodeFixesAtPosition(...).
  • Fixes are derived from getGraphQLDiagnostics, so they reuse the same LRU-cached diagnostics the editor's request is based on and stay consistent with the reported spans.
  • The 52001/52004 diagnostic spans can extend past the offending token (e.g. across the trailing newline), so the fix locates the token named in the message within the span and only replaces that; if the token can't be found in the span, no fix is offered.
  • The did-you-mean and deprecated fixes operate purely on diagnostic spans and so work in both call-expression and tagged-template mode; that said, the e2e coverage is call-expression mode only. The unused-field fix is call-expression mode by nature, since field-usage tracking (52005) only runs in that mode.
  • New fixture project test/e2e/fixture-project-code-fixes with a schema containing deprecated fields with and without parseable replacements; the existing tada fixture couldn't be extended because its schema is pinned by completion snapshots.

Test plan

  • test/e2e/code-fixes.test.ts (new): asserts the 52001/52004 diagnostics and the exact fix descriptions and text changes for a single suggestion, multiple suggestions (one fix each), "Use `name` instead", "This field is replaced by `power`", and asserts no fix for a reason without replacement.
  • test/e2e/unused-fieds.test.ts (extended): asserts exact whole-line deletions for a top-level and a nested unused field, and that no fix is offered when removing the listed fields would empty the selection set.
  • pnpm --filter @0no-co/graphqlsp run build passes; full pnpm run test:e2e passes: 12 files, 59 tests, 0 failures.

🤖 Generated with Claude Code

Adds a getCodeFixesAtPosition proxy that offers quick fixes for
GraphQLSP's own diagnostics:

- 'Did you mean' suggestions in validation messages (52001) become one
  rename fix per suggested replacement
- deprecated fields (52004) whose deprecation reason names a
  replacement (backtick-quoted word or single identifier after
  'use'/'replaced by') get a fix swapping in the replacement
- unused fields (52005) get a fix removing them from the document,
  including their line and indentation, unless the removal would leave
  the parent selection set empty

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@changeset-bot

changeset-bot Bot commented Jul 4, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 3ce7328

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

This PR includes changesets to release 1 package
Name Type
@0no-co/graphqlsp Minor

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant