graphql-sugar 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +12 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +5 -0
  5. data/CODE_OF_CONDUCT.md +74 -0
  6. data/Gemfile +4 -0
  7. data/LICENSE.txt +21 -0
  8. data/README.md +601 -0
  9. data/Rakefile +6 -0
  10. data/bin/console +14 -0
  11. data/bin/setup +8 -0
  12. data/graphql-sugar.gemspec +26 -0
  13. data/lib/generators/graphql/mutator/USAGE +8 -0
  14. data/lib/generators/graphql/mutator/mutator_generator.rb +9 -0
  15. data/lib/generators/graphql/mutator/templates/mutator.erb +15 -0
  16. data/lib/generators/graphql/resolver/USAGE +8 -0
  17. data/lib/generators/graphql/resolver/resolver_generator.rb +9 -0
  18. data/lib/generators/graphql/resolver/templates/resolver.erb +4 -0
  19. data/lib/generators/graphql/sugar/USAGE +10 -0
  20. data/lib/generators/graphql/sugar/sugar_generator.rb +17 -0
  21. data/lib/generators/graphql/sugar/templates/application_function.erb +3 -0
  22. data/lib/generators/graphql/sugar/templates/application_mutator.erb +3 -0
  23. data/lib/generators/graphql/sugar/templates/application_resolver.erb +3 -0
  24. data/lib/graphql/sugar/boot.rb +18 -0
  25. data/lib/graphql/sugar/define/attribute.rb +19 -0
  26. data/lib/graphql/sugar/define/attributes.rb +16 -0
  27. data/lib/graphql/sugar/define/model_class.rb +21 -0
  28. data/lib/graphql/sugar/define/mutator.rb +16 -0
  29. data/lib/graphql/sugar/define/parameter.rb +26 -0
  30. data/lib/graphql/sugar/define/relationship.rb +57 -0
  31. data/lib/graphql/sugar/define/relationships.rb +23 -0
  32. data/lib/graphql/sugar/define/resolver.rb +25 -0
  33. data/lib/graphql/sugar/function.rb +31 -0
  34. data/lib/graphql/sugar/mutator.rb +11 -0
  35. data/lib/graphql/sugar/resolver.rb +11 -0
  36. data/lib/graphql/sugar/version.rb +5 -0
  37. data/lib/graphql/sugar.rb +99 -0
  38. metadata +122 -0
