graphql 1.9.6 → 1.9.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (102) hide show
  1. checksums.yaml +5 -5
  2. data/lib/generators/graphql/install_generator.rb +2 -1
  3. data/lib/generators/graphql/templates/base_field.erb +7 -0
  4. data/lib/graphql/analysis/ast/visitor.rb +5 -2
  5. data/lib/graphql/execution/multiplex.rb +5 -1
  6. data/lib/graphql/query.rb +6 -1
  7. data/lib/graphql/relay/array_connection.rb +1 -1
  8. data/lib/graphql/schema.rb +15 -1
  9. data/lib/graphql/schema/argument.rb +5 -1
  10. data/lib/graphql/schema/input_object.rb +21 -12
  11. data/lib/graphql/schema/introspection_system.rb +6 -1
  12. data/lib/graphql/schema/member/has_arguments.rb +4 -2
  13. data/lib/graphql/schema/resolver.rb +8 -3
  14. data/lib/graphql/schema/subscription.rb +22 -0
  15. data/lib/graphql/schema/timeout.rb +109 -0
  16. data/lib/graphql/types/relay/base_edge.rb +0 -3
  17. data/lib/graphql/upgrader/member.rb +148 -111
  18. data/lib/graphql/version.rb +1 -1
  19. data/readme.md +1 -1
  20. data/spec/fixtures/upgrader/mutation.original.rb +28 -0
  21. data/spec/fixtures/upgrader/mutation.transformed.rb +28 -0
  22. data/spec/graphql/analysis/ast_spec.rb +27 -0
  23. data/spec/graphql/execution/instrumentation_spec.rb +34 -6
  24. data/spec/graphql/execution/multiplex_spec.rb +11 -0
  25. data/spec/graphql/internal_representation/rewrite_spec.rb +6 -1
  26. data/spec/graphql/schema/input_object_spec.rb +56 -7
  27. data/spec/graphql/schema/introspection_system_spec.rb +24 -0
  28. data/spec/graphql/schema/subscription_spec.rb +65 -0
  29. data/spec/graphql/schema/timeout_spec.rb +206 -0
  30. data/spec/integration/mongoid/star_trek/schema.rb +1 -2
  31. data/spec/integration/rails/graphql/input_object_spec.rb +19 -0
  32. data/spec/integration/rails/graphql/relay/array_connection_spec.rb +47 -28
  33. data/spec/integration/rails/graphql/schema_spec.rb +18 -0
  34. data/spec/integration/tmp/app/graphql/types/date_type.rb +14 -0
  35. data/spec/integration/tmp/dummy/Gemfile +50 -0
  36. data/spec/integration/tmp/dummy/README.md +24 -0
  37. data/spec/integration/tmp/dummy/Rakefile +6 -0
  38. data/spec/integration/tmp/dummy/app/assets/config/manifest.js +3 -0
  39. data/spec/integration/tmp/dummy/app/assets/javascripts/application.js +16 -0
  40. data/spec/integration/tmp/dummy/app/assets/javascripts/cable.js +13 -0
  41. data/spec/integration/tmp/dummy/app/assets/stylesheets/application.css +15 -0
  42. data/spec/integration/tmp/dummy/app/channels/application_cable/channel.rb +5 -0
  43. data/spec/integration/tmp/dummy/app/channels/application_cable/connection.rb +5 -0
  44. data/spec/integration/tmp/dummy/app/controllers/application_controller.rb +4 -0
  45. data/spec/integration/tmp/dummy/app/controllers/graphql_controller.rb +44 -0
  46. data/spec/integration/tmp/dummy/app/helpers/application_helper.rb +3 -0
  47. data/spec/integration/tmp/dummy/app/jobs/application_job.rb +3 -0
  48. data/spec/integration/tmp/dummy/app/mailers/application_mailer.rb +5 -0
  49. data/spec/integration/tmp/dummy/app/mydirectory/dummy_schema.rb +5 -0
  50. data/spec/integration/tmp/dummy/app/mydirectory/mutations/update_name.rb +15 -0
  51. data/spec/integration/tmp/dummy/app/mydirectory/types/base_enum.rb +5 -0
  52. data/spec/integration/tmp/dummy/app/mydirectory/types/base_input_object.rb +5 -0
  53. data/spec/integration/tmp/dummy/app/mydirectory/types/base_interface.rb +6 -0
  54. data/spec/integration/tmp/dummy/app/mydirectory/types/base_object.rb +5 -0
  55. data/spec/integration/tmp/dummy/app/mydirectory/types/base_scalar.rb +5 -0
  56. data/spec/integration/tmp/dummy/app/mydirectory/types/base_union.rb +5 -0
  57. data/spec/integration/tmp/dummy/app/mydirectory/types/mutation_type.rb +12 -0
  58. data/spec/integration/tmp/dummy/app/mydirectory/types/query_type.rb +14 -0
  59. data/spec/integration/tmp/dummy/app/views/layouts/application.html.erb +14 -0
  60. data/spec/integration/tmp/dummy/app/views/layouts/mailer.html.erb +13 -0
  61. data/spec/integration/tmp/dummy/app/views/layouts/mailer.text.erb +1 -0
  62. data/spec/integration/tmp/dummy/bin/bundle +3 -0
  63. data/spec/integration/tmp/dummy/bin/rails +4 -0
  64. data/spec/integration/tmp/dummy/bin/rake +4 -0
  65. data/spec/integration/tmp/dummy/bin/setup +34 -0
  66. data/spec/integration/tmp/dummy/bin/update +29 -0
  67. data/spec/integration/tmp/dummy/config.ru +5 -0
  68. data/spec/integration/tmp/dummy/config/application.rb +26 -0
  69. data/spec/integration/tmp/dummy/config/boot.rb +4 -0
  70. data/spec/integration/tmp/dummy/config/cable.yml +9 -0
  71. data/spec/integration/tmp/dummy/config/environment.rb +6 -0
  72. data/spec/integration/tmp/dummy/config/environments/development.rb +52 -0
  73. data/spec/integration/tmp/dummy/config/environments/production.rb +84 -0
  74. data/spec/integration/tmp/dummy/config/environments/test.rb +43 -0
  75. data/spec/integration/tmp/dummy/config/initializers/application_controller_renderer.rb +9 -0
  76. data/spec/integration/tmp/dummy/config/initializers/assets.rb +12 -0
  77. data/spec/integration/tmp/dummy/config/initializers/backtrace_silencers.rb +8 -0
  78. data/spec/integration/tmp/dummy/config/initializers/cookies_serializer.rb +6 -0
  79. data/spec/integration/tmp/dummy/config/initializers/filter_parameter_logging.rb +5 -0
  80. data/spec/integration/tmp/dummy/config/initializers/inflections.rb +17 -0
  81. data/spec/integration/tmp/dummy/config/initializers/mime_types.rb +5 -0
  82. data/spec/integration/tmp/dummy/config/initializers/new_framework_defaults.rb +24 -0
  83. data/spec/integration/tmp/dummy/config/initializers/session_store.rb +4 -0
  84. data/spec/integration/tmp/dummy/config/initializers/wrap_parameters.rb +10 -0
  85. data/spec/integration/tmp/dummy/config/locales/en.yml +23 -0
  86. data/spec/integration/tmp/dummy/config/puma.rb +48 -0
  87. data/spec/integration/tmp/dummy/config/routes.rb +9 -0
  88. data/spec/integration/tmp/dummy/config/secrets.yml +22 -0
  89. data/spec/integration/tmp/dummy/db/seeds.rb +8 -0
  90. data/spec/integration/tmp/dummy/log/test.log +0 -0
  91. data/spec/integration/tmp/dummy/public/404.html +67 -0
  92. data/spec/integration/tmp/dummy/public/422.html +67 -0
  93. data/spec/integration/tmp/dummy/public/500.html +66 -0
  94. data/spec/integration/tmp/dummy/public/apple-touch-icon-precomposed.png +0 -0
  95. data/spec/integration/tmp/dummy/public/apple-touch-icon.png +0 -0
  96. data/spec/integration/tmp/dummy/public/favicon.ico +0 -0
  97. data/spec/integration/tmp/dummy/public/robots.txt +5 -0
  98. data/spec/integration/tmp/dummy/test/test_helper.rb +8 -0
  99. data/spec/support/jazz.rb +6 -0
  100. data/spec/support/star_wars/schema.rb +1 -2
  101. metadata +171 -6
  102. data/spec/integration/tmp/app/graphql/types/bird_type.rb +0 -7
