From 63bc010acae40fd5026dd7f7a3ad0752c60c27c8 Mon Sep 17 00:00:00 2001 From: Ivan Goncharov Date: Mon, 13 Mar 2017 16:43:37 +0200 Subject: [PATCH] Add support for appliedDirectives in extendSchema --- src/utilities/extendSchema.js | 43 +++++++++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/src/utilities/extendSchema.js b/src/utilities/extendSchema.js index 77c45b383a4..9bacfaf577a 100644 --- a/src/utilities/extendSchema.js +++ b/src/utilities/extendSchema.js @@ -28,6 +28,7 @@ import { GraphQLScalarType, GraphQLEnumType, GraphQLInputObjectType, + GraphQLAppliedDirectives, isInputType, isOutputType, } from '../type/definition'; @@ -82,6 +83,7 @@ import type { import type { DocumentNode, + DirectiveNode, InputValueDefinitionNode, TypeNode, NamedTypeNode, @@ -95,6 +97,7 @@ import type { DirectiveDefinitionNode, } from '../language/ast'; +import { getArgumentValues } from '../execution/values'; /** * Produces a new schema given an existing schema and a document which may @@ -245,15 +248,37 @@ export function extendSchema( types.push(getTypeFromAST(typeDefinitionMap[typeName])); }); + const directives = getMergedDirectives(); + const innerDirectivesMap = keyValMap( + directives, + directive => directive.name, + directive => directive + ); + // Then produce and return a Schema with these types. return new GraphQLSchema({ query: queryType, mutation: mutationType, subscription: subscriptionType, types, - directives: getMergedDirectives(), + directives, }); + function makeAppliedDirectives(appliedDirectives: ?Array) { + return appliedDirectives && new GraphQLAppliedDirectives(keyValMap( + appliedDirectives, + directive => directive.name.value, + directive => (() => { + const directiveName = directive.name.value; + if (!innerDirectivesMap[directiveName]) { + throw new Error( + `Directive "${directiveName}" not found in document.`); + } + return getArgumentValues(innerDirectivesMap[directiveName], directive); + }) + )); + } + // Below are functions used for producing this schema that have closed over // this scope and have access to the schema, cache, and newly defined types. @@ -353,6 +378,7 @@ export function extendSchema( description: type.description, interfaces: () => extendImplementedInterfaces(type), fields: () => extendFieldMap(type), + appliedDirectives: type.appliedDirectives, isTypeOf: type.isTypeOf, }); } @@ -364,6 +390,7 @@ export function extendSchema( name: type.name, description: type.description, fields: () => extendFieldMap(type), + appliedDirectives: type.appliedDirectives, resolveType: type.resolveType, }); } @@ -373,6 +400,7 @@ export function extendSchema( name: type.name, description: type.description, types: type.getTypes().map(getTypeFromDef), + appliedDirectives: type.appliedDirectives, resolveType: type.resolveType, }); } @@ -413,6 +441,7 @@ export function extendSchema( deprecationReason: field.deprecationReason, type: extendFieldType(field.type), args: keyMap(field.args, arg => arg.name), + appliedDirectives: field.appliedDirectives, resolve: field.resolve, }; }); @@ -435,6 +464,7 @@ export function extendSchema( type: buildOutputFieldType(field.type), args: buildInputValues(field.arguments), deprecationReason: getDeprecationReason(field.directives), + appliedDirectives: makeAppliedDirectives(field.directives), }; }); }); @@ -471,6 +501,7 @@ export function extendSchema( description: getDescription(typeNode), interfaces: () => buildImplementedInterfaces(typeNode), fields: () => buildFieldMap(typeNode), + appliedDirectives: makeAppliedDirectives(typeNode.directives), }); } @@ -479,6 +510,7 @@ export function extendSchema( name: typeNode.name.value, description: getDescription(typeNode), fields: () => buildFieldMap(typeNode), + appliedDirectives: makeAppliedDirectives(typeNode.directives), resolveType: cannotExecuteExtendedSchema, }); } @@ -488,6 +520,7 @@ export function extendSchema( name: typeNode.name.value, description: getDescription(typeNode), types: typeNode.types.map(getObjectTypeFromAST), + appliedDirectives: makeAppliedDirectives(typeNode.directives), resolveType: cannotExecuteExtendedSchema, }); } @@ -496,6 +529,7 @@ export function extendSchema( return new GraphQLScalarType({ name: typeNode.name.value, description: getDescription(typeNode), + appliedDirectives: makeAppliedDirectives(typeNode.directives), serialize: id => id, // Note: validation calls the parse functions to determine if a // literal value is correct. Returning null would cause use of custom @@ -516,8 +550,10 @@ export function extendSchema( enumValue => ({ description: getDescription(enumValue), deprecationReason: getDeprecationReason(enumValue.directives), + appliedDirectives: makeAppliedDirectives(enumValue.directives), }), ), + appliedDirectives: makeAppliedDirectives(typeNode.directives), }); } @@ -526,6 +562,7 @@ export function extendSchema( name: typeNode.name.value, description: getDescription(typeNode), fields: () => buildInputValues(typeNode.fields), + appliedDirectives: makeAppliedDirectives(typeNode.directives), }); } @@ -556,6 +593,7 @@ export function extendSchema( description: getDescription(field), args: buildInputValues(field.arguments), deprecationReason: getDeprecationReason(field.directives), + appliedDirectives: makeAppliedDirectives(field.directives), }) ); } @@ -569,7 +607,8 @@ export function extendSchema( return { type, description: getDescription(value), - defaultValue: valueFromAST(value.defaultValue, type) + defaultValue: valueFromAST(value.defaultValue, type), + appliedDirectives: makeAppliedDirectives(value.directives), }; } );