Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Graphql 17 support #185

Merged
merged 13 commits into from
Mar 13, 2023
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
matrix:
node-version: [14, 16, 18]
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
graphql-version: [15, 16]
graphql-version: [15, 16, 17.0.0-alpha.2]

steps:
- uses: actions/checkout@v2
Expand Down
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,18 +39,18 @@
},
"coverageThreshold": {
"global": {
"branches": 92,
"branches": 91,
"functions": 96,
"lines": 96,
"statements": 96
}
}
},
"peerDependencies": {
"graphql": ">=15"
"graphql": ">=17"
Copy link
Member

Choose a reason for hiding this comment

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

This we should keep as >=15 for now, as we still support 15

},
"devDependencies": {
"@graphql-tools/schema": "^8.3.1",
"@graphql-tools/schema": "^9.0.8",
"@stryker-mutator/core": "^2.0.0",
"@stryker-mutator/jest-runner": "^2.0.0",
"@stryker-mutator/typescript": "^2.0.0",
Expand All @@ -72,7 +72,7 @@
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^5.1.1",
"eslint-plugin-standard": "^5.0.0",
"graphql": "^16.0.0",
"graphql": "^17.0.0-alpha.2",
Copy link
Member

Choose a reason for hiding this comment

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

This could be also changed back to 16 before merging, as 17 is nevertheless still alpha. We will keep support in test runs, though.

"jest": "^27.4.3",
"lint-staged": "^8.1.5",
"prettier": "^2.4.1",
Expand Down
3 changes: 1 addition & 2 deletions src/__tests__/json.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import fastJson from "fast-json-stringify";
import {
formatError,
GraphQLBoolean,
GraphQLError,
GraphQLID,
Expand All @@ -11,12 +10,12 @@ import {
GraphQLString,
parse,
GraphQLInt,
GraphQLScalarType,
versionInfo
} from "graphql";
import { buildExecutionContext } from "graphql/execution/execute";
import { compileQuery } from "../index";
import { queryToJSONSchema } from "../json";
import { formatError } from "../format-error";
import { makeExecutableSchema } from "@graphql-tools/schema";

describe("json schema creator", () => {
Expand Down
3 changes: 1 addition & 2 deletions src/__tests__/schema.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@ import {
GraphQLString,
IntrospectionQuery,
parse,
printSchema,
versionInfo
printSchema
} from "graphql";
import { compileQuery, isCompiledQuery } from "../index";

Expand Down
6 changes: 3 additions & 3 deletions src/__tests__/subscription.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@
*/

import {
ExecutionArgs,
ExecutionResult,
GraphQLBoolean,
GraphQLInt,
GraphQLList,
GraphQLObjectType,
GraphQLSchema,
GraphQLString,
parse,
SubscriptionArgs
parse
} from "graphql";
import { compileQuery, isAsyncIterable, isCompiledQuery } from "../execution";

Expand Down Expand Up @@ -68,7 +68,7 @@ async function subscribe({
rootValue,
contextValue,
variableValues
}: SubscriptionArgs): Promise<
}: ExecutionArgs): Promise<
AsyncIterableIterator<ExecutionResult> | ExecutionResult
> {
const prepared = compileQuery(schema, document, operationName || "");
Expand Down
7 changes: 5 additions & 2 deletions src/__tests__/variables.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ import {
GraphQLScalarType,
GraphQLSchema,
GraphQLString,
parse
parse,
versionInfo
} from "graphql";
import { GraphQLArgumentConfig } from "graphql/type/definition";
import { compileQuery, isCompiledQuery } from "../index";
Expand Down Expand Up @@ -283,7 +284,9 @@ describe("Execute: Handles inputs", () => {
errors: [
{
message:
'Argument "input" of type "TestInputObject" has invalid value {b: ["A", null, "C"], c: false}.',
versionInfo.major < 17
? 'Argument "input" of type "TestInputObject" has invalid value {b: ["A", null, "C"], c: false}.'
: 'Argument "input" of type "TestInputObject" has invalid value { b: ["A", null, "C"], c: false }.',
locations: [{ line: 3, column: 41 }]
}
]
Expand Down
39 changes: 28 additions & 11 deletions src/ast.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,13 @@ import {
VariableNode,
versionInfo
} from "graphql";
import { getFieldDef } from "graphql/execution/execute";
import { Kind, SelectionNode, TypeNode } from "graphql/language";
import { isAbstractType } from "graphql/type";
import { CompilationContext, GLOBAL_VARIABLES_NAME } from "./execution";
import createInspect from "./inspect";
import { Maybe } from "./types";
import * as execute from "graphql/execution/execute";
import { getGraphQLErrorOptions } from "./get-graphql-error-options";

export interface JitFieldNode extends FieldNode {
__internalShouldInclude?: string;
Expand Down Expand Up @@ -414,7 +415,7 @@ function compileSkipIncludeDirective(
if (ifNode == null) {
throw new GraphQLError(
`Directive '${directive.name.value}' is missing required arguments: 'if'`,
[directive]
getGraphQLErrorOptions([directive])
);
}

Expand All @@ -431,7 +432,7 @@ function compileSkipIncludeDirective(
}' has an invalid value (${valueFromASTUntyped(
ifNode.value
)}). Expected type 'Boolean!'`,
[ifNode]
getGraphQLErrorOptions([ifNode])
);
}
}
Expand All @@ -454,9 +455,10 @@ function validateSkipIncludeVariableType(
(it) => it.variable.name.value === variable.name.value
);
if (variableDefinition == null) {
throw new GraphQLError(`Variable '${variable.name.value}' is not defined`, [
variable
]);
throw new GraphQLError(
`Variable '${variable.name.value}' is not defined`,
getGraphQLErrorOptions([variable])
);
}

if (
Expand All @@ -470,7 +472,7 @@ function validateSkipIncludeVariableType(
`Variable '${variable.name.value}' of type '${typeNodeToString(
variableDefinition.type
)}' used in position expecting type 'Boolean!'`,
[variableDefinition]
getGraphQLErrorOptions([variableDefinition])
);
}
}
Expand Down Expand Up @@ -541,10 +543,25 @@ export function resolveFieldDef(

if (versionInfo.major < 16) {
const fieldName = fieldNode.name.value;
return getFieldDef(compilationContext.schema, parentType, fieldName as any);
return (execute as any).getFieldDef(
compilationContext.schema,
parentType,
fieldName as any
);
}

return getFieldDef(compilationContext.schema, parentType, fieldNode as any);
boopathi marked this conversation as resolved.
Show resolved Hide resolved
if (versionInfo.major < 17) {
return (execute as any).getFieldDef(
compilationContext.schema,
parentType,
fieldNode as any
);
}

return (compilationContext.schema as any).getField(
parentType,
fieldNode.name.value
);
}

