From b49653f8cd0dad0e67e54d54ac7a75b52f932da6 Mon Sep 17 00:00:00 2001 From: Yaacov Rydzinski Date: Tue, 5 Apr 2022 13:25:02 +0300 Subject: [PATCH] add implements to SDL for unions --- src/language/__tests__/schema-parser-test.ts | 21 ++++++++++++++++++++ src/language/ast.ts | 12 +++++++++-- src/language/parser.ts | 10 +++++++++- 3 files changed, 40 insertions(+), 3 deletions(-) diff --git a/src/language/__tests__/schema-parser-test.ts b/src/language/__tests__/schema-parser-test.ts index cbb337c337a..46cc0248b92 100644 --- a/src/language/__tests__/schema-parser-test.ts +++ b/src/language/__tests__/schema-parser-test.ts @@ -230,6 +230,24 @@ describe('Schema Parser', () => { }); }); + it('Union extension without types', () => { + const doc = parse('extend union HelloOrGoodbye implements Greeting'); + expectJSON(doc).toDeepEqual({ + kind: 'Document', + definitions: [ + { + kind: 'UnionTypeExtension', + name: nameNode('HelloOrGoodbye', { start: 13, end: 27 }), + interfaces: [typeNode('Greeting', { start: 39, end: 47 })], + directives: [], + types: [], + loc: { start: 0, end: 47 }, + }, + ], + loc: { start: 0, end: 47 }, + }); + }); + it('Object extension without fields followed by extension', () => { const doc = parse(` extend type Hello implements Greeting @@ -880,6 +898,7 @@ describe('Schema Parser', () => { kind: 'UnionTypeDefinition', name: nameNode('Hello', { start: 6, end: 11 }), description: undefined, + interfaces: [], directives: [], types: [typeNode('World', { start: 14, end: 19 })], loc: { start: 0, end: 19 }, @@ -899,6 +918,7 @@ describe('Schema Parser', () => { kind: 'UnionTypeDefinition', name: nameNode('Hello', { start: 6, end: 11 }), description: undefined, + interfaces: [], directives: [], types: [ typeNode('Wo', { start: 14, end: 16 }), @@ -921,6 +941,7 @@ describe('Schema Parser', () => { kind: 'UnionTypeDefinition', name: nameNode('Hello', { start: 6, end: 11 }), description: undefined, + interfaces: [], directives: [], types: [ typeNode('Wo', { start: 16, end: 18 }), diff --git a/src/language/ast.ts b/src/language/ast.ts index 0b30366df09..996ada86323 100644 --- a/src/language/ast.ts +++ b/src/language/ast.ts @@ -262,7 +262,13 @@ export const QueryDocumentKeys: { 'directives', 'fields', ], - UnionTypeDefinition: ['description', 'name', 'directives', 'types'], + UnionTypeDefinition: [ + 'description', + 'name', + 'interfaces', + 'directives', + 'types', + ], EnumTypeDefinition: ['description', 'name', 'directives', 'values'], EnumValueDefinition: ['description', 'name', 'directives'], InputObjectTypeDefinition: ['description', 'name', 'directives', 'fields'], @@ -274,7 +280,7 @@ export const QueryDocumentKeys: { ScalarTypeExtension: ['name', 'directives'], ObjectTypeExtension: ['name', 'interfaces', 'directives', 'fields'], InterfaceTypeExtension: ['name', 'interfaces', 'directives', 'fields'], - UnionTypeExtension: ['name', 'directives', 'types'], + UnionTypeExtension: ['name', 'interfaces', 'directives', 'types'], EnumTypeExtension: ['name', 'directives', 'values'], InputObjectTypeExtension: ['name', 'directives', 'fields'], }; @@ -624,6 +630,7 @@ export interface UnionTypeDefinitionNode { readonly loc?: Location; readonly description?: StringValueNode; readonly name: NameNode; + readonly interfaces?: ReadonlyArray; readonly directives?: ReadonlyArray; readonly types?: ReadonlyArray; } @@ -716,6 +723,7 @@ export interface UnionTypeExtensionNode { readonly kind: Kind.UNION_TYPE_EXTENSION; readonly loc?: Location; readonly name: NameNode; + readonly interfaces?: ReadonlyArray; readonly directives?: ReadonlyArray; readonly types?: ReadonlyArray; } diff --git a/src/language/parser.ts b/src/language/parser.ts index 282ee168596..dcf60dc0195 100644 --- a/src/language/parser.ts +++ b/src/language/parser.ts @@ -970,12 +970,14 @@ export class Parser { const description = this.parseDescription(); this.expectKeyword('union'); const name = this.parseName(); + const interfaces = this.parseImplementsInterfaces(); const directives = this.parseConstDirectives(); const types = this.parseUnionMemberTypes(); return this.node(start, { kind: Kind.UNION_TYPE_DEFINITION, description, name, + interfaces, directives, types, }); @@ -1249,14 +1251,20 @@ export class Parser { this.expectKeyword('extend'); this.expectKeyword('union'); const name = this.parseName(); + const interfaces = this.parseImplementsInterfaces(); const directives = this.parseConstDirectives(); const types = this.parseUnionMemberTypes(); - if (directives.length === 0 && types.length === 0) { + if ( + interfaces.length === 0 && + directives.length === 0 && + types.length === 0 + ) { throw this.unexpected(); } return this.node(start, { kind: Kind.UNION_TYPE_EXTENSION, name, + interfaces, directives, types, });