1
1
using HotChocolate . Fusion . Events ;
2
2
using HotChocolate . Fusion . Events . Contracts ;
3
3
using HotChocolate . Fusion . Extensions ;
4
+ using HotChocolate . Fusion . Info ;
4
5
using HotChocolate . Fusion . Language ;
5
6
using HotChocolate . Fusion . Validators ;
6
- using HotChocolate . Language ;
7
+ using HotChocolate . Types ;
8
+ using HotChocolate . Types . Mutable ;
7
9
using static HotChocolate . Fusion . Logging . LogEntryHelper ;
8
10
using static HotChocolate . Fusion . WellKnownArgumentNames ;
9
11
using static HotChocolate . Fusion . WellKnownDirectiveNames ;
10
- using static HotChocolate . Language . Utf8GraphQLParser . Syntax ;
11
12
12
13
namespace HotChocolate . Fusion . PostMergeValidationRules ;
13
14
@@ -20,62 +21,50 @@ namespace HotChocolate.Fusion.PostMergeValidationRules;
20
21
/// <seealso href="https://graphql.github.io/composite-schemas-spec/draft/#sec-Require-Invalid-Fields">
21
22
/// Specification
22
23
/// </seealso>
23
- internal sealed class RequireInvalidFieldsRule : IEventHandler < OutputFieldEvent >
24
+ internal sealed class RequireInvalidFieldsRule : IEventHandler < SchemaEvent >
24
25
{
25
- public void Handle ( OutputFieldEvent @event , CompositionContext context )
26
+ public void Handle ( SchemaEvent @event , CompositionContext context )
26
27
{
27
- var ( field , type , schema ) = @event ;
28
+ var schema = @event . Schema ;
28
29
29
- if ( field . HasFusionInaccessibleDirective ( )
30
- || type . HasFusionInaccessibleDirective ( )
31
- || ! field . HasFusionRequiresDirective ( ) )
32
- {
33
- return ;
34
- }
30
+ var sourceArgumentGroup = context . SchemaDefinitions
31
+ . SelectMany ( s => s . Types . OfType < MutableObjectTypeDefinition > ( ) , ( s , o ) => ( s , o ) )
32
+ . SelectMany ( x => x . o . Fields . AsEnumerable ( ) , ( x , f ) => ( x . s , x . o , f ) )
33
+ . SelectMany (
34
+ x => x . f . Arguments . AsEnumerable ( ) . Where ( a => a . HasRequireDirective ( ) ) ,
35
+ ( x , a ) => new FieldArgumentInfo ( a , x . f , x . o , x . s ) ) ;
35
36
36
37
var validator = new FieldSelectionMapValidator ( schema ) ;
37
- var fusionRequiresDirectives = field . Directives [ FusionRequires ] ;
38
38
39
- foreach ( var fusionRequiresDirective in fusionRequiresDirectives )
39
+ foreach ( var ( sourceArgument , sourceField , sourceType , sourceSchema ) in sourceArgumentGroup )
40
40
{
41
- var sourceSchemaName = ( string ) fusionRequiresDirective . Arguments [ Schema ] . Value ! ;
42
- var fieldArgumentValue = ( string ) fusionRequiresDirective . Arguments [ Field ] . Value ! ;
43
- var fieldDefinition = ParseFieldDefinition ( fieldArgumentValue ) ;
44
- var arguments = fieldDefinition . Arguments ;
45
- var map = ( ListValueNode ) fusionRequiresDirective . Arguments [ Map ] ;
46
-
47
- for ( var i = 0 ; i < arguments . Count ; i ++ )
48
- {
49
- var selectionMap = ( string ? ) map . Items [ i ] . Value ;
41
+ var requireDirective = sourceArgument . Directives [ Require ] . First ( ) ;
42
+ var fieldArgumentValue = ( string ) requireDirective . Arguments [ Field ] . Value ! ;
43
+ var fieldSelectionMapParser = new FieldSelectionMapParser ( fieldArgumentValue ) ;
44
+ var fieldSelectionMap = fieldSelectionMapParser . Parse ( ) ;
45
+ var inputType = schema . Types [ sourceArgument . Type . AsTypeDefinition ( ) . Name ] ;
46
+ var outputType = schema . Types [ sourceType . Name ] ;
47
+ var errors =
48
+ validator . Validate (
49
+ fieldSelectionMap ,
50
+ inputType ,
51
+ outputType ,
52
+ out var selectedFields ) ;
50
53
51
- if ( selectionMap is null )
52
- {
53
- continue ;
54
- }
54
+ // A selected field is defined in the same schema as the `require` directive.
55
+ var selectedFieldSameSchema =
56
+ selectedFields . Any ( f => f . GetSchemaNames ( ) . Contains ( sourceSchema . Name ) ) ;
55
57
56
- var fieldSelectionMapParser = new FieldSelectionMapParser ( selectionMap ) ;
57
- var fieldSelectionMap = fieldSelectionMapParser . Parse ( ) ;
58
- var argument = arguments [ i ] ;
59
- var inputType = schema . Types [ argument . Type . NamedType ( ) . Name . Value ] ;
60
- var errors =
61
- validator . Validate ( fieldSelectionMap , inputType , type , out var selectedFields ) ;
62
-
63
- // A selected field is defined in the same schema as the `require` directive.
64
- var selectedFieldSameSchema =
65
- selectedFields . Any ( f => f . GetSchemaNames ( ) . Contains ( sourceSchemaName ) ) ;
66
-
67
- if ( errors . Any ( ) || selectedFieldSameSchema )
68
- {
69
- context . Log . Write (
70
- RequireInvalidFields (
71
- fusionRequiresDirective ,
72
- argument . Name . Value ,
73
- field . Name ,
74
- type . Name ,
75
- sourceSchemaName ,
76
- schema ,
77
- errors ) ) ;
78
- }
58
+ if ( errors . Any ( ) || selectedFieldSameSchema )
59
+ {
60
+ context . Log . Write (
61
+ RequireInvalidFields (
62
+ requireDirective ,
63
+ sourceArgument . Name ,
64
+ sourceField . Name ,
65
+ sourceType . Name ,
66
+ sourceSchema ,
67
+ errors ) ) ;
79
68
}
80
69
}
81
70
}
0 commit comments