Module: GraphQL::StaticValidation::FieldsWillMerge
- Defined in:
- lib/graphql/static_validation/rules/fields_will_merge.rb
Defined Under Namespace
Classes: Field
Constant Summary collapse
- NO_ARGS =
Validates that a selection set is valid if all fields (including spreading any fragments) either correspond to distinct response names or can be merged without ambiguity.
Optimized algorithm based on: https://tech.new-work.se/graphql-overlapping-fields-can-be-merged-fast-ea6e92e0a01
Instead of comparing fields, fields-vs-fragments, and fragments-vs-fragments separately (which leads to exponential recursion through nested fragments), we flatten all fragment spreads into a single field map and compare within it.
GraphQL::EmptyObjects::EMPTY_HASH
Instance Method Summary collapse
-
#initialize ⇒ Object
-
#on_field(node, _parent) ⇒ Object
-
#on_operation_definition(node, _parent) ⇒ Object
Instance Method Details
#initialize ⇒ Object
38 39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/graphql/static_validation/rules/fields_will_merge.rb', line 38 def initialize(*) super @conflict_count = 0 @max_errors = context.max_errors @fragments = context.fragments # Track which sub-selection node pairs have been compared to prevent # infinite recursion with cyclic fragments @compared_sub_selections = {}.compare_by_identity # Cache mutually_exclusive? results for type pairs @mutually_exclusive_cache = {}.compare_by_identity # Cache collect_fields results for sub-selection comparison @sub_fields_cache = {}.compare_by_identity end |
#on_field(node, _parent) ⇒ Object
59 60 61 62 63 64 65 66 |
# File 'lib/graphql/static_validation/rules/fields_will_merge.rb', line 59 def on_field(node, _parent) if !node.selections.empty? && selections_may_conflict?(node.selections) @conflicts = nil conflicts_within_selection_set(node, type_definition) @conflicts&.each_value { |error_type| error_type.each_value { |error| add_error(error) } } end super end |
#on_operation_definition(node, _parent) ⇒ Object
52 53 54 55 56 57 |
# File 'lib/graphql/static_validation/rules/fields_will_merge.rb', line 52 def on_operation_definition(node, _parent) @conflicts = nil conflicts_within_selection_set(node, type_definition) @conflicts&.each_value { |error_type| error_type.each_value { |error| add_error(error) } } super end |