From 1597f5d89cd5350d262180a17d4d236e039af56c Mon Sep 17 00:00:00 2001 From: Ivan Goncharov Date: Sat, 20 Jun 2020 20:32:52 +0300 Subject: [PATCH] buildSchema: allow to reference introspection types (#2608) --- src/utilities/__tests__/buildASTSchema-test.js | 17 ++++++++++++++++- .../__tests__/KnownTypeNamesRule-test.js | 13 ++++++++++--- src/validation/rules/KnownTypeNamesRule.js | 14 +++++++++----- 3 files changed, 35 insertions(+), 9 deletions(-) diff --git a/src/utilities/__tests__/buildASTSchema-test.js b/src/utilities/__tests__/buildASTSchema-test.js index 1d74e35695..2bb6a32e21 100644 --- a/src/utilities/__tests__/buildASTSchema-test.js +++ b/src/utilities/__tests__/buildASTSchema-test.js @@ -12,7 +12,7 @@ import { parse } from '../../language/parser'; import { print } from '../../language/printer'; import { validateSchema } from '../../type/validate'; -import { __Schema } from '../../type/introspection'; +import { __Schema, __EnumValue } from '../../type/introspection'; import { assertDirective, GraphQLSkipDirective, @@ -1089,6 +1089,21 @@ describe('Schema Builder', () => { expect(schema.getType('__Schema')).to.equal(__Schema); }); + it('Allows to reference introspection types', () => { + const schema = buildSchema(` + type Query { + introspectionField: __EnumValue + } + `); + + const queryType = assertObjectType(schema.getType('Query')); + expect(queryType.getFields()).to.have.nested.property( + 'introspectionField.type', + __EnumValue, + ); + expect(schema.getType('__EnumValue')).to.equal(__EnumValue); + }); + it('Rejects invalid SDL', () => { const sdl = ` type Query { diff --git a/src/validation/__tests__/KnownTypeNamesRule-test.js b/src/validation/__tests__/KnownTypeNamesRule-test.js index adfe354a28..584ecab119 100644 --- a/src/validation/__tests__/KnownTypeNamesRule-test.js +++ b/src/validation/__tests__/KnownTypeNamesRule-test.js @@ -35,11 +35,16 @@ function expectValidSDL(sdlStr, schema) { describe('Validate: Known type names', () => { it('known type names are valid', () => { expectValid(` - query Foo($var: String, $required: [String!]!) { + query Foo( + $var: String + $required: [Int!]! + $introspectionType: __EnumValue + ) { user(id: 4) { pets { ... on Pet { name }, ...PetFields, ... { name } } } } + fragment PetFields on Pet { name } @@ -97,7 +102,7 @@ describe('Validate: Known type names', () => { }); describe('within SDL', () => { - it('use standard scalars', () => { + it('use standard types', () => { expectValidSDL(` type Query { string: String @@ -105,6 +110,7 @@ describe('Validate: Known type names', () => { float: Float boolean: Boolean id: ID + introspectionType: __EnumValue } `); }); @@ -239,7 +245,7 @@ describe('Validate: Known type names', () => { ]); }); - it('reference standard scalars inside extension document', () => { + it('reference standard types inside extension document', () => { const schema = buildSchema('type Foo'); const sdl = ` type SomeType { @@ -248,6 +254,7 @@ describe('Validate: Known type names', () => { float: Float boolean: Boolean id: ID + introspectionType: __EnumValue } `; diff --git a/src/validation/rules/KnownTypeNamesRule.js b/src/validation/rules/KnownTypeNamesRule.js index de602ec596..d8a0ad75d9 100644 --- a/src/validation/rules/KnownTypeNamesRule.js +++ b/src/validation/rules/KnownTypeNamesRule.js @@ -14,6 +14,7 @@ import { } from '../../language/predicates'; import { specifiedScalarTypes } from '../../type/scalars'; +import { introspectionTypes } from '../../type/introspection'; import type { ValidationContext, @@ -49,13 +50,13 @@ export function KnownTypeNamesRule( if (!existingTypesMap[typeName] && !definedTypes[typeName]) { const definitionNode = ancestors[2] ?? parent; const isSDL = definitionNode != null && isSDLNode(definitionNode); - if (isSDL && isSpecifiedScalarName(typeName)) { + if (isSDL && isStandardTypeName(typeName)) { return; } const suggestedTypes = suggestionList( typeName, - isSDL ? specifiedScalarsNames.concat(typeNames) : typeNames, + isSDL ? standardTypeNames.concat(typeNames) : typeNames, ); context.reportError( new GraphQLError( @@ -68,9 +69,12 @@ export function KnownTypeNamesRule( }; } -const specifiedScalarsNames = specifiedScalarTypes.map((type) => type.name); -function isSpecifiedScalarName(typeName) { - return specifiedScalarsNames.indexOf(typeName) !== -1; +const standardTypeNames = [...specifiedScalarTypes, ...introspectionTypes].map( + (type) => type.name, +); + +function isStandardTypeName(typeName) { + return standardTypeNames.indexOf(typeName) !== -1; } function isSDLNode(value: ASTNode | $ReadOnlyArray): boolean {