feat(federation): add FieldSet type for selections with inline fragments - #1644
Merged
Conversation
SelectionFromShape can't express selections that need inline fragments to select through a union or interface field, forcing an 'as unknown as' cast that disables checking entirely. FieldSet<Shape> is a branded string that builder.selection and ref.provides accept alongside checked selection strings, so complex selections need only a single explicit cast while keeping the shape for resolver parent typing. Fixes #1643 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DHyy8T9rZry73H64Dxj42L
The shape is inferred from the FieldSet brand, so builder.selection no longer needs an explicit generic argument when a cast is used. Update the example schema, type tests, docs site, and plugin README to show cast-only usage. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DHyy8T9rZry73H64Dxj42L
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
🦋 Changeset detectedLatest commit: 0234f36 The changes in this PR will be included in the next version bump. This PR includes changesets to release 3 packages
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 |
@pothos/core
@pothos/plugin-add-graphql
@pothos/plugin-complexity
@pothos/plugin-dataloader
@pothos/plugin-directives
@pothos/plugin-drizzle
@pothos/plugin-errors
@pothos/plugin-example
@pothos/plugin-federation
@pothos/plugin-grafast
@pothos/plugin-mocks
@pothos/plugin-prisma
@pothos/plugin-prisma-utils
@pothos/plugin-relay
@pothos/plugin-scope-auth
@pothos/plugin-simple-objects
@pothos/plugin-smart-subscriptions
@pothos/plugin-sub-graph
@pothos/plugin-tracing
@pothos/plugin-validation
@pothos/plugin-with-input
@pothos/plugin-zod
@pothos/tracing-newrelic
@pothos/tracing-opentelemetry
@pothos/tracing-sentry
@pothos/tracing-xray
commit: |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #1643
Problem
SelectionFromShapecan't express selections that need inline fragments to select through a union or interface field, so@key/@requires/@providesfield sets likemedia { ... on Image { url } ... on Video { url } }only compile with anas unknown as SelectionFromShape<...>cast, which turns checking off entirely and reads as a hack.Solution
Add a branded string type,
FieldSet<Shape>, accepted anywhere a checked selection string is —builder.selectionandref.provides. A single plainascast replaces the generic argument entirely (the shape is inferred from the brand and still drives resolverparenttyping):SelectionFromShapeis untouched, so existing checked strings, autocompletion, and type-check performance are unchanged. Un-branded plainstrings are still rejected, and aFieldSetbranded with one shape doesn't satisfy a selection for a different shape. The brand uses adeclare const unique symbol, so there is no runtime change anywhere.Fully checked fragment-aware selection types (template-literal and object-based forms) were prototyped and work, but were set aside as not worth the added type complexity; they could be layered on later without breaking this API.
Changes
src/types.ts: new exportedFieldSet<Shape>typesrc/schema-builder.ts,src/global-types.ts,src/external-ref.ts:builder.selectionandprovidesacceptFieldSet<Shape> | SelectionFromShape<Shape>tests/example/media/schema.ts: new example subgraph reproducing the issue's scenario; snapshot shows@requires(fields: "media { ... on Image { url } ... on Video { url } }")in the subgraph SDLtests/field-set-types.ts: type-level assertions (cast-only inference, plain strings still rejected, wrong-shape brands rejected, existing checking unchanged)federation.mdx) and plugin README: new "Selections with inline fragments" section@pothos/plugin-federationVerification
pnpm turbo run type test --filter='@pothos/plugin-federation': 8/8 tests pass, no type errors (TS 7.0.2)biome checkclean🤖 Generated with Claude Code
https://claude.ai/code/session_01DHyy8T9rZry73H64Dxj42L
Generated by Claude Code