@@ -55,7 +55,6 @@ module StarTrek
55
55
 
56
56
  class CustomBaseEdgeType < GraphQL::Types::Relay::BaseEdge
57
57
  node_type(BaseType)
58
- graphql_name "CustomBaseEdge"
59
58
  field :upcased_name, String, null: true
60
59
  field :upcased_parent_name, String, null: true
61
60
  field :edge_class_name, String, null: true
@@ -413,7 +412,7 @@ module StarTrek
413
412
  end
414
413
 
415
414
  def self.id_from_object(object, type, ctx)
416
- GraphQL::Schema::UniqueWithinType.encode(type.name, object.id)
415
+ GraphQL::Schema::UniqueWithinType.encode(type.graphql_name, object.id)
417
416
  end
418
417
 
419
418
  lazy_resolve(LazyWrapper, :value)
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+ require "spec_helper"
3
+
4
+ describe GraphQL::Schema::InputObject do
5
+ let(:input_object) do
6
+ Dummy::DairyProductInput.new(
7
+ { source: 'COW', fatContent: 0.8 },
8
+ defaults_used: Set.new,
9
+ context: GraphQL::Query::NullContext)
10
+ end
11
+
12
+ describe '#to_json' do
13
+ it 'returns JSON serialized representation of the variables hash' do
14
+ # Regression note: Previously, calling `to_json` on input objects caused stack too deep errors
15
+ assert_equal input_object.to_json, { source: "COW", fat_content: 0.8 }.to_json
16
+ end
17
+ end
18
+ end
19
+
@@ -65,35 +65,7 @@ describe GraphQL::Relay::ArrayConnection do
65
65
  assert_equal("NQ", result["data"]["rebels"]["ships"]["pageInfo"]["endCursor"])
