rails-graphql 1.0.0.rc1 → 1.0.0.rc2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/generators/graphql/templates/config.rb +2 -2
- data/lib/gql_parser.so +0 -0
- data/lib/rails/graphql/alternative/query.rb +4 -4
- data/lib/rails/graphql/alternative.rb +4 -0
- data/lib/rails/graphql/callback.rb +2 -1
- data/lib/rails/graphql/config.rb +13 -2
- data/lib/rails/graphql/directive.rb +1 -1
- data/lib/rails/graphql/field/proxied_field.rb +1 -1
- data/lib/rails/graphql/helpers/inherited_collection/base.rb +1 -1
- data/lib/rails/graphql/helpers/with_assignment.rb +5 -5
- data/lib/rails/graphql/helpers/with_fields.rb +1 -1
- data/lib/rails/graphql/helpers/with_schema_fields.rb +3 -3
- data/lib/rails/graphql/railties/controller.rb +10 -6
- data/lib/rails/graphql/request/component/operation.rb +1 -1
- data/lib/rails/graphql/request.rb +4 -4
- data/lib/rails/graphql/source/active_record/builders.rb +3 -4
- data/lib/rails/graphql/source/active_record_source.rb +5 -3
- data/lib/rails/graphql/source/base.rb +3 -2
- data/lib/rails/graphql/source/builder.rb +9 -4
- data/lib/rails/graphql/source.rb +8 -1
- data/lib/rails/graphql/type/creator.rb +8 -6
- data/lib/rails/graphql/type/input.rb +10 -3
- data/lib/rails/graphql/type/object.rb +1 -1
- data/lib/rails/graphql/type/scalar/date_scalar.rb +1 -1
- data/lib/rails/graphql/type/scalar/date_time_scalar.rb +1 -1
- data/lib/rails/graphql/type/scalar/time_scalar.rb +1 -1
- data/lib/rails/graphql/type/scalar.rb +1 -1
- data/lib/rails/graphql/type_map.rb +7 -5
- data/lib/rails/graphql/version.rb +1 -1
- data/lib/rails/graphql.rb +2 -1
- data/test/assets/mysql.gql +3 -3
- data/test/assets/sqlite.gql +3 -3
- data/test/graphql/source_test.rb +1 -1
- data/test/integration/global_id_test.rb +2 -2
- data/test/integration/resolver_precedence_test.rb +1 -1
- data/test/integration/sqlite/star_wars_global_id_test.rb +1 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3c29232c14870c44aeab62fba29beda42f8f99a8047bf83f717149e6fc2e5d7c
|
4
|
+
data.tar.gz: 196468f3151958620774998650fe7a5f70e0b3204fdb5a028b31c634d21a9cb0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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 =
|
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 =
|
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
|
-
:
|
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
|
@@ -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)
|
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
|
|
data/lib/rails/graphql/config.rb
CHANGED
@@ -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
|
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
|
|
@@ -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
|
-
|
65
|
-
|
66
|
-
|
64
|
+
super.tap do
|
65
|
+
break unless (klass = safe_assigned_class)
|
66
|
+
break if GraphQL.type_map.exist?(klass, namespaces: namespaces)
|
67
67
|
|
68
|
-
|
69
|
-
|
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:
|
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
|
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 = +" [#{
|
142
|
-
+"#{DESCRIBE_HEADER}# Schema #{
|
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.
|
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
|
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
|
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
|
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 =
|
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
|
-
#
|
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
|
-
#
|
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
|
-
|
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
|
data/lib/rails/graphql/source.rb
CHANGED
@@ -85,7 +85,13 @@ module Rails
|
|
85
85
|
|
86
86
|
# Get the main name of the source
|
87
87
|
def base_name
|
88
|
-
|
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 ||
|
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(
|
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
|
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
|
@@ -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://
|
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://
|
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://
|
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
|
@@ -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?(
|
160
|
+
return unless object.const_defined?(NESTED_MODULE, false)
|
159
161
|
|
160
|
-
nested_mod = object.const_get(
|
161
|
-
|
162
|
-
object.send(:remove_const,
|
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
|
|
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
|
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
|
data/test/assets/mysql.gql
CHANGED
@@ -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://
|
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://
|
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://
|
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 {
|
data/test/assets/sqlite.gql
CHANGED
@@ -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://
|
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://
|
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://
|
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 {
|
data/test/graphql/source_test.rb
CHANGED
@@ -35,7 +35,7 @@ class Integration_GlobalIDTest < GraphQL::IntegrationTestCase
|
|
35
35
|
end
|
36
36
|
|
37
37
|
def test_create_object_field
|
38
|
-
obj = SCHEMA
|
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
|
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
|
100
|
+
object = SCHEMA.const_get(:NestedTypes)::Object1Object
|
101
101
|
field = object[:field1]
|
102
102
|
|
103
103
|
# (1) Block has higher precedence than default value
|
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.
|
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-
|
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://
|
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.
|
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
|