rails-graphql 1.0.0.rc1 → 1.0.0.rc2

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 +4 -4
  2. data/lib/generators/graphql/templates/config.rb +2 -2
  3. data/lib/gql_parser.so +0 -0
  4. data/lib/rails/graphql/alternative/query.rb +4 -4
  5. data/lib/rails/graphql/alternative.rb +4 -0
  6. data/lib/rails/graphql/callback.rb +2 -1
  7. data/lib/rails/graphql/config.rb +13 -2
  8. data/lib/rails/graphql/directive.rb +1 -1
  9. data/lib/rails/graphql/field/proxied_field.rb +1 -1
  10. data/lib/rails/graphql/helpers/inherited_collection/base.rb +1 -1
  11. data/lib/rails/graphql/helpers/with_assignment.rb +5 -5
  12. data/lib/rails/graphql/helpers/with_fields.rb +1 -1
  13. data/lib/rails/graphql/helpers/with_schema_fields.rb +3 -3
  14. data/lib/rails/graphql/railties/controller.rb +10 -6
  15. data/lib/rails/graphql/request/component/operation.rb +1 -1
  16. data/lib/rails/graphql/request.rb +4 -4
  17. data/lib/rails/graphql/source/active_record/builders.rb +3 -4
  18. data/lib/rails/graphql/source/active_record_source.rb +5 -3
  19. data/lib/rails/graphql/source/base.rb +3 -2
  20. data/lib/rails/graphql/source/builder.rb +9 -4
  21. data/lib/rails/graphql/source.rb +8 -1
  22. data/lib/rails/graphql/type/creator.rb +8 -6
  23. data/lib/rails/graphql/type/input.rb +10 -3
  24. data/lib/rails/graphql/type/object.rb +1 -1
  25. data/lib/rails/graphql/type/scalar/date_scalar.rb +1 -1
  26. data/lib/rails/graphql/type/scalar/date_time_scalar.rb +1 -1
  27. data/lib/rails/graphql/type/scalar/time_scalar.rb +1 -1
  28. data/lib/rails/graphql/type/scalar.rb +1 -1
  29. data/lib/rails/graphql/type_map.rb +7 -5
  30. data/lib/rails/graphql/version.rb +1 -1
  31. data/lib/rails/graphql.rb +2 -1
  32. data/test/assets/mysql.gql +3 -3
  33. data/test/assets/sqlite.gql +3 -3
  34. data/test/graphql/source_test.rb +1 -1
  35. data/test/integration/global_id_test.rb +2 -2
  36. data/test/integration/resolver_precedence_test.rb +1 -1
  37. data/test/integration/sqlite/star_wars_global_id_test.rb +1 -1
  38. metadata +4 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4567d054599bcd2c6c93008cd8e82cad8259bf15db57a508eb5ebc671faf64e1
4
- data.tar.gz: d75085b1ccf8125a31a442369b13628bab65cd6aaa7b8c48ebb85016156a19d4
3
+ metadata.gz: 3c29232c14870c44aeab62fba29beda42f8f99a8047bf83f717149e6fc2e5d7c
4
+ data.tar.gz: 196468f3151958620774998650fe7a5f70e0b3204fdb5a028b31c634d21a9cb0
5
5
  SHA512:
6
- metadata.gz: f7349679b342745edc2bbf8c89b2c1c3687db9331de6883d042eb1523c3a77566cc0485382b5f1eb6dc3656cee4aed7b77f22ce268417b77564f702185415601
7
- data.tar.gz: 38dc53be74565810ce48c474c3c4ea2ceb01cdbb947dfe771647032f7cdc314cb645daf226b32f3d2d62b2f4fe62db3cfab1815481d218b9ac24e37c4c47a203
6
+ metadata.gz: a17d0f98a0473afd6d221d98b967068ae9d97da363e44e92817729e23a204510768c72bed50a858816e9d7eeda8b0fcdefe83c56d9782e8abe06d71bea6e0f75
7
+ data.tar.gz: c4258dfce30c7aedba8a3f2c1a9a6c20b0eca30ae520888efac8dfeb3f5267654d74e2992b9794bdb892a2f84d8f1be68d6d71e637ebaa48ee780d3b019ccf25
@@ -40,7 +40,7 @@ Rails::GraphQL.configure do |config|
40
40
  # Introspection is enabled by default. It is recommended to only use
41
41
  # introspection during development and tests, never in production.
42
42
  # This can also be set per schema level.
43
- config.enable_introspection = true
43
+ config.enable_introspection = !Rails.env.production?
44
44
 
45
45
  # Define the names of the schema/operations types. The single "_" is a
46
46
  # suggestion. In an application that has a Subscription object, it will
