forked from STI/Astroport.ONE
43 lines
1.4 KiB
Python
43 lines
1.4 KiB
Python
|
from typing import Any, Dict, List
|
||
|
|
||
|
from ...error import GraphQLError
|
||
|
from ...language import NameNode, ObjectFieldNode
|
||
|
from . import ASTValidationContext, ASTValidationRule
|
||
|
|
||
|
__all__ = ["UniqueInputFieldNamesRule"]
|
||
|
|
||
|
|
||
|
class UniqueInputFieldNamesRule(ASTValidationRule):
|
||
|
"""Unique input field names
|
||
|
|
||
|
A GraphQL input object value is only valid if all supplied fields are uniquely
|
||
|
named.
|
||
|
|
||
|
See https://spec.graphql.org/draft/#sec-Input-Object-Field-Uniqueness
|
||
|
"""
|
||
|
|
||
|
def __init__(self, context: ASTValidationContext):
|
||
|
super().__init__(context)
|
||
|
self.known_names_stack: List[Dict[str, NameNode]] = []
|
||
|
self.known_names: Dict[str, NameNode] = {}
|
||
|
|
||
|
def enter_object_value(self, *_args: Any) -> None:
|
||
|
self.known_names_stack.append(self.known_names)
|
||
|
self.known_names = {}
|
||
|
|
||
|
def leave_object_value(self, *_args: Any) -> None:
|
||
|
self.known_names = self.known_names_stack.pop()
|
||
|
|
||
|
def enter_object_field(self, node: ObjectFieldNode, *_args: Any) -> None:
|
||
|
known_names = self.known_names
|
||
|
field_name = node.name.value
|
||
|
if field_name in known_names:
|
||
|
self.report_error(
|
||
|
GraphQLError(
|
||
|
f"There can be only one input field named '{field_name}'.",
|
||
|
[known_names[field_name], node.name],
|
||
|
)
|
||
|
)
|
||
|
else:
|
||
|
known_names[field_name] = node.name
|