def factory(nodes: SelectionNodes) -> graphql.InlineFragmentNode: return graphql.InlineFragmentNode( type_condition=graphql.NamedTypeNode( name=graphql.NameNode(value=type_name), ), selection_set=graphql.SelectionSetNode(kind="selection_set", selections=nodes), )
def factory(tup: FieldNodeInput) -> graphql.FieldNode: return graphql.FieldNode( name=graphql.NameNode(value=name), arguments=tup[0], selection_set=graphql.SelectionSetNode( kind="selection_set", selections=add_selection_aliases(tup[1])), )
def create_document( target_field: str, target_operation: str, original_selections: List[graphql.SelectionNode], fragments: List[graphql.FragmentDefinitionNode], variables: List[graphql.VariableDefinitionNode], operation_name: graphql.NameNode, ) -> graphql.DocumentNode: """ https://github.com/apollographql/graphql-tools/blob/d3cbefc6b8a432c5b22f1ce25e56757ef03f4227/src/stitching/delegateToSchema.ts#L139 """ selections: List[graphql.SelectionNode] = [] args: List[graphql.ArgumentNode] = [] for field in original_selections: selections.extend(getattr(field.selection_set, "selections", [])) args.extend(field.arguments or []) if selections: selection_set = graphql.SelectionSetNode(selections=selections) else: selection_set = None root_field = graphql.FieldNode( alias=None, arguments=args, selection_set=selection_set, name=graphql.NameNode(value=target_field), ) root_selection_set = graphql.SelectionSetNode(selections=[root_field]) operation_definition = graphql.OperationDefinitionNode( operation=target_operation, variable_definitions=variables, selection_set=root_selection_set, name=operation_name, ) return graphql.DocumentNode(definitions=[operation_definition, *fragments])
def make_document_node(selections: SelectionNodes, *, kind: graphql.OperationType) -> graphql.DocumentNode: """Create top-level node for an operation AST.""" return graphql.DocumentNode( kind="document", definitions=[ graphql.OperationDefinitionNode( kind="operation_definition", operation=kind, selection_set=graphql.SelectionSetNode(kind="selection_set", selections=selections), ) ], )
def add_variables_to_root_field(schema: graphql.GraphQLSchema, document: graphql.DocumentNode, args: Dict[str, Any]) -> GraphQLRequest: """ https://github.com/apollographql/graphql-tools/blob/0046a0e3bf2a120a59e4f4e392d4ddc3728e4f3c/src/transforms/AddArgumentsAsVariables.ts#L47 """ operations = [ d for d in document.definitions if d.kind == "operation_definition" ] fragments = [ d for d in document.definitions if d.kind == "fragment_definition" ] variable_names = {} for operation in operations: existing_variables = set(v.variable.name.value for v in operation.variable_definitions) variable_counter = 0 variables = {} def generate_variable_name(arg_name: str) -> str: nonlocal variable_counter variable_name = f"_v{variable_counter}_{arg_name}" while variable_name in existing_variables: variable_counter += 1 variable_name = f"_v{variable_counter}_{arg_name}" return variable_name if operation.operation == operation.operation.SUBSCRIPTION: op_type = schema.subscription_type elif operation.operation == operation.operation.MUTATION: op_type = schema.mutation_type elif operation.operation == operation.operation.QUERY: op_type = schema.query_type else: raise ValueError("Unexpected operation.") if not op_type: continue new_selection_set = [] for selection in operation.selection_set.selections: if selection.kind == "field": new_args = {arg.name.value: arg for arg in selection.arguments} name = selection.name.value field = op_type.fields[name] for argument_name, argument in field.args.items(): if argument_name in args: variable_name = generate_variable_name(argument_name) variable_names[argument_name] = variable_name new_args[argument_name] = graphql.ArgumentNode( name=graphql.NameNode(value=argument_name), value=graphql.VariableNode(name=graphql.NameNode( value=variable_name)), ) existing_variables.add(variable_name) variables[ variable_name] = graphql.VariableDefinitionNode( variable=graphql.VariableNode( name=graphql.NameNode( value=variable_name)), type=type_to_ast(graphql_type=argument.type), ) selection.arguments = list(new_args.values()) new_selection_set.append(selection) operation.variable_definitions.extend(variables.values()) operation.selection_set = graphql.SelectionSetNode( selections=new_selection_set) new_variables = { variable_names[name]: args[name] for name in variable_names } new_document = graphql.DocumentNode(definitions=operations + fragments) return GraphQLRequest(document=document, variables=new_variables)