66
66
  end
67
67
 
68
- it "provides bidirectional_pagination" do
69
- result = star_wars_query(query_string, "first" => 1)
70
- last_cursor = get_last_cursor(result)
71
-
72
- # When going forwards, bi-directional pagination
73
- # returns `true` even for `hasPreviousPage`
74
- result = star_wars_query(query_string, "first" => 1, "after" => last_cursor)
75
- assert_equal(true, get_page_info(result, "ships")["hasNextPage"])
76
- assert_equal(false, get_page_info(result, "ships")["hasPreviousPage"])
77
-
78
- result = with_bidirectional_pagination {
79
- star_wars_query(query_string, "first" => 3, "after" => last_cursor)
80
- }
81
- assert_equal(true, get_page_info(result, "ships")["hasNextPage"])
82
- assert_equal(true, get_page_info(result, "ships")["hasPreviousPage"])
83
-
84
- # When going backwards, bi-directional pagination
85
- # returns true for `hasNextPage`
86
- last_cursor = get_last_cursor(result)
87
- result = star_wars_query(query_string, "last" => 1, "before" => last_cursor)
88
- assert_equal(false, get_page_info(result, "ships")["hasNextPage"])
89
- assert_equal(true, get_page_info(result, "ships")["hasPreviousPage"])
90
68
 
91
- result = with_bidirectional_pagination {
92
- star_wars_query(query_string, "last" => 2, "before" => last_cursor)
93
- }
94
- assert_equal(true, get_page_info(result, "ships")["hasNextPage"])
95
- assert_equal(true, get_page_info(result, "ships")["hasPreviousPage"])
96
- end
97
69
 
98
70
  it 'slices the result' do
99
71
  result = star_wars_query(query_string, "first" => 1)
