def _get_basic_schema_ast(query_type):
    """Create a basic AST Document representing a nearly blank schema.

    The output AST contains a single query type, whose name is the input string. The query type
    is guaranteed to be the second entry of Document definitions, after the schema definition.
    The query type has no fields.

    Args:
        query_type: str, name of the query type for the schema

    Returns:
        DocumentNode, representing a nearly blank schema
    """
    blank_ast = ast_types.DocumentNode(definitions=[
        ast_types.SchemaDefinitionNode(
            operation_types=[
                ast_types.OperationTypeDefinitionNode(
                    operation=ast_types.OperationType.QUERY,
                    type=ast_types.NamedTypeNode(name=ast_types.NameNode(
                        value=query_type)),
                )
            ],
            directives=[],
        ),
        ast_types.ObjectTypeDefinitionNode(
            name=ast_types.NameNode(value=query_type),
            fields=[],
            interfaces=[],
            directives=[],
        ),
    ])
    return blank_ast
def _build_stitch_directive(source_field_name, sink_field_name):
    """Build a Directive node for the stitch directive."""
    return ast_types.DirectiveNode(
        name=ast_types.NameNode(value="stitch"),
        arguments=[
            ast_types.ArgumentNode(
                name=ast_types.NameNode(value="source_field"),
                value=ast_types.StringValueNode(value=source_field_name),
            ),
            ast_types.ArgumentNode(
                name=ast_types.NameNode(value="sink_field"),
                value=ast_types.StringValueNode(value=sink_field_name),
            ),
        ],
    )
Exemple #3
0
    def args(self, **kwargs):
        if self.camelcase:
            self.args_to_camelcase(kwargs)
        argument_nodes = list()
        for name, value in kwargs.items():
            arg = self.field.args.get(name)
            if not arg:
                raise ValueError(f"Invalid argument {name} for field {self.name}")
            arg_type_serializer = get_arg_serializer(arg.type)
            value = arg_type_serializer(value)

            argument_nodes.append(
                ast.ArgumentNode(
                    name=ast.NameNode(value=name), value=get_ast_value(value)
                )
            )
        self.ast_field.arguments = FrozenList(argument_nodes)
        return self
Exemple #4
0
def _name(value):
    return ast.NameNode(value=value) if value is not None else None
Exemple #5
0
 def alias(self, alias):
     self.ast_field.alias = ast.NameNode(value=alias)
     return self
Exemple #6
0
 def __init__(self, name, f, camelcase=True):
     self.field = f
     self.ast_field = ast.FieldNode(name=ast.NameNode(value=name), arguments=[])
     self.selection_set = None
     self.camelcase = camelcase
def _add_edge_field(source_type_node, sink_type_name, source_field_name,
                    sink_field_name, edge_name, direction):
    """Add one direction of the specified edge as a field of the source type.

    Args:
        source_type_node: (Interface/Object)TypeDefinitionNode, where a new field representing
                          one direction of the edge will be added.
        sink_type_name: str, name of the type that the edge leads to
        source_field_name: str, name of the source side field that will be stitched
        sink_field_name: str, name of the sink side field that will be stitched
        edge_name: str, name of the edge that will be used to name the new field
        direction: str, either OUTBOUND_EDGE_DIRECTION or INBOUND_EDGE_DIRECTION ('out'
                   or 'in')

    Returns:
        (Interface/Object)TypeDefinitionNode, updated version of source_type_node.

    Raises:
        - SchemaNameConflictError if the new cross-schema edge name causes a name conflict with
          existing fields, or fields created by previous cross-schema edges
    """
    type_fields = source_type_node.fields

    if direction not in (OUTBOUND_EDGE_DIRECTION, INBOUND_EDGE_DIRECTION):
        raise AssertionError(
            u'Input "direction" must be either "{}" or "{}".'.format(
                OUTBOUND_EDGE_DIRECTION, INBOUND_EDGE_DIRECTION))
    new_edge_field_name = direction + "_" + edge_name

    # Error if new edge causes a field name clash
    if any(field.name.value == new_edge_field_name for field in type_fields):
        raise SchemaNameConflictError(
            u'New field "{}" under type "{}" created by the {}bound field of edge named '
            u'"{}" clashes with an existing field of the same name. Consider changing the '
            u"name of your edge to avoid name conflicts.".format(
                new_edge_field_name, source_type_node.name.value, direction,
                edge_name))

    new_edge_field_node = ast_types.FieldDefinitionNode(
        name=ast_types.NameNode(value=new_edge_field_name),
        arguments=[],
        type=ast_types.ListTypeNode(type=ast_types.NamedTypeNode(
            name=ast_types.NameNode(value=sink_type_name), ), ),
        directives=[
            _build_stitch_directive(source_field_name, sink_field_name),
        ],
    )

    new_type_fields = list(type_fields)
    new_type_fields.append(new_edge_field_node)
    if type(source_type_node) == ast_types.ObjectTypeDefinitionNode:
        new_source_type_node = ast_types.ObjectTypeDefinitionNode(
            description=source_type_node.description,
            name=source_type_node.name,
            directives=source_type_node.directives,
            fields=new_type_fields,
            interfaces=source_type_node.interfaces,
        )
    elif type(source_type_node) == ast_types.InterfaceTypeDefinitionNode:
        new_source_type_node = ast_types.InterfaceTypeDefinitionNode(
            description=source_type_node.description,
            name=source_type_node.name,
            directives=source_type_node.directives,
            fields=new_type_fields,
        )
    else:
        raise AssertionError(
            u'Input "source_type_node" must be of type {} or {}. Received type {}'
            .format(
                ast_types.ObjectTypeDefinitionNode,
                ast_types.InterfaceTypeDefinitionNode,
                type(source_type_node),
            ))
    return new_source_type_node