Skip to content

Add support for graphql-js v17#8313

Open
egoodwinx wants to merge 1 commit into
ardatan:masterfrom
egoodwinx:feat/graphql-17-support
Open

Add support for graphql-js v17#8313
egoodwinx wants to merge 1 commit into
ardatan:masterfrom
egoodwinx:feat/graphql-17-support

Conversation

@egoodwinx

Copy link
Copy Markdown

Description

Currently patching issues in the Yoga update.

  • @graphql-tools/executor: implement the new required getAbortSignal/getAsyncHelpers methods on GraphQLResolveInfo, and adapt variable coercion to graphql-js v17's coerceInputValue/validateInputValue split (falling back to the old callback-based API on graphql-js < 17)
  • @graphql-tools/utils: fix getArgumentValues to use coerceInputLiteral on graphql-js v17, where valueFromAST no longer rejects AST literals of the wrong kind; wrap flat variableValues maps into the structured shape graphql-js v17's own getDirectiveValues/getArgumentValues expect
  • @graphql-tools/schema: fix addResolversToSchema so that custom scalar __serialize/__parseValue resolvers also update coerceOutputValue/coerceInputValue, which is what graphql-js v17 actually calls during execution
  • widen the graphql peer dependency range to include ^17.0.0 for @graphql-tools/executor-apollo-link and @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.

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as
    expected)
  • This change requires a documentation update

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

  • Unit Tests

Test Environment:

  • OS:
  • @graphql-tools/...:
  • NodeJS:

Checklist:

  • I have followed the
    CONTRIBUTING doc and the
    style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests and linter rules pass locally with my changes
  • Any dependent changes have been merged and published in downstream modules

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...

@changeset-bot

changeset-bot Bot commented Jul 22, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: ccbcce9

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

This PR includes changesets to release 29 packages
Name Type
@graphql-tools/executor-urql-exchange Minor
@graphql-tools/executor-apollo-link Minor
@graphql-tools/git-loader Minor
@graphql-tools/executor Minor
@graphql-tools/optimize Minor
@graphql-tools/schema Minor
@graphql-tools/utils Minor
@graphql-tools/webpack-loader Patch
graphql-tools Patch
@graphql-tools/load Patch
@graphql-tools/mock Patch
@graphql-tools/graphql-tag-pluck Patch
@graphql-tools/import Patch
@graphql-tools/links Patch
@graphql-tools/merge Patch
@graphql-tools/node-require Patch
@graphql-tools/relay-operation-optimizer Patch
@graphql-tools/resolvers-composition Patch
@graphql-tools/apollo-engine-loader Patch
@graphql-tools/code-file-loader Patch
@graphql-tools/github-loader Patch
@graphql-tools/graphql-file-loader Patch
@graphql-tools/json-file-loader Patch
@graphql-tools/module-loader Patch
@graphql-tools/url-loader Patch
@graphql-tools/executor-envelop Patch
@graphql-tools/executor-legacy-ws Patch
@graphql-tools/executor-yoga Patch
@graphql-tools/jest-transform Patch

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

@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Added compatibility support for GraphQL.js v17 across execution, directives, arguments, variable coercion, and schema handling.
    • Improved resolver execution metadata, including abort signals and async helpers.
    • Added support for GraphQL.js v17 scalar coercion behavior and nested variable values.
    • Expanded GraphQL.js v17 support for Apollo Link and urql integrations.
  • Bug Fixes

    • Improved validation and error reporting for invalid variables and default values.
    • Updated scalar handling to keep legacy resolver behavior consistent across GraphQL.js versions.

Walkthrough

This change adds GraphQL.js v17 compatibility across variable coercion, executor resolver metadata, scalar resolver configuration, package peer support, type patches, and version-aware tests.

Changes

GraphQL.js v17 compatibility

