77 * @flow strict
88 */
99
10- import type { ValidationContext } from '../ValidationContext' ;
10+ import type {
11+ ValidationContext ,
12+ SDLValidationContext ,
13+ } from '../ValidationContext' ;
1114import { GraphQLError } from '../../error/GraphQLError' ;
15+ import { Kind } from '../../language/kinds' ;
1216import inspect from '../../jsutils/inspect' ;
1317import keyMap from '../../jsutils/keyMap' ;
1418import { isNonNullType } from '../../type/definition' ;
@@ -28,12 +32,13 @@ export function missingFieldArgMessage(
2832export function missingDirectiveArgMessage (
2933 directiveName : string ,
3034 argName : string ,
31- type : string ,
35+ type ?: ? string ,
3236) : string {
33- return (
34- `Directive "@${ directiveName } " argument "${ argName } " of type ` +
35- `"${ type } " is required but not provided.`
36- ) ;
37+ let msg = `Directive "@${ directiveName } " argument "${ argName } "` ;
38+ if ( type ) {
39+ msg += ' of type ' + type ;
40+ }
41+ return msg + ' is required but not provided.' ;
3742}
3843
3944/**
@@ -46,12 +51,13 @@ export function ProvidedRequiredArguments(
4651 context : ValidationContext ,
4752) : ASTVisitor {
4853 return {
54+ ...ProvidedRequiredArgumentsOnDirectives ( context ) ,
4955 Field : {
5056 // Validate on leave to allow for deeper errors to appear first.
5157 leave ( node ) {
5258 const fieldDef = context . getFieldDef ( ) ;
5359 if ( ! fieldDef ) {
54- return false ;
60+ return ;
5561 }
5662 const argNodes = node . arguments || [ ] ;
5763
@@ -77,34 +83,63 @@ export function ProvidedRequiredArguments(
7783 }
7884 } ,
7985 } ,
86+ } ;
87+ }
88+
89+ // @internal
90+ export function ProvidedRequiredArgumentsOnDirectives (
91+ context : ValidationContext | SDLValidationContext ,
92+ ) : ASTVisitor {
93+ const requiredArgsMap = Object . create ( null ) ;
94+ const schema = context . getSchema ( ) ;
8095
96+ if ( schema ) {
97+ for ( const directive of schema . getDirectives ( ) ) {
98+ const requredArgs = directive . args . filter (
99+ arg => isNonNullType ( arg . type ) && arg . defaultValue === undefined ,
100+ ) ;
101+ requiredArgsMap [ directive . name ] = requredArgs . map ( arg => arg . name ) ;
102+ }
103+ }
104+
105+ const astDefinitions = context . getDocument ( ) . definitions ;
106+ for ( const def of astDefinitions ) {
107+ if ( def . kind === Kind . DIRECTIVE_DEFINITION ) {
108+ const requredArgs = ( def . arguments || [ ] ) . filter (
109+ arg => arg . type . kind === Kind . NON_NULL_TYPE && arg . defaultValue == null ,
110+ ) ;
111+
112+ requiredArgsMap [ def . name . value ] = requredArgs . map ( arg => arg . name . value ) ;
113+ }
114+ }
115+
116+ return {
81117 Directive : {
82118 // Validate on leave to allow for deeper errors to appear first.
83119 leave ( node ) {
84- const directiveDef = context . getDirective ( ) ;
85- if ( ! directiveDef ) {
86- return false ;
87- }
88- const argNodes = node . arguments || [ ] ;
120+ const directiveName = node . name . value ;
121+ const requiredArgs = requiredArgsMap [ directiveName ] ;
122+ if ( requiredArgs ) {
123+ const argNodes = node . arguments || [ ] ;
124+ const argNodeMap = keyMap ( argNodes , arg => arg . name . value ) ;
125+ for ( const argName of requiredArgs ) {
126+ if ( ! argNodeMap [ argName ] ) {
127+ const directiveDef = schema && schema . getDirective ( directiveName ) ;
128+ const argDef =
129+ directiveDef &&
130+ directiveDef . args . find ( arg => arg . name === argName ) ;
89131
90- const argNodeMap = keyMap ( argNodes , arg => arg . name . value ) ;
91- for ( const argDef of directiveDef . args ) {
92- const argNode = argNodeMap [ argDef . name ] ;
93- if (
94- ! argNode &&
95- isNonNullType ( argDef . type ) &&
96- argDef . defaultValue === undefined
97- ) {
98- context . reportError (
99- new GraphQLError (
100- missingDirectiveArgMessage (
101- node . name . value ,
102- argDef . name ,
103- inspect ( argDef . type ) ,
132+ context . reportError (
133+ new GraphQLError (
134+ missingDirectiveArgMessage (
135+ directiveName ,
136+ argName ,
137+ argDef && inspect ( argDef . type ) ,
138+ ) ,
139+ [ node ] ,
104140 ) ,
105- [ node ] ,
106- ) ,
107- ) ;
141+ ) ;
142+ }
108143 }
109144 }
110145 } ,
0 commit comments