Method: GraphQL::Schema::Field#calculate_complexity

Defined in:
lib/graphql/schema/field.rb

#calculate_complexity(query:, nodes:, child_complexity:) ⇒ Object



472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
# File 'lib/graphql/schema/field.rb', line 472

def calculate_complexity(query:, nodes:, child_complexity:)
  if respond_to?(:complexity_for)
    lookahead = GraphQL::Execution::Lookahead.new(query: query, field: self, ast_nodes: nodes, owner_type: owner)
    complexity_for(child_complexity: child_complexity, query: query, lookahead: lookahead)
  elsif connection?
    arguments = query.arguments_for(nodes.first, self)
    max_possible_page_size = nil
    if arguments.respond_to?(:[]) # It might have been an error
      if arguments[:first]
        max_possible_page_size = arguments[:first]
      end

      if arguments[:last] && (max_possible_page_size.nil? || arguments[:last] > max_possible_page_size)
        max_possible_page_size = arguments[:last]
      end
    elsif arguments.is_a?(GraphQL::ExecutionError) || arguments.is_a?(GraphQL::UnauthorizedError)
      raise arguments
    end

    if max_possible_page_size.nil?
      max_possible_page_size = default_page_size || query.schema.default_page_size || max_page_size || query.schema.default_max_page_size
    end

    if max_possible_page_size.nil?
      raise GraphQL::Error, "Can't calculate complexity for #{path}, no `first:`, `last:`, `default_page_size`, `max_page_size` or `default_max_page_size`"
    else
       = 0
      lookahead = GraphQL::Execution::Lookahead.new(query: query, field: self, ast_nodes: nodes, owner_type: owner)

      lookahead.selections.each do |next_lookahead|
        # this includes `pageInfo`, `nodes` and `edges` and any custom fields
        # TODO this doesn't support procs yet -- unlikely to need it.
         += next_lookahead.field.complexity
        if next_lookahead.name != :nodes && next_lookahead.name != :edges
          # subfields, eg, for pageInfo -- assumes no subselections
           += next_lookahead.selections.size
        end
      end

      # Possible bug: selections on `edges` and `nodes` are _both_ multiplied here. Should they be?
      items_complexity = child_complexity - 
      subfields_complexity = (max_possible_page_size * items_complexity) + 
      # Apply this field's own complexity
      apply_own_complexity_to(subfields_complexity, query, nodes)
    end
  else
    apply_own_complexity_to(child_complexity, query, nodes)
  end
end