Sha256: b1579024c2f9f9692af2f9a5bede229fc987b4fe2ff22380b6249e6b7a67c4f2

Contents?: true

Size: 1.41 KB

Versions: 10

Compression:

Stored size: 1.41 KB

Contents

module GraphQL
  module StaticValidation
    class FragmentsAreFinite
      include GraphQL::StaticValidation::Message::MessageHelper

      def validate(context)
        context.visitor[GraphQL::Language::Nodes::FragmentDefinition] << ->(node, parent) {
          if has_nested_spread?(node, [], context)
            context.errors << message("Fragment #{node.name} contains an infinite loop", node, context: context)
          end
        }
      end

      private

      def has_nested_spread?(fragment_def, parent_fragment_names, context)
        nested_spreads = get_spreads(fragment_def.selections)

        nested_spreads.any? do |spread|
          nested_def = context.fragments[spread.name]
          if nested_def.nil?
            # this is another kind of error
            false
          else
            parent_fragment_names.include?(spread.name) || has_nested_spread?(nested_def, parent_fragment_names + [fragment_def.name], context)
          end
        end
      end

      # Find spreads contained in this selection & return them in a flat array
      def get_spreads(selection)
        case selection
        when GraphQL::Language::Nodes::FragmentSpread
          [selection]
        when GraphQL::Language::Nodes::Field, GraphQL::Language::Nodes::InlineFragment
          get_spreads(selection.selections)
        when Array
          selection.map { |s| get_spreads(s) }.flatten
        end
      end
    end
  end
end

Version data entries

10 entries across 10 versions & 1 rubygems

Version Path
graphql-1.2.6 lib/graphql/static_validation/rules/fragments_are_finite.rb
graphql-1.2.5 lib/graphql/static_validation/rules/fragments_are_finite.rb
graphql-1.2.4 lib/graphql/static_validation/rules/fragments_are_finite.rb
graphql-1.2.3 lib/graphql/static_validation/rules/fragments_are_finite.rb
graphql-1.2.2 lib/graphql/static_validation/rules/fragments_are_finite.rb
graphql-1.2.1 lib/graphql/static_validation/rules/fragments_are_finite.rb
graphql-1.2.0 lib/graphql/static_validation/rules/fragments_are_finite.rb
graphql-1.1.0 lib/graphql/static_validation/rules/fragments_are_finite.rb
graphql-1.0.0 lib/graphql/static_validation/rules/fragments_are_finite.rb
graphql-0.19.4 lib/graphql/static_validation/rules/fragments_are_finite.rb