diff --git a/src/utilities/__tests__/buildClientSchema-test.ts b/src/utilities/__tests__/buildClientSchema-test.ts index 818198bf7b..b6b433626d 100644 --- a/src/utilities/__tests__/buildClientSchema-test.ts +++ b/src/utilities/__tests__/buildClientSchema-test.ts @@ -571,6 +571,21 @@ describe('Type System: build schema from introspection', () => { expect(cycleIntrospection(sdl)).to.equal(sdl); }); + it('builds a schema with @oneOf directive', () => { + const sdl = dedent` + type Query { + someField(someArg: SomeInputObject): String + } + + input SomeInputObject @oneOf { + someInputField1: String + someInputField2: String + } + `; + + expect(cycleIntrospection(sdl)).to.equal(sdl); + }); + it('can use client schema for limited execution', () => { const schema = buildSchema(` scalar CustomScalar diff --git a/src/utilities/__tests__/getIntrospectionQuery-test.ts b/src/utilities/__tests__/getIntrospectionQuery-test.ts index 62f64c968e..b8e59fcd0c 100644 --- a/src/utilities/__tests__/getIntrospectionQuery-test.ts +++ b/src/utilities/__tests__/getIntrospectionQuery-test.ts @@ -117,6 +117,14 @@ describe('getIntrospectionQuery', () => { ); }); + it('include "isOneOf" field on input objects', () => { + expectIntrospectionQuery().toNotMatch('isOneOf'); + + expectIntrospectionQuery({ inputObjectOneOf: true }).toMatch('isOneOf', 1); + + expectIntrospectionQuery({ inputObjectOneOf: false }).toNotMatch('isOneOf'); + }); + it('include deprecated input field and args', () => { expectIntrospectionQuery().toMatch('includeDeprecated: true', 2); diff --git a/src/utilities/buildClientSchema.ts b/src/utilities/buildClientSchema.ts index ab50728554..16d7ecfe18 100644 --- a/src/utilities/buildClientSchema.ts +++ b/src/utilities/buildClientSchema.ts @@ -311,6 +311,7 @@ export function buildClientSchema( name: inputObjectIntrospection.name, description: inputObjectIntrospection.description, fields: () => buildInputValueDefMap(inputObjectIntrospection.inputFields), + isOneOf: inputObjectIntrospection.isOneOf, }); } diff --git a/src/utilities/getIntrospectionQuery.ts b/src/utilities/getIntrospectionQuery.ts index 5eb182bc36..2305a8cc8b 100644 --- a/src/utilities/getIntrospectionQuery.ts +++ b/src/utilities/getIntrospectionQuery.ts @@ -32,6 +32,12 @@ export interface IntrospectionOptions { * Default: false */ inputValueDeprecation?: boolean; + + /** + * Whether target GraphQL server supports `@oneOf` input objects. + * Default: false + */ + inputObjectOneOf?: boolean; } /** @@ -45,6 +51,7 @@ export function getIntrospectionQuery(options?: IntrospectionOptions): string { directiveIsRepeatable: false, schemaDescription: false, inputValueDeprecation: false, + inputObjectOneOf: false, ...options, }; @@ -62,6 +69,7 @@ export function getIntrospectionQuery(options?: IntrospectionOptions): string { function inputDeprecation(str: string) { return optionsWithDefault.inputValueDeprecation ? str : ''; } + const inputObjectOneOf = optionsWithDefault.inputObjectOneOf ? 'isOneOf' : ''; return ` query IntrospectionQuery { @@ -90,6 +98,7 @@ export function getIntrospectionQuery(options?: IntrospectionOptions): string { name ${descriptions} ${specifiedByUrl} + ${inputObjectOneOf} fields(includeDeprecated: true) { name ${descriptions} @@ -259,6 +268,7 @@ export interface IntrospectionInputObjectType { readonly name: string; readonly description?: Maybe; readonly inputFields: ReadonlyArray; + readonly isOneOf: boolean; } export interface IntrospectionListTypeRef< diff --git a/src/utilities/introspectionFromSchema.ts b/src/utilities/introspectionFromSchema.ts index 041a0ce489..f4ae3f7512 100644 --- a/src/utilities/introspectionFromSchema.ts +++ b/src/utilities/introspectionFromSchema.ts @@ -30,6 +30,7 @@ export function introspectionFromSchema( directiveIsRepeatable: true, schemaDescription: true, inputValueDeprecation: true, + inputObjectOneOf: true, ...options, };