Layer / File(s) Summary
Compatibility helpers and argument coercion
packages/utils/src/graphqlJSCompat.ts, packages/utils/src/getArgumentValues.ts, packages/utils/src/getDirectiveExtensions.ts, packages/utils/src/collectFields.ts, packages/utils/tests/getArgumentValues.spec.ts
Adds version-gated GraphQL.js exports, structured variable values, runtime-to-AST conversion, and v17-compatible argument and directive coercion.
Executor coercion and resolver metadata
packages/executor/src/execution/execute.ts, packages/executor/src/execution/values.ts, packages/executor/src/execution/__tests__/*
Updates variable coercion and diagnostics, exposes abort and async helpers, and adapts resolver and stream directive variable values.
Scalar resolver configuration
packages/schema/src/addResolversToSchema.ts, packages/utils/tests/mapSchema.test.ts
Maps legacy scalar methods to GraphQL.js v17 coercion methods and removes conflicting literal parsing configuration when applicable.
Version adoption and compatibility validation
package.json, packages/*/package.json, packages/loaders/git/tests/*, packages/optimize/tests/*, packages/schema/tests/*, patches/*, .changeset/*
Enables GraphQL.js v17 in package metadata, updates type patches, records release support, and adjusts version-specific AST, parser, and error expectations.

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
Loading

Suggested reviewers: ardatan, enisdenjo

Poem

A rabbit hops through version seventeen,
Coercing values crisp and clean.
Scalars mirror, resolvers cheer,
New async helpers now appear.
Tests bloom bright in GraphQL’s lane!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 47.06% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: adding graphql-js v17 support.
Description check ✅ Passed The description is detailed and clearly describes the graphql-js v17 compatibility work in this PR.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.json

Traceback (most recent call last):
File "/usr/local/bin/checkov", line 2, in
from checkov.main import Checkov
ModuleNotFoundError: No module named 'checkov'

packages/executor/package.json

Traceback (most recent call last):
File "/usr/local/bin/checkov", line 2, in
from checkov.main import Checkov
ModuleNotFoundError: No module named 'checkov'

packages/executors/apollo-link/package.json

Traceback (most recent call last):
File "/usr/local/bin/checkov", line 2, in
from checkov.main import Checkov
ModuleNotFoundError: No module named 'checkov'

  • 1 others
🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 win

Keep updateResolversInPlace consistent with the cloned-schema path.

The in-place path updates parseValue/coerceInputValue, but updateResolversInPlace: true keeps the existing scalar’s original parseLiteral even when resolver input coercing is overridden. Since execution falls back to parseLiteral when a scalar has no coerceInputLiteral, 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 win

Clear the inherited coerceInputLiteral when overriding scalar coercion.

GraphQLScalarType.toConfig() carries the current scalar coercion methods, including coerceInputLiteral. If a resolver only overrides parseValue/coerceInputValue without also overriding literal coercion, leave coerceInputLiteral on the copied config and literal argument coercion can still use the old resolver implementation. Remove it unless the resolver supplies a fresh coerceInputLiteral.

🤖 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

📥 Commits

Reviewing files that changed from the base of the PR and between f0782ce and ccbcce9.

📒 Files selected for processing (24)
  • .changeset/bold-webs-behave.md
  • package.json
  • packages/executor/package.json
  • packages/executor/src/execution/__tests__/executor-test.ts
  • packages/executor/src/execution/__tests__/oneOf-test.ts
  • packages/executor/src/execution/__tests__/variables-test.ts
  • packages/executor/src/execution/execute.ts
  • packages/executor/src/execution/values.ts
  • packages/executors/apollo-link/package.json
  • packages/executors/urql-exchange/package.json
  • packages/loaders/git/tests/loader.spec.ts
  • packages/optimize/tests/remove-empty-nodes.spec.ts
  • packages/optimize/tests/remove-loc.spec.ts
  • packages/schema/src/addResolversToSchema.ts
  • packages/schema/tests/schemaGenerator.test.ts
  • packages/utils/src/collectFields.ts
  • packages/utils/src/getArgumentValues.ts
  • packages/utils/src/getDirectiveExtensions.ts
  • packages/utils/src/graphqlJSCompat.ts
  • packages/utils/src/index.ts
  • packages/utils/tests/getArgumentValues.spec.ts
  • packages/utils/tests/mapSchema.test.ts
  • patches/@types+relay-compiler+8.0.4.patch
  • patches/subscriptions-transport-ws+0.11.0.patch

Comment on lines 52 to +73
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;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/sh
rg -n -C6 'defaultValue|defaultInput|valueNode.kind === Kind.VARIABLE' \
  packages/utils/src/getArgumentValues.ts

Repository: 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; }
done

Repository: 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:


🌐 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:


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.

Comment on lines +95 to +104
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] };
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/sh
rg -n -C4 'buildVariableSources|toGraphQLJSVariableValues|variableDefinitions|signature' \
  packages/utils packages/executor

Repository: 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"
fi

Repository: 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:


🌐 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:


🌐 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:


🌐 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:


🌐 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:


🌐 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:


🌐 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:


🌐 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:


🌐 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:


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.

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