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
|