Skip to content

Support fragment arguments on GraphQL 17 - #429

Draft
JoviDeCroock wants to merge 1 commit into
mainfrom
feat/fragment-arguments
Draft

Support fragment arguments on GraphQL 17#429
JoviDeCroock wants to merge 1 commit into
mainfrom
feat/fragment-arguments

Conversation

@JoviDeCroock

Copy link
Copy Markdown
Member

Stops fragment arguments from being reported as syntax errors when the project is on GraphQL 17:

query Page($size: Int!) {
  product {
    ...Fields(size: $size)
  }
}

fragment Fields($size: Int! = 64) on Product {
  image(size: $size)
}

What changed

  • New src/graphql/parse.ts wraps graphql's parse with experimentalFragmentArguments, the option GraphQL 17 gates this syntax behind. Every call site that parsed documents — ast/index.ts, autoComplete.ts, checkImports.ts, definition.ts, diagnostics.ts, fieldUsage.ts — now goes through it. GraphQL 15 and 16 ignore unknown parse options, so nothing changes there: the syntax keeps reporting a syntax error, because those versions genuinely can't represent it.
  • Diagnostics no longer call getDiagnostics, which parses the document itself without those options. getDocumentDiagnostics reproduces what it does — concatenating the printed external fragments, then validating — but parses with our options and hands the AST to validateQuery. GraphQL 17's specifiedRules already validate fragment arguments (required, unknown, and mis-typed arguments), so no custom rules are needed. If the document genuinely doesn't parse, it falls back to getDiagnostics for the ranged syntax error it produces.
  • The external fragments are printed with graphql's print rather than @0no-co/graphql.web's, so the AST is printed by the same version that parsed it. Printing a GraphQL 17 fragment definition with graphql.web 1.3 silently drops its argument definitions, which would then surface as bogus validation errors.

Not covered here

Persisted-document hashing (persisted.ts) parses and prints with @0no-co/graphql.web, which can't represent fragment arguments until 0no-co/graphql.web#83 lands. Routing it through graphql instead isn't an option — the hash is derived from graphql.web's printed output, so switching printers would invalidate every existing persisted hash. Left as a follow-up: bump the dependency once that release is out. This is not a regression; that path never handled the syntax.

Tests

test/unit/fragmentArguments.test.ts pins both halves of the contract: that PARSE_OPTIONS is what unlocks the syntax on GraphQL 17 (a graphql17 dev alias is added for this), and that the option is inert on the GraphQL 16 the repo tests against — ordinary documents still parse, and a fragment-arguments document still produces exactly one syntax diagnostic through the fallback rather than crashing.

The end-to-end "no diagnostics on GraphQL 17" case isn't covered in CI. The plugin resolves graphql from packages/graphqlsp/node_modules, which is 16 for every fixture project, and aliasing it in Vitest doesn't reach graphql-language-service, which resolves its own copy and then rejects the schema as coming "from another module or realm". Getting real coverage means running the suite (or a fixture project) against GraphQL 17, which felt like a separate change. Verified by hand in the meantime.

Full unit suite passes (21). All e2e files pass except unused-fieds and multi-schema-tada, which fail identically on main in this environment and vary run to run (2–5 failures for the same code), so they look load-related rather than caused by this change.

🤖 Generated with Claude Code

Parses every document with `experimentalFragmentArguments` and validates
the parsed document instead of letting graphql-language-service re-parse it
without that option, so `fragment Fields($size: Int!) on Product` and
`...Fields(size: $size)` stop being reported as syntax errors. Older GraphQL
versions ignore the option.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@changeset-bot

changeset-bot Bot commented Aug 22, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: d0d3425

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