/**
Expand Down Expand Up @@ -686,7 +703,7 @@ export function getArgumentDefs(
`Argument "${name}" of type "${argType}" has invalid value ${print(
argumentNode.value
)}.`,
argumentNode.value
getGraphQLErrorOptions(argumentNode.value)
);
}

Expand All @@ -709,7 +726,7 @@ export function getArgumentDefs(
`"${argType}" must not be null.`
: `Argument "${name}" of required type ` +
`"${argType}" was not provided.`,
node
getGraphQLErrorOptions(node)
);
}
}
Expand Down
31 changes: 20 additions & 11 deletions src/compat.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import * as GraphQL from "graphql";
import { GraphQLSchema, versionInfo } from "graphql";
import * as utilities from "graphql/utilities";
import { GraphQLObjectType } from "graphql/type/definition";
import { OperationDefinitionNode } from "graphql/language/ast";

/**
* A helper to support backward compatibility for different versions of graphql-js.
Expand All @@ -14,14 +17,20 @@ import * as GraphQL from "graphql";
*
* GraphQL v17 would remove getOperationRootType.
*/
export function getOperationRootType(
schema: GraphQL.GraphQLSchema,
operation: GraphQL.OperationDefinitionNode
) {
if (GraphQL.getOperationRootType) {
return GraphQL.getOperationRootType(schema, operation);
} else {
// the use of any is to support graphql v15 types which will not use this codepath
return (schema as any).getRootType(operation.operation)!;

export const getOperationRootType = (
schema: GraphQLSchema,
operation: OperationDefinitionNode
): GraphQLObjectType => {
Copy link
Member

Choose a reason for hiding this comment

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

nit: please refactor this arrow function expression to function declaration.

if (versionInfo.major < 16) {
return (utilities as any).getOperationRootType(schema, operation);
}
}

const type = (schema as any).getRootType(operation.operation);

if (!type) {
throw new Error(`No root type for operation ${operation.operation}`);
}

return type;
};
5 changes: 3 additions & 2 deletions src/execution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ import {
ObjectPath,
resolveFieldDef
} from "./ast";
import { getOperationRootType } from "./compat";
import { GraphQLError as GraphqlJitError } from "./error";
import createInspect from "./inspect";
import { queryToJSONSchema } from "./json";
Expand All @@ -62,6 +61,8 @@ import {
compileVariableParsing,
failToParseVariables
} from "./variables";
import { getGraphQLErrorOptions } from "./get-graphql-error-options";
import { getOperationRootType } from "./compat";

const inspect = createInspect();

Expand Down Expand Up @@ -1706,7 +1707,7 @@ function compileSubscriptionOperation(
if (!field) {
throw new GraphQLError(
`The subscription field "${fieldName}" is not defined.`,
fieldNodes
getGraphQLErrorOptions(fieldNodes)
);
}

Expand Down
11 changes: 11 additions & 0 deletions src/format-error.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { GraphQLError, versionInfo } from "graphql";
import * as utilities from "graphql/error";
import { GraphQLFormattedError } from "graphql/error";

export const formatError = (error: GraphQLError): GraphQLFormattedError => {
Copy link
Member

Choose a reason for hiding this comment

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

nit: please refactor to function declaration instead of using arrow function expression.

if (versionInfo.major < 16) {
return (utilities as any).formatError(error);
}

return (error as any).toJSON();
};
13 changes: 13 additions & 0 deletions src/get-graphql-error-options.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { Maybe } from "graphql/jsutils/Maybe";
import { ASTNode } from "graphql/language/ast";
import { GraphQLError, versionInfo } from "graphql";

export const getGraphQLErrorOptions = (
Copy link
Member

Choose a reason for hiding this comment

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

move this to the src/compat.ts file

nodes: Maybe<ReadonlyArray<ASTNode> | ASTNode>
): ConstructorParameters<typeof GraphQLError>[1] => {
if (versionInfo.major < 16) {
return nodes as any;
}

return { nodes } as any;
};
58 changes: 29 additions & 29 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -446,30 +446,30 @@
minimatch "^3.0.4"
strip-json-comments "^3.1.1"

"@graphql-tools/merge@^8.2.1":
version "8.2.1"
resolved "https://registry.yarnpkg.com/@graphql-tools/merge/-/merge-8.2.1.tgz#bf83aa06a0cfc6a839e52a58057a84498d0d51ff"
integrity sha512-Q240kcUszhXiAYudjuJgNuLgy9CryDP3wp83NOZQezfA6h3ByYKU7xI6DiKrdjyVaGpYN3ppUmdj0uf5GaXzMA==
dependencies:
"@graphql-tools/utils" "^8.5.1"
tslib "~2.3.0"

"@graphql-tools/schema@^8.3.1":
version "8.3.1"
resolved "https://registry.yarnpkg.com/@graphql-tools/schema/-/schema-8.3.1.tgz#1ee9da494d2da457643b3c93502b94c3c4b68c74"
integrity sha512-3R0AJFe715p4GwF067G5i0KCr/XIdvSfDLvTLEiTDQ8V/hwbOHEKHKWlEBHGRQwkG5lwFQlW1aOn7VnlPERnWQ==
dependencies:
"@graphql-tools/merge" "^8.2.1"
"@graphql-tools/utils" "^8.5.1"
tslib "~2.3.0"
"@graphql-tools/merge@8.3.10":
version "8.3.10"
resolved "https://registry.yarnpkg.com/@graphql-tools/merge/-/merge-8.3.10.tgz#81f374bc1e8c81d45cb1003d8ed05f181b7e6bd5"
integrity sha512-/hSg69JwqEA+t01wQmMGKPuaJ9VJBSz6uAXhbNNrTBJu8bmXljw305NVXM49pCwDKFVUGtbTqYrBeLcfT3RoYw==
dependencies:
"@graphql-tools/utils" "9.0.1"
tslib "^2.4.0"

"@graphql-tools/schema@^9.0.8":
version "9.0.8"
resolved "https://registry.yarnpkg.com/@graphql-tools/schema/-/schema-9.0.8.tgz#df3119c8543e6dacf425998f83aa714e2ee86eb0"
integrity sha512-PnES7sNkhQ/FdPQhP7cup0OIzwzQh+nfjklilU7YJzE209ACIyEQtxoNCfvPW5eV6hc9bWsBQeI3Jm4mMtwxNA==
dependencies:
"@graphql-tools/merge" "8.3.10"
"@graphql-tools/utils" "9.0.1"
tslib "^2.4.0"
value-or-promise "1.0.11"

"@graphql-tools/utils@^8.5.1":
version "8.6.1"
resolved "https://registry.yarnpkg.com/@graphql-tools/utils/-/utils-8.6.1.tgz#52c7eb108f2ca2fd01bdba8eef85077ead1bf882"
integrity sha512-uxcfHCocp4ENoIiovPxUWZEHOnbXqj3ekWc0rm7fUhW93a1xheARNHcNKhwMTR+UKXVJbTFQdGI1Rl5XdyvDBg==
"@graphql-tools/utils@9.0.1":
version "9.0.1"
resolved "https://registry.yarnpkg.com/@graphql-tools/utils/-/utils-9.0.1.tgz#04933b34c3435ef9add4f8bdfdf452040376f9d0"
integrity sha512-z6FimVa5E44bHKmqK0/uMp9hHvHo2Tkt9A5rlLb40ReD/8IFKehSXLzM4b2N1vcP7mSsbXIdDK9Aoc8jT/he1Q==
dependencies:
tslib "~2.3.0"
tslib "^2.4.0"

"@graphql-typed-document-node/core@^3.1.1":
version "3.1.1"
Expand Down Expand Up @@ -2653,10 +2653,10 @@ graceful-fs@^4.2.4:
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.8.tgz#e412b8d33f5e006593cbd3cee6df9f2cebbe802a"
integrity sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==

graphql@^16.0.0:
version "16.2.0"
resolved "https://registry.yarnpkg.com/graphql/-/graphql-16.2.0.tgz#de3150e80f1fc009590b92a9d16ab1b46e12b656"
integrity sha512-MuQd7XXrdOcmfwuLwC2jNvx0n3rxIuNYOxUtiee5XOmfrWo613ar2U8pE7aHAKh8VwfpifubpD9IP+EdEAEOsA==
graphql@^17.0.0-alpha.2:
version "17.0.0-alpha.2.canary.pr.3791.264f22163eb937ff87a420be9f7d45965f2cbf07"
resolved "https://registry.yarnpkg.com/graphql/-/graphql-17.0.0-alpha.2.canary.pr.3791.264f22163eb937ff87a420be9f7d45965f2cbf07.tgz#3835b1183f4a7a735d629df575a29cba3829f1ea"
integrity sha512-foJTYdXFHaZNx0M5eks57HBGSNwtfxQWcR7REVG3IB9Q0Ah3pumvN4Jk8GciWARv4/ySP/hKpGMqMFy1TKlqqg==

has-ansi@^2.0.0:
version "2.0.0"
Expand Down Expand Up @@ -5374,10 +5374,10 @@ tslib@^1.8.1, tslib@^1.9.0, tslib@~1.9.3:
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286"
integrity sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==

tslib@~2.3.0:
version "2.3.1"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01"
integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==
tslib@^2.4.0:
version "2.4.1"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.1.tgz#0d0bfbaac2880b91e22df0768e55be9753a5b17e"
integrity sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==

tsutils@^3.21.0:
version "3.21.0"
Expand Down