@@ -286,5 +258,52 @@ describe GraphQL::Relay::ArrayConnection do
286
258
  assert_equal(first_second_and_third_names, get_names(result))
287
259
  end
288
260
  end
261
+
262
+ describe "bidirectional pagination" do
263
+ it "provides bidirectional_pagination" do
264
+ result = star_wars_query(query_string, "first" => 1)
265
+ last_cursor = get_last_cursor(result)
266
+
267
+ # When going forwards, bi-directional pagination
268
+ # returns `true` even for `hasPreviousPage`
269
+ result = star_wars_query(query_string, "first" => 1, "after" => last_cursor)
270
+ assert_equal(true, get_page_info(result, "ships")["hasNextPage"])
271
+ assert_equal(false, get_page_info(result, "ships")["hasPreviousPage"])
272
+
273
+ result = with_bidirectional_pagination {
274
+ star_wars_query(query_string, "first" => 3, "after" => last_cursor)
275
+ }
276
+ assert_equal(true, get_page_info(result, "ships")["hasNextPage"])
277
+ assert_equal(true, get_page_info(result, "ships")["hasPreviousPage"])
278
+
279
+ # When going backwards, bi-directional pagination
280
+ # returns true for `hasNextPage`
281
+ last_cursor = get_last_cursor(result)
282
+ result = star_wars_query(query_string, "last" => 1, "before" => last_cursor)
283
+ assert_equal(false, get_page_info(result, "ships")["hasNextPage"])
284
+ assert_equal(true, get_page_info(result, "ships")["hasPreviousPage"])
285
+
286
+ result = with_bidirectional_pagination {
287
+ star_wars_query(query_string, "last" => 2, "before" => last_cursor)
288
+ }
289
+ assert_equal(true, get_page_info(result, "ships")["hasNextPage"])
290
+ assert_equal(true, get_page_info(result, "ships")["hasPreviousPage"])
291
+ end
292
+
293
+ it "returns correct page info when the before cursor belongs to the last element in the array" do
294
+ result = with_bidirectional_pagination{
295
+ star_wars_query(query_string, "last" => 1)
296
+ }
297
+
298
+ last_cursor = get_last_cursor(result)
299
+
300
+ result = with_bidirectional_pagination{
301
+ star_wars_query(query_string, "before" => last_cursor, "last" => 1)
302
+ }
303
+
304
+ assert_equal(true, get_page_info(result, "ships")["hasNextPage"])
305
+ assert_equal(true, get_page_info(result, "ships")["hasPreviousPage"])
306
+ end
307
+ end
289
308
  end
290
309
  end
@@ -129,6 +129,24 @@ describe GraphQL::Schema do
129
129
  end
130
130
  end
131
131
 
132
+ describe "#disable_introspection_entry_points" do
133
+ it "enables entry points by default" do
134
+ refute_empty empty_schema.introspection_system.entry_points
135
+ end
136
+
137
+ describe "when disable_introspection_entry_points is configured" do
138
+ let(:schema) do
139
+ GraphQL::Schema.define do
140
+ disable_introspection_entry_points
141
+ end
142
+ end
143
+
144
+ it "clears entry points" do
145
+ assert_empty schema.introspection_system.entry_points
146
+ end
147
+ end
148
+ end
149
+
132
150
  describe "object_from_id" do
133
151
  describe "when the hook wasn't implemented" do
134
152
  it "raises not implemented" do