@@ -93,5 +93,5 @@ Rails::GraphQL.configure do |config|
93
93
  # behaves closer to YAML. The received value is ensured to be wrapped in
94
94
  # "{}". If that produces unexpected results, you can assign a proc and then
95
95
  # parse the value in any other way.
96
- # config.literal_input_parser = JSON.method(:parse)
96
+ # config.literal_input_parser = Psych.method(:safe_load)
97
97
  end
data/lib/gql_parser.so CHANGED
Binary file
@@ -15,9 +15,9 @@ module Rails
15
15
  self.abstract = true
16
16
 
17
17
  class << self
18
- delegate :gql_name, :to_sym, :desc, :argument, :ref_argument, :id_argument,
19
- :use, :internal?, :disabled?, :enabled?, :disable!, :enable!, :rename!,
20
- :authorize, :on, :description=, :description, to: :field
18
+ delegate :gql_name, :to_sym, :desc, :arguments, :argument, :ref_argument, :id_argument,
19
+ :use, :internal?, :disabled?, :enabled?, :disable!, :enable!, :rename!, :authorize,
20
+ :on, :description=, :description, to: :field
21
21
 
22
22
  # Returns the type of the field class
23
23
  def type_field_class
@@ -85,7 +85,7 @@ module Rails
85
85
  def field_class
86
86
  return @field.class if defined?(@field)
87
87
  list = Helpers::WithSchemaFields::TYPE_FIELD_CLASS
88
- GraphQL::Field.const_get(list[type_field_class])
88
+ GraphQL::Field.const_get(list[type_field_class], false)
89
89
  end
90
90
  end
91
91
  end
@@ -10,6 +10,10 @@ module Rails
10
10
  autoload :Mutation
11
11
  autoload :Subscription
12
12
 
13
+ autoload_at "#{__dir__}/alternative/query" do
14
+ autoload :Field
15
+ end
16
+
13
17
  autoload_at "#{__dir__}/alternative/field_set" do
14
18
  autoload :FieldSet
15
19
  autoload :MutationSet
@@ -83,7 +83,8 @@ module Rails
83
83
  # Find the proper owner of the symbol based callback
84
84
  def owner
85
85
  @owner ||= target.all_owners.find do |item|
86
- item.is_a?(Class) ? item.method_defined?(block) : item.respond_to?(block)
86
+ item.is_a?(Class) && item.included_modules.include?(Helpers::Instantiable) &&
87
+ item.method_defined?(block)
87
88
  end || target
88
89
  end
89
90
 
@@ -29,8 +29,8 @@ module Rails
29
29
 
30
30
  # The list of nested paths inside of the graphql folder that does not
31
31
  # require to be in their own namespace.
32
- config.paths = %w[directives fields sources enums inputs interfaces object
33
- scalars unions].to_set
32
+ config.paths = %w[directives fields sources enums inputs interfaces objects
33
+ scalars unions concerns].to_set
34
34
 
35
35
  # This is very similar to `ActiveRecord` verbose logs, which simply show the
36
36
  # path of the file that started a GraphQL request.
@@ -180,6 +180,17 @@ module Rails
180
180
  # parse the value in any other way.
181
181
  config.literal_input_parser = JSON.method(:parse)
182
182
 
183
+ # A mapping for the internal parameters and where they should be taken
184
+ # from. You can point to nested values using dot notation.
185
+ # TODO: Needs implementation
186
+ config.params_mapping = {
187
+ query: 'query',
188
+ variables: 'variables',
189
+ operation_name: 'operation_name',
190
+ query_cache_key: 'extensions.persistedQuery.sha256Hash',
191
+ query_cache_version: 'extensions.persistedQuery.version',
192
+ }
193
+
183
194
  # TODO: To be implemented
184
195
  # allow_query_serialization
185
196
  end
@@ -129,7 +129,7 @@ module Rails
129
129
  GraphQL.enumerate(setting).map do |item|
130
130
  next item unless item.is_a?(String) || item.is_a?(Symbol)
131
131
  GraphQL.type_map.fetch(item, namespaces: namespaces) ||
132
- ::GraphQL.const_get(item)
132
+ ::GraphQL.const_get(item, false)
133
133
  end
134
134
  end
135
135
 
@@ -72,7 +72,7 @@ module Rails
72
72
 
73
73
  # Override this to include proxied owners
74
74
  def all_owners
75
- super + proxied_owner.all_owners
75
+ super + @field.all_owners
76
76
  end
77
77
 
78
78
  # Return the proxied field
@@ -12,7 +12,7 @@ module Rails
12
12
  # Just a little helper to initialize the iterator form a given +source+
13
13
  def self.handle(source, ivar, type)
14
14
  klass = (type == :array || type == :set) ? :Array : :Hash
