forked from STI/Astroport.ONE
47 lines
1.5 KiB
Python
47 lines
1.5 KiB
Python
from typing import Any, Dict
|
|
|
|
from ...error import GraphQLError
|
|
from ...language import DirectiveDefinitionNode, NameNode, VisitorAction, SKIP
|
|
from . import SDLValidationContext, SDLValidationRule
|
|
|
|
__all__ = ["UniqueDirectiveNamesRule"]
|
|
|
|
|
|
class UniqueDirectiveNamesRule(SDLValidationRule):
|
|
"""Unique directive names
|
|
|
|
A GraphQL document is only valid if all defined directives have unique names.
|
|
"""
|
|
|
|
def __init__(self, context: SDLValidationContext):
|
|
super().__init__(context)
|
|
self.known_directive_names: Dict[str, NameNode] = {}
|
|
self.schema = context.schema
|
|
|
|
def enter_directive_definition(
|
|
self, node: DirectiveDefinitionNode, *_args: Any
|
|
) -> VisitorAction:
|
|
directive_name = node.name.value
|
|
|
|
if self.schema and self.schema.get_directive(directive_name):
|
|
self.report_error(
|
|
GraphQLError(
|
|
f"Directive '@{directive_name}' already exists in the schema."
|
|
" It cannot be redefined.",
|
|
node.name,
|
|
)
|
|
)
|
|
else:
|
|
if directive_name in self.known_directive_names:
|
|
self.report_error(
|
|
GraphQLError(
|
|
f"There can be only one directive named '@{directive_name}'.",
|
|
[self.known_directive_names[directive_name], node.name],
|
|
)
|
|
)
|
|
else:
|
|
self.known_directive_names[directive_name] = node.name
|
|
return SKIP
|
|
|
|
return None
|