11use graphql_parser:: Pos ;
2+ use graphql_tools:: validation:: rules:: * ;
3+ use graphql_tools:: validation:: validate:: { validate, ValidationPlan } ;
4+ use lazy_static:: lazy_static;
25use std:: collections:: { HashMap , HashSet } ;
36use std:: hash:: { Hash , Hasher } ;
47use std:: sync:: Arc ;
@@ -9,11 +12,10 @@ use graph::data::graphql::{
912 ext:: { DocumentExt , TypeExt } ,
1013 ObjectOrInterface ,
1114} ;
15+ use graph:: data:: query:: QueryExecutionError ;
1216use graph:: data:: query:: { Query as GraphDataQuery , QueryVariables } ;
1317use 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 } ;
1719
1820use crate :: introspection:: introspection_schema;
1921use crate :: query:: { ast as qast, ext:: BlockConstraint } ;
@@ -23,6 +25,41 @@ use crate::{
2325 schema:: api:: ErrorPolicy ,
2426} ;
2527
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+
2663#[ derive( Clone , Debug ) ]
2764pub enum ComplexityError {
2865 TooDeep ,
@@ -115,6 +152,24 @@ impl Query {
115152 max_complexity : Option < u64 > ,
116153 max_depth : u8 ,
117154 ) -> 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+
118173 let mut operation = None ;
119174 let mut fragments = HashMap :: new ( ) ;
120175 for defn in query. document . definitions . into_iter ( ) {
0 commit comments