15
- InheritedCollection.const_get(klass).new(source, ivar, type)
15
+ InheritedCollection.const_get(klass, false).new(source, ivar, type)
16
16
  end
17
17
 
18
18
  def initialize(source, ivar, type)
@@ -61,12 +61,12 @@ module Rails
61
61
  return if abstract?
62
62
  return super unless assigned?
63
63
 
64
- result = super
65
- return result unless (klass = safe_assigned_class)
66
- return result if GraphQL.type_map.exist?(klass, namespaces: namespaces)
64
+ super.tap do
65
+ break unless (klass = safe_assigned_class)
66
+ break if GraphQL.type_map.exist?(klass, namespaces: namespaces)
67
67
 
68
- GraphQL.type_map.register_alias(klass, to_sym, namespaces: namespaces)
69
- result
68
+ GraphQL.type_map.register_alias(klass, gql_name, namespaces: namespaces)
69
+ end
70
70
  end
71
71
 
72
72
  protected
@@ -159,7 +159,7 @@ module Rails
159
159
  # Import a module containing several classes to be imported
160
160
  def import_all(mod, recursive: false, **xargs)
161
161
  mod.constants.each do |const_name|
162
- object = mod.const_get(const_name)
162
+ object = mod.const_get(const_name, false)
163
163
 
164
164
  import(object, **xargs) if object.is_a?(Class)
165
165
  import_all(object, recursive: recursive, **xargs) if recursive && object.is_a?(Module)
@@ -105,7 +105,7 @@ module Rails
105
105
  # Add a new field of the give +type+
106
106
  # See {OutputField}[rdoc-ref:Rails::GraphQL::OutputField] class.
107
107
  def add_field(type, *args, **xargs, &block)
108
- klass = Field.const_get(TYPE_FIELD_CLASS[type])
108
+ klass = Field.const_get(TYPE_FIELD_CLASS[type], false)
109
109
  object = klass.new(*args, **xargs, owner: self, &block)
110
110
 
111
111
  raise DuplicatedError, (+<<~MSG).squish if has_field?(type, object.name)
@@ -126,7 +126,7 @@ module Rails
126
126
  A #{field.schema_type} field cannot be added as a #{type} field.
127
127
  MSG
128
128
 
129
- klass = Field.const_get(TYPE_FIELD_CLASS[type])
129
+ klass = Field.const_get(TYPE_FIELD_CLASS[type], false)
130
130
  raise ArgumentError, (+<<~MSG).squish unless field.is_a?(klass)
131
131
  The #{field.class.name} is not a valid field for #{type} fields.
132
132
  MSG
@@ -236,7 +236,7 @@ module Rails
236
236
  # TODO: Maybe add deepness into the recursive value
237
237
  def import_all_into(type, mod, recursive: false, **xargs)
238
238
  mod.constants.each do |const_name|
239
- object = mod.const_get(const_name)
239
+ object = mod.const_get(const_name, false)
240
240
 
241
241
  import_into(type, object, **xargs) if object.is_a?(Class)
242
242
  import_all_into(type, object, recursive: recursive, **xargs) if recursive && object.is_a?(Module)
@@ -33,8 +33,12 @@ module Rails
33
33
  end
34
34
 
35
35
  # GET /describe
36
- def describe
37
- render plain: gql_schema_header + gql_describe_schema + gql_schema_footer
36
+ def describe(schema = gql_schema)
37
+ render plain: [
38
+ gql_schema_header(schema),
39
+ gql_describe_schema(schema),
40
+ gql_schema_footer,
41
+ ].join
38
42
  end
39
43
 
40
44
  # GET /graphiql
@@ -128,7 +132,7 @@ module Rails
128
132
  end
129
133
 
130
134
  # Shows a text representation of the schema
