Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions .changeset/bold-webs-behave.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
'@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
---

Add support for graphql-js v17

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

since this PR is not only about bumping the version, it would be great to summarise what you did in order to get the v17 working. nothing too fancy, a summary of which issues were addressed


Core fixes (graphql-js v17 compatibility)

@graphql-tools/executor: buildResolveInfo implements v17's new required getAbortSignal()/getAsyncHelpers() on GraphQLResolveInfo, and wraps info.variableValues in v17's structured {coerced, sources} shape (previously leaked a flat map); variable coercion adapted to v17's coerceInputValue/validateInputValue split, including default-value coercion for both variables and arguments.
@graphql-tools/utils: getArgumentValues migrated to coerceInputLiteral (v17 stopped rejecting AST literals of the wrong kind via valueFromAST); new graphqlJSCompat.ts module centralizes version-detection (getOptionalGraphQLJSExport) and the flat-map ↔ {coerced, sources} conversion (toGraphQLJSVariableValues) shared across the package; fixed a bug where non-null arguments with schema-defined (SDL) defaults, referenced via an unprovided variable, incorrectly threw instead of applying the default.
@graphql-tools/schema: addResolversToSchema updates coerceOutputValue/coerceInputValue (what v17 actually calls at runtime) whenever a scalar resolver overrides serialize/parseValue, including a fix for a stale-closure bug when rebuilding scalar types.
Compatibility widening

graphql peer range widened to include ^17.0.0 for @graphql-tools/executor-apollo-link and @graphql-tools/executor-urql-exchange.
Two new patch-package patches fixing incorrect/outdated .d.ts files in @types/relay-compiler and subscriptions-transport-ws that referenced graphql-js exports removed/renamed in v17.
Tests

Executor, schema, loader, and optimize test suites made version-aware (versionInfo.major >= 17 branches) where v17 output differs from v15/v16.
New getArgumentValues.spec.ts covering the coerceInputLiteral-nested-variable and SDL-default-value fixes.
Tooling

Root graphql devDependency/override pinned to 17.0.2.
CI (tests.yml, uncommitted): merged the temporary v17-only test job into the main matrix (now tests full suite against v15/v16/v17, excluding Node 18 × v17 since v17 requires Node ≥22), removed the old temp job, and re-labeled the "Full Check" job to reflect it now runs on v17.
Changeset: minor bump for 7 affected packages.
58 changes: 6 additions & 52 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ jobs:
- name: Type Check
run: npm run ts:check
check:
name: Full Check on GraphQL v16
name: Full Check on GraphQL v17
runs-on: ubuntu-latest
steps:
- name: Checkout Master
Expand Down Expand Up @@ -69,6 +69,11 @@ jobs:
graphql_version:
- 15
- 16
- 17
exclude:
# graphql@17's minimum supported Node version is 22
- node-version: 18
graphql_version: 17
steps:
- name: Checkout Master
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
Expand Down Expand Up @@ -108,57 +113,6 @@ jobs:
max_attempts: 5
command: npm run ${{matrix.name == 'Leak' && 'test:leaks' || 'test'}} --ci

test-v17-temp: # FIXME: Gradual support for graphql@17, once every package is compatible, this should be merged back to main step
name:
Test on Node ${{matrix.node-version}} (${{matrix.os}}) and GraphQL
v${{matrix.graphql_version}}
runs-on: ${{matrix.os}}
strategy:
fail-fast: false
matrix:
os: [windows-latest, ubuntu-latest] # remove windows to speed up the tests
node-version: [22, 24] # 17 minimum node support is 22
graphql_version:
- 17.0.0
steps:
- name: Checkout Master
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7

- name: Skip Puppeteer browser download on Windows
if: matrix.os == 'windows-latest'
shell: bash
run: echo "PUPPETEER_SKIP_DOWNLOAD=true" >> "$GITHUB_ENV"

