@@ -194,6 +194,71 @@ def add_input_to_create(schema: GraphQLSchema):
194
194
return schema
195
195
196
196
197
+ def _get_keys_for_type (type_ : GraphQLType ):
198
+ keys = []
199
+ if hasattr (type_ , 'ast_node' ) and type_ .ast_node is not None :
200
+ directives = {directive .name .value : directive for directive in type_ .ast_node .directives }
201
+ if 'key' in directives :
202
+ arguments = {arg .name .value : arg for arg in directives ['key' ].arguments }
203
+ if 'fields' in arguments :
204
+ keys .append ([val .value for val in arguments ['fields' ].value .values ])
205
+ return keys
206
+
207
+
208
+ def add_key_input_types (schema : GraphQLSchema ):
209
+ """
210
+ Add create and connect types for creating objects.
211
+ :param schema:
212
+ :return:
213
+ """
214
+ # add create types (placeholders)
215
+ make_types = ''
216
+ extend_fields = ''
217
+ for _type in schema .type_map .values ():
218
+ if not is_schema_defined_type (_type ) or is_interface_type (_type ):
219
+ continue
220
+ keys = _get_keys_for_type (_type )
221
+ # TODO: Modify this when we need to handle multiple keys.
222
+ if len (keys ) > 0 :
223
+ for key in keys [:1 ]:
224
+ make_types += f'input _KeyFor{ _type .name } '
225
+ extend_fields += f'\n extend input _KeyFor{ _type .name } {{ '
226
+ for key_field in key :
227
+ if key_field not in _type .fields :
228
+ raise Exception (f'Field "{ key_field } " in @key directive for { _type } is not a field of { _type } !' )
229
+ for field_name , field in _type .fields .items ():
230
+ # TODO: Modify this if we need to verify that the key fields are in the object
231
+ if field_name not in key :
232
+ continue
233
+ extend_fields += f'{ field_name } : { field .type } '
234
+ extend_fields += '} '
235
+ schema = add_to_schema (schema , make_types )
236
+ schema = add_to_schema (schema , extend_fields )
237
+ return schema
238
+
239
+
240
+ def add_key_queries (schema : GraphQLSchema ):
241
+ """
242
+ Add query to get object based on ID.
243
+ :param schema:
244
+ :return:
245
+ """
246
+ # Create queries for object types
247
+ make = ''
248
+ for _type in schema .type_map .values ():
249
+ if not is_schema_defined_type (_type ):
250
+ continue
251
+ keys = _get_keys_for_type (_type )
252
+ # TODO: Handle multiple keys here, somehow.
253
+ if len (keys ) > 0 :
254
+ # for key in keys[:1]:
255
+ query_name = f'{ decapitalize (_type .name )} ByKey'
256
+ key_type = f'_KeyFor{ _type .name } '
257
+ make += f'extend type Query {{ { query_name } (key:{ key_type } !): { _type .name } }} '
258
+ schema = add_to_schema (schema , make )
259
+ return schema
260
+
261
+
197
262
def extend_connect (schema : GraphQLSchema , _type : GraphQLType , field_type : GraphQLType , field_name : str ):
198
263
"""
199
264
Add connect type.
0 commit comments