131
- def gql_describe_schema(schema = gql_schema)
135
+ def gql_describe_schema(schema)
132
136
  schema.to_gql(
133
137
  with_descriptions: !params.key?(:without_descriptions),
134
138
  with_spec: !params.key?(:without_spec),
@@ -137,9 +141,9 @@ module Rails
137
141
 
138
142
  # Print a header of the current schema for the description process
139
143
  # TODO: Maybe add a way to detect from which file the schema is being loaded
140
- def gql_schema_header
141
- ns = +" [#{gql_schema.namespace}]" if gql_schema.namespace != :base
142
- +"#{DESCRIBE_HEADER}# Schema #{gql_schema.name}#{ns}\n"
144
+ def gql_schema_header(schema)
145
+ ns = +" [#{schema.namespace}]" if schema.namespace != :base
146
+ +"#{DESCRIBE_HEADER}# Schema #{schema.name}#{ns}\n"
143
147
  end
144
148
 
145
149
  # Show the footer of the describe page
@@ -18,7 +18,7 @@ module Rails
18
18
 
19
19
  # Helper method to initialize an operation given the node
20
20
  def build(request, node)
21
- request.build(const_get(node.type.to_s.classify), request, node)
21
+ request.build(const_get(node.type.to_s.classify, false), request, node)
22
22
  end
23
23
 
24
24
  # Rewrite the kind to always return +:operation+
@@ -95,12 +95,12 @@ module Rails
95
95
 
96
96
  # Allow accessing component-based objects through the request
97
97
  def const_defined?(name, *)
98
- Component.const_defined?(name) || super
98
+ Component.const_defined?(name, false) || super
99
99
  end
100
100
 
101
101
  # Allow accessing component-based objects through the request
102
102
  def const_missing(name)
103
- Component.const_defined?(name) ? Component.const_get(name) : super
103
+ Component.const_defined?(name, false) ? Component.const_get(name, false) : super
104
104
  end
105
105
  end
106
106
 
@@ -476,13 +476,13 @@ module Rails
476
476
  modules.each do |mod|
477
477
  mod.constants.each do |const_name|
478
478
  const_name = const_name.to_s
479
- const = mod.const_get(const_name)
479
+ const = mod.const_get(const_name, false)
480
480
  next unless const.is_a?(Module)
481
481
 
482
482
  # Find the related request class to extend
483
483
  klass = const_name === 'Request' ? self.class : begin
484
484
  const_name.split('_').inject(self.class) do |k, next_const|
485
- k.const_defined?(next_const) ? k.const_get(next_const) : break
485
+ k.const_defined?(next_const) ? k.const_get(next_const, false) : break
486
486
  end
487
487
  end
488
488
 
@@ -66,7 +66,7 @@ module Rails
66
66
  return remove_instance_variable(:@enums) if enums.blank?
67
67
 
68
68
  @enums = enums.each_with_object({}) do |(attribute, setting), hash|
69
- class_name = base_name + attribute.to_s.classify
69
+ class_name = base_name.tr('_', '') + attribute.to_s.classify
70
70
  hash[attribute.to_s] = create_enum(class_name, setting)
71
71
  rescue DuplicatedError
72
72
  next
@@ -75,15 +75,14 @@ module Rails
75
75
 
76
76
  # Build all necessary attribute fields into the given +holder+
77
77
  def build_attribute_fields(holder, **field_options)
78
- each_attribute(holder) do |key, type, **options|
79
- next if holder.has_field?(key) || skip_field?(key, on: holder.kind)
80
78
 
79
+ each_attribute(holder) do |key, type, **options|
81
80
  str_key = key.to_s
82
81
  type = (defined?(@enums) && @enums.key?(str_key) && @enums[str_key]) ||
83
82
  (id_columns.include?(str_key) && :id) || type
84
83
 
85
84
  options[:null] = !attr_required?(key) unless options.key?(:null)
86
- holder.field(key, type, **options.merge(field_options[key] || {}))
85
+ holder.safe_field(key, type, **options.merge(field_options[key] || {}))
87
86
  end
88
87
  end
89
88
 
@@ -30,7 +30,7 @@ module Rails
30
30
 
31
31
  # Marks if the source should be threated as an interface, meaning that
32
32
  # no object will be created, instead an interface will
33
- class_attribute :act_as_interface, instance_accessor: false, default: false
33
+ class_attribute :act_as_interface, instance_accessor: false
34
34
 
35
35
  # The name of the class (or the class itself) to be used as superclass for
36
36
  # the generate GraphQL interface type of this source
@@ -125,7 +125,8 @@ module Rails
125
125
 
126
126
  # Set the assignment to a model with a similar name as the source
127
127
  def assigned_to
128
- @assigned_to ||= name.delete_prefix('GraphQL::')[0..-7]
128
+ return @assigned_to if defined?(@assigned_to)
129
+ @assigned_to = base_name.gsub('_', '::')
129
130
  end
130
131
 
131
132
  # Stores columns associated with enums so that the fields can have a
@@ -147,7 +148,8 @@ module Rails
147
148
 
148
149
  # Checks if the source is building an interface instead of an object
149
150
  def interface?
150
- defined?(@interface) || act_as_interface? || sti_interface?
151
+ defined?(@interface) || act_as_interface == true ||
152
+ (act_as_interface != false && sti_interface?)
151
153
  end
152
154
 
153
155
  # Provides access to the default plural query field, for associations interconnection
@@ -62,17 +62,18 @@ module Rails
62
62
  xargs[:values] = enumerator.sort_by(&:last).map(&:first)
63
63
  xargs[:indexed] = enumerator.first.last.is_a?(Numeric)
64
64
 
65
- create_type(:enum, enum_name.classify, **xargs, &block)
65
+ create_type(:enum, enum_name.to_s.classify, **xargs, &block)
66
66
  end
67
67
 
68
68
  # Helper method to create a class based on the given +type+ and
69
69
  # allows several other settings to be executed on it
70
- def create_type(type = nil, name = base_name, **xargs, &block)
70
+ def create_type(type = nil, name = nil, **xargs, &block)
71
71
  xargs[:owner] ||= self
72
72
  xargs[:namespaces] = namespaces
73
73
  xargs[:assigned_to] = safe_assigned_class
74
74
  superclass = xargs.delete(:superclass) || type
75
75
 
76
+ name ||= base_name.tr('_', '')
76
77
  GraphQL::Type.create!(self, name, superclass, **xargs, &block)
77
78
  end
78
79
 
@@ -21,13 +21,13 @@ module Rails
21
21
  build_all! unless abstract?
22
22
  end
23
23
 
24
- # Allows building anything that is in hooks
24
+ # Make sure to properly indicate about build methods
25
25
  def respond_to_missing?(method_name, *)
26
26
  return super unless method_name.to_s.start_with?('build_') &&
27
27
  hook_names.include?(method_name.to_s[6..-1].to_sym)
28
28
  end
29
29
 
30
- # Allow fast creation of values
30
+ # Allows all sorts of building methods to be called
31
31
  def method_missing(method_name, *args, **xargs, &block)
32
32
  return super unless method_name.to_s.start_with?('build_')
33
33
 
@@ -47,6 +47,11 @@ module Rails
47
47
  @built ||= Set.new
48
48
  end
49
49
 
50
+ # Mark as built before running the hooks
51
+ def run_hooks(type, *)
52
+ built.add(type)
53
+ end
54
+
50
55
  private
51
56
 
52
57
  # Import all options-based settings for skipping field
@@ -93,7 +98,6 @@ module Rails
93
98
  # Build all the objects associated with this source
94
99
  def build!(type)
95
100
  ensure_build!(type)
96
- built << type
97
101
 
98
102
  schema_type = Helpers::WithSchemaFields::TYPE_FIELD_CLASS.key?(type)
99
103
  catch(:skip) { run_hooks(:start) } unless built?(:start)
@@ -106,7 +110,8 @@ module Rails
106
110
  def hook_scope_for(type, schema_type)
107
111
  type = type.to_sym
108
112
  klass = schema_type ? 'WithSchemaFields::ScopedConfig' : 'AttributeDelegator'
109
- Source::ScopedConfig.new(self, Helpers.const_get(klass).new(self, type), type)
113
+ klass = Helpers.const_get(klass, false).new(self, type)
114
+ Source::ScopedConfig.new(self, klass, type)
110
115
  end
111
116
 
112
117
  end
@@ -85,7 +85,13 @@ module Rails
85
85
 
86
86
  # Get the main name of the source
87
87
  def base_name
88
- name.demodulize[0..-7]
88
+ @base_name ||= begin
89
+ nested = "::#{Type::Creator::NESTED_MODULE}::"
90
+
91
+ value = name.delete_prefix('GraphQL::')
92
+ value = name.split(nested).last if name.include?(nested)
93
+ value.chomp('Source')
94
+ end
89
95
  end
90
96
 
91
97
  # :singleton-method:
@@ -214,6 +220,7 @@ module Rails
214
220
 
215
221
  # Run a list of hooks using the +source+ as the instance of the block
216
222
  def run_hooks(hook_name, source = self)
223
+ super
217
224
  all_hooks.try(:[], hook_name.to_sym)&.reverse_each do |block|
218
225
  source.instance_exec(&block)
219
226
  end
@@ -127,10 +127,10 @@ module Rails
127
127
 
128
128
  # Create the class under the nested module
129
129
  return base.const_set(name, Class.new(superclass)) \
130
- unless base.const_defined?(name)
130
+ unless base.const_defined?(name, false)
131
131
 
132
132
  # Get the existing class and check for the once setting
133
- klass = base.const_get(name)
133
+ klass = base.const_get(name, false)
134
134
  return klass unless !once? && klass < superclass
135
135
 
136
136
  # Created once or not from the same superclass
@@ -141,7 +141,7 @@ module Rails
141
141
 
142
142
  # Make sure to properly get the superclass
143
143
  def sanitize_superclass(value)
144
- value = Type.const_get(value.to_s.classify) unless value.is_a?(Class)
144
+ value = Type.const_get(value.to_s.classify, false) unless value.is_a?(Class)
145
145
 
146
146
  valid_class = value.is_a?(Class) && value.respond_to?(:kind)
147
147
  valid_class &= SUPPORTED_KINDS.include?(value.kind)
@@ -155,7 +155,7 @@ module Rails
155
155
  # Let's clean up the name
156
156
  def sanitize_name(name_or_object)
157
157
  name = name_or_object.is_a?(Module) ? name_or_object.name : name_or_object.to_s
158
- name = name.classify.gsub(/::/, '_')
158
+ name = name.classify.delete_prefix('GraphQL::').gsub(/::/, '_')
159
159
  name.end_with?(name_suffix) ? name : name + name_suffix
160
160
  end
161
161
 
@@ -174,9 +174,11 @@ module Rails
174
174
  def base_module
175
175
  base = @from.is_a?(Module) ? @from : @from.class
176
176
  if base.const_defined?(NESTED_MODULE, false)
177
- base.const_get(NESTED_MODULE)
177
+ base.const_get(NESTED_MODULE, false)
178
178
  else
179
- base.const_set(NESTED_MODULE, Module.new)
179
+ base.const_set(NESTED_MODULE, Module.new).tap do
180
+ base.private_constant(NESTED_MODULE)
181
+ end
180
182
  end
181
183
  end
182
184
 
@@ -114,7 +114,7 @@ module Rails
114
114
  delegate_missing_to :resource
115
115
 
116
116
  def initialize(args = nil, **xargs)
117
- @args = args || OpenStruct.new(xargs.transform_keys { |key| key.to_s.underscore })
117
+ @args = args || build_ostruct(xargs)
118
118
  @args.freeze
119
119
 
120
120
  validate! if args.nil?
@@ -135,7 +135,7 @@ module Rails
135
135
 
136
136
  # Just return the arguments as an hash
137
137
  def params
138
- parametrize(self)
138
+ parametrize(@args.to_h)
139
139
  end
140
140
 
141
141
  # Correctly turn all the arguments into their +as_json+ version and
@@ -184,12 +184,19 @@ module Rails
184
184
  end
185
185
  end
186
186
 
187
+ protected
188
+
189
+ # A helper to turn a hash into a proper Open Struct instance
190
+ def build_ostruct(hash)
191
+ OpenStruct.new(hash.transform_keys { |key| key.to_s.underscore })
192
+ end
193
+
187
194
  private
188
195
 
189
196
  # Make sure to turn inputs into params
190
197
  def parametrize(input)
191
198
  case input
192
- when Type::Input then parametrize(input.args.to_h)
199
+ when Type::Input then input.params
193
200
  when Array then input.map(&method(:parametrize))
194
201
  when Hash then input.transform_values(&method(:parametrize))
195
202
  else input
@@ -77,7 +77,7 @@ module Rails
77
77
 
78
78
  def inspect
79
79
  return super if self.eql?(Type::Object)
80
- fields = @fields.values.map(&:inspect)
80
+ fields = @fields&.values&.map(&:inspect)
81
81
  fields = fields.presence && +" {#{fields.join(', ')}}"
82
82
 
83
83
  directives = inspect_directives
@@ -7,7 +7,7 @@ module Rails
7
7
  class Scalar::DateScalar < Scalar
8
8
  desc 'The Date scalar type represents a ISO 8601 string value.'
9
9
 
10
- use :specified_by, url: 'https://www.rfc-editor.org/rfc/rfc3339'
10
+ use :specified_by, url: 'https://en.wikipedia.org/wiki/ISO_8601'
11
11
 
12
12
  class << self
13
13
  def valid_input?(value)
@@ -9,7 +9,7 @@ module Rails
9
9
 
10
10
  desc 'The DateTime scalar type represents a ISO 8601 string value.'
11
11
 
12
- use :specified_by, url: 'https://www.rfc-editor.org/rfc/rfc3339'
12
+ use :specified_by, url: 'https://en.wikipedia.org/wiki/ISO_8601'
13
13
 
14
14
  class << self
15
15
  def valid_input?(value)
@@ -13,7 +13,7 @@ module Rails
13
13
  minutes, seconds, and milliseconds.
14
14
  MSG
15
15
 
16
- use :specified_by, url: 'https://www.rfc-editor.org/rfc/rfc3339'
16
+ use :specified_by, url: 'https://en.wikipedia.org/wiki/ISO_8601'
17
17
 
18
18
  # A +base_object+ helps to identify what methods are actually available
19
19
  # to work as resolvers
@@ -48,7 +48,7 @@ module Rails
48
48
 
49
49
  # Transforms the given value to its representation in a JSON string
50
50
  def to_json(value)
51
- as_json(value)&.inspect
51
+ as_json(value).inspect
52
52
  end
53
53
 
54
54
  # Transforms the given value to its representation in a Hash object
@@ -19,6 +19,7 @@ module Rails
19
19
  extend ActiveSupport::Autoload
20
20
 
21
21
  FILTER_REGISTER_TRACE = /((inherited|initialize)'$|schema\.rb:\d+)/.freeze
22
+ NESTED_MODULE = Type::Creator::NESTED_MODULE
22
23
 
23
24
  # Store all the base classes that are managed by the Type Map
24
25
  mattr_accessor :base_classes, instance_writer: false,
@@ -97,6 +98,8 @@ module Rails
97
98
  ns = @module_namespaces[mod]
98
99
  break ns unless ns.nil?
99
100
  end
101
+ rescue ::NameError
102
+ # If any module parent can't be found, there is no much we can do
100
103
  end
101
104
 
102
105
  # Register a given object, which must be a class where the namespaces and
@@ -144,7 +147,6 @@ module Rails
144
147
  # Unregister all the provided objects by simply assigning nil to their
145
148
  # final value on the index
146
149
  def unregister(*objects)
147
- sub_mod = Type::Creator::NESTED_MODULE
148
150
  objects.each do |object|
149
151
  namespaces = sanitize_namespaces(namespaces: object.namespaces, exclusive: true)
150
152
  namespaces << :base if namespaces.empty?
@@ -155,11 +157,11 @@ module Rails
155
157
  @objects -= 1
156
158
  end
157
159
 
158
- return unless object.const_defined?(sub_mod, false)
160
+ return unless object.const_defined?(NESTED_MODULE, false)
159
161
 
160
- nested_mod = object.const_get(sub_mod)
161
- unregister(*nested_mod.constants.map(&nested_mod.method(:const_get)))
162
- object.send(:remove_const, sub_mod)
162
+ nested_mod = object.const_get(NESTED_MODULE, false)
163
+ nested_mod.constants.each { |name| nested_mod.const_get(name, false).unregister! }
164
+ object.send(:remove_const, NESTED_MODULE)
163
165
  end
164
166
  end
165
167
 
@@ -15,7 +15,7 @@ module Rails
15
15
  MAJOR = 1
16
16
  MINOR = 0
17
17
  TINY = 0
18
- PRE = 'rc1'
18
+ PRE = 'rc2'
19
19
 
20
20
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
21
21
  end
data/lib/rails/graphql.rb CHANGED
@@ -7,6 +7,7 @@ require 'active_support'
7
7
 
8
8
  require 'active_support/core_ext/module/attribute_accessors_per_thread'
9
9
  require 'active_support/core_ext/string/strip'
10
+ require 'active_support/core_ext/enumerable'
10
11
 
11
12
  require 'rails/graphql/version'
12
13
  require 'rails/graphql/uri'
@@ -40,7 +41,7 @@ module Rails
40
41
  # * <tt>Directives:</tt> A directive definition belongs to the introspection
41
42
  # and is handled in the Singleton extent. They are handled as instance
42
43
  # whenever a definition or an execution uses them.
43
- # * <tt>Fields:</tt> Many other types and helper containers holds a serie of
44
+ # * <tt>Fields:</tt> Many other types and helper containers holds a series of
44
45
  # fields, which means that fields with the same name will probably behave
45
46
  # differently.
46
47
  module GraphQL
@@ -22,10 +22,10 @@ scalar Binary @specifiedBy(url: "https://www.rfc-editor.org/rfc/rfc3548")
22
22
  scalar Boolean
23
23
 
24
24
  "The Date scalar type represents a ISO 8601 string value."
25
- scalar Date @specifiedBy(url: "https://www.rfc-editor.org/rfc/rfc3339")
25
+ scalar Date @specifiedBy(url: "https://en.wikipedia.org/wiki/ISO_8601")
26
26
 
27
27
  "The DateTime scalar type represents a ISO 8601 string value."
28
- scalar DateTime @specifiedBy(url: "https://www.rfc-editor.org/rfc/rfc3339")
28
+ scalar DateTime @specifiedBy(url: "https://en.wikipedia.org/wiki/ISO_8601")
29
29
 
30
30
  """
31
31
  The Decimal scalar type represents signed fractional values with extra precision.
@@ -61,7 +61,7 @@ scalar String
61
61
  The Time scalar type that represents a distance in time using hours,
62
62
  minutes, seconds, and milliseconds.
63
63
  """
64
- scalar Time @specifiedBy(url: "https://www.rfc-editor.org/rfc/rfc3339")
64
+ scalar Time @specifiedBy(url: "https://en.wikipedia.org/wiki/ISO_8601")
65
65
 
66
66
  "The valid locations that a directive may be placed."
67
67
  enum __DirectiveLocation {
@@ -22,10 +22,10 @@ scalar Binary @specifiedBy(url: "https://www.rfc-editor.org/rfc/rfc3548")
22
22
  scalar Boolean
23
23
 
24
24
  "The Date scalar type represents a ISO 8601 string value."
25
- scalar Date @specifiedBy(url: "https://www.rfc-editor.org/rfc/rfc3339")
25
+ scalar Date @specifiedBy(url: "https://en.wikipedia.org/wiki/ISO_8601")
26
26
 
27
27
  "The DateTime scalar type represents a ISO 8601 string value."
28
- scalar DateTime @specifiedBy(url: "https://www.rfc-editor.org/rfc/rfc3339")
28
+ scalar DateTime @specifiedBy(url: "https://en.wikipedia.org/wiki/ISO_8601")
29
29
 
30
30
  """
31
31
  The Decimal scalar type represents signed fractional values with extra precision.
@@ -61,7 +61,7 @@ scalar String
61
61
  The Time scalar type that represents a distance in time using hours,
62
62
  minutes, seconds, and milliseconds.
63
63
  """
64
- scalar Time @specifiedBy(url: "https://www.rfc-editor.org/rfc/rfc3339")
64
+ scalar Time @specifiedBy(url: "https://en.wikipedia.org/wiki/ISO_8601")
65
65
 
66
66
  "The valid locations that a directive may be placed."
67
67
  enum __DirectiveLocation {
@@ -25,7 +25,7 @@ class GraphQL_SourceTest < GraphQL::TestCase
25
25
 
26
26
  def test_base_name
27
27
  described_class.stub(:abstract?, false) do
28
- assert_equal('DESCRIBED', described_class.base_name)
28
+ assert_equal('DESCRIBED_CLASS', described_class.base_name)
29
29
  end
30
30
  end
31
31
 
@@ -35,7 +35,7 @@ class Integration_GlobalIDTest < GraphQL::IntegrationTestCase
35
35
  end
36
36
 
37
37
  def test_create_object_field
38
- obj = SCHEMA::NestedTypes::HumanObject[:name]
38
+ obj = SCHEMA.const_get(:NestedTypes)::HumanObject[:name]
39
39
  assert_gid_value('gql://start-wars-mem/Human/name', obj)
40
40
  end
41
41
 
@@ -85,7 +85,7 @@ class Integration_GlobalIDTest < GraphQL::IntegrationTestCase
85
85
 
86
86
  def test_parse_object_field
87
87
  obj = find_gid('gql://start-wars-mem/Human/name')
88
- assert_equal(SCHEMA::NestedTypes::HumanObject[:name], obj)
88
+ assert_equal(SCHEMA.const_get(:NestedTypes)::HumanObject[:name], obj)
89
89
  end
90
90
 
91
91
  def test_parse_scalar_type
@@ -97,7 +97,7 @@ class Integration_ResolverPrecedenceTest < GraphQL::IntegrationTestCase
97
97
  end
98
98
 
99
99
  def test_simple_object
100
- object = SCHEMA::NestedTypes::Object1Object
100
+ object = SCHEMA.const_get(:NestedTypes)::Object1Object
101
101
  field = object[:field1]
102
102
 
103
103
  # (1) Block has higher precedence than default value
@@ -84,6 +84,6 @@ class Integration_SQLite_StarWarsGlobalIDTest < GraphQL::IntegrationTestCase
84
84
  end
85
85
 
86
86
  def source
87
- StartWarsSqliteSchema::NestedTypes::LiteFactionSource
87
+ StartWarsSqliteSchema.const_get(:NestedTypes)::LiteFactionSource
88
88
  end
89
89
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails-graphql
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.rc1
4
+ version: 1.0.0.rc2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Carlos Silva
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-02-06 00:00:00.000000000 Z
11
+ date: 2023-02-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -397,7 +397,7 @@ homepage: https://github.com/virtualshield/rails-graphql
397
397
  licenses:
398
398
  - MIT
399
399
  metadata:
400
- homepage_uri: https://www.rails-graphql.dev/
400
+ homepage_uri: https://rails-graphql.dev/
401
401
  source_code_uri: https://github.com/virtualshield/rails-graphql
402
402
  bug_tracker_uri: https://github.com/virtualshield/rails-graphql/issues
403
403
  changelog_uri: https://github.com/virtualshield/rails-graphql/blob/master/CHANGELOG.md
@@ -418,7 +418,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
418
418
  - !ruby/object:Gem::Version
419
419
  version: 1.3.1
420
420
  requirements: []
421
- rubygems_version: 3.2.33
421
+ rubygems_version: 3.3.26
422
422
  signing_key:
423
423
  specification_version: 4
424
424
  summary: GraphQL meets RoR with the most Ruby-like DSL