graphql 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 290e890d0a805c3587000af2fbbacf910cf8baf0
4
- data.tar.gz: 745511749686efb279e0ee7b7af2484d0ccd82ed
3
+ metadata.gz: 6184108ff2ba0151d12bfaeb02feeacbdeba74cc
4
+ data.tar.gz: 2a9cb034382d28f96a7e29024814848b63596a49
5
5
  SHA512:
6
- metadata.gz: 81ba92e0aed50365b5ccd78ab02c035bc0a1ae212669f7d5c668cbe7fec3e48158f9a53a5859b2ece3ebc54d3634187635477a85cf50f2b8d24a822476517b53
7
- data.tar.gz: 3a46fb67c848c7b85768979071d28df3b2e21e29087395b5a3ab2297d0660bd51ba84c628678e098a1faae392ef9a4e30d8be0007575ef32468f98c2c043badf
6
+ metadata.gz: 7bb555f0b19ce78ea3f79ba7388f31509c26e2518fc1c207a25e83bcdd4f38e3670194bcb26a1447dc134a5949e58d10e12da79846bb2b3fb4dab0d688561a8a
7
+ data.tar.gz: 695837ba820b7709453584800eaa6d3f4082edc9d443055ab52d42e0db3b895189c2c10113a04d43e44c70726365621b99a878cc68a371acd85b46aeb05b925a
@@ -5,20 +5,21 @@ require "parslet"
5
5
  require "singleton"
6
6
 
7
7
  module GraphQL
8
- autoload(:Call, "graphql/call")
9
- autoload(:Connection, "graphql/connection")
10
- autoload(:Field, "graphql/field")
11
- autoload(:FieldDefiner, "graphql/field_definer")
12
- autoload(:Node, "graphql/node")
13
- autoload(:Parser, "graphql/parser")
14
- autoload(:Query, "graphql/query")
15
- autoload(:RootCall, "graphql/root_call")
8
+ autoload(:Call, "graphql/call")
9
+ autoload(:Connection, "graphql/connection")
10
+ autoload(:Field, "graphql/field")
11
+ autoload(:FieldDefiner, "graphql/field_definer")
12
+ autoload(:Node, "graphql/node")
13
+ autoload(:Parser, "graphql/parser")
14
+ autoload(:Query, "graphql/query")
15
+ autoload(:RootCall, "graphql/root_call")
16
16
  autoload(:RootCallArgument, "graphql/root_call_argument")
17
- autoload(:RootCallArgumentDefiner, "graphql/root_call_argument_definer")
18
- autoload(:Schema, "graphql/schema")
19
- autoload(:Transform, "graphql/transform")
20
- autoload(:VERSION, "graphql/version")
17
+ autoload(:RootCallArgumentDefiner, "graphql/root_call_argument_definer")
18
+ autoload(:Schema, "graphql/schema")
19
+ autoload(:Transform, "graphql/transform")
20
+ autoload(:VERSION, "graphql/version")
21
21
 
22
+ # These objects are used for introspections (eg, responding to `schema()` calls).
22
23
  module Introspection
23
24
  autoload(:CallNode, "graphql/introspection/call_node")
24
25
  autoload(:Connection, "graphql/introspection/connection")
@@ -31,7 +32,7 @@ module GraphQL
31
32
  autoload(:TypeNode, "graphql/introspection/type_node")
32
33
  end
33
34
 
34
-
35
+ # These objects are skinny wrappers for going from the AST to actual {Node} and {Field} instances.
35
36
  module Syntax
36
37
  autoload(:Call, "graphql/syntax/call")
37
38
  autoload(:Field, "graphql/syntax/field")
@@ -40,6 +41,7 @@ module GraphQL
40
41
  autoload(:Variable, "graphql/syntax/variable")
41
42
  end
42
43
 
44
+ # These fields wrap Ruby data types and some GraphQL internal values.
43
45
  module Types
44
46
  autoload(:BooleanField, "graphql/types/boolean_field")
45
47
  autoload(:ConnectionField, "graphql/types/connection_field")
@@ -49,35 +51,41 @@ module GraphQL
49
51
  autoload(:StringField, "graphql/types/string_field")
50
52
  autoload(:TypeField, "graphql/types/type_field")