@@ -0,0 +1,9 @@
1
+ module Graphql
2
+ class ResolverGenerator < Rails::Generators::NamedBase
3
+ source_root File.expand_path('../templates', __FILE__)
4
+
5
+ def create_resolver
6
+ template 'resolver.erb', File.join('app/graphql/resolvers', class_path, "#{file_name}_resolver.rb")
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,4 @@
1
+ class <%= class_name %>Resolver < ApplicationResolver
2
+ def resolve
3
+ end
4
+ end
@@ -0,0 +1,10 @@
1
+ Description:
2
+ Installs GraphQL::Sugar
3
+
4
+ Example:
5
+ rails generate graphql:sugar
6
+
7
+ This will create:
8
+ app/graphql/functions/application_function.rb
9
+ app/graphql/resolvers/application_resolver.rb
10
+ app/graphql/mutators/application_mutator.rb
@@ -0,0 +1,17 @@
1
+ module Graphql
2
+ class SugarGenerator < Rails::Generators::Base
3
+ source_root File.expand_path('../templates', __FILE__)
4
+
5
+ def add_paths
6
+ application { 'config.eager_load_paths += Dir["#{config.root}/app/graphql/functions/**/"]' }
7
+ application { 'config.eager_load_paths += Dir["#{config.root}/app/graphql/mutators/**/"]' }
8
+ application { 'config.eager_load_paths += Dir["#{config.root}/app/graphql/resolvers/**/"]' }
9
+ end
10
+
11
+ def create_application_files
12
+ template 'application_function.erb', 'app/graphql/functions/application_function.rb'
13
+ template 'application_resolver.erb', 'app/graphql/resolvers/application_resolver.rb'
14
+ template 'application_mutator.erb', 'app/graphql/mutators/application_mutator.rb'
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,3 @@
1
+ class ApplicationFunction < GraphQL::Function
2
+ include GraphQL::Sugar::Function
3
+ end
@@ -0,0 +1,3 @@
1
+ class ApplicationMutator < ApplicationFunction
2
+ include GraphQL::Sugar::Mutator
3
+ end
@@ -0,0 +1,3 @@
1
+ class ApplicationResolver < ApplicationFunction
2
+ include GraphQL::Sugar::Resolver
3
+ end
@@ -0,0 +1,18 @@
1
+ GraphQL::ObjectType.accepts_definitions(
2
+ resolver: GraphQL::Sugar::Define::Resolver,
3
+ mutator: GraphQL::Sugar::Define::Mutator,
4
+ model_class: GraphQL::Sugar::Define::ModelClass,
5
+ attribute: GraphQL::Sugar::Define::Attribute,
6
+ attributes: GraphQL::Sugar::Define::Attributes,
7
+ relationship: GraphQL::Sugar::Define::Relationship,
8
+ relationships: GraphQL::Sugar::Define::Relationships
9
+ )
10
+
11
+ GraphQL::Field.accepts_definitions(
12
+ parameter: GraphQL::Sugar::Define::Parameter
13
+ )
14
+
15
+ GraphQL::InputObjectType.accepts_definitions(
16
+ model_class: GraphQL::Define.assign_metadata_key(:model_class),
17
+ parameter: GraphQL::Sugar::Define::Parameter
18
+ )
@@ -0,0 +1,19 @@
1
+ module GraphQL
2
+ module Sugar
3
+ module Define
4
+ module Attribute
5
+ def self.call(type_defn, field_name, type_or_field = nil, desc = nil, **kwargs, &block) # rubocop:disable Metrics/ParameterLists
6
+ model_class = Sugar.get_model_class(type_defn)
7
+ column_name = Sugar.get_column_name(field_name)
8
+
9
+ type_or_field ||= kwargs[:type] if !kwargs[:type].nil?
10
+ type_or_field ||= Sugar.get_graphql_type(model_class, column_name)
11
+
12
+ kwargs[:property] ||= column_name.to_sym if kwargs[:resolve].nil?
13
+
14
+ GraphQL::Define::AssignObjectField.call(type_defn, field_name, type_or_field, desc, **kwargs, &block)
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,16 @@
1
+ module GraphQL
2
+ module Sugar
3
+ module Define
4
+ module Attributes
5
+ def self.call(type_defn, *field_names)
6
+ model_class = Sugar.get_model_class(type_defn)
7
+
8
+ field_names = model_class.columns_hash.keys.map(&:to_sym) if field_names.count == 0
9
+ field_names.each do |field_name|
10
+ Sugar::Define::Attribute.call(type_defn, field_name)
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,21 @@
1
+ module GraphQL
2
+ module Sugar
3
+ module Define
4
+ module ModelClass
5
+ def self.call(type_defn, model_class, type_name = nil)
6
+ type_defn.name = type_name || model_class.to_s
7
+ type_defn.metadata[:model_class] = model_class
8
+
9
+ common_field_names = [:id, :createdAt, :updatedAt]
10
+ common_field_names.each do |common_field_name|
11
+ begin
12
+ Sugar::Define::Attribute.call(type_defn, common_field_name)
13
+ rescue => e
14
+ Rails.logger.warn e
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,16 @@
1
+ module GraphQL
2
+ module Sugar
3
+ module Define
4
+ module Mutator
5
+ def self.call(type_defn, field_name, type_or_field = nil, desc = nil, **kwargs, &block) # rubocop:disable Metrics/ParameterLists
6
+ # Automatically determine function
7
+ function_class = Sugar.get_mutator_function(field_name)
8
+ kwargs[:function] ||= function_class.new
9
+ kwargs[:resolve] ||= ->(obj, args, ctx) { function_class.new.call(obj, args, ctx) }
10
+
11
+ GraphQL::Define::AssignObjectField.call(type_defn, field_name, type_or_field, desc, **kwargs, &block)
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,26 @@
1
+ module GraphQL
2
+ module Sugar
3
+ module Define
4
+ module Parameter
5
+ def self.call(type_defn, name, type = nil, *args, **kwargs, &block) # rubocop:disable Metrics/ParameterLists
6
+ model_class = type_defn.metadata[:model_class]
7
+
8
+ type ||= kwargs[:type]
9
+
10
+ if type.nil?
11
+ column_name = Sugar.get_column_name(name)
12
+ type = Sugar.get_graphql_type(model_class, column_name, enforce_non_null: false)
13
+ end
14
+
15
+ if kwargs[:as].nil?
16
+ field_name = name.to_s.underscore.to_sym
17
+ field_name = "#{field_name}_attributes".to_sym if model_class && model_class.nested_attributes_options[field_name]
18
+ kwargs[:as] = field_name
19
+ end
20
+
21
+ GraphQL::Define::AssignArgument.call(type_defn, name, type, *args, **kwargs, &block)
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,57 @@
1
+ module GraphQL
2
+ module Sugar
3
+ module Define
4
+ module Relationship
5
+ def self.call(type_defn, field_name)
6
+ model_class = Sugar.get_model_class(type_defn)
7
+ association_name = Sugar.get_association_name(field_name)
8
+ association = model_class.reflect_on_association(association_name)
9
+
10
+ if association.association_class == ActiveRecord::Associations::BelongsToAssociation
11
+ define_belongs_to(type_defn, field_name, model_class, association_name, association)
12
+ elsif association.association_class == ActiveRecord::Associations::HasOneAssociation ||
13
+ association.association_class == ActiveRecord::Associations::HasManyAssociation
14
+ define_has_many(type_defn, field_name, model_class, association_name, association)
15
+ end
16
+ end
17
+
18
+ def self.define_belongs_to(type_defn, field_name, model_class, association_name, association)
19
+ key_field_name = association.foreign_key.to_s.camelize(:lower).to_sym
20
+ key_type = GraphQL::ID_TYPE
21
+ key_property = association.foreign_key.to_sym
22
+
23
+ type = "Types::#{association.klass}Type".constantize
24
+ property = association_name.to_sym
25
+
26
+ key_column_details = Sugar.get_column_details(model_class, association.foreign_key)
27
+ is_not_null = !key_column_details.null || Sugar.validates_presence?(model_class, association_name)
28
+
29
+ if is_not_null
30
+ key_type = key_type.to_non_null_type
31
+ type = type.to_non_null_type
32
+ end
33
+
34
+ GraphQL::Define::AssignObjectField.call(type_defn, key_field_name, type: key_type, property: key_property)
35
+ GraphQL::Define::AssignObjectField.call(type_defn, field_name, type: type, property: property)
36
+ end
37
+
38
+ def self.define_has_many(type_defn, field_name, _model_class, association_name, association)
39
+ kwargs = {}
40
+
41
+ kwargs[:type] = "Types::#{association.klass}Type".constantize
42
+ kwargs[:type] = kwargs[:type].to_non_null_type.to_list_type
43
+
44
+ begin
45
+ function_class = Sugar.get_resolver_function(field_name)
46
+ kwargs[:function] ||= function_class.new
47
+ kwargs[:resolve] ||= ->(obj, args, ctx) { function_class.new.call(obj, args, ctx) }
48
+ rescue
49
+ kwargs[:property] = association_name.to_sym
50
+ end
51
+
52
+ GraphQL::Define::AssignObjectField.call(type_defn, field_name, **kwargs)
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,23 @@
1
+ module GraphQL
2
+ module Sugar
3
+ module Define
4
+ module Relationships
5
+ def self.call(type_defn, *field_names)
6
+ model_class = Sugar.get_model_class(type_defn)
7
+
8
+ if field_names.count == 0
9
+ [:belongs_to, :has_one, :has_many].each do |macro|
10
+ model_class.reflect_on_all_associations(macro).each do |association|
11
+ field_names << association.name
12
+ end
13
+ end
14
+ end
15
+
16
+ field_names.each do |field_name|
17
+ Sugar::Define::Relationship.call(type_defn, field_name)
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,25 @@
1
+ module GraphQL
2
+ module Sugar
3
+ module Define
4
+ module Resolver
5
+ def self.call(type_defn, field_name, type_or_field = nil, desc = nil, **kwargs, &block) # rubocop:disable Metrics/ParameterLists
6
+ # Automatically determine type
7
+ type_or_field ||= kwargs[:type] if !kwargs[:type].nil?
8
+ type_or_field ||= Sugar.get_resolver_graphql_type(field_name)
9
+
10
+ # Automatically determine if plural, modify type to !types[Type] if true
11
+ plural = kwargs[:plural]
12
+ plural = Sugar.get_resolver_plural(field_name) if plural.nil?
13
+ type_or_field = type_or_field.to_list_type.to_non_null_type if plural
14
+
15
+ # Automatically determine function
16
+ function_class = Sugar.get_resolver_function(field_name)
17
+ kwargs[:function] ||= function_class.new
18
+ kwargs[:resolve] ||= ->(obj, args, ctx) { function_class.new.call(obj, args, ctx) }
19
+
20
+ GraphQL::Define::AssignObjectField.call(type_defn, field_name, type_or_field, desc, **kwargs, &block)
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,31 @@
1
+ module GraphQL
2
+ module Sugar
3
+ module Function
4
+ def self.included(base)
5
+ base.extend ClassMethods
6
+ base.class_eval do
7
+ attr_reader :object
8
+ attr_reader :params
9
+ attr_reader :context
10
+ end
11
+ end
12
+
13
+ module ClassMethods
14
+ # Workaround:
15
+ # A `GraphQL::Function` is supposed to be a 'reusable container for field logic'.
16
+ # However, extended Field DSL (specified using `GraphQL::Field.accepts_definitions(...)`)
17
+ # is not available within Functions. Therefore, re-defining it here.
18
+ def parameter(name, *args, **kwargs, &block)
19
+ kwargs[:as] ||= name.to_s.underscore.to_sym
20
+ argument(name, *args, **kwargs, &block)
21
+ end
22
+ end
23
+
24
+ def call(obj, args, ctx)
25
+ @object = obj
26
+ @params = args.to_h.deep_symbolize_keys
27
+ @context = ctx
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,11 @@
1
+ module GraphQL
2
+ module Sugar
3
+ module Mutator
4
+ def call(obj, args, ctx)
5
+ super
6
+
7
+ mutate
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module GraphQL
2
+ module Sugar
3
+ module Resolver
4
+ def call(obj, args, ctx)
5
+ super
6
+
7
+ resolve
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,5 @@
1
+ module GraphQL
2
+ module Sugar
3
+ VERSION = '0.1.1'
4
+ end
5
+ end
@@ -0,0 +1,99 @@
1
+ require 'graphql/sugar/version'
2
+
3
+ module GraphQL
4
+ module Sugar
5
+ GRAPHQL_TYPE_MAPPING = {
6
+ integer: GraphQL::INT_TYPE,
7
+ float: GraphQL::FLOAT_TYPE,
8
+ decimal: GraphQL::FLOAT_TYPE,
9
+ boolean: GraphQL::BOOLEAN_TYPE,
10
+ string: GraphQL::STRING_TYPE
11
+ }.freeze
12
+
13
+ def self.get_resolver_graphql_type(field_name)
14
+ "Types::#{field_name.to_s.classify}Type".constantize
15
+ end
16
+
17
+ def self.get_resolver_function(field_name)
18
+ "#{field_name.to_s.camelize}Resolver".constantize
19
+ end
20
+
21
+ def self.get_resolver_plural(field_name)
22
+ field_string = field_name.to_s
23
+ field_string.pluralize == field_string
24
+ end
25
+
26
+ def self.get_mutator_function(field_name)
27
+ "#{field_name.to_s.camelize}Mutator".constantize
28
+ end
29
+
30
+ def self.get_model_class(type_defn)
31
+ model_class = type_defn.metadata[:model_class]
32
+ raise "You must define a `model_class` first in `#{type_defn.class}`." if model_class.blank?
33
+ model_class
34
+ end
35
+
36
+ def self.get_column_name(field_name)
37
+ field_name.to_s.underscore
38
+ end
39
+
40
+ def self.get_column_details(model_class, column_name)
41
+ column_details = model_class.columns_hash[column_name]
42
+ raise "The attribute '#{column_name}' doesn't exist in model '#{model_class}'." if column_details.blank?
43
+ column_details
44
+ end
45
+
46
+ def self.get_graphql_type(model_class, column_name, enforce_non_null: true) # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
47
+ return GraphQL::ID_TYPE.to_non_null_type if column_name == model_class.primary_key
48
+
49
+ column_details = get_column_details(model_class, column_name)
50
+
51
+ belongs_to_association = model_class.reflect_on_all_associations(:belongs_to).find { |a| a.foreign_key == column_name }
52
+
53
+ type = if model_class.defined_enums.key?(column_name)
54
+ GraphQL::STRING_TYPE
55
+ elsif belongs_to_association.present?
56
+ GraphQL::ID_TYPE
57
+ else
58
+ GRAPHQL_TYPE_MAPPING[column_details.type] || GraphQL::STRING_TYPE
59
+ end
60
+
61
+ type = type.to_list_type if column_details.array?
62
+
63
+ if enforce_non_null
64
+ is_not_null = !column_details.null
65
+ is_not_null ||= Sugar.validates_presence?(model_class, column_name)
66
+ is_not_null ||= Sugar.validates_presence?(model_class, belongs_to_association.name) if belongs_to_association.present?
67
+ type = type.to_non_null_type if is_not_null
68
+ end
69
+
70
+ type
71
+ end
72
+
73
+ def self.get_association_name(field_name)
74
+ field_name.to_s.underscore
75
+ end
76
+
77
+ def self.validates_presence?(model_class, column_name)
78
+ column_validators = model_class.validators_on(column_name)
79
+ column_validators.any? do |validator|
80
+ validator.class == ActiveRecord::Validations::PresenceValidator &&
81
+ !validator.options.key?(:if) &&
82
+ !validator.options.key?(:unless)
83
+ end
84
+ end
85
+ end
86
+ end
87
+
88
+ require 'graphql/sugar/define/resolver'
89
+ require 'graphql/sugar/define/mutator'
90
+ require 'graphql/sugar/define/model_class'
91
+ require 'graphql/sugar/define/attribute'
92
+ require 'graphql/sugar/define/attributes'
93
+ require 'graphql/sugar/define/relationship'
94
+ require 'graphql/sugar/define/relationships'
95
+ require 'graphql/sugar/define/parameter'
96
+ require 'graphql/sugar/function'
97
+ require 'graphql/sugar/resolver'
98
+ require 'graphql/sugar/mutator'
99
+ require 'graphql/sugar/boot'
metadata ADDED
@@ -0,0 +1,122 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: graphql-sugar
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Pradeep Kumar
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2017-10-25 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.14'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.14'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ description:
56
+ email:
57
+ - pradeep@keepworks.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - ".gitignore"
63
+ - ".rspec"
64
+ - ".travis.yml"
65
+ - CODE_OF_CONDUCT.md
66
+ - Gemfile
67
+ - LICENSE.txt
68
+ - README.md
69
+ - Rakefile
70
+ - bin/console
71
+ - bin/setup
72
+ - graphql-sugar.gemspec
73
+ - lib/generators/graphql/mutator/USAGE
74
+ - lib/generators/graphql/mutator/mutator_generator.rb
75
+ - lib/generators/graphql/mutator/templates/mutator.erb
76
+ - lib/generators/graphql/resolver/USAGE
77
+ - lib/generators/graphql/resolver/resolver_generator.rb
78
+ - lib/generators/graphql/resolver/templates/resolver.erb
79
+ - lib/generators/graphql/sugar/USAGE
80
+ - lib/generators/graphql/sugar/sugar_generator.rb
81
+ - lib/generators/graphql/sugar/templates/application_function.erb
82
+ - lib/generators/graphql/sugar/templates/application_mutator.erb
83
+ - lib/generators/graphql/sugar/templates/application_resolver.erb
84
+ - lib/graphql/sugar.rb
85
+ - lib/graphql/sugar/boot.rb
86
+ - lib/graphql/sugar/define/attribute.rb
87
+ - lib/graphql/sugar/define/attributes.rb
88
+ - lib/graphql/sugar/define/model_class.rb
89
+ - lib/graphql/sugar/define/mutator.rb
90
+ - lib/graphql/sugar/define/parameter.rb
91
+ - lib/graphql/sugar/define/relationship.rb
92
+ - lib/graphql/sugar/define/relationships.rb
93
+ - lib/graphql/sugar/define/resolver.rb
94
+ - lib/graphql/sugar/function.rb
95
+ - lib/graphql/sugar/mutator.rb
96
+ - lib/graphql/sugar/resolver.rb
97
+ - lib/graphql/sugar/version.rb
98
+ homepage: https://github.com/keepworks/graphql-sugar
99
+ licenses:
100
+ - MIT
101
+ metadata: {}
102
+ post_install_message:
103
+ rdoc_options: []
104
+ require_paths:
105
+ - lib
106
+ required_ruby_version: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ required_rubygems_version: !ruby/object:Gem::Requirement
112
+ requirements:
113
+ - - ">="
114
+ - !ruby/object:Gem::Version
115
+ version: '0'
116
+ requirements: []
117
+ rubyforge_project:
118
+ rubygems_version: 2.6.8
119
+ signing_key:
120
+ specification_version: 4
121
+ summary: A sweet, extended DSL written on top of the graphql-ruby gem.
122
+ test_files: []