Astroport.ONE/venv/lib/python3.11/site-packages/graphql/validation/rules/no_unused_fragments.py

54 lines
1.7 KiB
Python
Raw Normal View History

2024-03-01 16:15:45 +01:00
from typing import Any, List
from ...error import GraphQLError
from ...language import (
FragmentDefinitionNode,
OperationDefinitionNode,
VisitorAction,
SKIP,
)
from . import ASTValidationContext, ASTValidationRule
__all__ = ["NoUnusedFragmentsRule"]
class NoUnusedFragmentsRule(ASTValidationRule):
"""No unused fragments
A GraphQL document is only valid if all fragment definitions are spread within
operations, or spread within other fragments spread within operations.
See https://spec.graphql.org/draft/#sec-Fragments-Must-Be-Used
"""
def __init__(self, context: ASTValidationContext):
super().__init__(context)
self.operation_defs: List[OperationDefinitionNode] = []
self.fragment_defs: List[FragmentDefinitionNode] = []
def enter_operation_definition(
self, node: OperationDefinitionNode, *_args: Any
) -> VisitorAction:
self.operation_defs.append(node)
return SKIP
def enter_fragment_definition(
self, node: FragmentDefinitionNode, *_args: Any
) -> VisitorAction:
self.fragment_defs.append(node)
return SKIP
def leave_document(self, *_args: Any) -> None:
fragment_names_used = set()
get_fragments = self.context.get_recursively_referenced_fragments
for operation in self.operation_defs:
for fragment in get_fragments(operation):
fragment_names_used.add(fragment.name.value)
for fragment_def in self.fragment_defs:
frag_name = fragment_def.name.value
if frag_name not in fragment_names_used:
self.report_error(
GraphQLError(f"Fragment '{frag_name}' is never used.", fragment_def)
)