diff --git a/CHANGELOG.md b/CHANGELOG.md index a7afc7f607..a2b20504f0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,7 +17,7 @@ - `apollo-env` - - `apollo-graphql` - - + - buildSchemaFromSDL - support meta fields on abstract types [#1330](https://github.com/apollographql/apollo-tooling/pull/1330) - `apollo-language-server` - - `apollo-tools` diff --git a/packages/apollo-graphql/src/schema/__tests__/buildSchemaFromSDL.test.ts b/packages/apollo-graphql/src/schema/__tests__/buildSchemaFromSDL.test.ts index aa5597d428..025317589f 100644 --- a/packages/apollo-graphql/src/schema/__tests__/buildSchemaFromSDL.test.ts +++ b/packages/apollo-graphql/src/schema/__tests__/buildSchemaFromSDL.test.ts @@ -4,7 +4,8 @@ import { GraphQLSchema, GraphQLDirective, DirectiveLocation, - GraphQLObjectType + GraphQLObjectType, + GraphQLAbstractType } from "graphql"; import astSerializer from "./snapshotSerializers/astSerializer"; @@ -345,6 +346,7 @@ type MutationRoot { ); }); }); + describe(`resolvers`, () => { it(`should add a resolver for a field`, () => { const name = () => {}; @@ -372,5 +374,53 @@ type MutationRoot { expect(nameField.resolve).toEqual(name); }); + + it(`should add meta fields to abstract types`, () => { + const typeDefs = gql` + union Animal = Dog + + interface Creature { + name: String! + legs: Int! + } + + type Dog { + id: ID! + } + + type Cat implements Creature { + meow: Boolean! + } + `; + + const resolveTypeUnion = (obj: any) => { + return "Dog"; + }; + + const resolveTypeInterface = (obj: any) => { + if (obj.meow) { + return "Cat"; + } + throw Error("Couldn't resolve interface"); + }; + + const resolvers = { + Animal: { + __resolveType: resolveTypeUnion + }, + Creature: { + __resolveType: resolveTypeInterface + } + }; + + const schema = buildSchemaFromSDL([{ typeDefs, resolvers }]); + const animalUnion = schema.getType("Animal") as GraphQLAbstractType; + const creatureInterface = schema.getType( + "Creature" + ) as GraphQLAbstractType; + + expect(animalUnion.resolveType).toBe(resolveTypeUnion); + expect(creatureInterface.resolveType).toBe(resolveTypeInterface); + }); }); }); diff --git a/packages/apollo-graphql/src/schema/buildSchemaFromSDL.ts b/packages/apollo-graphql/src/schema/buildSchemaFromSDL.ts index ef84762d1b..76d33e1bec 100644 --- a/packages/apollo-graphql/src/schema/buildSchemaFromSDL.ts +++ b/packages/apollo-graphql/src/schema/buildSchemaFromSDL.ts @@ -13,7 +13,8 @@ import { SchemaDefinitionNode, SchemaExtensionNode, OperationTypeNode, - GraphQLObjectType + GraphQLObjectType, + isAbstractType } from "graphql"; import { validateSDL } from "graphql/validation/validate"; import { isDocumentNode, isNode } from "../utilities/graphql"; @@ -206,6 +207,15 @@ export function addResolversToSchema( ) { for (const [typeName, fieldConfigs] of Object.entries(resolvers)) { const type = schema.getType(typeName); + + if (isAbstractType(type)) { + for (const [fieldName, fieldConfig] of Object.entries(fieldConfigs)) { + if (fieldName.startsWith("__")) { + (type as any)[fieldName.substring(2)] = fieldConfig; + } + } + } + if (!isObjectType(type)) continue; const fieldMap = type.getFields();