51
53
  end
52
-
54
+ # @abstract
55
+ # Base class for all errors, so you can rescue from all graphql errors at once.
53
56
  class Error < RuntimeError; end
57
+ # This node doesn't have a field with that name.
54
58
  class FieldNotDefinedError < Error
55
59
  def initialize(class_name, field_name)
56
60
  super("#{class_name}##{field_name} was requested, but it isn't defined. Defined fields are: #{SCHEMA.field_names}")
57
61
  end
58
62
  end
63
+ # There's no Node defined for that kind of object.
59
64
  class NodeNotDefinedError < Error
60
65
  def initialize(node_name)
61
66
  super("#{node_name} was requested but was not found. Defined nodes are: #{SCHEMA.type_names}")
62
67
  end
63
68
  end
69
+ # This node doesn't have a connection with that name.
64
70
  class ConnectionNotDefinedError < Error
65
71
  def initialize(node_name)
66
72
  super("#{node_name} was requested but was not found. Defined connections are: #{SCHEMA.connection_names}")
67
73
  end
68
74
  end
75
+ # The root call of this query isn't in the schema.
69
76
  class RootCallNotDefinedError < Error
70
77
  def initialize(name)
71
78
  super("Call '#{name}' was requested but was not found. Defined calls are: #{SCHEMA.call_names}")
72
79
  end
73
80
  end
81
+ # The query couldn't be parsed.
74
82
  class SyntaxError < Error
75
83
  def initialize(line, col, string)
76
84
  lines = string.split("\n")
77
85
  super("Syntax Error at (#{line}, #{col}), check usage: #{string}")
78
86
  end
79
87
  end
80
-
88
+ # This root call takes different arguments.
81
89
  class RootCallArgumentError < Error
82
90
  def initialize(declaration, actual)
83
91
  super("Wrong type for #{declaration.name}: expected a #{declaration.type} but got #{actual}")
@@ -85,6 +93,7 @@ module GraphQL
85
93
  end
86
94
 
87
95
  PARSER = Parser.new
96
+ # This singleton contains all defined nodes and fields.
88
97
  SCHEMA = Schema.instance
89
98
  TRANSFORM = Transform.new
90
99
  # preload these so they're in SCHEMA
@@ -1,3 +1,4 @@
1
+ # Created by {Field.call}, used internally by GraphQL.
1
2
  class GraphQL::Call
2
3
  attr_reader :name, :lambda
3
4
  def initialize(name:, lambda:)
@@ -1,3 +1,44 @@
1
+ # {Connection}s wrap collections of objects.
2
+ #
3
+ # Out of the box, the only field it has is `edges`, which provides access to the members of the collection.
4
+ #
5
+ # You can define a custom {Connection} to use. This allows you to define fields at the collection level (rather than the item level)
6
+ #
7
+ # Custom fields can access the collection as {Field#items}.
8
+ #
9
+ # @example
10
+ # class UpvotesConnection < GraphQL::Collection
11
+ # field.number(:count)
12
+ # field.boolean(:any)
13
+ #
14
+ # def count
15
+ # items.count
16
+ # end
17
+ #
18
+ # def any
19
+ # items.any?
20
+ # end
21
+ # end
22
+ #
23
+ # # Then, this connection will be used for connections whose names match:
24
+ # class PostNode < GraphQL::Node
25
+ # field.connection(:upvotes)
26
+ # # ^^ uses `UpvotesConnection` based on naming convention
27
+ # end
28
+ #
29
+ # # And you can use the fields in a query:
30
+ # <<QUERY
31
+ # find_post(10) {
32
+ # title,
33
+ # upvotes {
34
+ # count,
35
+ # any,
36
+ # edges {
37
+ # node { created_at }
38
+ # }
39
+ # }
40
+ # }
41
+ # QUERY
1
42
  class GraphQL::Connection < GraphQL::Node
2
43
  exposes "Array"
3
44
  field.any(:edges)
@@ -10,6 +51,7 @@ class GraphQL::Connection < GraphQL::Node
10
51
  @query = query
11
52
  end
12
53
 
54
+ # Returns the members of the collection, after any calls on the corresponding {Field} have been applied
13
55
  def items
14
56
  @target
15
57
  end
