1
1
use graphql_parser:: Pos ;
2
+ use graphql_tools:: validation:: rules:: * ;
3
+ use graphql_tools:: validation:: validate:: { validate, ValidationPlan } ;
4
+ use lazy_static:: lazy_static;
2
5
use std:: collections:: { HashMap , HashSet } ;
3
6
use std:: hash:: { Hash , Hasher } ;
4
7
use std:: sync:: Arc ;
@@ -9,11 +12,10 @@ use graph::data::graphql::{
9
12
ext:: { DocumentExt , TypeExt } ,
10
13
ObjectOrInterface ,
11
14
} ;
15
+ use graph:: data:: query:: QueryExecutionError ;
12
16
use graph:: data:: query:: { Query as GraphDataQuery , QueryVariables } ;
13
17
use graph:: data:: schema:: ApiSchema ;
14
- use graph:: prelude:: {
15
- info, o, q, r, s, BlockNumber , CheapClone , Logger , QueryExecutionError , TryFromValue ,
16
- } ;
18
+ use graph:: prelude:: { info, o, q, r, s, BlockNumber , CheapClone , Logger , TryFromValue } ;
17
19
18
20
use crate :: introspection:: introspection_schema;
19
21
use crate :: query:: { ast as qast, ext:: BlockConstraint } ;
@@ -23,6 +25,41 @@ use crate::{
23
25
schema:: api:: ErrorPolicy ,
24
26
} ;
25
27
28
+ lazy_static ! {
29
+ static ref GRAPHQL_VALIDATION_PLAN : ValidationPlan = ValidationPlan :: from(
30
+ if std:: env:: var( "DISABLE_GRAPHQL_VALIDATIONS" )
31
+ . unwrap_or_else( |_| "false" . into( ) )
32
+ . parse:: <bool >( )
33
+ . unwrap_or_else( |_| false )
34
+ {
35
+ vec![ ]
36
+ } else {
37
+ vec![
38
+ Box :: new( UniqueOperationNames { } ) ,
39
+ Box :: new( LoneAnonymousOperation { } ) ,
40
+ Box :: new( SingleFieldSubscriptions { } ) ,
41
+ Box :: new( KnownTypeNames { } ) ,
42
+ Box :: new( FragmentsOnCompositeTypes { } ) ,
43
+ Box :: new( VariablesAreInputTypes { } ) ,
44
+ Box :: new( LeafFieldSelections { } ) ,
45
+ Box :: new( FieldsOnCorrectType { } ) ,
46
+ Box :: new( UniqueFragmentNames { } ) ,
47
+ Box :: new( KnownFragmentNames { } ) ,
48
+ Box :: new( NoUnusedFragments { } ) ,
49
+ Box :: new( OverlappingFieldsCanBeMerged { } ) ,
50
+ Box :: new( NoFragmentsCycle { } ) ,
51
+ Box :: new( PossibleFragmentSpreads { } ) ,
52
+ Box :: new( NoUnusedVariables { } ) ,
53
+ Box :: new( NoUndefinedVariables { } ) ,
54
+ Box :: new( KnownArgumentNames { } ) ,
55
+ Box :: new( UniqueArgumentNames { } ) ,
56
+ Box :: new( UniqueVariableNames { } ) ,
57
+ Box :: new( ProvidedRequiredArguments { } ) ,
58
+ ]
59
+ }
60
+ ) ;
61
+ }
62
+
26
63
#[ derive( Clone , Debug ) ]
27
64
pub enum ComplexityError {
28
65
TooDeep ,
@@ -115,6 +152,24 @@ impl Query {
115
152
max_complexity : Option < u64 > ,
116
153
max_depth : u8 ,
117
154
) -> Result < Arc < Self > , Vec < QueryExecutionError > > {
155
+ let validation_errors = validate (
156
+ & schema. document ( ) ,
157
+ & query. document ,
158
+ & GRAPHQL_VALIDATION_PLAN ,
159
+ ) ;
160
+
161
+ if validation_errors. len ( ) > 0 {
162
+ return Err ( validation_errors
163
+ . into_iter ( )
164
+ . map ( |e| {
165
+ QueryExecutionError :: ValidationError (
166
+ e. locations . clone ( ) . into_iter ( ) . nth ( 0 ) ,
167
+ e. message ,
168
+ )
169
+ } )
170
+ . collect ( ) ) ;
171
+ }
172
+
118
173
let mut operation = None ;
119
174
let mut fragments = HashMap :: new ( ) ;
120
175
for defn in query. document . definitions . into_iter ( ) {
0 commit comments