Coverage for graphqler / compiler / resolvers / mutation_object_resolver.py: 75%
32 statements
« prev ^ index » next coverage.py v7.13.4, created at 2026-03-20 10:09 -0400
« prev ^ index » next coverage.py v7.13.4, created at 2026-03-20 10:09 -0400
1"""
2This will resolve the inputs of a mutation to object. A few fields will be introduced to a mutation, namely:
3mutationType: One of [CREATE,UPDATE,DELETE,UNKNOWN] - this is determined semantically
4hardDependsOn: A dictionary of inputname-object name that is required
5 in the input (NON-NULL), depends on, ie: {'userId': 'User'}
6softDependsOn: A dictionary of inputname-object name, depends on, ie: {'userId': 'User'}
7"""
9import re
11from .resolver import Resolver
14class MutationObjectResolver(Resolver):
15 def __init__(self):
16 super().__init__()
18 def resolve(
19 self,
20 objects: dict,
21 mutations: dict,
22 input_objects: dict,
23 ) -> dict:
24 """Resolve mutation inputs to queries based on semantical understanding of IDs and adds the mutation type
25 one of [CREATE, UPDATE, DELETE, UNKNOWN]
27 Args:
28 objects (dict): Objects to link the mutations to
29 mutations (dict): Mutations to parse through
30 input_objects (dict): Input objects to recursively search through different input object inputs
32 Returns:
33 dict: The mutations enriched with aforementioned fields
34 """
35 for mutation_name, mutation in mutations.items():
36 mutation_type = self.get_mutation_action(mutation_name, mutation["description"])
37 inputs_related_to_ids = self.get_inputs_related_to_ids(mutation["inputs"], input_objects)
38 resolved_objects_to_inputs = self.resolve_inputs_related_to_ids_to_objects(mutation_name, inputs_related_to_ids, objects)
40 # Assign the enrichments
41 mutations[mutation_name]["hardDependsOn"] = resolved_objects_to_inputs["hardDependsOn"]
42 mutations[mutation_name]["softDependsOn"] = resolved_objects_to_inputs["softDependsOn"]
43 mutations[mutation_name]["mutationType"] = mutation_type
45 return mutations
47 def get_mutation_action(self, mutation_name: str, mutation_description: str | None) -> str:
48 """Gets the method action as a string by checking both the method name and method description
50 Args:
51 mutation_name (str): The mutation name
52 mutation_description (str | None): The mutation description
54 Returns:
55 str: One of [CREATE,UDPATE,DELETE,UNKNOWN]
56 """
57 create_pattern = re.compile(r"(create|add|insert)", re.IGNORECASE)
58 update_pattern = re.compile(r"(update|modify|edit)", re.IGNORECASE)
59 delete_pattern = re.compile(r"(delete|remove|erase)", re.IGNORECASE)
61 # Check if the method name matches any pattern
62 if create_pattern.search(mutation_name):
63 return "CREATE"
64 elif update_pattern.search(mutation_name):
65 return "UPDATE"
66 elif delete_pattern.search(mutation_name):
67 return "DELETE"
69 # Check if the method description matches any pattern
70 if mutation_description:
71 if create_pattern.search(mutation_description):
72 return "CREATE"
73 elif update_pattern.search(mutation_description):
74 return "UPDATE"
75 elif delete_pattern.search(mutation_description):
76 return "DELETE"
78 return "UNKNOWN"