- name: Setup env
uses: the-guild-org/shared-config/setup@v1
with:
node-version: ${{matrix.node-version}}

- name: Use GraphQL v${{matrix.graphql_version}}
run: |
node ./scripts/match-graphql.js ${{matrix.graphql_version}}
npm install
git checkout package-lock.json
npx rimraf packages/**/*/node_modules/graphql
npx rimraf packages/executor/node_modules/graphql
- name: Cache Jest
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6
with:
path: .cache/jest
key:
${{ runner.os }}-${{matrix.node-version}}-${{matrix.graphql_version}}-jest-${{
hashFiles('package-lock.json') }}
restore-keys: |
${{ runner.os }}-${{matrix.node-version}}-${{matrix.graphql_version}}-jest-
# - name: Build
# run: npm run build
- name: Tests
uses: nick-fields/retry@ad984534de44a9489a53aefd81eb77f87c70dc60 # v4
with:
timeout_minutes: 10
max_attempts: 5
command: npm run test --ci -- "packages/(utils|merge)" # TODO: add more packages once compatible

test-bun:
name: Unit Test on Bun
runs-on: ubuntu-latest
Expand Down
95 changes: 27 additions & 68 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@
"eslint-plugin-promise": "7.3.0",
"globals": "17.8.0",
"globby": "11.1.0",
"graphql": "16.14.0",
"graphql": "17.0.2",
"graphql-yoga": "5.21.2",
"husky": "9.1.7",
"jest": "30.4.2",
Expand All @@ -106,13 +106,14 @@
"wonka": "6.3.6"
},
"overrides": {
"@n1ru4l/in-memory-live-query-store": "0.11.0",
"cookie": "2.0.1",
"esbuild": "0.28.1",
"estree-util-value-to-estree": "3.5.0",
"extract-zip": {
"yauzl": "3.3.0"
},
"graphql": "16.14.0",
"graphql": "17.0.2",
"miniflare": {
"undici": "8.9.0"
},
Expand Down
2 changes: 1 addition & 1 deletion packages/executor/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
},
"devDependencies": {
"cross-inspect": "1.0.1",
"graphql": "^16.14.0"
"graphql": "^17.0.2"
},
"publishConfig": {
"directory": "dist",
Expand Down
5 changes: 4 additions & 1 deletion packages/executor/src/execution/__tests__/executor-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
GraphQLUnionType,
Kind,
parse,
versionInfo,
} from 'graphql';
import { expectJSON } from '../../__testUtils__/expectJSON.js';
import { resolveOnNextTick } from '../../__testUtils__/resolveOnNextTick.js';
Expand Down Expand Up @@ -207,6 +208,8 @@ describe('Execute: Handles basic execution tasks', () => {
'operation',
'variableValues',
'signal',
'getAbortSignal',
'getAsyncHelpers',
]);

const operation = document.definitions[0];
Expand All @@ -226,7 +229,7 @@ describe('Execute: Handles basic execution tasks', () => {
expect(resolvedInfo).toMatchObject({
fieldNodes: [field],
path: { prev: undefined, key: 'result', typename: 'Test' },
variableValues: { var: 'abc' },
variableValues: versionInfo.major >= 17 ? { coerced: { var: 'abc' } } : { var: 'abc' },
});
});

Expand Down
11 changes: 2 additions & 9 deletions packages/executor/src/execution/__tests__/oneOf-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,17 +72,10 @@ if (versionInfo.major !== 16) {
const result = executeQuery(query, rootValue);

expectJSON(result).toDeepEqual({
data: {
test: null,
},
errors: [
{
locations: [{ column: 23, line: 3 }],
message:
// This type of error would be caught at validation-time
// hence the vague error message here.
'Argument "input" of non-null type "TestInputObject!" must not be null.',
path: ['test'],
locations: [{ column: 43, line: 2 }],
message: 'Variable "$input" has invalid default value.',
},
],
});
Expand Down
Loading
Loading