@@ -0,0 +1,14 @@
1
+ # typed: true
2
+ module Types
3
+ class DateType < Types::BaseScalar
4
+ def self.coerce_input(input_value, context)
5
+ # Override this to prepare a client-provided GraphQL value for your Ruby code
6
+ input_value
7
+ end
8
+
9
+ def self.coerce_result(ruby_value, context)
10
+ # Override this to serialize a Ruby value for the GraphQL response
11
+ ruby_value.to_s
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,50 @@
1
+ source 'https://rubygems.org'
2
+
3
+ git_source(:github) do |repo_name|
4
+ repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?("/")
5
+ "https://github.com/#{repo_name}.git"
6
+ end
7
+
8
+
9
+ # Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
10
+ gem 'rails', '~> 5.0.7', '>= 5.0.7.2'
11
+ # Use Puma as the app server
12
+ gem 'puma', '~> 3.0'
13
+ # Use SCSS for stylesheets
14
+ gem 'sass-rails', '~> 5.0'
15
+ # Use Uglifier as compressor for JavaScript assets
16
+ gem 'uglifier', '>= 1.3.0'
17
+ # Use CoffeeScript for .coffee assets and views
18
+ gem 'coffee-rails', '~> 4.2'
19
+ # See https://github.com/rails/execjs#readme for more supported runtimes
20
+ # gem 'therubyracer', platforms: :ruby
21
+
22
+ # Use jquery as the JavaScript library
23
+ gem 'jquery-rails'
24
+ # Turbolinks makes navigating your web application faster. Read more: https://github.com/turbolinks/turbolinks
25
+ gem 'turbolinks', '~> 5'
26
+ # Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
27
+ gem 'jbuilder', '~> 2.5'
28
+ # Use Redis adapter to run Action Cable in production
29
+ # gem 'redis', '~> 3.0'
30
+ # Use ActiveModel has_secure_password
31
+ # gem 'bcrypt', '~> 3.1.7'
32
+
33
+ # Use Capistrano for deployment
34
+ # gem 'capistrano-rails', group: :development
35
+
36
+ group :development, :test do
37
+ # Call 'byebug' anywhere in the code to stop execution and get a debugger console
38
+ gem 'byebug', platform: :mri
39
+ end
40
+
41
+ group :development do
42
+ # Access an IRB console on exception pages or by using <%= console %> anywhere in the code.
43
+ gem 'web-console', '>= 3.3.0'
44
+ gem 'listen', '~> 3.0.5'
45
+ end
46
+
47
+ # Windows does not include zoneinfo files, so bundle the tzinfo-data gem
48
+ gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
49
+
50
+ gem 'graphiql-rails', group: :development
@@ -0,0 +1,24 @@
1
+ # README
2
+
3
+ This README would normally document whatever steps are necessary to get the
4
+ application up and running.
5
+
6
+ Things you may want to cover:
7
+
8
+ * Ruby version
9
+
10
+ * System dependencies
11
+
12
+ * Configuration
13
+
14
+ * Database creation
15
+
16
+ * Database initialization
17
+
18
+ * How to run the test suite
19
+
20
+ * Services (job queues, cache servers, search engines, etc.)
21
+
22
+ * Deployment instructions
23
+
24
+ * ...
@@ -0,0 +1,6 @@
1
+ # Add your own tasks in files placed in lib/tasks ending in .rake,
2
+ # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3
+
4
+ require_relative 'config/application'
5
+
6
+ Rails.application.load_tasks
@@ -0,0 +1,3 @@
1
+ //= link_tree ../images
2
+ //= link_directory ../javascripts .js
3
+ //= link_directory ../stylesheets .css
@@ -0,0 +1,16 @@
1
+ // This is a manifest file that'll be compiled into application.js, which will include all the files
2
+ // listed below.
3
+ //
4
+ // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5
+ // or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
6
+ //
7
+ // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8
+ // compiled file. JavaScript code in this file should be added after the last require_* statement.
9
+ //
10
+ // Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
11
+ // about supported directives.
12
+ //
13
+ //= require jquery
14
+ //= require jquery_ujs
15
+ //= require turbolinks
16
+ //= require_tree .
@@ -0,0 +1,13 @@
1
+ // Action Cable provides the framework to deal with WebSockets in Rails.
2
+ // You can generate new channels where WebSocket features live using the rails generate channel command.
3
+ //
4
+ //= require action_cable
5
+ //= require_self
6
+ //= require_tree ./channels
7
+
8
+ (function() {
9
+ this.App || (this.App = {});
10
+
11
+ App.cable = ActionCable.createConsumer();
12
+
13
+ }).call(this);
@@ -0,0 +1,15 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the bottom of the
9
+ * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
10
+ * files in this directory. Styles in this file should be added after the last require_* statement.
11
+ * It is generally better to create a new file per style scope.
12
+ *
13
+ *= require_tree .
14
+ *= require_self
15
+ */
@@ -0,0 +1,5 @@
1
+ # typed: strong
2
+ module ApplicationCable
3
+ class Channel < ActionCable::Channel::Base
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ # typed: strong
2
+ module ApplicationCable
3
+ class Connection < ActionCable::Connection::Base
4
+ end
5
+ end
@@ -0,0 +1,4 @@
1
+ # typed: false
2
+ class ApplicationController < ActionController::Base
3
+ protect_from_forgery with: :exception
4
+ end
@@ -0,0 +1,44 @@
1
+ # typed: false
2
+ class GraphqlController < ApplicationController
3
+ def execute
4
+ variables = ensure_hash(params[:variables])
5
+ query = params[:query]
6
+ operation_name = params[:operationName]
7
+ context = {
8
+ # Query context goes here, for example:
9
+ # current_user: current_user,
10
+ }
11
+ result = DummySchema.execute(query, variables: variables, context: context, operation_name: operation_name)
12
+ render json: result
13
+ rescue => e
14
+ raise e unless Rails.env.development?
15
+ handle_error_in_development e
16
+ end
17
+
18
+ private
19
+
20
+ # Handle form data, JSON body, or a blank value
21
+ def ensure_hash(ambiguous_param)
22
+ case ambiguous_param
23
+ when String
24
+ if ambiguous_param.present?
25
+ ensure_hash(JSON.parse(ambiguous_param))
26
+ else
27
+ {}
28
+ end
29
+ when Hash, ActionController::Parameters
30
+ ambiguous_param
31
+ when nil
32
+ {}
33
+ else
34
+ raise ArgumentError, "Unexpected parameter: #{ambiguous_param}"
35
+ end
36
+ end
37
+
38
+ def handle_error_in_development(e)
39
+ logger.error e.message
40
+ logger.error e.backtrace.join("\n")
41
+
42
+ render json: { error: { message: e.message, backtrace: e.backtrace }, data: {} }, status: 500
43
+ end
44
+ end
@@ -0,0 +1,3 @@
1
+ # typed: strong
2
+ module ApplicationHelper
3
+ end
@@ -0,0 +1,3 @@
1
+ # typed: strong
2
+ class ApplicationJob < ActiveJob::Base
3
+ end
@@ -0,0 +1,5 @@
1
+ # typed: false
2
+ class ApplicationMailer < ActionMailer::Base
3
+ default from: 'from@example.com'
4
+ layout 'mailer'
5
+ end
@@ -0,0 +1,5 @@
1
+ # typed: strict
2
+ class DummySchema < GraphQL::Schema
3
+ mutation(Types::MutationType)
4
+ query(Types::QueryType)
5
+ end
@@ -0,0 +1,15 @@
1
+ # typed: strong
2
+ module Mutations
3
+ class UpdateName < GraphQL::Schema::RelayClassicMutation
4
+ # TODO: define return fields
5
+ # field :post, Types::PostType, null: false
6
+
7
+ # TODO: define arguments
8
+ # argument :name, String, required: true
9
+
10
+ # TODO: define resolve method
11
+ # def resolve(name:)
12
+ # { post: ... }
13
+ # end
14
+ end
15
+ end
@@ -0,0 +1,5 @@
1
+ # typed: strong
2
+ module Types
3
+ class BaseEnum < GraphQL::Schema::Enum
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ # typed: strong
2
+ module Types
3
+ class BaseInputObject < GraphQL::Schema::InputObject
4
+ end
5
+ end
@@ -0,0 +1,6 @@
1
+ # typed: strong
2
+ module Types
3
+ module BaseInterface
4
+ include GraphQL::Schema::Interface
5
+ end
6
+ end
@@ -0,0 +1,5 @@
1
+ # typed: strong
2
+ module Types
3
+ class BaseObject < GraphQL::Schema::Object
4
+ end
5
+ end