Example #1
0
 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),
     )
Example #2
0
 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 object_field_nodes(
    name: str, field: graphql.GraphQLInputField
) -> st.SearchStrategy[graphql.ObjectFieldNode]:
    return st.builds(
        partial(graphql.ObjectFieldNode,
                name=graphql.NameNode(value=name)),  # type: ignore
        value=value_nodes(field.type),
    )
def list_of_arguments(
    **kwargs: graphql.GraphQLArgument
) -> st.SearchStrategy[List[graphql.ArgumentNode]]:
    """Generate a list `graphql.ArgumentNode` for a field."""
    return st.tuples(*(
        st.builds(partial(graphql.ArgumentNode,
                          name=graphql.NameNode(value=name)),
                  value=argument_values(argument))  # type: ignore
        for name, argument in kwargs.items())).map(finalize_arguments)
Example #5
0
 def add_alias(frag: graphql.InlineFragmentNode) -> graphql.InlineFragmentNode:
     # Add an alias for all fields that have the same name with already selected ones but a different type
     fragment_type = type_map[frag.type_condition.name.value]
     for selected in frag.selection_set.selections:
         field_name = selected.name.value
         if field_name in seen:
             field_type = fragment_type.fields[field_name].type
             if not is_equal_type(seen[field_name], field_type):
                 selected.alias = graphql.NameNode(value=f"{field_name}_{make_type_name(field_type)}")
     return frag
def field_nodes(
        name: str,
        field: graphql.GraphQLField) -> st.SearchStrategy[graphql.FieldNode]:
    """Generate a single field node with optional children."""
    return st.builds(
        partial(graphql.FieldNode,
                name=graphql.NameNode(value=name)),  # type: ignore
        arguments=list_of_arguments(**field.args),
        selection_set=st.builds(make_selection_set_node,
                                selections=fields_for_type(field)),
    )
def maybe_add_alias(field_node: graphql.FieldNode,
                    arguments: List[graphql.ArgumentNode],
                    seen: Dict[Tuple[str, str], List]) -> None:
    for argument in arguments:
        key = (field_node.name.value, argument.name.value)
        value = argument.value
        if key in seen:
            # Simply add an alias, the values could be the same, so it not technically necessary, but this is safe
            # and simpler, but a bit reduces the possible input variety
            field_node.alias = graphql.NameNode(
                value=f"{field_node.name.value}_{len(seen[key])}")
            seen[key].append(value)
        else:
            seen[key] = [value]
Example #8
0
 def inner(draw: Any) -> List[graphql.ArgumentNode]:
     args = []
     for name, argument in arguments.items():
         default = argument.ast_node.default_value if argument.ast_node is not None else None
         try:
             argument_strategy = self.values(argument.type, default=default)
         except InvalidArgument:
             if not isinstance(argument.type, graphql.GraphQLNonNull):
                 # If the type is nullable, then either generate `null` or skip it completely
                 if draw(st.booleans()):
                     args.append(graphql.ArgumentNode(name=graphql.NameNode(value=name), value=nodes.Null))
                 continue
             raise
         args.append(draw(argument_strategy.map(factories.argument(name))))
     return args
def type_to_ast(graphql_type):
    """
    https://github.com/apollographql/graphql-tools/blob/0046a0e3bf2a120a59e4f4e392d4ddc3728e4f3c/src/transforms/AddArgumentsAsVariables.ts#L171
    """
    if isinstance(graphql_type, graphql.GraphQLNonNull):
        inner_type = type_to_ast(graphql_type.of_type)
        if inner_type.kind in ("list_type", "named_type"):
            return graphql.NonNullTypeNode(type=inner_type)
        else:
            raise ValueError("Incorrect inner non-null type.")

    elif isinstance(graphql_type, graphql.GraphQLList):
        return graphql.ListTypeNode(type=type_to_ast(graphql_type.of_type))
    else:
        return graphql.NamedTypeNode(name=graphql.NameNode(
            value=str(graphql_type)))
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 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)
Example #12
0
 def factory(value: graphql.ValueNode) -> graphql.ObjectFieldNode:
     return graphql.ObjectFieldNode(name=graphql.NameNode(value=name),
                                    value=value)
Example #13
0
 def factory(value: graphql.ValueNode) -> graphql.ArgumentNode:
     return graphql.ArgumentNode(name=graphql.NameNode(value=name),
                                 value=value)