From bce6a7387af97934d0b5005c7519307b811517db Mon Sep 17 00:00:00 2001 From: Ivan Goncharov Date: Fri, 17 Dec 2021 17:22:18 +0200 Subject: [PATCH 1/2] Switch to graphql@16.2 Fixes #361 --- package-lock.json | 18 ++++++------ package.json | 4 +-- src/__tests__/starWarsSchema.ts | 2 +- src/connection/__tests__/connection-test.ts | 5 +--- src/connection/connection.ts | 20 +++++-------- src/mutation/__tests__/mutation-test.ts | 31 ++++++++------------- src/mutation/mutation.ts | 21 +++++--------- src/node/__tests__/global-test.ts | 6 ++-- src/node/__tests__/node-test.ts | 7 ++--- src/node/__tests__/nodeAsync-test.ts | 2 +- src/node/__tests__/plural-test.ts | 3 +- 11 files changed, 47 insertions(+), 72 deletions(-) diff --git a/package-lock.json b/package-lock.json index d02282b..109fb6d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27,7 +27,7 @@ "eslint-plugin-istanbul": "0.1.2", "eslint-plugin-node": "11.1.0", "flow-bin": "0.159.0", - "graphql": "15.8.0", + "graphql": "16.2.0", "mocha": "9.1.1", "nyc": "15.1.0", "prettier": "2.4.0", @@ -37,7 +37,7 @@ "node": "^12.20.0 || ^14.15.0 || >= 15.9.0" }, "peerDependencies": { - "graphql": "^15.5.3" + "graphql": "^16.2.0" } }, "node_modules/@babel/code-frame": { @@ -4455,12 +4455,12 @@ "dev": true }, "node_modules/graphql": { - "version": "15.8.0", - "resolved": "https://registry.npmjs.org/graphql/-/graphql-15.8.0.tgz", - "integrity": "sha512-5gghUc24tP9HRznNpV2+FIoq3xKkj5dTQqf4v0CpdPbFVwFkWoxOM+o+2OC9ZSvjEMTjfmG9QT+gcvggTwW1zw==", + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.2.0.tgz", + "integrity": "sha512-MuQd7XXrdOcmfwuLwC2jNvx0n3rxIuNYOxUtiee5XOmfrWo613ar2U8pE7aHAKh8VwfpifubpD9IP+EdEAEOsA==", "dev": true, "engines": { - "node": ">= 10.x" + "node": "^12.22.0 || ^14.16.0 || >=16.0.0" } }, "node_modules/growl": { @@ -10934,9 +10934,9 @@ "dev": true }, "graphql": { - "version": "15.8.0", - "resolved": "https://registry.npmjs.org/graphql/-/graphql-15.8.0.tgz", - "integrity": "sha512-5gghUc24tP9HRznNpV2+FIoq3xKkj5dTQqf4v0CpdPbFVwFkWoxOM+o+2OC9ZSvjEMTjfmG9QT+gcvggTwW1zw==", + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.2.0.tgz", + "integrity": "sha512-MuQd7XXrdOcmfwuLwC2jNvx0n3rxIuNYOxUtiee5XOmfrWo613ar2U8pE7aHAKh8VwfpifubpD9IP+EdEAEOsA==", "dev": true }, "growl": { diff --git a/package.json b/package.json index a7d1dbe..2eba46a 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,7 @@ "build": "node resources/build.js" }, "peerDependencies": { - "graphql": "^15.5.3" + "graphql": "^16.2.0" }, "devDependencies": { "@babel/core": "7.15.5", @@ -61,7 +61,7 @@ "eslint-plugin-istanbul": "0.1.2", "eslint-plugin-node": "11.1.0", "flow-bin": "0.159.0", - "graphql": "15.8.0", + "graphql": "16.2.0", "mocha": "9.1.1", "nyc": "15.1.0", "prettier": "2.4.0", diff --git a/src/__tests__/starWarsSchema.ts b/src/__tests__/starWarsSchema.ts index 8606720..ea600cc 100644 --- a/src/__tests__/starWarsSchema.ts +++ b/src/__tests__/starWarsSchema.ts @@ -116,7 +116,7 @@ const { nodeInterface, nodeField } = nodeDefinitions( return getShip(id); } }, - (obj) => (obj.ships ? factionType : shipType), + (obj) => (obj.ships ? factionType.name : shipType.name), ); /** diff --git a/src/connection/__tests__/connection-test.ts b/src/connection/__tests__/connection-test.ts index df091b9..7662a1d 100644 --- a/src/connection/__tests__/connection-test.ts +++ b/src/connection/__tests__/connection-test.ts @@ -55,7 +55,6 @@ const userType = new GraphQLObjectType({ const { connectionType: friendConnection } = connectionDefinitions({ name: 'Friend', - // @ts-expect-error nodeType: new GraphQLNonNull(userType), resolveNode: (edge) => allUsers[edge.node], edgeFields: () => ({ @@ -73,7 +72,6 @@ const { connectionType: friendConnection } = connectionDefinitions({ }); const { connectionType: userConnection } = connectionDefinitions({ - // @ts-expect-error nodeType: new GraphQLNonNull(userType), resolveNode: (edge) => allUsers[edge.node], }); @@ -184,8 +182,7 @@ describe('connectionDefinition()', () => { }); it('generates correct types', () => { - // FIXME remove trimEnd after we update to `graphql@16.0.0` - expect(printSchema(schema).trimEnd()).to.deep.equal(dedent` + expect(printSchema(schema)).to.deep.equal(dedent` type Query { user: User } diff --git a/src/connection/connection.ts b/src/connection/connection.ts index bbb6ce6..1483ad4 100644 --- a/src/connection/connection.ts +++ b/src/connection/connection.ts @@ -6,14 +6,15 @@ import { GraphQLString, GraphQLBoolean, getNamedType, + resolveObjMapThunk, } from 'graphql'; import type { GraphQLNamedOutputType, GraphQLFieldConfigArgumentMap, - GraphQLFieldConfigMap, + GraphQLFieldConfig, GraphQLFieldResolver, - Thunk, + ThunkObjMap, } from 'graphql'; /** @@ -79,8 +80,8 @@ export interface ConnectionConfig { nodeType: GraphQLNamedOutputType | GraphQLNonNull; resolveNode?: GraphQLFieldResolver; resolveCursor?: GraphQLFieldResolver; - edgeFields?: Thunk>; - connectionFields?: Thunk>; + edgeFields?: ThunkObjMap>; + connectionFields?: ThunkObjMap>; } export interface GraphQLConnectionDefinitions { @@ -88,13 +89,6 @@ export interface GraphQLConnectionDefinitions { connectionType: GraphQLObjectType; } -function resolveMaybeThunk(thingOrThunk: Thunk): T { - return typeof thingOrThunk === 'function' - ? // @ts-expect-error - if it's a function, we assume a thunk without arguments - thingOrThunk() - : thingOrThunk; -} - /** * Returns a GraphQLObjectType for a connection with the given name, * and whose nodes are of the specified type. @@ -118,7 +112,7 @@ export function connectionDefinitions( resolve: config.resolveCursor, description: 'A cursor for use in pagination', }, - ...resolveMaybeThunk(config.edgeFields ?? {}), + ...resolveObjMapThunk(config.edgeFields ?? {}), }), }); @@ -134,7 +128,7 @@ export function connectionDefinitions( type: new GraphQLList(edgeType), description: 'A list of edges.', }, - ...resolveMaybeThunk(config.connectionFields ?? {}), + ...resolveObjMapThunk(config.connectionFields ?? {}), }), }); diff --git a/src/mutation/__tests__/mutation-test.ts b/src/mutation/__tests__/mutation-test.ts index 80d0c52..ea5c508 100644 --- a/src/mutation/__tests__/mutation-test.ts +++ b/src/mutation/__tests__/mutation-test.ts @@ -8,6 +8,7 @@ import { GraphQLSchema, graphql, graphqlSync, + printType, printSchema, } from 'graphql'; @@ -39,7 +40,7 @@ function wrapInSchema(mutationFields: { } describe('mutationWithClientMutationId()', () => { - it('requires an argument', () => { + it.only('requires an argument', () => { const someMutation = mutationWithClientMutationId({ name: 'SomeMutation', inputFields: {}, @@ -48,24 +49,17 @@ describe('mutationWithClientMutationId()', () => { }, mutateAndGetPayload: dummyResolve, }); - const schema = wrapInSchema({ someMutation }); - const source = ` - mutation { - someMutation { - result - } - } - `; - expect(graphqlSync({ schema, source })).to.deep.equal({ - errors: [ - { - message: - 'Field "someMutation" argument "input" of type "SomeMutationInput!" is required, but it was not provided.', - locations: [{ line: 3, column: 9 }], - }, - ], + const wrapperType = new GraphQLObjectType({ + name: 'WrapperType', + fields: { someMutation }, }); + + expect(printType(wrapperType)).to.deep.equal(dedent` + type WrapperType { + someMutation(input: SomeMutationInput!): SomeMutationPayload + } + `); }); it('returns the same client mutation ID', () => { @@ -317,8 +311,7 @@ describe('mutationWithClientMutationId()', () => { const schema = wrapInSchema({ someMutation }); - // FIXME remove trimEnd after we update to `graphql@16.0.0` - expect(printSchema(schema).trimEnd()).to.deep.equal(dedent` + expect(printSchema(schema)).to.deep.equal(dedent` type Query { dummy: Int } diff --git a/src/mutation/mutation.ts b/src/mutation/mutation.ts index c1e1fef..c18ac12 100644 --- a/src/mutation/mutation.ts +++ b/src/mutation/mutation.ts @@ -3,26 +3,19 @@ import { GraphQLNonNull, GraphQLObjectType, GraphQLString, + resolveObjMapThunk, } from 'graphql'; import type { GraphQLFieldConfig, GraphQLFieldExtensions, - GraphQLInputFieldConfigMap, - GraphQLFieldConfigMap, + GraphQLInputFieldConfig, GraphQLResolveInfo, - Thunk, + ThunkObjMap, } from 'graphql'; type MutationFn = (object: any, ctx: any, info: GraphQLResolveInfo) => unknown; -function resolveMaybeThunk(thingOrThunk: Thunk): T { - return typeof thingOrThunk === 'function' - ? // @ts-expect-error - if it's a function, we assume a thunk without arguments - thingOrThunk() - : thingOrThunk; -} - /** * A description of a mutation consumable by mutationWithClientMutationId * to create a GraphQLFieldConfig for that mutation. @@ -42,8 +35,8 @@ interface MutationConfig { description?: string; deprecationReason?: string; extensions?: GraphQLFieldExtensions; - inputFields: Thunk; - outputFields: Thunk>; + inputFields: ThunkObjMap; + outputFields: ThunkObjMap>; mutateAndGetPayload: MutationFn; } @@ -56,13 +49,13 @@ export function mutationWithClientMutationId( ): GraphQLFieldConfig { const { name, inputFields, outputFields, mutateAndGetPayload } = config; const augmentedInputFields = () => ({ - ...resolveMaybeThunk(inputFields), + ...resolveObjMapThunk(inputFields), clientMutationId: { type: GraphQLString, }, }); const augmentedOutputFields = () => ({ - ...resolveMaybeThunk(outputFields), + ...resolveObjMapThunk(outputFields), clientMutationId: { type: GraphQLString, }, diff --git a/src/node/__tests__/global-test.ts b/src/node/__tests__/global-test.ts index 76a4772..9409af4 100644 --- a/src/node/__tests__/global-test.ts +++ b/src/node/__tests__/global-test.ts @@ -59,15 +59,15 @@ const { nodeField, nodeInterface } = nodeDefinitions( }, (obj) => { if (obj.name) { - return userType; + return userType.name; } if (obj.photoId) { - return photoType; + return photoType.name; } // istanbul ignore else (Can't be reached) if (obj.text) { - return postType; + return postType.name; } }, ); diff --git a/src/node/__tests__/node-test.ts b/src/node/__tests__/node-test.ts index cf8ebbe..68a3094 100644 --- a/src/node/__tests__/node-test.ts +++ b/src/node/__tests__/node-test.ts @@ -48,11 +48,11 @@ const { nodeField, nodesField, nodeInterface } = nodeDefinitions( }, (obj) => { if (userData.includes(obj)) { - return userType; + return userType.name; } // istanbul ignore else (Can't be reached) if (photoData.includes(obj)) { - return photoType; + return photoType.name; } }, ); @@ -315,8 +315,7 @@ describe('Node interface and fields', () => { }); it('generates correct types', () => { - // FIXME remove trimEnd after we update to `graphql@16.0.0` - expect(printSchema(schema).trimEnd()).to.deep.equal(dedent` + expect(printSchema(schema)).to.deep.equal(dedent` """An object with an ID""" interface Node { """The id of the object.""" diff --git a/src/node/__tests__/nodeAsync-test.ts b/src/node/__tests__/nodeAsync-test.ts index 19f5c9c..bdb3782 100644 --- a/src/node/__tests__/nodeAsync-test.ts +++ b/src/node/__tests__/nodeAsync-test.ts @@ -25,7 +25,7 @@ const userData = [ const { nodeField, nodeInterface } = nodeDefinitions( (id) => userData.find((obj) => obj.id === id), - () => userType, + () => userType.name, ); const userType: GraphQLObjectType = new GraphQLObjectType({ diff --git a/src/node/__tests__/plural-test.ts b/src/node/__tests__/plural-test.ts index dbfeb56..638a9c8 100644 --- a/src/node/__tests__/plural-test.ts +++ b/src/node/__tests__/plural-test.ts @@ -78,8 +78,7 @@ describe('pluralIdentifyingRootField()', () => { }); it('generates correct types', () => { - // FIXME remove trimEnd after we update to `graphql@16.0.0` - expect(printSchema(schema).trimEnd()).to.deep.equal(dedent` + expect(printSchema(schema)).to.deep.equal(dedent` type Query { """Map from a username to the user""" usernames(usernames: [String!]!): [User] From 76d3466d6b6ecaad2a241f5e86830e18227942da Mon Sep 17 00:00:00 2001 From: Ivan Goncharov Date: Fri, 17 Dec 2021 18:18:36 +0200 Subject: [PATCH 2/2] Remove accidental 'it.only' --- src/mutation/__tests__/mutation-test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mutation/__tests__/mutation-test.ts b/src/mutation/__tests__/mutation-test.ts index ea5c508..887be21 100644 --- a/src/mutation/__tests__/mutation-test.ts +++ b/src/mutation/__tests__/mutation-test.ts @@ -40,7 +40,7 @@ function wrapInSchema(mutationFields: { } describe('mutationWithClientMutationId()', () => { - it.only('requires an argument', () => { + it('requires an argument', () => { const someMutation = mutationWithClientMutationId({ name: 'SomeMutation', inputFields: {},