Add support for graphql-js v17#8313
Conversation
🦋 Changeset detectedLatest commit: ccbcce9 The changes in this PR will be included in the next version bump. This PR includes changesets to release 29 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 |
📝 WalkthroughSummary by CodeRabbit
WalkthroughThis change adds GraphQL.js v17 compatibility across variable coercion, executor resolver metadata, scalar resolver configuration, package peer support, type patches, and version-aware tests. ChangesGraphQL.js v17 compatibility
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant Execution
participant GraphQLJSCompat
participant Resolver
Execution->>GraphQLJSCompat: convert variable values
GraphQLJSCompat-->>Execution: return v17-compatible variableValues
Execution->>Resolver: provide GraphQLResolveInfo and directive values
Resolver-->>Execution: resolve fields using updated execution metadata
Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 Checkov (3.3.8)package.jsonTraceback (most recent call last): packages/executor/package.jsonTraceback (most recent call last): packages/executors/apollo-link/package.jsonTraceback (most recent call last):
🔧 ESLint
ESLint install timed out. The project may have too many dependencies for the sandbox. 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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
packages/schema/src/addResolversToSchema.ts (2)
189-215: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winKeep
updateResolversInPlaceconsistent with the cloned-schema path.The in-place path updates
parseValue/coerceInputValue, butupdateResolversInPlace: truekeeps the existing scalar’s originalparseLiteraleven when resolver input coercing is overridden. Since execution falls back toparseLiteralwhen a scalar has nocoerceInputLiteral, remove/override the literal parser in the same scalar-override branch used by the mapped-schema path so both modes use the same new input coercer.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/schema/src/addResolversToSchema.ts` around lines 189 - 215, Update the scalar override branch in updateResolversInPlace so overriding input coercion also removes or replaces the existing scalar parseLiteral handler, matching the cloned-schema path. Ensure execution cannot retain the original parseLiteral when resolver input coercing is provided, so both schema update modes use the new coercer consistently.
313-354: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winClear the inherited
coerceInputLiteralwhen overriding scalar coercion.
GraphQLScalarType.toConfig()carries the current scalar coercion methods, includingcoerceInputLiteral. If a resolver only overridesparseValue/coerceInputValuewithout also overriding literal coercion, leavecoerceInputLiteralon the copied config and literal argument coercion can still use the old resolver implementation. Remove it unless the resolver supplies a freshcoerceInputLiteral.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/schema/src/addResolversToSchema.ts` around lines 313 - 354, Update the scalar coercion cleanup after the resolver fields are copied so that when coerceInputValueOverridden is true and parseLiteralOverridden is false, it also removes the inherited coerceInputLiteral configuration. Preserve coerceInputLiteral when the resolver explicitly overrides literal coercion, using the existing detection symbols in the surrounding scalar setup.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/utils/src/getArgumentValues.ts`:
- Around line 52-73: Update the missing-variable handling in getArgumentValues
to reuse the existing graphql v17 arg.default coercion path when the referenced
variable has no coerced value, instead of checking only legacy arg.defaultValue.
Preserve the current coercion and invalid-default error behavior, while ensuring
field arguments referencing absent variables receive the v17 default before
non-null validation.
In `@packages/utils/src/graphqlJSCompat.ts`:
- Around line 95-104: Update buildVariableSources to preserve each variable’s
declared GraphQL input type instead of assigning anyValueType to every variable.
Pass variableDefinitions alongside variableValues from toGraphQLJSVariableValues
and build each source signature from the corresponding definition type,
preserving nested enum and custom-scalar literal/coercion behavior.
---
Outside diff comments:
In `@packages/schema/src/addResolversToSchema.ts`:
- Around line 189-215: Update the scalar override branch in
updateResolversInPlace so overriding input coercion also removes or replaces the
existing scalar parseLiteral handler, matching the cloned-schema path. Ensure
execution cannot retain the original parseLiteral when resolver input coercing
is provided, so both schema update modes use the new coercer consistently.
- Around line 313-354: Update the scalar coercion cleanup after the resolver
fields are copied so that when coerceInputValueOverridden is true and
parseLiteralOverridden is false, it also removes the inherited
coerceInputLiteral configuration. Preserve coerceInputLiteral when the resolver
explicitly overrides literal coercion, using the existing detection symbols in
the surrounding scalar setup.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 56f44631-bb26-48ef-ade2-2b0b1a78f5df
📒 Files selected for processing (24)
.changeset/bold-webs-behave.mdpackage.jsonpackages/executor/package.jsonpackages/executor/src/execution/__tests__/executor-test.tspackages/executor/src/execution/__tests__/oneOf-test.tspackages/executor/src/execution/__tests__/variables-test.tspackages/executor/src/execution/execute.tspackages/executor/src/execution/values.tspackages/executors/apollo-link/package.jsonpackages/executors/urql-exchange/package.jsonpackages/loaders/git/tests/loader.spec.tspackages/optimize/tests/remove-empty-nodes.spec.tspackages/optimize/tests/remove-loc.spec.tspackages/schema/src/addResolversToSchema.tspackages/schema/tests/schemaGenerator.test.tspackages/utils/src/collectFields.tspackages/utils/src/getArgumentValues.tspackages/utils/src/getDirectiveExtensions.tspackages/utils/src/graphqlJSCompat.tspackages/utils/src/index.tspackages/utils/tests/getArgumentValues.spec.tspackages/utils/tests/mapSchema.test.tspatches/@types+relay-compiler+8.0.4.patchpatches/subscriptions-transport-ws+0.11.0.patch
| if (!argumentNode) { | ||
| if ('default' in (arg as any) && (arg as any).default) { | ||
| // graphql v17 | ||
| coercedValues[arg.name] = | ||
| 'value' in (arg as any).default | ||
| ? (arg as any).default.value | ||
| : valueFromASTUntyped((arg as any).default.literal); | ||
| const defaultInput = (arg as any).default; | ||
| if ('value' in defaultInput) { | ||
| coercedValues[arg.name] = defaultInput.value; | ||
| } else { | ||
| const coercedDefaultValue = coerceInputLiteral | ||
| ? coerceInputLiteral(defaultInput.literal, arg.type) | ||
| : valueFromASTUntyped(defaultInput.literal); | ||
| if (coercedDefaultValue === undefined) { | ||
| // Schema validation should catch an invalid default value before | ||
| // execution; this mirrors graphql-js's own `coerceDefaultValue`, | ||
| // which treats this case as an invariant failure rather than | ||
| // silently producing `undefined`. | ||
| throw createGraphQLError( | ||
| `Argument "${arg.name}" has invalid default value ${print(defaultInput.literal)}.`, | ||
| { nodes: [defaultInput.literal] }, | ||
| ); | ||
| } | ||
| coercedValues[arg.name] = coercedDefaultValue; | ||
| } |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/sh
rg -n -C6 'defaultValue|defaultInput|valueNode.kind === Kind.VARIABLE' \
packages/utils/src/getArgumentValues.tsRepository: ardatan/graphql-tools
Length of output: 2517
🏁 Script executed:
#!/bin/sh
set -eu
echo "== file outline =="
ast-grep outline packages/utils/src/getArgumentValues.ts || true
echo "== relevant file section =="
cat -n packages/utils/src/getArgumentValues.ts | sed -n '1,130p'
echo "== package graphql versions and utils dependencies =="
for f in package.json packages/utils/package.json yarn.lock package-lock.json pnpm-lock.yaml; do
[ -f "$f" ] && { echo "-- $f"; rg -n '"graphql"|dependencies|devDependencies|`@graphql-tools/utils`|graphql\.lock|packages/utils' "$f" | head -80 || true; }
doneRepository: ardatan/graphql-tools
Length of output: 8671
🌐 Web query:
graphql-js v17 values.js coerceArgumentValues variable values defaultValue
💡 Result:
In GraphQL.js v17, the handling of default values for arguments has undergone a significant architectural change to improve type safety and introspection accuracy [1][2]. Legacy Approach (Deprecated) The legacy method of defining default values involved the defaultValue property [1][3]. This property expected an already-coerced JavaScript value ("internal input value") [3][4]. Because this value was already coerced, GraphQL.js could not easily validate it against the argument type or represent it accurately in introspection without re-converting it [1][2]. New Approach (v17 Stable) In v17, the library introduced a more explicit default object format for programmatic schemas [1][2]. This is the recommended approach for new code [1][2]: - default: { value: <raw_input_value> }: Use this when you have the raw, uncoerced JavaScript input value [1][2]. - default: { literal: <graphql_literal> }: Use this if you already have the GraphQL literal representation [1][2]. By storing the raw input value rather than the pre-coerced internal value, GraphQL.js can perform validation and coercion at execution time [1][2]. This ensures that defaults are correctly validated against the schema, fixes issues where incorrect default values were previously accepted, and allows for accurate representation in schema introspection [1][2]. Implementation Details - Coercion Behavior: When an argument value is missing, the execution logic—governed by the internal coerceArgumentValues logic—checks for the presence of a default [5]. If a default is defined (as a raw value), it is coerced according to the input coercion rules of the argument's type [2][6]. - defaultValue Support: While defaultValue remains available in v17 as a migration bridge for legacy code, it is deprecated and scheduled for removal in v18 [1][2]. - Schema Representation: On a built schema, these defaults are represented as argument.default.value [1][2]. This change aligns GraphQL.js more closely with the GraphQL specification's requirements for handling input coercion and ensures consistent behavior across different ways of defining a schema (e.g., SDL vs. programmatic) [1][2][7].
Citations:
- 1: https://www.graphql-js.org/docs/passing-arguments/
- 2: https://github.com/graphql/graphql-js/blob/17.x.x/website/pages/docs/passing-arguments.mdx
- 3: https://github.com/graphql/graphql-js/blob/17.x.x/website/pages/upgrade-guides/v16-v17.mdx
- 4: RFC: Default value validation & coercion graphql/graphql-js#3049
- 5: https://github.com/graphql/graphql-spec/blob/main/spec/Section%206%20--%20Execution.md
- 6: RFC: Default value validation & coercion graphql/graphql-js#3814
- 7: [RFC] Default value coercion rules graphql/graphql-spec#793
🌐 Web query:
app.unpkg.com graphql@17.0.1 values.js "if (argumentValue === undefined)" "arg.default"
💡 Result:
The code reference arg.default in values.js of graphql@17.0.1 pertains to the updated mechanism for handling argument default values introduced in GraphQL.js v17 [1][2]. In GraphQL.js v17, the library tightened its handling of JavaScript-specific undefined values, treating them as absent at user-visible input boundaries [1]. When an argument is not provided (i.e., its argumentValue is undefined), the library checks for a configured default value [1]. Key aspects of this change include: 1. Explicit Default Shape: While legacy schemas may use the defaultValue property, v17 introduces an explicit default object structure, represented as default: { value } (for raw JS input) or default: { literal } (for GraphQL literals) [2]. Within the schema definition, this is stored and accessed via argument.default [2]. 2. Improved Validation and Coercion: Keeping the raw input value in the default object—rather than an already-coerced value—allows GraphQL.js to perform proper validation and coercion during execution [2]. This avoids previous issues where default values were not consistently validated against the argument's type [3] or were improperly reconstructed during introspection [4]. 3. Undefined as Absence: If a variable or input field is undefined, it is treated as if it were not provided, allowing the relevant default value (defined via arg.default) to be applied during the execution process [1]. This behavioral change ensures that default values are handled more consistently and accurately, aligning with GraphQL specifications for input coercion [1][2].
Citations:
- 1: https://www.graphql-js.org/upgrade-guides/v16-v17/
- 2: https://www.graphql-js.org/docs/passing-arguments/
- 3: Validation of argument default values graphql/graphql-js#2606
- 4: Default value declared via SDL may not introspect correctly graphql/graphql-js#3051
Apply v17 defaults when a referenced variable is absent.
The v17 arg.default branch only handles a missing argument node. For field(arg: $missing), the missing-variable path still checks only legacy arg.defaultValue, so a v17 default is skipped and non-null fallback can throw. Reuse the v17 coercion path when a variable has no coerced value.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/utils/src/getArgumentValues.ts` around lines 52 - 73, Update the
missing-variable handling in getArgumentValues to reuse the existing graphql v17
arg.default coercion path when the referenced variable has no coerced value,
instead of checking only legacy arg.defaultValue. Preserve the current coercion
and invalid-default error behavior, while ensuring field arguments referencing
absent variables receive the v17 default before non-null validation.
| const anyValueType = new GraphQLScalarType({ | ||
| name: '_GraphQLToolsAnyValue', | ||
| valueToLiteral: valueToASTLiteral, | ||
| } as any); | ||
|
|
||
| function buildVariableSources(variableValues: Record<string, any>): Record<string, unknown> { | ||
| const sources: Record<string, unknown> = Object.create(null); | ||
| for (const varName of Object.keys(variableValues)) { | ||
| sources[varName] = { signature: { type: anyValueType }, value: variableValues[varName] }; | ||
| } |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift
🧩 Analysis chain
🏁 Script executed:
#!/bin/sh
rg -n -C4 'buildVariableSources|toGraphQLJSVariableValues|variableDefinitions|signature' \
packages/utils packages/executorRepository: ardatan/graphql-tools
Length of output: 18936
🏁 Script executed:
#!/bin/sh
set -eu
echo "== graphqlJSCompat outline =="
ast-grep outline packages/utils/src/graphqlJSCompat.ts || true
echo
echo "== graphqlJSCompat relevant lines =="
cat -n packages/utils/src/graphqlJSCompat.ts | sed -n '1,150p'
echo
echo "== getArgumentValues relevant lines =="
cat -n packages/utils/src/getArgumentValues.ts | sed -n '1,120p'
echo
echo "== package versions =="
for f in package.json packages/utils/package.json packages/executor/package.json; do
if test -f "$f"; then
echo "--- $f"
sed -n '1,220p' "$f"
fi
done
echo
echo "== node_modules graphql version if present =="
if [ -d node_modules/graphql ]; then
node -e 'const p=require("./node_modules/graphql/package.json"); console.log(p.version)'
else
echo "node_modules/graphql not present"
fiRepository: ardatan/graphql-tools
Length of output: 20581
🌐 Web query:
graphql-js 17 coerceInputLiteral variable replacement signature type custom scalar valueToLiteral
💡 Result:
In GraphQL.js v17, the API for custom scalars has been updated to align with GraphQL specification terminology [1][2]. The legacy v16 methods (serialize, parseValue, parseLiteral) remain available as deprecated aliases, but the new preferred methods are: 1. coerceOutputValue: Replaces serialize [1][3]. 2. coerceInputValue: Replaces parseValue [1][3]. 3. coerceInputLiteral: Replaces parseLiteral [1][3]. 4. valueToLiteral: A new method to convert external input values into GraphQL literals (replaces astFromValue for custom scalar support) [1][3]. Key changes regarding variable replacement and signatures: Signature Change: Unlike the legacy parseLiteral(ast, variables), the new coerceInputLiteral(ast) signature receives a constant literal (ConstValueNode) and does not accept a variables argument [4][3]. Automatic Replacement: During standard GraphQL execution, the library automatically handles variable replacement before calling coerceInputLiteral. This ensures that the scalar always receives a constant value [1][3][5]. Manual Replacement: If you invoke coerceInputLiteral directly outside of the standard execution flow—such as in standalone tooling or utility functions—you must manually call replaceVariables(ast, variables) before passing the literal to coerceInputLiteral [6][1][3]. New Utility: The replaceVariables utility is now a stable API provided by GraphQL.js to support this variable substitution in custom code [6][7]. For scalars supporting both v16 and v17, it is recommended to maintain the v16 names until you can drop v16 support, at which point you should migrate to the v17 names and implement valueToLiteral [1][3][2].
Citations:
- 1: https://www.graphql-js.org/docs/custom-scalars/
- 2: https://graphql.org/blog/2026-06-15-introducing-graphql-js-v17/
- 3: https://www.graphql-js.org/docs/advanced-custom-scalars/
- 4: RFC: Default value validation & coercion graphql/graphql-js#3814
- 5: Add valueToLiteral() graphql/graphql-js#3812
- 6: https://github.com/graphql/graphql-js/blob/17.x.x/website/pages/upgrade-guides/v16-v17.mdx
- 7: https://www.graphql-js.org/upgrade-guides/v16-v17/
🌐 Web query:
graphql-js 17 source signature object literal coercion variable nested object coerceInputLiteral signature.type
💡 Result:
In GraphQL.js v17, coerceInputLiteral is the standard utility for converting constant GraphQL literal AST nodes into internal JavaScript values [1][2]. It effectively replaced the legacy valueFromAST method [3][2]. The signature of coerceInputLiteral in v17 is defined as [4][5]: export declare function coerceInputLiteral( valueNode: ValueNode, type: GraphQLInputType, variableValues?: Maybe, fragmentVariableValues?: Maybe): unknown; Key aspects of its usage and behavior include: Coercion Logic: It is designed for constant literals. During standard GraphQL execution, the library calls replaceVariables before performing scalar literal coercion [6][7]. If you are calling coerceInputLiteral directly outside of the standard execution flow—especially when variables are involved—you must manually call replaceVariables first to resolve them [6][7]. Return Value: In v17, the function returns undefined when coercion fails [1][2]. This is a behavioral change from some previous versions and is optimized for callers that prefer a clear success or failure signal [1][2]. If you require detailed diagnostic errors, you should use the validateInputLiteral utility instead [1][2]. Scalar Methods: As part of the v17 transition, scalar types now use coerceInputLiteral (replacing the legacy parseLiteral) to align with GraphQL specification terminology [2][6][7]. While legacy names are often available as deprecated aliases, implementation of the new coercion hooks is the recommended best practice for v17 and future versions [2][6][7]. Nested Objects: When coercing nested objects (e.g., GraphQLInputObjectType), the utility recursively applies the coercion logic based on the provided GraphQLInputType schema [8][5]. Proper schema definition and type matching are required to ensure nested objects are coerced correctly into their corresponding internal JavaScript representations [8][5].
Citations:
- 1: https://github.com/graphql/graphql-js/blob/17.x.x/website/pages/upgrade-guides/v16-v17.mdx
- 2: https://www.graphql-js.org/upgrade-guides/v16-v17/
- 3: Add coerceInputLiteral() graphql/graphql-js#3092
- 4: https://app.unpkg.com/graphql@17.0.1/files/utilities/coerceInputValue.d.ts
- 5: https://www.graphql-js.org/api-v17/utilities/
- 6: https://www.graphql-js.org/docs/advanced-custom-scalars/
- 7: https://www.graphql-js.org/docs/custom-scalars/
- 8: https://github.com/graphql/graphql-js/blob/16.x.x/website/pages/api-v17/utilities.mdx
🌐 Web query:
"coerceInputLiteral" "signature" graphql-js 17 coerceInputValue.js
💡 Result:
In GraphQL.js v17, the coerceInputLiteral function is located in the utilities module (typically exported from utilities/coerceInputValue.ts) [1][2]. It is used to coerce a GraphQL Value AST node into an internal runtime JavaScript value based on a specified GraphQL input type [3][1]. The function signature for coerceInputLiteral in GraphQL.js v17 is [1]: coerceInputLiteral( valueNode: ValueNode, type: GraphQLInputType, variableValues?: Maybe, fragmentVariableValues?: Maybe,): unknown; Key details regarding its usage and behavior: 1. Purpose: It serves as the v17 replacement for the legacy valueFromAST function, providing a modernized and more strictly typed interface for literal coercion [4][5]. 2. Return Value: It returns the coerced internal value. If the value cannot be validly coerced according to the provided type, it returns undefined [4][1]. 3. Variable Handling: Unlike some other coercion helpers, coerceInputLiteral supports both operation-level variables (via variableValues) and fragment-level variables (via fragmentVariableValues) [1][5]. If you are calling this outside of standard execution, you may need to ensure variables are appropriately processed [6]. 4. Comparison with v16: In v16, similar logic was often handled by parseLiteral methods on custom scalars or the utility valueFromAST [4][6]. In v17, coerceInputLiteral is the standard recommended utility for this purpose [4]. For diagnostic needs (such as requiring detailed errors when coercion fails), the library provides a separate validateInputLiteral function [4][1].
Citations:
- 1: https://www.graphql-js.org/api-v17/utilities/
- 2: https://app.unpkg.com/graphql@17.0.0/files/execution/values.mjs.map
- 3: https://www.graphql-js.org/api-v17/type/
- 4: https://www.graphql-js.org/upgrade-guides/v16-v17/
- 5: Add coerceInputLiteral() graphql/graphql-js#3809
- 6: https://www.graphql-js.org/docs/custom-scalars/
🌐 Web query:
site:app.unpkg.com/graphql@17.0.1/files/utilities/coerceInputValue.js "signature" "replaceVariables"
💡 Result:
The replaceVariables function is utilized in various software contexts, most notably within GraphQL.js and Grafana. Because it is a common name for utility functions, its signature depends entirely on the specific library or framework being used. GraphQL (GraphQL.js) In GraphQL.js, replaceVariables is a utility used to replace variables within an Abstract Syntax Tree (AST) value literal [1][2]. Signature: replaceVariables( valueNode: ValueNode, variableValues?: Maybe, fragmentVariableValues?: Maybe): ConstValueNode [1] Grafana In Grafana plugin development, replaceVariables is used to interpolate dashboard or global variables within strings, such as JavaScript code or panel configurations [3][4]. While specific implementations may vary by context (e.g., access via context.grafana.replaceVariables), it typically acts as an interpolation function [5][3]. General Signature pattern: replaceVariables(stringOrTemplate: string): string [3][4] Other Contexts - MediaWiki: The Parser class includes a method to replace magic variables, templates, and template arguments [6]. Signature: replaceVariables($text, $frame = false, $argsOnly = false) [6] - Twill (CMS): A command-line utility for handling stubs [7]. Signature: replaceVariables(array $variables, string $stub, array|null $delimiters = null) [7] Always consult the documentation for the specific library or framework you are using to ensure the correct signature and expected behavior [2][8].
Citations:
- 1: https://www.graphql-js.org/api-v17/utilities/
- 2: https://www.graphql-js.org/upgrade-guides/v16-v17/
- 3: https://grafana.com/docs/plugins/marcusolsson-dynamictext-panel/latest/features/variables/
- 4: https://community.grafana.com/t/how-can-i-get-grafana-dashboard-variables-in-panel-javascript/121612
- 5: https://grafana.com/docs/grafana/v7.2/packages_api/data/standardeditorcontext/
- 6: https://doc.wikimedia.org/mediawiki-core/1.43.3/php/classMediaWiki_1_1Parser_1_1Parser.html
- 7: https://twillcms.com/docs/api/main/A17/Twill/Commands/GeneratePackageCommand.html
- 8: Consolidate template interpolation grafana/grafana#27079
🌐 Web query:
graphql-js 17 coerceInputLiteral source.signature.type input object fields variable node coerceInputLiteral
💡 Result:
In graphql-js v17, coerceInputLiteral is a utility function used to convert GraphQL value AST nodes into internal JavaScript values based on a provided GraphQL input type [1][2]. It replaces the legacy valueFromAST function [3][4][5]. Key details regarding its usage and behavior include: Signature and Arguments The function signature is defined as [1][2]: coerceInputLiteral(valueNode: ValueNode, type: GraphQLInputType, variableValues?: Maybe, fragmentVariableValues?: Maybe): unknown; - valueNode: The GraphQL value AST node to be coerced [1][2]. - type: The GraphQL input type to coerce the literal against [1][2]. - variableValues (optional): Operation variable values, typically obtained via getVariableValues [1][2]. - fragmentVariableValues (optional): Fragment variable values for the current fragment scope [1][2]. Behavior and v17 Changes - Coercion Results: Unlike some previous methods that might throw errors for invalid input, coerceInputLiteral returns undefined when coercion fails [1][3][4]. This design is optimized for callers that prefer to receive either a successfully coerced value or a failure indicator [3][4]. - Variable Handling: In v17, coerceInputLiteral operates on constant literals [4][6]. During standard GraphQL execution, the library automatically calls replaceVariables to resolve any variables within the AST before invoking coerceInputLiteral [4][6][7]. If you are calling this utility directly outside of the standard execution flow, you must manually call replaceVariables first to ensure variables are resolved [4][6][7]. - Validation vs. Coercion: If your use case requires diagnostic error information rather than just a failure indicator, you should use validateInputLiteral instead [3][4]. Relationship to Other APIs coerceInputLiteral is part of the standardized coercion terminology introduced in v17, which aligns the library more closely with the GraphQL specification [4][7]. It is the intended replacement for the legacy parseLiteral hook in Custom Scalars and the general-purpose valueFromAST function [3][4][8].
Citations:
- 1: https://github.com/graphql/graphql-js/blob/17.x.x/website/pages/api-v17/utilities.mdx
- 2: https://www.graphql-js.org/api-v17/utilities/
- 3: https://github.com/graphql/graphql-js/blob/17.x.x/website/pages/upgrade-guides/v16-v17.mdx
- 4: https://www.graphql-js.org/upgrade-guides/v16-v17/
- 5: Add coerceInputLiteral() graphql/graphql-js#3092
- 6: https://www.graphql-js.org/docs/advanced-custom-scalars/
- 7: https://www.graphql-js.org/docs/custom-scalars/
- 8: https://www.graphql-js.org/api-v17/type/
🌐 Web query:
"package.exports" "coerceInputValue.d.ts" "graphql@17.0.1"
💡 Result:
In GraphQL.js v17.0.1, the coerceInputValue function is exported via the package's module entry points, consistent with the project's use of package exports [1]. You can access it from the utilities entry point: import { coerceInputValue } from 'graphql/utilities'; [2] Key changes in v17 regarding this function include: 1. API Signature and Behavior: The signature has been simplified. It no longer accepts an onError callback [2][3]. Instead, the function now returns undefined when coercion fails [1][2]. This change is optimized for callers that prefer a straightforward coerced value or a failure indicator [1]. 2. Diagnostic Errors: If you require diagnostic errors for failed coercion, you should now use the new validateInputValue function instead of coerceInputValue [1][2]. 3. Entry Points: GraphQL.js v17 utilizes package.exports to enforce public entry points [1]. You should import from defined paths like graphql/utilities, graphql/execution, or graphql/type, rather than relying on internal file paths [1]. The type definitions for this function are provided in the package at utilities/coerceInputValue.d.ts (and the corresponding.d.mts) [2][3][4].
Citations:
- 1: https://www.graphql-js.org/upgrade-guides/v16-v17/
- 2: https://app.unpkg.com/graphql@17.0.1/files/utilities/coerceInputValue.d.ts
- 3: https://app.unpkg.com/graphql@17.0.1/files/utilities/coerceInputValue.d.mts
- 4: https://npmx.dev/diff/graphql/v/17.0.0-alpha.14...17.0.1
🌐 Web query:
repo:graphql/graphql-js 17.x.x coerceInputValue.ts variableValues sources
💡 Result:
In GraphQL.js v17.x.x, coerceInputValue.ts provides a refined utility for coercing JavaScript values (often external inputs or variable values) against a GraphQL Input Type [1][2][3]. Key aspects of its design and usage in v17 include: Behavioral Change: The function no longer processes or reports diagnostic errors internally [4][5]. Instead, when coercion fails, it returns undefined [2][6][4]. This makes the function optimized for performance in scenarios where the caller only needs to know if coercion succeeded or failed [4][5]. Diagnostic Errors: If your application requires detailed diagnostic error information (e.g., for reporting why a specific variable value failed validation), you should use the new validateInputValue utility instead [4][5][7]. Integration with Variable Values: The v17 upgrade introduces a more consistent coercion model [4]. While getVariableValues internally handles the mapping of operation variable definitions to provided inputs, direct callers of coerceInputValue are expected to handle coercion outcomes (successful value or undefined) [4][5][7]. The return value of variable-related processing has been updated to support richer metadata, including the ability to distinguish between provided values and default values through objects that preserve original sources [7]. Migration Note: If you are upgrading from v16, note that parseValue (the former name for this capability on scalar/enum types) has been replaced by coerceInputValue [4][5]. Codebases should be updated to use the new coerceInputValue utility and, where error reporting is necessary, pair it with the corresponding validation utilities [4][5]. Top results: [4][5][3][7]
Citations:
- 1: https://unpkg.com/browse/graphql@17.0.2/utilities/coerceInputValue.d.ts
- 2: https://app.unpkg.com/graphql@17.0.0/files/utilities/coerceInputValue.d.mts
- 3: https://github.com/graphql/graphql-js/tree/next/src/utilities
- 4: https://www.graphql-js.org/upgrade-guides/v16-v17/
- 5: https://github.com/graphql/graphql-js/blob/17.x.x/website/pages/upgrade-guides/v16-v17.mdx
- 6: https://app.unpkg.com/graphql@17.0.0/files/utilities/coerceInputValue.mjs
- 7: RFC: Default value validation & coercion graphql/graphql-js#3814
🌐 Web query:
raw.githubusercontent.com graphql graphql-js 17.x.x src utilities coerceInputValue.js replaceVariables variableValues sources
💡 Result:
In GraphQL.js version 17.x.x, replaceVariables is a utility function used to convert a GraphQL Value AST containing variables into a constant value AST by substituting those variables with their corresponding values [1][2]. This function is primarily used to ensure that only complete, constant values are utilized during the input coercion of custom scalars that accept complex literals [1][2]. Because coercion methods like coerceInputLiteral (which replaced the v16 parseLiteral) receive constant literals rather than variables, replaceVariables must be called during execution—or by tooling—to resolve any variables before the coercion occurs [3]. The function signature is: replaceVariables( valueNode: ValueNode, variableValues?: Maybe, fragmentVariableValues?: Maybe): ConstValueNode; When replaceVariables encounters a variable, it looks up the value in the provided variableValues or fragmentVariableValues maps [4][2]. If a variable value is missing, it may default to null or utilize a default value if one is defined in the variable's signature [4]. The function recursively processes OBJECT and LIST nodes to ensure all nested variables are fully resolved [4]. Key context regarding your query: - coerceInputValue (which handles runtime JavaScript values) and coerceInputLiteral (which handles AST literals) are the standard v17 coercion utilities [3][5]. - replaceVariables is effectively the bridge that allows AST-based input handling to support variables before they reach scalar coercion logic [3]. - The variableValues passed to replaceVariables are typically those returned by the execution engine's getVariableValues function [1][2].
Citations:
- 1: https://app.unpkg.com/graphql@17.0.1/files/utilities/replaceVariables.d.mts
- 2: https://www.graphql-js.org/api-v17/utilities/
- 3: https://www.graphql-js.org/docs/advanced-custom-scalars/
- 4: https://app.unpkg.com/graphql@17.0.1/files/utilities/replaceVariables.mjs
- 5: https://github.com/graphql/graphql-js/blob/next/src/index.ts
🌐 Web query:
"graphql@17.0.2" "replaceVariables.mjs" "\"signature\""
💡 Result:
In graphql-js version 17, replaceVariables.mjs is a utility function used to replace GraphQL Variables found within an AST Value literal with actual values [1][2]. The term "signature" referenced in the source code of replaceVariables.mjs [3] refers to the internal metadata object—often labeled as signature—associated with variable values [3]. When replaceVariables processes an AST node, it checks variable value sources to determine if a variable has a defined value or a default value [3]. The "signature" property contains this information, including: 1. default: The literal value to use if the variable is undefined [3]. 2. type: The GraphQL type associated with the variable, used for coercion [3]. This utility is primarily used to ensure that only complete constant values are utilized during the input coercion of custom scalars that accept complex literals [1][2]. GraphQL.js calls this function automatically during execution, but developers using literal coercion helpers directly outside of the standard execution flow should manually call replaceVariables before coercing literals that may contain variables [4].
Citations:
- 1: https://app.unpkg.com/graphql@17.0.0/files/utilities/replaceVariables.d.mts
- 2: https://github.com/graphql/graphql-js/blob/16.x.x/website/pages/api-v17/utilities.mdx
- 3: https://app.unpkg.com/graphql@17.0.1/files/utilities/replaceVariables.mjs
- 4: https://www.graphql-js.org/upgrade-guides/v16-v17/
Preserve each variable’s declared input type in variable sources.
buildVariableSources() assigns the same _GraphQLToolsAnyValue scalar to every variable, so graphql-js v17 replaces variable nodes in literal tree values with that scalar’s valueToASTLiteral before coercion. As a result, nested enum/custom-scalar values can be serialized as their string forms instead of preserving the source literal/coercion behavior, e.g. enum RED becoming "RED" inside an object argument. Build the source wrappers from the real variable definitions/types or pass variableDefinitions alongside the values to toGraphQLJSVariableValues() and build per-variable scalar signatures.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/utils/src/graphqlJSCompat.ts` around lines 95 - 104, Update
buildVariableSources to preserve each variable’s declared GraphQL input type
instead of assigning anyValueType to every variable. Pass variableDefinitions
alongside variableValues from toGraphQLJSVariableValues and build each source
signature from the corresponding definition type, preserving nested enum and
custom-scalar literal/coercion behavior.
Description
Currently patching issues in the Yoga update.
@graphql-tools/executor: implement the new requiredgetAbortSignal/getAsyncHelpersmethods onGraphQLResolveInfo, and adapt variable coercion to graphql-js v17'scoerceInputValue/validateInputValuesplit (falling back to the old callback-based API on graphql-js < 17)@graphql-tools/utils: fixgetArgumentValuesto usecoerceInputLiteralon graphql-js v17, wherevalueFromASTno longer rejects AST literals of the wrong kind; wrap flatvariableValuesmaps into the structured shape graphql-js v17's owngetDirectiveValues/getArgumentValuesexpect@graphql-tools/schema: fixaddResolversToSchemaso that custom scalar__serialize/__parseValueresolvers also updatecoerceOutputValue/coerceInputValue, which is what graphql-js v17 actually calls during executiongraphqlpeer dependency range to include^17.0.0for@graphql-tools/executor-apollo-linkand@graphql-tools/executor-urql-exchange(their underlying libraries already support graphql-js v17)Related # (issue)
Type of change
Please delete options that are not relevant.
expected)
Screenshots/Sandbox (if appropriate/relevant):
Adding links to sandbox or providing screenshots can help us understand more about this PR and take
action on it as appropriate
How Has This Been Tested?
Please describe the tests that you ran to verify your changes. Provide instructions so we can
reproduce. Please also list any relevant details for your test configuration
Test Environment:
@graphql-tools/...:Checklist:
CONTRIBUTING doc and the
style guidelines of this project
Further comments
If this is a relatively large or complex change, kick off the discussion by explaining why you chose
the solution you did and what alternatives you considered, etc...