-
-
Notifications
You must be signed in to change notification settings - Fork 917
/
SchemaBuilderExtensions.cs
91 lines (77 loc) · 3.39 KB
/
SchemaBuilderExtensions.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
using GraphQL.Types;
using GraphQLParser.AST;
namespace GraphQL.Utilities
{
internal static class SchemaBuilderExtensions
{
private const string AST_METAFIELD = "__AST_MetaField__"; // TODO: possible remove
private const string EXTENSION_AST_METAFIELD = "__EXTENSION_AST_MetaField__"; // TODO: possible remove
public static bool IsExtensionType(this IProvideMetadata type)
{
return type.HasExtensionAstTypes()
&& !type.AstTypeHasFields();
}
public static bool AstTypeHasFields(this IProvideMetadata type)
{
return GetAstType<ASTNode>(type) switch
{
GraphQLObjectTypeDefinition otd => otd.Fields?.Any() ?? false,
GraphQLInterfaceTypeDefinition itd => itd.Fields?.Any() ?? false,
_ => false
};
}
public static T? GetAstType<T>(this IProvideMetadata type) where T : class // TODO: possible remove
{
return type.GetMetadata<T>(AST_METAFIELD);
}
public static TMetadataProvider SetAstType<TMetadataProvider>(this TMetadataProvider provider, ASTNode node) // TODO: possible remove
where TMetadataProvider : IProvideMetadata
{
provider.WithMetadata(AST_METAFIELD, node); //TODO: remove?
if (node is IHasDirectivesNode ast)
provider.CopyDirectivesFrom(ast);
return provider;
}
public static TMetadataProvider CopyDirectivesFrom<TMetadataProvider>(this TMetadataProvider provider, IHasDirectivesNode node)
where TMetadataProvider : IProvideMetadata
{
if (node.Directives?.Count > 0)
{
foreach (var directive in node.Directives)
{
provider.ApplyDirective(directive!.Name.StringValue, d => //ISSUE:allocation
{
if (directive.Arguments?.Count > 0)
{
foreach (var arg in directive.Arguments)
d.AddArgument(new DirectiveArgument(arg.Name.StringValue) { Value = arg.Value.ParseAnyLiteral() }); //ISSUE:allocation
}
});
}
}
return provider;
}
public static bool HasExtensionAstTypes(this IProvideMetadata type)
{
return type.HasMetadata(EXTENSION_AST_METAFIELD) && GetExtensionAstTypes(type).Count > 0;
}
public static void AddExtensionAstType<T>(this IProvideMetadata type, T astType)
where T : ASTNode
{
var types = GetExtensionAstTypes(type);
types.Add(astType);
type.Metadata[EXTENSION_AST_METAFIELD] = types;
if (astType is IHasDirectivesNode ast)
type.CopyDirectivesFrom(ast);
}
public static List<ASTNode> GetExtensionAstTypes(this IProvideMetadata type)
{
return type.GetMetadata(EXTENSION_AST_METAFIELD, () => new List<ASTNode>())!;
}
public static IEnumerable<GraphQLDirective> GetExtensionDirectives<T>(this IProvideMetadata type) where T : ASTNode
{
var types = type.GetExtensionAstTypes().OfType<IHasDirectivesNode>().Where(n => n.Directives != null);
return types.SelectMany(x => x.Directives!);
}
}
}