Skip to content

Commit ee2353e

Browse files
fix(interfaces): support GraphQL extensions (#1776)
Co-authored-by: Michał Lytek <[email protected]>
1 parent 42e1a8a commit ee2353e

File tree

2 files changed

+118
-0
lines changed

2 files changed

+118
-0
lines changed

src/schema/schema-generator.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,7 @@ export abstract class SchemaGenerator {
405405
name: interfaceType.name,
406406
description: interfaceType.description,
407407
astNode: getInterfaceTypeDefinitionNode(interfaceType.name, interfaceType.directives),
408+
extensions: interfaceType.extensions,
408409
interfaces: () => {
409410
let interfaces = (interfaceType.interfaceClasses || []).map<GraphQLInterfaceType>(
410411
interfaceClass =>

tests/functional/extensions.ts

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import "reflect-metadata";
22
import {
33
type GraphQLFieldMap,
44
type GraphQLInputObjectType,
5+
GraphQLInterfaceType,
56
type GraphQLObjectType,
67
type GraphQLSchema,
78
} from "graphql";
@@ -11,6 +12,7 @@ import {
1112
Field,
1213
FieldResolver,
1314
InputType,
15+
InterfaceType,
1416
Mutation,
1517
ObjectType,
1618
Query,
@@ -90,6 +92,29 @@ describe("Extensions", () => {
9092
}
9193
}
9294

95+
@InterfaceType()
96+
@Extensions({ meta: "interfaceExtensionData" })
97+
class SampleInterfaceType {
98+
@Field()
99+
@Extensions({ meta: "interfaceFieldExtensionData" })
100+
withInterfaceFieldExtension!: string;
101+
}
102+
103+
@ObjectType({
104+
implements: [SampleInterfaceType],
105+
})
106+
class SampleObjectInterfaceImplementation extends SampleInterfaceType {}
107+
108+
@InterfaceType({
109+
implements: [SampleInterfaceType],
110+
})
111+
class SampleInterfaceInterfaceImplementation extends SampleInterfaceType {}
112+
113+
@ObjectType({
114+
implements: [SampleInterfaceInterfaceImplementation],
115+
})
116+
class SampleObjectInterfaceInterfaceImplementation extends SampleInterfaceInterfaceImplementation {}
117+
93118
@Resolver()
94119
class SampleResolver {
95120
@Query(() => SampleObjectType)
@@ -102,6 +127,26 @@ describe("Extensions", () => {
102127
return new ExtensionsOnClassObjectType();
103128
}
104129

130+
@Query(() => SampleObjectInterfaceImplementation)
131+
sampleObjectInterfaceImplementation(): SampleObjectInterfaceImplementation {
132+
return new SampleObjectInterfaceImplementation();
133+
}
134+
135+
@Query(() => SampleInterfaceInterfaceImplementation)
136+
sampleInterfaceInterfaceImplementation(): SampleInterfaceInterfaceImplementation {
137+
return new SampleInterfaceInterfaceImplementation();
138+
}
139+
140+
@Query(() => SampleObjectInterfaceInterfaceImplementation)
141+
sampleObjectInterfaceInterfaceImplementation(): SampleObjectInterfaceInterfaceImplementation {
142+
return new SampleObjectInterfaceInterfaceImplementation();
143+
}
144+
145+
@Query(() => SampleInterfaceType)
146+
sampleInterfaceType(): SampleInterfaceType {
147+
return new SampleObjectInterfaceImplementation();
148+
}
149+
105150
@Query()
106151
@Extensions({ mandatory: true })
107152
queryWithExtensions(): string {
@@ -269,6 +314,78 @@ describe("Extensions", () => {
269314
});
270315
});
271316

317+
describe("Interface Fields", () => {
318+
it("should add extensions to interface types", async () => {
319+
const fields = (schema.getType("SampleInterfaceType") as GraphQLObjectType).getFields();
320+
expect(fields.withInterfaceFieldExtension.extensions).toEqual({
321+
meta: "interfaceFieldExtensionData",
322+
});
323+
});
324+
325+
it("should add extensions to ObjectType which extends InterfaceType", async () => {
326+
const fields = (
327+
schema.getType("SampleObjectInterfaceImplementation") as GraphQLObjectType
328+
).getFields();
329+
expect(fields.withInterfaceFieldExtension.extensions).toEqual({
330+
meta: "interfaceFieldExtensionData",
331+
});
332+
});
333+
334+
it("should add extensions to Interface which extends InterfaceType", async () => {
335+
const fields = (
336+
schema.getType("SampleInterfaceInterfaceImplementation") as GraphQLObjectType
337+
).getFields();
338+
expect(fields.withInterfaceFieldExtension.extensions).toEqual({
339+
meta: "interfaceFieldExtensionData",
340+
});
341+
});
342+
343+
it("should add extensions to ObjectType which extends InterfaceType which extends InterfaceType", async () => {
344+
const fields = (
345+
schema.getType("SampleInterfaceInterfaceImplementation") as GraphQLObjectType
346+
).getFields();
347+
expect(fields.withInterfaceFieldExtension.extensions).toEqual({
348+
meta: "interfaceFieldExtensionData",
349+
});
350+
});
351+
});
352+
353+
describe("Interface Class", () => {
354+
it("should add extensions to interface types", async () => {
355+
const sampleInterface = schema.getType("SampleInterfaceType") as GraphQLInterfaceType;
356+
expect(sampleInterface.extensions).toEqual({
357+
meta: "interfaceExtensionData",
358+
});
359+
});
360+
361+
it("should add extensions to ObjectType which extends InterfaceType", async () => {
362+
const sampleInterface = schema.getType(
363+
"SampleObjectInterfaceImplementation",
364+
) as GraphQLInterfaceType;
365+
expect(sampleInterface.extensions).toEqual({
366+
meta: "interfaceExtensionData",
367+
});
368+
});
369+
370+
it("should add extensions to InterfaceType which extends InterfaceType", async () => {
371+
const sampleInterface = schema.getType(
372+
"SampleInterfaceInterfaceImplementation",
373+
) as GraphQLInterfaceType;
374+
expect(sampleInterface.extensions).toEqual({
375+
meta: "interfaceExtensionData",
376+
});
377+
});
378+
379+
it("should add extensions to ObjectType which extends InterfaceType which extends InterfaceType", async () => {
380+
const sampleInterface = schema.getType(
381+
"SampleObjectInterfaceInterfaceImplementation",
382+
) as GraphQLInterfaceType;
383+
expect(sampleInterface.extensions).toEqual({
384+
meta: "interfaceExtensionData",
385+
});
386+
});
387+
});
388+
272389
describe("Inheritance", () => {
273390
beforeAll(async () => {
274391
getMetadataStorage().clear();

0 commit comments

Comments
 (0)