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.
- 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
|