forked from STI/Astroport.ONE
50 lines
1.5 KiB
Python
50 lines
1.5 KiB
Python
|
from typing import Any, Union, cast
|
||
|
|
||
|
from ...error import GraphQLError
|
||
|
from ...language import (
|
||
|
DirectiveDefinitionNode,
|
||
|
DocumentNode,
|
||
|
ExecutableDefinitionNode,
|
||
|
SchemaDefinitionNode,
|
||
|
SchemaExtensionNode,
|
||
|
TypeDefinitionNode,
|
||
|
VisitorAction,
|
||
|
SKIP,
|
||
|
)
|
||
|
from . import ASTValidationRule
|
||
|
|
||
|
__all__ = ["ExecutableDefinitionsRule"]
|
||
|
|
||
|
|
||
|
class ExecutableDefinitionsRule(ASTValidationRule):
|
||
|
"""Executable definitions
|
||
|
|
||
|
A GraphQL document is only valid for execution if all definitions are either
|
||
|
operation or fragment definitions.
|
||
|
|
||
|
See https://spec.graphql.org/draft/#sec-Executable-Definitions
|
||
|
"""
|
||
|
|
||
|
def enter_document(self, node: DocumentNode, *_args: Any) -> VisitorAction:
|
||
|
for definition in node.definitions:
|
||
|
if not isinstance(definition, ExecutableDefinitionNode):
|
||
|
def_name = (
|
||
|
"schema"
|
||
|
if isinstance(
|
||
|
definition, (SchemaDefinitionNode, SchemaExtensionNode)
|
||
|
)
|
||
|
else "'{}'".format(
|
||
|
cast(
|
||
|
Union[DirectiveDefinitionNode, TypeDefinitionNode],
|
||
|
definition,
|
||
|
).name.value
|
||
|
)
|
||
|
)
|
||
|
self.report_error(
|
||
|
GraphQLError(
|
||
|
f"The {def_name} definition is not executable.",
|
||
|
definition,
|
||
|
)
|
||
|
)
|
||
|
return SKIP
|