Module: GraphQL::Analysis::AST

Defined in:
lib/graphql/analysis/ast/query_depth.rb,
lib/graphql/analysis/ast.rb,
lib/graphql/analysis/ast/visitor.rb,
lib/graphql/analysis/ast/analyzer.rb,
lib/graphql/analysis/ast/field_usage.rb,
lib/graphql/analysis/ast/max_query_depth.rb,
lib/graphql/analysis/ast/query_complexity.rb,
lib/graphql/analysis/ast/max_query_complexity.rb

Overview

Calculate the complexity of a query, using Field#complexity values.

Defined Under Namespace

Classes: Analyzer, FieldUsage, MaxQueryComplexity, MaxQueryDepth, QueryComplexity, QueryDepth, Visitor

Class Method Summary collapse

Class Method Details

.analysis_errors(results) ⇒ Object



86
87
88
# File 'lib/graphql/analysis/ast.rb', line 86

def analysis_errors(results)
  results.flatten.tap { _1.select! { |r| r.is_a?(GraphQL::AnalysisError) } }
end

.analyze_multiplex(multiplex, analyzers) ⇒ Array<Any>

Analyze a multiplex, and all queries within. Multiplex analyzers are ran for all queries, keeping state. Query analyzers are ran per query, without carrying state between queries.



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/graphql/analysis/ast.rb', line 22

def analyze_multiplex(multiplex, analyzers)
  multiplex_analyzers = analyzers.map { |analyzer| analyzer.new(multiplex) }

  multiplex.current_trace.analyze_multiplex(multiplex: multiplex) do
    query_results = multiplex.queries.map do |query|
      if query.valid?
        analyze_query(
          query,
          query.analyzers,
          multiplex_analyzers: multiplex_analyzers
        )
      else
        []
      end
    end

    multiplex_results = multiplex_analyzers.map(&:result)
    multiplex_errors = analysis_errors(multiplex_results)

    multiplex.queries.each_with_index do |query, idx|
      query.analysis_errors = multiplex_errors + analysis_errors(query_results[idx])
    end
    multiplex_results
  end
end

.analyze_query(query, analyzers, multiplex_analyzers: []) ⇒ Array<Any>



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/graphql/analysis/ast.rb', line 51

def analyze_query(query, analyzers, multiplex_analyzers: [])
  query.current_trace.analyze_query(query: query) do
    query_analyzers = analyzers
      .map { |analyzer| analyzer.new(query) }
      .tap { _1.select!(&:analyze?) }

    analyzers_to_run = query_analyzers + multiplex_analyzers
    if analyzers_to_run.any?

      analyzers_to_run.select!(&:visit?)
      if analyzers_to_run.any?
        visitor = GraphQL::Analysis::AST::Visitor.new(
          query: query,
          analyzers: analyzers_to_run
        )

        # `nil` or `0` causes no timeout
        Timeout::timeout(query.validate_timeout_remaining) do
          visitor.visit
        end

        if visitor.rescued_errors.any?
          return visitor.rescued_errors
        end
      end

      query_analyzers.map(&:result)
    else
      []
    end
  end
rescue Timeout::Error
  [GraphQL::AnalysisError.new("Timeout on validation of query")]
end