@@ -15,6 +15,14 @@ import {
1515 GraphQLEnumValueConfigMap ,
1616 GraphQLUnionType ,
1717 GraphQLTypeResolver ,
18+ GraphQLDirective ,
19+ GraphQLNonNull ,
20+ DirectiveNode ,
21+ ObjectTypeExtensionNode ,
22+ ObjectTypeDefinitionNode ,
23+ FieldDefinitionNode ,
24+ specifiedDirectives ,
25+ ArgumentNode ,
1826} from "graphql" ;
1927import { withFilter , ResolverFn } from "graphql-subscriptions" ;
2028
@@ -40,9 +48,13 @@ import {
4048 ConflictingDefaultValuesError ,
4149 InterfaceResolveTypeError ,
4250} from "../errors" ;
43- import { ResolverFilterData , ResolverTopicData , TypeResolver } from "../interfaces" ;
51+ import { ResolverFilterData , ResolverTopicData , TypeResolver , Maybe } from "../interfaces" ;
4452import { getFieldMetadataFromInputType , getFieldMetadataFromObjectType } from "./utils" ;
4553import { ensureInstalledCorrectGraphQLPackage } from "../utils/graphql-version" ;
54+ import {
55+ DirectiveClassMetadata ,
56+ DirectiveFieldMetadata ,
57+ } from "../metadata/definitions/directive-metadata" ;
4658
4759interface AbstractInfo {
4860 isAbstract : boolean ;
@@ -73,6 +85,7 @@ export interface SchemaGeneratorOptions extends BuildContextOptions {
7385 * Disable checking on build the correctness of a schema
7486 */
7587 skipCheck ?: boolean ;
88+ directives ?: GraphQLDirective [ ] ;
7689}
7790
7891export abstract class SchemaGenerator {
@@ -104,6 +117,7 @@ export abstract class SchemaGenerator {
104117 mutation : this . buildRootMutationType ( ) ,
105118 subscription : this . buildRootSubscriptionType ( ) ,
106119 types : this . buildOtherTypes ( ) ,
120+ directives : options . directives ,
107121 } ) ;
108122
109123 BuildContext . reset ( ) ;
@@ -255,12 +269,66 @@ export abstract class SchemaGenerator {
255269 return superClassTypeInfo ? superClassTypeInfo . type : undefined ;
256270 } ;
257271 const interfaceClasses = objectType . interfaceClasses || [ ] ;
272+
273+ const classDirectiveAstNodes = (
274+ name : string ,
275+ classMetas ?: DirectiveClassMetadata [ ] ,
276+ ) : ObjectTypeDefinitionNode | undefined => {
277+ if ( ! classMetas || ! classMetas . length ) {
278+ return ;
279+ }
280+
281+ const directives : DirectiveNode [ ] = classMetas . map ( meta =>
282+ this . createDirective ( meta . name , meta . args ) ,
283+ ) ;
284+
285+ return {
286+ kind : "ObjectTypeDefinition" ,
287+ name : {
288+ kind : "Name" ,
289+ value : name ,
290+ } ,
291+ interfaces : [ ] ,
292+ directives,
293+ } ;
294+ } ;
295+
296+ const fieldDirectiveAstNodes = (
297+ name : string ,
298+ fieldMetas ?: DirectiveFieldMetadata [ ] ,
299+ ) : FieldDefinitionNode | undefined => {
300+ if ( ! fieldMetas || ! fieldMetas . length ) {
301+ return ;
302+ }
303+
304+ const directives : DirectiveNode [ ] = fieldMetas . map ( meta =>
305+ this . createDirective ( meta . name , meta . args ) ,
306+ ) ;
307+
308+ return {
309+ kind : "FieldDefinition" ,
310+ type : {
311+ kind : "NamedType" ,
312+ name : {
313+ kind : "Name" ,
314+ value : name ,
315+ } ,
316+ } ,
317+ name : {
318+ kind : "Name" ,
319+ value : name ,
320+ } ,
321+ directives,
322+ } ;
323+ } ;
324+
258325 return {
259326 target : objectType . target ,
260327 isAbstract : objectType . isAbstract || false ,
261328 type : new GraphQLObjectType ( {
262329 name : objectType . name ,
263330 description : objectType . description ,
331+ astNode : classDirectiveAstNodes ( objectType . name , objectType . directives ) ,
264332 interfaces : ( ) => {
265333 let interfaces = interfaceClasses . map < GraphQLInterfaceType > (
266334 interfaceClass =>
@@ -295,6 +363,7 @@ export abstract class SchemaGenerator {
295363 : createSimpleFieldResolver ( field ) ,
296364 description : field . description ,
297365 deprecationReason : field . deprecationReason ,
366+ astNode : fieldDirectiveAstNodes ( field . name , field . directives ) ,
298367 } ;
299368 return fieldsMap ;
300369 } ,
@@ -604,4 +673,34 @@ export abstract class SchemaGenerator {
604673 return this . objectTypesInfo . find ( objectType => objectType . target === resolvedType ) ! . type ;
605674 } ;
606675 }
676+
677+ private static createDirective ( name : string , args ?: { [ name : string ] : any } ) : DirectiveNode {
678+ const directiveArguments : ArgumentNode [ ] = [ ] ;
679+
680+ if ( args ) {
681+ Object . keys ( args ) . forEach ( arg => {
682+ directiveArguments . push ( {
683+ kind : "Argument" ,
684+ name : {
685+ kind : "Name" ,
686+ value : arg ,
687+ } ,
688+ value : {
689+ kind : "StringValue" ,
690+ value : args [ arg ] ,
691+ block : false ,
692+ } ,
693+ } ) ;
694+ } ) ;
695+ }
696+
697+ return {
698+ kind : "Directive" ,
699+ name : {
700+ kind : "Name" ,
701+ value : name ,
702+ } ,
703+ arguments : directiveArguments ,
704+ } ;
705+ }
607706}
0 commit comments