Class: GraphQL::REPL::Expression

Inherits:
Object
  • Object
show all
Defined in:
lib/graphql/repl.rb

Instance Method Summary collapse

Constructor Details

#initialize(schema, str) ⇒ Expression

Returns a new instance of Expression.



72
73
74
75
# File 'lib/graphql/repl.rb', line 72

def initialize(schema, str)
  @schema = schema
  @str = str
end

Instance Method Details

#callsObject



77
78
79
80
81
# File 'lib/graphql/repl.rb', line 77

def calls
  proxy = Proxy.new
  b = proxy.get_binding
  b.eval(@str).calls
end

#completionsObject



83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/graphql/repl.rb', line 83

def completions
  first, partial = @str.scan(/^(.+)\.(.*)$/)[0]

  if first
    type = Expression.new(@schema, first).return_type
  else
    partial = @str
    type = @schema.query.to_s
  end

  if type
    @schema.types[type].all_fields.map(&:name).grep(/^#{partial}/).map { |name|
      [first, name].compact.join(".")
    }
  else
    []
  end
end

#documentObject



115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/graphql/repl.rb', line 115

def document
  calls = self.calls

  operation_type = case calls[0][0]
  when :query
    calls.shift
    "query"
  when :mutation
    calls.shift
    "mutation"
  else
    "query"
  end

  selection = calls.reverse.reduce(nil) do |child, call|
    case call[0]
    when :[]
      child
    when :on
      type = GraphQL::Language::Nodes::TypeName.new(name: call[1].to_s)
      node = GraphQL::Language::Nodes::InlineFragment.new(type: type)
      node.selections = [child] if child
      node
    else
      arguments = []

      (call[1] || {}).each do |name, value|
        arguments << GraphQL::Language::Nodes::Argument.new(name: name.to_s, value: value)
      end

      node = GraphQL::Language::Nodes::Field.new(name: call[0].to_s, arguments: arguments)
      node.selections = [child] if child
      node
    end
  end

  operation = GraphQL::Language::Nodes::OperationDefinition.new(operation_type: operation_type, selections: [selection])
  GraphQL::Language::Nodes::Document.new(definitions: [operation])
end

#error_messageObject



191
192
193
194
195
196
# File 'lib/graphql/repl.rb', line 191

def error_message
  validator = GraphQL::StaticValidation::Validator.new(schema: @schema)
  query = GraphQL::Query.new(@schema, document: document)
  errors = validator.validate(query)
  errors.fetch(:errors)[0]&.message
end

#response_pathObject



102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/graphql/repl.rb', line 102

def response_path
  calls.reduce([]) do |path, (name, *args)|
    case name
    when :query, :mutation, :on
      path
    when :[]
      path << args[0]
    else
      path << name.to_s
    end
  end
end

#return_typeObject



155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
# File 'lib/graphql/repl.rb', line 155

def return_type
  visitor = GraphQL::Language::Visitor.new(document)
  type_stack = GraphQL::StaticValidation::TypeStack.new(@schema, visitor)

  stack = []

  visitor[GraphQL::Language::Nodes::OperationDefinition] << ->(node, _parent) do
    stack << type_stack.object_types.last
  end
  visitor[GraphQL::Language::Nodes::FragmentDefinition] << ->(node, _parent) do
    stack << type_stack.object_types.last
  end
  visitor[GraphQL::Language::Nodes::Field] << ->(node, _parent) do
    stack << type_stack.field_definitions.last&.type
  end
  visitor[GraphQL::Language::Nodes::InlineFragment] << ->(node, _parent) do
    stack << type_stack.object_types.last
  end
  visitor.visit

  type = stack.last
  type = type.of_type if type.is_a?(GraphQL::NonNullType)

  if type.is_a?(GraphQL::ListType)
    if response_path.last.is_a?(Integer)
      type.unwrap.name
    else
      "List"
    end
  elsif type
    type.name
  else
    nil
  end
end