@@ -34,6 +76,8 @@ class GraphQL::Connection < GraphQL::Node
34
76
  end
35
77
 
36
78
  attr_accessor :default_connection
79
+ # Call this to make a the class the default connection
80
+ # when one isn't found by name.
37
81
  def default_connection!
38
82
  GraphQL::Connection.default_connection = self
39
83
  end
@@ -1,3 +1,42 @@
1
+ # {Field}s are used to safely lookup values on {Node}s. When you define a custom field, you can access it from {Node.field}
2
+ #
3
+ # `graphql` has built-in fields for some Ruby data types:
4
+ # - `boolean`: {Types::BooleanField}
5
+ # - `number`: {Types::NumberField}
6
+ # - `string`: {Types::StringField}
7
+ #
8
+ # You can define custom fields that allow you to control how values are exposed.
9
+ # - {Field.type} defines how it can be used inside {Node.field} calls.
10
+ # - {Field.call} defines calls that can mutate the value before it is added to the response.
11
+ #
12
+ # @example
13
+ # # For example, an `AddressField` which wraps a string but exposes address-specific information
14
+ # class AddressField < GraphQL::Field
15
+ # type :address
16
+ # # ^^ now you can use it with `field.address` in node definitions
17
+ #
18
+ # # calls can modify the value:
19
+ # # eg, get the numbers at the beginning:
20
+ # call :house_number, -> (prev_value) { prev_value[/^\d*/]}
21
+ # # get everything after a space:
22
+ # call :street_name, -> (prev_value) { prev_value[/\s.*$/].strip }
23
+ # end
24
+ #
25
+ # # Then, use it in a node definition:
26
+ # class HouseNode < GraphQL::Node
27
+ # exposes("House")
28
+ # # create an `AddressField` for this node called `street_address`:
29
+ # field.address(:street_address)
30
+ # end
31
+ #
32
+ # # Then, use the field in queries:
33
+ # <<QUERY
34
+ # find_house(1) {
35
+ # street_address,
36
+ # street_address.house_number() as number,
37
+ # street_address.street_name() as street,
38
+ # }
39
+ # QUERY
1
40
  class GraphQL::Field
2
41
  attr_reader :query, :owner, :calls, :fields
3
42
  def initialize(query: nil, owner: nil, calls: [], fields: [])
@@ -8,7 +47,7 @@ class GraphQL::Field
8
47
  end
9
48
 
10
49
  def raw_value
11
- owner.send(method)
50
+ owner.send(name)
12
51
  end
13
52
 
14
53
  def as_result
@@ -43,8 +82,6 @@ class GraphQL::Field
43
82
  end
44
83
  end
45
84
 
46
- def method; name; end
47
-
48
85
  class << self
49
86
  def inherited(child_class)
50
87
  GraphQL::SCHEMA.add_field(child_class)
@@ -72,7 +109,18 @@ class GraphQL::Field
72
109
  super
73
110
  end
74
111
  end
75
-
112
+ # @param [Symbol] type_name the name used for getting this field from the {GraphQL::SCHEMA}.
113
+ # Defines the name used for getting fields of this type from the schema.
114
+ # @example
115
+ # # define the field with its type:
116
+ # class IPAddressField < GraphQL::Field
117
+ # type :ip_address
118
+ # end
119
+ #
120
+ # # then, attach fields of this type to your nodes:
121
+ # class ServerNode < GraphQL::Field
122
+ # field.ip_address(:static_ip_address)
123
+ # end
76
124
  def type(value_type_name)
77
125
  @value_type = value_type_name.to_s
78
126
  GraphQL::SCHEMA.add_field(self)
@@ -103,14 +151,31 @@ class GraphQL::Field
103
151
  rescue NoMethodError
104
152
  {}
105
153
  end
154
+ # @param [String] name the identifier for this call
155
+ # @param [lambda] operation the transformation this call makes
156
+ #
157
+ # Define a call that can be made on this field.
158
+ # The `lambda` receives arguments:
159
+ # - 1: `previous_value` -- the value of this field
160
+ # - *: arguments passed in the query (as strings)
161
+ #
162
+ # @example
163
+ # # upcase a string field:
164
+ # call :upcase, -> (prev_value) { prev_value.upcase }
165
+ # @example
166
+ # # tests a number field:
167
+ # call :greater_than, -> (prev_value, test_value) { prev_value > test_value.to_f }
168
+ # # (`test_value` is passed in as a string)
169
+ def call(name, lambda)
170
+ _calls[name.to_s] = GraphQL::Call.new(name: name.to_s, lambda: lambda)
171
+ end
172
+
173
+ private
106
174
 
