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
|