From 94ec0820a1e11abc0f6a2937bcde47afdc1259b1 Mon Sep 17 00:00:00 2001 From: Ivan Goncharov Date: Tue, 10 May 2022 13:48:07 +0300 Subject: [PATCH] validateSchema: unify check of root types --- src/jsutils/__tests__/capitalize-test.ts | 21 ++++++++++++ src/jsutils/capitalize.ts | 6 ++++ src/type/validate.ts | 43 +++++++++--------------- 3 files changed, 43 insertions(+), 27 deletions(-) create mode 100644 src/jsutils/__tests__/capitalize-test.ts create mode 100644 src/jsutils/capitalize.ts diff --git a/src/jsutils/__tests__/capitalize-test.ts b/src/jsutils/__tests__/capitalize-test.ts new file mode 100644 index 0000000000..48ae886c11 --- /dev/null +++ b/src/jsutils/__tests__/capitalize-test.ts @@ -0,0 +1,21 @@ +import { expect } from 'chai'; +import { describe, it } from 'mocha'; + +import { capitalize } from '../capitalize'; + +describe('capitalize', () => { + it('Converts the first character of string to upper case and the remaining to lower case', () => { + expect(capitalize('')).to.equal(''); + + expect(capitalize('a')).to.equal('A'); + expect(capitalize('A')).to.equal('A'); + + expect(capitalize('ab')).to.equal('Ab'); + expect(capitalize('aB')).to.equal('Ab'); + expect(capitalize('Ab')).to.equal('Ab'); + expect(capitalize('AB')).to.equal('Ab'); + + expect(capitalize('platypus')).to.equal('Platypus'); + expect(capitalize('PLATYPUS')).to.equal('Platypus'); + }); +}); diff --git a/src/jsutils/capitalize.ts b/src/jsutils/capitalize.ts new file mode 100644 index 0000000000..064dddcf0f --- /dev/null +++ b/src/jsutils/capitalize.ts @@ -0,0 +1,6 @@ +/** + * Converts the first character of string to upper case and the remaining to lower case. + */ +export function capitalize(str: string): string { + return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase(); +} diff --git a/src/type/validate.ts b/src/type/validate.ts index 126e97d980..9ce665435a 100644 --- a/src/type/validate.ts +++ b/src/type/validate.ts @@ -1,3 +1,4 @@ +import { capitalize } from '../jsutils/capitalize'; import { inspect } from '../jsutils/inspect'; import type { Maybe } from '../jsutils/Maybe'; @@ -112,37 +113,25 @@ class SchemaValidationContext { function validateRootTypes(context: SchemaValidationContext): void { const schema = context.schema; - const queryType = schema.getQueryType(); - if (!queryType) { + + if (schema.getQueryType() == null) { context.reportError('Query root type must be provided.', schema.astNode); - } else if (!isObjectType(queryType)) { - context.reportError( - `Query root type must be Object type, it cannot be ${inspect( - queryType, - )}.`, - getOperationTypeNode(schema, OperationTypeNode.QUERY) ?? - (queryType as any).astNode, - ); } - const mutationType = schema.getMutationType(); - if (mutationType && !isObjectType(mutationType)) { - context.reportError( - 'Mutation root type must be Object type if provided, it cannot be ' + - `${inspect(mutationType)}.`, - getOperationTypeNode(schema, OperationTypeNode.MUTATION) ?? - (mutationType as any).astNode, - ); - } + for (const operationType of Object.values(OperationTypeNode)) { + const rootType = schema.getRootType(operationType); - const subscriptionType = schema.getSubscriptionType(); - if (subscriptionType && !isObjectType(subscriptionType)) { - context.reportError( - 'Subscription root type must be Object type if provided, it cannot be ' + - `${inspect(subscriptionType)}.`, - getOperationTypeNode(schema, OperationTypeNode.SUBSCRIPTION) ?? - (subscriptionType as any).astNode, - ); + if (rootType != null && !isObjectType(rootType)) { + const operationTypeStr = capitalize(operationType); + const rootTypeStr = inspect(rootType); + context.reportError( + operationType === OperationTypeNode.QUERY + ? `${operationTypeStr} root type must be Object type, it cannot be ${rootTypeStr}.` + : `${operationTypeStr} root type must be Object type if provided, it cannot be ${rootTypeStr}.`, + getOperationTypeNode(schema, operationType) ?? + (rootType as any).astNode, + ); + } } }