1
- from typing import Any , Dict , List , Optional , Tuple , Union
1
+ from typing import Any , Dict , List , Optional , Set , Tuple , Union
2
2
3
3
from graphql import (
4
4
ArgumentNode ,
12
12
13
13
14
14
class GraphQLArgument :
15
- def __init__ (self , argument_name : str ):
15
+ def __init__ (self , argument_name : str , argument_value : Any ):
16
16
self ._name = argument_name
17
- self ._variable_name = argument_name
17
+ self ._value = argument_value
18
18
19
- def to_ast (self , idx : int ) -> ArgumentNode :
19
+ def to_ast (self ) -> ArgumentNode :
20
20
return ArgumentNode (
21
21
name = NameNode (value = self ._name ),
22
- value = VariableNode (name = NameNode (value = f" { idx } _ { self ._variable_name } " )),
22
+ value = VariableNode (name = NameNode (value = self ._value )),
23
23
)
24
24
25
25
26
26
class GraphQLField :
27
27
def __init__ (
28
- self , field_name : str , arguments : Optional [Dict [str , Any ]] = None
28
+ self , field_name : str , arguments : Optional [Dict [str , Dict [ str , Any ] ]] = None
29
29
) -> None :
30
30
self ._field_name = field_name
31
31
self ._variables = arguments or {}
32
- self ._arguments = [ GraphQLArgument ( k ) for k in self . _variables ]
32
+ self ._formatted_variables : Dict [ str , Dict [ str , Any ]] = {}
33
33
self ._subfields : List [GraphQLField ] = []
34
34
self ._alias : Optional [str ] = None
35
35
self ._inline_fragments : Dict [str , Tuple [GraphQLField , ...]] = {}
36
36
37
- def get_variables_types (self , idx : int ) -> Dict [str , Any ]:
38
- return {f"{ idx } _{ k } " : v ["type" ] for k , v in self ._variables .items ()}
39
-
40
- def get_processed_variables (self , idx : int ) -> Dict [str , Any ]:
41
- return {f"{ idx } _{ k } " : v ["value" ] for k , v in self ._variables .items ()}
42
-
43
37
def alias (self , alias : str ) -> "GraphQLField" :
44
38
self ._alias = alias
45
39
return self
@@ -53,28 +47,72 @@ def add_inline_fragment(self, type_name: str, *subfields: "GraphQLField") -> Non
53
47
def _build_field_name (self ) -> str :
54
48
return f"{ self ._alias } : { self ._field_name } " if self ._alias else self ._field_name
55
49
56
- def _build_selections (self , idx : int ) -> List [Union [FieldNode , InlineFragmentNode ]]:
50
+ def _build_selections (
51
+ self , idx : int , used_names : Set [str ]
52
+ ) -> List [Union [FieldNode , InlineFragmentNode ]]:
57
53
selections : List [Union [FieldNode , InlineFragmentNode ]] = [
58
- subfield .to_ast (idx ) for subfield in self ._subfields
54
+ subfield .to_ast (idx , used_names ) for subfield in self ._subfields
59
55
]
60
56
for name , subfields in self ._inline_fragments .items ():
61
57
selections .append (
62
58
InlineFragmentNode (
63
59
type_condition = NamedTypeNode (name = NameNode (value = name )),
64
60
selection_set = SelectionSetNode (
65
- selections = [subfield .to_ast (idx ) for subfield in subfields ]
61
+ selections = [
62
+ subfield .to_ast (idx , used_names ) for subfield in subfields
63
+ ]
66
64
),
67
65
)
68
66
)
69
67
return selections
70
68
71
- def to_ast (self , idx : int ) -> FieldNode :
69
+ def _format_variable_name (
70
+ self , idx : int , var_name : str , used_names : Set [str ]
71
+ ) -> str :
72
+ base_name = f"{ idx } _{ var_name } "
73
+ unique_name = base_name
74
+ counter = 1
75
+ while unique_name in used_names :
76
+ unique_name = f"{ base_name } _{ counter } "
77
+ counter += 1
78
+ used_names .add (unique_name )
79
+ return unique_name
80
+
81
+ def _collect_all_variables (self , idx : int , used_names : Set [str ]) -> None :
82
+ self ._formatted_variables = {}
83
+ for k , v in self ._variables .items ():
84
+ unique_name = self ._format_variable_name (idx , k , used_names )
85
+ self ._formatted_variables [unique_name ] = {
86
+ "name" : k ,
87
+ "type" : v ["type" ],
88
+ "value" : v ["value" ],
89
+ }
90
+
91
+ def to_ast (self , idx : int , used_names : Optional [Set [str ]] = None ) -> FieldNode :
92
+ if used_names is None :
93
+ used_names = set ()
94
+ self ._collect_all_variables (idx , used_names )
95
+ formatted_args = [
96
+ GraphQLArgument (v ["name" ], k ).to_ast ()
97
+ for k , v in self ._formatted_variables .items ()
98
+ ]
72
99
return FieldNode (
73
100
name = NameNode (value = self ._build_field_name ()),
74
- arguments = [ arg . to_ast ( idx ) for arg in self . _arguments ] ,
101
+ arguments = formatted_args ,
75
102
selection_set = (
76
- SelectionSetNode (selections = self ._build_selections (idx ))
103
+ SelectionSetNode (selections = self ._build_selections (idx , used_names ))
77
104
if self ._subfields or self ._inline_fragments
78
105
else None
79
106
),
80
107
)
108
+
109
+ def get_formatted_variables (self ) -> Dict [str , Dict [str , Any ]]:
110
+ formatted_variables = self ._formatted_variables
111
+ for subfield in self ._subfields :
112
+ subfield .get_formatted_variables ()
113
+ self ._formatted_variables .update (subfield ._formatted_variables )
114
+ for subfields in self ._inline_fragments .values ():
115
+ for subfield in subfields :
116
+ subfield .get_formatted_variables ()
117
+ self ._formatted_variables .update (subfield ._formatted_variables )
118
+ return formatted_variables
0 commit comments