Release Notes
This is a release focused on GraphQL specification compliance and correctness. I had an agent do several rounds of review over the entire codebase, which uncovered a lot of edge cases and quirks. It also includes several hot-path performance improvements and hardening of the client code generator.
Bug Fixes
Parsing
- Fix float literals with both fraction and exponent being truncated by @ghostdogpr in #3014
- Preserve out-of-range float literals as
BigDecimalby @ghostdogpr in #3022 - Reject out-of-range Int and Long argument literals instead of wrapping by @ghostdogpr in #3029
- Fix enum values whose names start with
true/false/nullbeing mis-parsed by @ghostdogpr in #3026 - Support variable-width unicode escape sequences in string values by @ghostdogpr in #3031
- Parse
VARIABLE_DEFINITIONdirective location by @ghostdogpr in #3020 - Fix compact block-string description ending in backslash-quote by @ghostdogpr in #3021
Validation & variable coercion
- Fix field-merge validation missing nested argument conflicts by @ghostdogpr in #3018
- Fix field-merge validation using queryType as parent for all operations by @ghostdogpr in #3027
- Reject unknown input-object fields in lists and oneOf inputs by @ghostdogpr in #3023
- Validate directives on variable definitions and required directive arguments by @ghostdogpr in #3024
- Reject explicit null for non-null variables and non-null list items by @ghostdogpr in #3033
- Coerce out-of-Long-range integer literals to Float/Double via BigInt by @ghostdogpr in #3034
- Collect variables used in operation-level directives by @ghostdogpr in #3032
- Fix duplicate fragment spread ignoring per-spread
@skip/@includeby @ghostdogpr in #3028 - Fix
RenameTyperenaming enum values that collide with a type name by @ghostdogpr in #3030
Execution & incremental delivery
- Fix nested lists computing item-nullability at the wrong level by @ghostdogpr in #3016
- Fix
@streamlist-field validation by @ghostdogpr in #3015 - Advance
@streampath index across chunks by @ghostdogpr in #3017 - Fix defer/stream label uniqueness check aborting in single-feature mode by @ghostdogpr in #3035
Rendering
- Escape control characters when rendering GraphQL string values by @ghostdogpr in #3036
- Fix block-string line terminators and control-character rendering by @ghostdogpr in #3025
Client & codegen
- Fix client field-name collision rendering and decoding by @ghostdogpr in #3037
- Fix codegen
ClientWriterenum encoder, enum.value, and doc-comment escaping by @ghostdogpr in #3038 - Fail client codegen for value-less enums, objects, interfaces and input objects by @ghostdogpr in #3051
Adapters & interop
- Prefer SSE over
graphql-response+jsonin tapir content negotiation by @ghostdogpr in #3041 - Fix jsoniter number parser miscounting digits of a number at end of input by @ghostdogpr in #3043
- Encode GET query-param variables and extensions as JSON, not GraphQL syntax by @ghostdogpr in #3044
- Select a single supported subprotocol for WebSocket negotiation by @ghostdogpr in #3045
Stitching
- Do not forward schema field-definition directives in proxied remote queries by @ghostdogpr in #3046
Federation & tools
- Fix federation
@connectdirective builder and connect spec version by @ghostdogpr in #3039 - Preserve and compare interface-implements-interface relationships in tools by @ghostdogpr in #3040
Tracing
- Mask list, enum and boolean argument values in
SchemaTracerby @ghostdogpr in #3042
Performance Improvements
- Hoist directive-resolver closure out of the per-field
Field.applyrecursion by @ghostdogpr in #3047 - Index input-object fields by name to remove O(n·m) validation scans by @ghostdogpr in #3048
- Trim per-node allocations in the circe/play/zio JSON codecs by @ghostdogpr in #3049
- Capture string-literal character runs in a single pass in the parser by @ghostdogpr in #3050