107
175
  def _calls
108
176
  @calls ||= {}
109
177
  end
110
178
 
111
- def call(name, lambda)
112
- _calls[name.to_s] = GraphQL::Call.new(name: name.to_s, lambda: lambda)
113
- end
114
179
  end
115
180
 
116
181
  type :any
@@ -1,9 +1,13 @@
1
+ # Every {Node} class has a {FieldDefiner} instance that
2
+ # enables the `field.{something}` API.
1
3
  class GraphQL::FieldDefiner
2
4
  attr_reader :owner_class
3
5
  def initialize(owner_class)
4
6
  @owner_class = owner_class
5
7
  end
6
8
 
9
+ # `method_name` is used as a field type and looked up against {GraphQL::SCHEMA}.
10
+ # `args[0]` is the name for the field of that type.
7
11
  def method_missing(method_name, *args, &block)
8
12
  type = GraphQL::SCHEMA.get_field(method_name)
9
13
  if type.present?
@@ -13,6 +17,8 @@ class GraphQL::FieldDefiner
13
17
  end
14
18
  end
15
19
 
20
+ private
21
+
16
22
  def create_field(field_name, type: nil, description: nil)
17
23
  field_name = field_name.to_s
18
24
  field_class = GraphQL::Field.create_class({
@@ -1,3 +1,6 @@
1
+ # Parser is a [parslet](http://kschiess.github.io/parslet/) parser for parsing queries.
2
+ #
3
+ # If it failes to parse, a {SyntaxError} is raised.
1
4
  class GraphQL::Parser < Parslet::Parser
2
5
  root(:query)
3
6
  rule(:query) { node.repeat.as(:nodes) >> variable.repeat.as(:variables) }
@@ -7,7 +7,9 @@
7
7
  # result = query.as_result
8
8
 
9
9
  class GraphQL::Query
10
- attr_reader :query_string, :root, :context
10
+ # This is the object passed to {#initialize} as `context:`
11
+ attr_reader :context
12
+ attr_reader :query_string, :root
11
13
 
12
14
  # @param [String] query_string the string to be parsed
13
15
  # @param [Object] context an object which will be available to all nodes and fields in the schema
@@ -34,6 +34,8 @@
34
34
  #
35
35
  class GraphQL::RootCall
36
36
  attr_reader :query, :arguments
37
+
38
+ # Validates arguments against declared {.argument}s
37
39
  def initialize(query:, syntax_arguments:)
38
40
  @query = query
39
41
 
@@ -46,18 +48,23 @@ class GraphQL::RootCall
46
48
  syntax_arg
47
49
  end
48
50
 
49
- self.class.typecast(idx, value)
51
+ typecast(idx, value)
50
52
  end
51
53
  end
52
54
 
55
+ # @param [Array] args (splat) all args provided in query string (as strings)
56
+ # This method is invoked with the arguments provided to the query.
57
+ # It should do work and return values matching the {.returns} declarations
53
58
  def execute!(*args)
54
59
  raise NotImplementedError, "Do work in this method"
55
60
  end
56
61
 
62
+ # The object passed to {Query#initialize} as `context`
57
63
  def context
58
64
  query.context
59
65
  end
60
66
 
67
+ # Executes the call, validates the return values against declared {.returns}, then returns the return values.
61
68
  def as_result
62
69
  return_declarations = self.class.return_declarations
63
70
  raise "#{self.class.name} must declare returns" unless return_declarations.present?
@@ -123,7 +130,10 @@ class GraphQL::RootCall
123
130
  end
124
131
 
125
132
  # @return [GraphQL::RootCallArgumentDefiner] definer
126
- # Use this object to declare arguments.
133
+ # Use this object to declare arguments. They must be declared in order
134
+ # @example
135
+ # argument.string("post_title")
136
+ # argument.object("comment_data") # allows a JSON object
127
137
  def argument
128
138
  @argument ||= GraphQL::RootCallArgumentDefiner.new(self)
129
139
  end
@@ -138,39 +148,42 @@ class GraphQL::RootCall
138
148
  rescue NoMethodError
139
149
  own
140
150
  end
151
+ end
141
152
 
142
- def argument_for_index(idx)
143
- if arguments.first.any_number
144
- arguments.first
145
- else
146
- arguments[idx]
147
- end
148
- end
153
+ private
149
154
 
150
- TYPE_CHECKS = {
151
- "object" => Hash,
152
- "number" => Numeric,
153
- "string" => String,
154
- }
155
+ TYPE_CHECKS = {
156
+ "object" => Hash,
157
+ "number" => Numeric,
158
+ "string" => String,
159
+ }
155
160
 
156
- def typecast(idx, value)
157
- arg_dec = argument_for_index(idx)
158
- expected_type = arg_dec.type
159
- expected_type_class = TYPE_CHECKS[expected_type]
161
+ def argument_for_index(idx)
162
+ if self.class.arguments.first.any_number
163
+ self.class.arguments.first
164
+ else
165
+ self.class.arguments[idx]
166
+ end
167
+ end
160
168
 
161
- if expected_type == "string"
162
- parsed_value = value
163
- else
164
- parsed_value = JSON.parse('{ "value" : ' + value + '}')["value"]
165
- end
169
+ def typecast(idx, value)
170
+ arg_dec = argument_for_index(idx)
171
+ expected_type = arg_dec.type
172
+ expected_type_class = TYPE_CHECKS[expected_type]
166
173
 
167
- if !parsed_value.is_a?(expected_type_class)
168
- raise GraphQL::RootCallArgumentError.new(arg_dec, value)
169
- end
174
+ if expected_type == "string"
175
+ parsed_value = value
176
+ else
177
+ parsed_value = JSON.parse('{ "value" : ' + value + '}')["value"]
178
+ end
170
179
 
171
- parsed_value
172
- rescue JSON::ParserError
180
+ if !parsed_value.is_a?(expected_type_class)
173
181
  raise GraphQL::RootCallArgumentError.new(arg_dec, value)
174
182
  end
183
+
184
+ parsed_value
185
+ rescue JSON::ParserError
186
+ raise GraphQL::RootCallArgumentError.new(arg_dec, value)
175
187
  end
188
+
176
189
  end
@@ -1,3 +1,4 @@
1
+ # Created by {RootCall.argument}, used internally by GraphQL
1
2
  class GraphQL::RootCallArgument
2
3
  attr_reader :type, :name, :any_number
3
4
  def initialize(type:, name:, any_number: false)
@@ -1,3 +1,4 @@
1
+ # Enables the {RootCall.argument} API, used internall by GraphQL
1
2
  class GraphQL::RootCallArgumentDefiner
2
3
  ARGUMENT_TYPES = [:string, :object, :number]
3
4
 
@@ -1,6 +1,6 @@
1
1
  # {GraphQL::SCHEMA} keeps track of defined nodes, fields and calls.
2
+ #
2
3
  # Although you don't interact with it directly, it responds to queries for `schema()` and `__type__` info.
3
-
4
4
  class GraphQL::Schema
5
5
  include Singleton
6
6
  attr_reader :types, :calls, :fields, :class_names, :connections
@@ -1,3 +1,4 @@
1
+ # {Transform} is a [parslet](http://kschiess.github.io/parslet/) transform for for turning the AST into objects in {GraphQL::Syntax}.
1
2
  class GraphQL::Transform < Parslet::Transform
2
3
  # query
3
4
  rule(nodes: sequence(:n), variables: sequence(:v)) { GraphQL::Syntax::Query.new(nodes: n, variables: v)}
@@ -1,3 +1,3 @@
1
1
  module GraphQL
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
data/readme.md CHANGED
@@ -3,30 +3,31 @@
3
3
  [![Build Status](https://travis-ci.org/rmosolgo/graphql-ruby.svg?branch=master)](https://travis-ci.org/rmosolgo/graphql-ruby)
4
4
  [![Gem Version](https://badge.fury.io/rb/graphql.svg)](https://rubygems.org/gems/graphql)
5
5
  [![Dependency Status](https://gemnasium.com/rmosolgo/graphql-ruby.svg)](https://gemnasium.com/rmosolgo/graphql-ruby)
6
+ [![Code Climate](https://codeclimate.com/github/rmosolgo/graphql-ruby/badges/gpa.svg)](https://codeclimate.com/github/rmosolgo/graphql-ruby)
7
+ [![Test Coverage](https://codeclimate.com/github/rmosolgo/graphql-ruby/badges/coverage.svg)](https://codeclimate.com/github/rmosolgo/graphql-ruby)
8
+ ![image](https://cloud.githubusercontent.com/assets/2231765/6424458/d5fd3896-beae-11e4-892a-77e135e6bf37.png)
6
9
 
10
+ Create a GraphQL interface by implementing [__nodes__](#nodes) and [__calls__](#calls), then running [__queries__](#queries).
7
11
 
8
- Create a GraphQL interface by implementing _nodes_ and _connections_, then running queries.
12
+ API Docs: <http://rubydoc.info/gems/graphql>
9
13
 
10
14
  ## To do:
11
15
 
12
-
13
16
  - Allow a default connection class, or some way to infer connection from name
14
17
  - right now, `Introspection::Connection` isn't getting used, only `ApplicationConnection` is.
15
-
16
18
  - How do you express failure? HTTP response? `errors` key?
17
- - Handle blank objects in nested calls
19
+ - Handle blank objects in nested calls (how? wait for spec)
18
20
  - Implement calls as arguments
19
21
  - double-check how to handle `pals.first(3) { count }`
20
22
  - Implement call argument introspection (wait for spec)
21
23
  - For fields that return objects, can they be queried _without_ other fields? Or must they always have fields?
22
- - __document__ (wait for spec)
23
24
 
24
25
  ## Example Implementation
25
26
 
26
27
  - See test implementation in [`/spec/support/dummy_app/nodes.rb`](https://github.com/rmosolgo/graphql/blob/master/spec/support/nodes.rb)
27
28
  - See `graphql-ruby-demo` with Rails on [github](https://github.com/rmosolgo/graphql-ruby-demo) or [heroku](http://graphql-ruby-demo.herokuapp.com/)
28
29
 
29
- ![gql](https://cloud.githubusercontent.com/assets/2231765/6217972/5d24edda-b5ce-11e4-9e07-3548304af862.png)
30
+ <a href="http://graphql-ruby-demo.herokuapp.com/" target="_blank"><img src="https://cloud.githubusercontent.com/assets/2231765/6217972/5d24edda-b5ce-11e4-9e07-3548304af862.png" style="max-width: 800px;"/></a>
30
31
 
31
32
 
32
33
  ## Usage
@@ -147,4 +148,3 @@ result
147
148
  ```
148
149
 
149
150
  You could do something like this [inside a Rails controller](https://github.com/rmosolgo/graphql-ruby-demo/blob/master/app/controllers/queries_controller.rb#L5).
150
-
@@ -9,11 +9,8 @@ describe GraphQL::Field do
9
9
  it 'is present' do
10
10
  assert_equal field.name, "high_fives"
11
11
  end
12
- end
13
-
14
- describe '#method' do
15
12
  it 'defaults to name' do
16
- assert_equal "high_fives", field.method
13
+ assert_equal "high_fives", field.name
17
14
  end
18
15
  end
19
16
 
@@ -1,3 +1,6 @@
1
+ require "codeclimate-test-reporter"
2
+ CodeClimate::TestReporter.start
3
+
1
4
  require 'date'
2
5
  require "minitest/autorun"
3
6
  require "minitest/focus"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: graphql
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robert Mosolgo
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: 1.6.2
41
+ - !ruby/object:Gem::Dependency
42
+ name: codeclimate-test-reporter
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0.4'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0.4'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: pry
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -204,7 +218,7 @@ files:
204
218
  - spec/spec_helper.rb
205
219
  - spec/support/dummy_app.rb
206
220
  - spec/support/nodes.rb
207
- homepage: http://github.com/rmosolgo/graphql
221
+ homepage: http://github.com/rmosolgo/graphql-ruby
208
222
  licenses:
209
223
  - MIT
210
224
  metadata: {}