Module: OpticsAgent::Normalization::Query
- Includes:
- GraphQL::Language
- Included in:
- Reporting::Query
- Defined in:
- lib/optics-agent/normalization/query.rb
Instance Method Summary collapse
-
#normalize(query_string) ⇒ Object
query is a query string.
Instance Method Details
#normalize(query_string) ⇒ Object
query is a query string
9 10 11 12 13 14 15 16 17 18 19 20 21 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 47 48 49 50 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 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'lib/optics-agent/normalization/query.rb', line 9 def normalize(query_string) document = GraphQL.parse(query_string) # to store results output = '' used_fragment_names = [] current = {} visitor = Visitor.new(document) stack = [] Nodes.constants.each do |constant| mod = Nodes.const_get(constant) next unless mod.is_a? Module visitor[mod].enter << -> (_, _) do stack.unshift( arguments: [], directives: [], selections: [] ) end visitor[mod].leave << -> (_, _) { current = stack.shift } end visitor[Nodes::Argument].leave << -> (node, parent) do stack[0][:arguments] << "#{node.name}:#{genericize_type(node.value)}" end visitor[Nodes::Directive].leave << -> (node, parent) do id = "@#{node.name}" arguments = current[:arguments] unless arguments.empty? id << "(#{arguments.sort.join(', ')})" end stack[0][:directives] << id end visitor[Nodes::Field].leave << -> (node, parent) do id = node.name arguments = current[:arguments] unless arguments.empty? id << "(#{arguments.sort.join(', ')})" end directives = current[:directives] unless directives.empty? id << " #{directives.sort.join(' ')}" end selections = current[:selections] unless selections.empty? id << ' ' + block(selections) end stack[0][:selections] << id end visitor[Nodes::InlineFragment].leave << -> (node, parent) do selections = current[:selections] stack[0][:selections] << "... on #{node.type.name} #{block(selections)}" end visitor[Nodes::FragmentSpread].leave << -> (node, parent) do used_fragment_names << node.name stack[0][:selections] << "...#{node.name}" end visitor[Nodes::OperationDefinition].leave << -> (node, parent) do # no need to walk this, I don't think anything else can have vars vars = nil unless node.variables.empty? variable_strs = node.variables.sort_by(&:name).map do |variable| "$#{variable.name}:#{format_argument_type(variable.type)}" end vars = "(#{variable_strs.join(',')})" end query_content = block(current[:selections]) if (node.name || vars || node.operation_type != 'query') parts = [node.operation_type] parts << "#{node.name}#{vars}" if (node.name || vars) parts << query_content output << parts.join(' ') else output << query_content end end visitor[Nodes::FragmentDefinition].leave << -> (node, parent) do selections = current[:selections] if (used_fragment_names.include?(node.name)) output << " fragment #{node.name} on #{node.type.name} " \ + block(selections) end end visitor.visit output end |