From 56c37d85f75bc9be4b40e882486203a7fa8beb41 Mon Sep 17 00:00:00 2001 From: Jesse Rosenberger Date: Wed, 8 Jul 2020 00:28:59 +0300 Subject: [PATCH] Preparations for graphql@15.x. (#1743) This PR makes the minimal number of changes necessary for the apollo-tooling's repository's tests to pass for the planned graphql@15.x release. Notable changes to implementations are as follows: an adjustment to account for the new onError callback introduced by graphql/graphql-js#2074, which deprecated the previously used ValidationContext.prototype.getErrors method. utilize the GraphQLEnumValueConfig type instead of GraphQLEnumValue (which lead to the removal of the name field, which isn't actually needed when building the values for the GraphQLEnumType constructor. Ref: graphql/graphql-js#2303 Co-authored-by: Trevor Scheer --- CHANGELOG.md | 5 ++-- package-lock.json | 18 ++++--------- package.json | 2 +- .../__snapshots__/jsonOutput.ts.snap | 27 ++++++++++++------- .../src/codeGeneration.ts | 1 - packages/apollo-graphql/package.json | 2 +- .../__tests__/buildSchemaFromSDL.test.ts | 6 ++--- .../src/schema/buildSchemaFromSDL.ts | 6 ++--- packages/apollo-language-server/package.json | 2 +- .../src/errors/validation.ts | 22 +++++++++++++-- .../src/project/client.ts | 7 +++-- .../src/providers/schema/file.ts | 2 +- packages/apollo/package.json | 2 +- packages/apollo/src/Command.ts | 2 +- .../client/__tests__/generate.test.ts | 5 ++-- .../commands/service/__tests__/check.test.ts | 2 +- 16 files changed, 65 insertions(+), 46 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ffec0cb148..96dc92f3ec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ ## Upcoming - `apollo` - - + - Add support for graphql version ^15 [#1743](https://github.com/apollographql/apollo-tooling/pull/1743) - `apollo-codegen-flow` - - `apollo-codegen-scala` @@ -17,9 +17,10 @@ - `apollo-env` - - `apollo-graphql` - - + - Add support for graphql version ^15 [#1743](https://github.com/apollographql/apollo-tooling/pull/1743) - `apollo-language-server` - Fix definition navigation for vscode using localSchemaFile [#1996](https://github.com/apollographql/apollo-tooling/pull/1996) + - Add support for graphql version ^15 [#1743](https://github.com/apollographql/apollo-tooling/pull/1743) - `apollo-tools` - - `vscode-apollo` diff --git a/package-lock.json b/package-lock.json index 1de1e1a845..11f9e54d10 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3156,7 +3156,7 @@ "git-rev-sync": "2.0.0", "git-url-parse": "^11.1.2", "glob": "7.1.5", - "graphql": "14.0.2 - 14.2.0 || ^14.3.1", + "graphql": "14.0.2 - 14.2.0 || ^14.3.1 || ^15.0.0", "graphql-tag": "2.10.3", "listr": "0.14.3", "lodash.identity": "3.0.0", @@ -4358,7 +4358,7 @@ "cosmiconfig": "^5.0.6", "dotenv": "^8.0.0", "glob": "^7.1.3", - "graphql": "14.0.2 - 14.2.0 || ^14.3.1", + "graphql": "14.0.2 - 14.2.0 || ^14.3.1 || ^15.0.0", "graphql-tag": "^2.10.1", "lodash.debounce": "^4.0.8", "lodash.merge": "^4.6.1", @@ -7945,12 +7945,9 @@ "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==" }, "graphql": { - "version": "14.5.7", - "resolved": "https://registry.npmjs.org/graphql/-/graphql-14.5.7.tgz", - "integrity": "sha512-as410RMJSUFqF8RcH2QWxZ5ioqHzsH9VWnWbaU+UnDXJ/6azMDIYPrtXCBPXd8rlunEVb7W8z6fuUnNHMbFu9A==", - "requires": { - "iterall": "^1.2.2" - } + "version": "15.2.0", + "resolved": "https://registry.npmjs.org/graphql/-/graphql-15.2.0.tgz", + "integrity": "sha512-tsceRyHfgzZo+ee0YK3o8f0CR0cXAXxRlxoORWFo/CoM1bVy3UXGWeyzBcf+Y6oqPvO27BDmOEVATcunOO/MrQ==" }, "graphql-tag": { "version": "2.10.1", @@ -8957,11 +8954,6 @@ "is-object": "^1.0.1" } }, - "iterall": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/iterall/-/iterall-1.2.2.tgz", - "integrity": "sha512-yynBb1g+RFUPY64fTrFv7nsjRrENBQJaX2UL+2Szc9REFrSNm1rpSXHGzhmAy7a9uv3vlvgBlXnf9RqmPH1/DA==" - }, "java-properties": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/java-properties/-/java-properties-1.0.2.tgz", diff --git a/package.json b/package.json index 4b69a5462a..44d960a879 100644 --- a/package.json +++ b/package.json @@ -76,7 +76,7 @@ "@types/node-fetch": "2.5.7", "@types/table": "4.0.7", "cross-env": "^7.0.2", - "graphql": "14.5.7", + "graphql": "15.2.0", "heroku-cli-util": "8.0.12", "husky": "3.1.0", "jest": "24.9.0", diff --git a/packages/apollo-codegen-core/src/__tests__/__snapshots__/jsonOutput.ts.snap b/packages/apollo-codegen-core/src/__tests__/__snapshots__/jsonOutput.ts.snap index 747e859839..8890634635 100644 --- a/packages/apollo-codegen-core/src/__tests__/__snapshots__/jsonOutput.ts.snap +++ b/packages/apollo-codegen-core/src/__tests__/__snapshots__/jsonOutput.ts.snap @@ -49,7 +49,8 @@ exports[`JSON output should generate JSON output for a mutation with an enum and \\"responseName\\": \\"__typename\\", \\"fieldName\\": \\"__typename\\", \\"type\\": \\"String!\\", - \\"isConditional\\": false + \\"isConditional\\": false, + \\"isDeprecated\\": false }, { \\"responseName\\": \\"stars\\", @@ -176,7 +177,8 @@ exports[`JSON output should generate JSON output for a query with a fragment spr \\"responseName\\": \\"__typename\\", \\"fieldName\\": \\"__typename\\", \\"type\\": \\"String!\\", - \\"isConditional\\": false + \\"isConditional\\": false, + \\"isDeprecated\\": false }, { \\"responseName\\": \\"id\\", @@ -217,7 +219,8 @@ exports[`JSON output should generate JSON output for a query with a fragment spr \\"responseName\\": \\"__typename\\", \\"fieldName\\": \\"__typename\\", \\"type\\": \\"String!\\", - \\"isConditional\\": false + \\"isConditional\\": false, + \\"isDeprecated\\": false }, { \\"responseName\\": \\"name\\", @@ -240,7 +243,8 @@ exports[`JSON output should generate JSON output for a query with a fragment spr \\"responseName\\": \\"__typename\\", \\"fieldName\\": \\"__typename\\", \\"type\\": \\"String!\\", - \\"isConditional\\": false + \\"isConditional\\": false, + \\"isDeprecated\\": false }, { \\"responseName\\": \\"name\\", @@ -271,7 +275,8 @@ exports[`JSON output should generate JSON output for a query with a fragment spr \\"responseName\\": \\"__typename\\", \\"fieldName\\": \\"__typename\\", \\"type\\": \\"String!\\", - \\"isConditional\\": false + \\"isConditional\\": false, + \\"isDeprecated\\": false }, { \\"responseName\\": \\"name\\", @@ -321,7 +326,8 @@ exports[`JSON output should generate JSON output for a query with a nested selec \\"responseName\\": \\"__typename\\", \\"fieldName\\": \\"__typename\\", \\"type\\": \\"String!\\", - \\"isConditional\\": false + \\"isConditional\\": false, + \\"isDeprecated\\": false }, { \\"responseName\\": \\"name\\", @@ -343,7 +349,8 @@ exports[`JSON output should generate JSON output for a query with a nested selec \\"responseName\\": \\"__typename\\", \\"fieldName\\": \\"__typename\\", \\"type\\": \\"String!\\", - \\"isConditional\\": false + \\"isConditional\\": false, + \\"isDeprecated\\": false }, { \\"responseName\\": \\"name\\", @@ -411,7 +418,8 @@ exports[`JSON output should generate JSON output for a query with an enum variab \\"responseName\\": \\"__typename\\", \\"fieldName\\": \\"__typename\\", \\"type\\": \\"String!\\", - \\"isConditional\\": false + \\"isConditional\\": false, + \\"isDeprecated\\": false }, { \\"responseName\\": \\"name\\", @@ -500,7 +508,8 @@ exports[`JSON output should generate JSON output for a subscription 1`] = ` \\"responseName\\": \\"__typename\\", \\"fieldName\\": \\"__typename\\", \\"type\\": \\"String!\\", - \\"isConditional\\": false + \\"isConditional\\": false, + \\"isDeprecated\\": false }, { \\"responseName\\": \\"id\\", diff --git a/packages/apollo-codegen-scala/src/codeGeneration.ts b/packages/apollo-codegen-scala/src/codeGeneration.ts index deb1699530..2d6a7f8617 100644 --- a/packages/apollo-codegen-scala/src/codeGeneration.ts +++ b/packages/apollo-codegen-scala/src/codeGeneration.ts @@ -48,7 +48,6 @@ import { import { GraphQLType } from "graphql"; import { Property } from "./language"; import { GraphQLCompositeType } from "graphql"; -import { createLexer } from "graphql/language"; export function generateSource(context: LegacyCompilerContext) { const generator = new CodeGenerator(context); diff --git a/packages/apollo-graphql/package.json b/packages/apollo-graphql/package.json index 05b5ce289e..ea3edfcf71 100644 --- a/packages/apollo-graphql/package.json +++ b/packages/apollo-graphql/package.json @@ -15,7 +15,7 @@ "lodash.sortby": "^4.7.0" }, "peerDependencies": { - "graphql": "^14.2.1" + "graphql": "^14.2.1 || ^15.0.0" }, "jest": { "preset": "ts-jest", diff --git a/packages/apollo-graphql/src/schema/__tests__/buildSchemaFromSDL.test.ts b/packages/apollo-graphql/src/schema/__tests__/buildSchemaFromSDL.test.ts index 806e464274..9a812fcebb 100644 --- a/packages/apollo-graphql/src/schema/__tests__/buildSchemaFromSDL.test.ts +++ b/packages/apollo-graphql/src/schema/__tests__/buildSchemaFromSDL.test.ts @@ -282,7 +282,7 @@ type MutationRoot { ` ) ).toThrowErrorMatchingInlineSnapshot( - `"There can be only one directive named \\"something\\"."` + `"There can be only one directive named \\"@something\\"."` ); }); @@ -303,7 +303,7 @@ type MutationRoot { }) ) ).toThrowErrorMatchingInlineSnapshot( - `"Directive \\"something\\" already exists in the schema. It cannot be redefined."` + `"Directive \\"@something\\" already exists in the schema. It cannot be redefined."` ); }); @@ -348,7 +348,7 @@ type MutationRoot { ` ) ).toThrowErrorMatchingInlineSnapshot( - `"Unknown directive \\"something\\"."` + `"Unknown directive \\"@something\\"."` ); }); }); diff --git a/packages/apollo-graphql/src/schema/buildSchemaFromSDL.ts b/packages/apollo-graphql/src/schema/buildSchemaFromSDL.ts index 528e8cc375..274937091e 100644 --- a/packages/apollo-graphql/src/schema/buildSchemaFromSDL.ts +++ b/packages/apollo-graphql/src/schema/buildSchemaFromSDL.ts @@ -18,7 +18,7 @@ import { isAbstractType, isScalarType, isEnumType, - GraphQLEnumValue + GraphQLEnumValueConfig } from "graphql"; import { validateSDL } from "graphql/validation/validate"; import { isDocumentNode, isNode } from "../utilities/graphql"; @@ -247,18 +247,18 @@ export function addResolversToSchema( if (isEnumType(type)) { const values = type.getValues(); - const newValues: { [key: string]: GraphQLEnumValue } = {}; + const newValues: { [key: string]: GraphQLEnumValueConfig } = {}; values.forEach(value => { let newValue = (fieldConfigs as any)[value.name]; if (newValue === undefined) { newValue = value.name; } + newValues[value.name] = { value: newValue, deprecationReason: value.deprecationReason, description: value.description, astNode: value.astNode, - name: value.name, extensions: undefined }; }); diff --git a/packages/apollo-language-server/package.json b/packages/apollo-language-server/package.json index b4b35511a5..60d172fc24 100644 --- a/packages/apollo-language-server/package.json +++ b/packages/apollo-language-server/package.json @@ -34,7 +34,7 @@ "cosmiconfig": "^5.0.6", "dotenv": "^8.0.0", "glob": "^7.1.3", - "graphql": "14.0.2 - 14.2.0 || ^14.3.1", + "graphql": "14.0.2 - 14.2.0 || ^14.3.1 || ^15.0.0", "graphql-tag": "^2.10.1", "lodash.debounce": "^4.0.8", "lodash.merge": "^4.6.1", diff --git a/packages/apollo-language-server/src/errors/validation.ts b/packages/apollo-language-server/src/errors/validation.ts index c9fa38cb4d..e7c23831d2 100644 --- a/packages/apollo-language-server/src/errors/validation.ts +++ b/packages/apollo-language-server/src/errors/validation.ts @@ -51,7 +51,18 @@ export function getValidationErrors( rules: ValidationRule[] = defaultValidationRules ) { const typeInfo = new TypeInfo(schema); - const context = new ValidationContext(schema, document, typeInfo); + + // The 4th argument to `ValidationContext` is an `onError` callback. This was + // introduced by https://github.com/graphql/graphql-js/pull/2074 and first + // published in graphql@14.5.0. It is meant to replace the `getErrors` method + // which was previously used. Since we support versions of graphql older than + // that, it's possible that this callback will not be invoked and we'll need + // to resort to using `getErrors`. Therefore, although we'll collect errors + // via this callback, if `getErrors` is present on the context we create, + // we'll go ahead and use that instead. + const errors: GraphQLError[] = []; + const onError = (err: GraphQLError) => errors.push(err); + const context = new ValidationContext(schema, document, typeInfo, onError); if (fragments) { (context as any)._fragments = fragments; @@ -60,7 +71,14 @@ export function getValidationErrors( const visitors = rules.map(rule => rule(context)); // Visit the whole document with each instance of all provided rules. visit(document, visitWithTypeInfo(typeInfo, visitInParallel(visitors))); - return context.getErrors(); + + // @ts-ignore + // `getErrors` is gone in `graphql@15`, but we still support older versions. + if (typeof context.getErrors === "function") return context.getErrors(); + + // If `getErrors` doesn't exist, we must be on a `graphql@15` or higher, + // so we'll use the errors we collected via the `onError` callback. + return errors; } export function validateQueryDocument( diff --git a/packages/apollo-language-server/src/project/client.ts b/packages/apollo-language-server/src/project/client.ts index 1b983e90df..66e3ff2764 100644 --- a/packages/apollo-language-server/src/project/client.ts +++ b/packages/apollo-language-server/src/project/client.ts @@ -18,12 +18,9 @@ import { FieldNode, ObjectTypeDefinitionNode, GraphQLObjectType, - DefinitionNode, - DirectiveDefinitionNode + DefinitionNode } from "graphql"; import { ValidationRule } from "graphql/validation/ValidationContext"; -import Maybe from "graphql/tsutils/Maybe"; - import { NotificationHandler, DiagnosticSeverity } from "vscode-languageserver"; import { rangeForASTNode } from "../utilities/source"; @@ -50,6 +47,8 @@ import { } from "../diagnostics"; import URI from "vscode-uri"; +type Maybe = null | undefined | T; + function schemaHasASTNodes(schema: GraphQLSchema): boolean { const queryType = schema && schema.getQueryType(); return !!(queryType && queryType.astNode); diff --git a/packages/apollo-language-server/src/providers/schema/file.ts b/packages/apollo-language-server/src/providers/schema/file.ts index 388391cfdd..ddf78f4893 100644 --- a/packages/apollo-language-server/src/providers/schema/file.ts +++ b/packages/apollo-language-server/src/providers/schema/file.ts @@ -71,7 +71,7 @@ export class FileSchemaProvider implements GraphQLSchemaProvider { const ext = extname(path); - // an actual introspectionQuery result, convert to DocumentNode + // an actual introspection query result, convert to DocumentNode if (ext === ".json") { const parsed = JSON.parse(result); const __schema = parsed.data diff --git a/packages/apollo/package.json b/packages/apollo/package.json index f3fd1249ae..5f313a1c2e 100644 --- a/packages/apollo/package.json +++ b/packages/apollo/package.json @@ -56,7 +56,7 @@ "git-rev-sync": "2.0.0", "git-url-parse": "^11.1.2", "glob": "7.1.5", - "graphql": "14.0.2 - 14.2.0 || ^14.3.1", + "graphql": "14.0.2 - 14.2.0 || ^14.3.1 || ^15.0.0", "graphql-tag": "2.10.3", "listr": "0.14.3", "lodash.identity": "3.0.0", diff --git a/packages/apollo/src/Command.ts b/packages/apollo/src/Command.ts index aeb4046182..6a46bf632c 100644 --- a/packages/apollo/src/Command.ts +++ b/packages/apollo/src/Command.ts @@ -75,7 +75,7 @@ export abstract class ProjectCommand extends Command { return JSON.stringify({ [key]: value }); }, description: - "Additional header to send to server for introspectionQuery. May be used multiple times to add multiple headers. NOTE: The `--endpoint` flag is REQUIRED if using the `--header` flag." + "Additional header to send during introspection. May be used multiple times to add multiple headers. NOTE: The `--endpoint` flag is REQUIRED if using the `--header` flag." }), endpoint: flags.string({ description: "The URL for the CLI use to introspect your service" diff --git a/packages/apollo/src/commands/client/__tests__/generate.test.ts b/packages/apollo/src/commands/client/__tests__/generate.test.ts index a63a967e70..458fc6a665 100644 --- a/packages/apollo/src/commands/client/__tests__/generate.test.ts +++ b/packages/apollo/src/commands/client/__tests__/generate.test.ts @@ -4,7 +4,7 @@ import path from "path"; import fs from "fs"; import { test as setup } from "apollo-cli-test"; import { - introspectionQuery, + getIntrospectionQuery, print, execute, buildSchema, @@ -46,7 +46,8 @@ const { // introspection results of a schema, JSON.stringified const fullSchemaJsonString = JSON.stringify( - execute(buildSchema(graphQLSchema), gql(introspectionQuery)).data.__schema + execute(buildSchema(graphQLSchema), gql(getIntrospectionQuery())).data + .__schema ); // to be used for sample js files that contain client side schema definitions diff --git a/packages/apollo/src/commands/service/__tests__/check.test.ts b/packages/apollo/src/commands/service/__tests__/check.test.ts index b483c6f227..a9fbc6a588 100644 --- a/packages/apollo/src/commands/service/__tests__/check.test.ts +++ b/packages/apollo/src/commands/service/__tests__/check.test.ts @@ -103,7 +103,7 @@ function uncaptureApplicationOutput(): string | null { function sdlToIntrospectionQueryResult(schemaSdl: string) { return graphql.graphqlSync( graphql.buildSchema(schemaSdl), - graphql.introspectionQuery + graphql.getIntrospectionQuery() ).data; }