graphiti_gql 0.2.22 → 0.2.25
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/Gemfile.lock +6 -6
- data/lib/graphiti_gql/graphiti_hax.rb +119 -14
- data/lib/graphiti_gql/loaders/many_to_many.rb +6 -4
- data/lib/graphiti_gql/schema/fields/attribute.rb +4 -18
- data/lib/graphiti_gql/schema/fields/to_many.rb +54 -14
- data/lib/graphiti_gql/schema/query.rb +7 -20
- data/lib/graphiti_gql/schema/registry.rb +2 -1
- data/lib/graphiti_gql/schema/resource_type.rb +66 -7
- data/lib/graphiti_gql/schema.rb +37 -2
- data/lib/graphiti_gql/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ae5d9ce0fe34ef8d53204f8c292b5d09cb58c821ec413804a169e3a562061ad2
|
|
4
|
+
data.tar.gz: 02fc540e3203efe6311fba2d30c3b8b75308103cffe4b5df1f01b29dac804e74
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e01483c436cbc15cb0c80598725a16440ba0254242554c9a2401c4dd72ca5cd4b847941fe3d02da7a4d023640b7ca20824e2537a04654dc2d46c192e53885863
|
|
7
|
+
data.tar.gz: 13478f1634bcb76c13cf9aef90c036fb5636a55c72643db21e854cca9679c4c735e848c6245e73d2194374fa54ee34eecda4cc17240f5cbe491acf14a0ef9db9
|
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
graphiti_gql (0.2.
|
|
4
|
+
graphiti_gql (0.2.25)
|
|
5
5
|
activemodel (> 6.0, < 8.0)
|
|
6
6
|
graphiti (~> 1.3.9)
|
|
7
7
|
graphql (~> 2.0)
|
|
@@ -21,9 +21,9 @@ GEM
|
|
|
21
21
|
coderay (1.1.3)
|
|
22
22
|
concurrent-ruby (1.1.10)
|
|
23
23
|
diff-lcs (1.5.0)
|
|
24
|
-
dry-container (0.10.
|
|
24
|
+
dry-container (0.10.1)
|
|
25
25
|
concurrent-ruby (~> 1.0)
|
|
26
|
-
dry-core (0.8.
|
|
26
|
+
dry-core (0.8.1)
|
|
27
27
|
concurrent-ruby (~> 1.0)
|
|
28
28
|
dry-inflector (0.3.0)
|
|
29
29
|
dry-logic (1.2.0)
|
|
@@ -48,13 +48,13 @@ GEM
|
|
|
48
48
|
graphql-batch (0.5.1)
|
|
49
49
|
graphql (>= 1.10, < 3)
|
|
50
50
|
promise.rb (~> 0.7.2)
|
|
51
|
-
i18n (1.
|
|
51
|
+
i18n (1.12.0)
|
|
52
52
|
concurrent-ruby (~> 1.0)
|
|
53
53
|
jsonapi-renderer (0.2.2)
|
|
54
54
|
jsonapi-serializable (0.3.1)
|
|
55
55
|
jsonapi-renderer (~> 0.2.0)
|
|
56
56
|
method_source (1.0.0)
|
|
57
|
-
minitest (5.
|
|
57
|
+
minitest (5.16.2)
|
|
58
58
|
promise.rb (0.7.4)
|
|
59
59
|
pry (0.13.1)
|
|
60
60
|
coderay (~> 1.1)
|
|
@@ -76,7 +76,7 @@ GEM
|
|
|
76
76
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
77
77
|
rspec-support (~> 3.11.0)
|
|
78
78
|
rspec-support (3.11.0)
|
|
79
|
-
tzinfo (2.0.
|
|
79
|
+
tzinfo (2.0.5)
|
|
80
80
|
concurrent-ruby (~> 1.0)
|
|
81
81
|
|
|
82
82
|
PLATFORMS
|
|
@@ -25,6 +25,10 @@ module GraphitiGql
|
|
|
25
25
|
end
|
|
26
26
|
end
|
|
27
27
|
|
|
28
|
+
def value_object?
|
|
29
|
+
self.class.value_object?
|
|
30
|
+
end
|
|
31
|
+
|
|
28
32
|
def filterings
|
|
29
33
|
@filterings ||= begin
|
|
30
34
|
if @params.key?(:filter)
|
|
@@ -67,6 +71,11 @@ module GraphitiGql
|
|
|
67
71
|
end
|
|
68
72
|
|
|
69
73
|
class_methods do
|
|
74
|
+
def config
|
|
75
|
+
return @config if @config
|
|
76
|
+
super
|
|
77
|
+
@config = @config.merge(value_objects: {}, is_value_object: false)
|
|
78
|
+
end
|
|
70
79
|
|
|
71
80
|
def attribute(*args)
|
|
72
81
|
super(*args).tap do
|
|
@@ -79,7 +88,14 @@ module GraphitiGql
|
|
|
79
88
|
end
|
|
80
89
|
|
|
81
90
|
def filter(name, *args, &blk)
|
|
91
|
+
is_bool = (filters[name] && filters[name][:type] == :boolean) ||
|
|
92
|
+
args[0] == :boolean
|
|
93
|
+
opts = args.length == 1 ? args[0] : args[1]
|
|
94
|
+
boolean_array = is_bool && opts[:single] == false
|
|
82
95
|
super
|
|
96
|
+
# default behavior is to force single: true
|
|
97
|
+
filters[name][:single] = false if boolean_array
|
|
98
|
+
|
|
83
99
|
opts = args.extract_options!
|
|
84
100
|
if opts[:if]
|
|
85
101
|
attributes[name][:filterable] = opts[:if]
|
|
@@ -93,6 +109,40 @@ module GraphitiGql
|
|
|
93
109
|
super
|
|
94
110
|
end
|
|
95
111
|
end
|
|
112
|
+
|
|
113
|
+
def value_object?
|
|
114
|
+
!!config[:is_value_object]
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def value_object!
|
|
118
|
+
config[:is_value_object] = true
|
|
119
|
+
self.adapter = ::Graphiti::Adapters::Null
|
|
120
|
+
config[:filters] = {}
|
|
121
|
+
config[:stats] = {}
|
|
122
|
+
config[:sorts] = {}
|
|
123
|
+
config[:attributes].delete(:id)
|
|
124
|
+
define_method :base_scope do
|
|
125
|
+
{}
|
|
126
|
+
end
|
|
127
|
+
define_method :resolve do |parent|
|
|
128
|
+
[parent]
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def value_object(name, opts = {})
|
|
133
|
+
opts[:array] ||= false
|
|
134
|
+
opts[:null] ||= true
|
|
135
|
+
config[:value_objects][name] = Graphiti::ValueObjectAssociation.new(
|
|
136
|
+
name,
|
|
137
|
+
parent_resource_class: self,
|
|
138
|
+
resource_class: opts[:resource],
|
|
139
|
+
_alias: opts[:alias],
|
|
140
|
+
is_array: opts[:array],
|
|
141
|
+
null: opts[:null],
|
|
142
|
+
readable: opts[:readable],
|
|
143
|
+
deprecation_reason: opts[:deprecation_reason]
|
|
144
|
+
)
|
|
145
|
+
end
|
|
96
146
|
end
|
|
97
147
|
end
|
|
98
148
|
Graphiti::Resource.send(:prepend, ResourceExtras)
|
|
@@ -196,26 +246,14 @@ module GraphitiGql
|
|
|
196
246
|
module ManyToManyExtras
|
|
197
247
|
def self.prepended(klass)
|
|
198
248
|
klass.class_eval do
|
|
199
|
-
attr_reader :join_table_alias, :edge_magic
|
|
200
|
-
|
|
201
|
-
class << self
|
|
202
|
-
attr_reader :edge_resource
|
|
203
|
-
|
|
204
|
-
def attribute(*args, &blk)
|
|
205
|
-
@edge_resource ||= Class.new(Graphiti::Resource) do
|
|
206
|
-
def self.abstract_class?
|
|
207
|
-
true
|
|
208
|
-
end
|
|
209
|
-
end
|
|
210
|
-
@edge_resource.attribute(*args, &blk)
|
|
211
|
-
end
|
|
212
|
-
end
|
|
249
|
+
attr_reader :join_table_alias, :edge_magic, :edge_resource
|
|
213
250
|
end
|
|
214
251
|
end
|
|
215
252
|
|
|
216
253
|
def initialize(name, opts = {})
|
|
217
254
|
@join_table_alias = opts[:join_table_alias]
|
|
218
255
|
@edge_magic = opts[:edge_magic] == false ? false : true
|
|
256
|
+
@edge_resource = opts[:edge_resource]
|
|
219
257
|
super
|
|
220
258
|
end
|
|
221
259
|
|
|
@@ -276,6 +314,20 @@ module GraphitiGql
|
|
|
276
314
|
description: 'Datetime with milliseconds'
|
|
277
315
|
}
|
|
278
316
|
|
|
317
|
+
[:string, :integer, :float, :datetime, :precise_datetime].each do |kind|
|
|
318
|
+
duped_hash = Graphiti::Util::Hash.deep_dup(Graphiti::Types[:hash])
|
|
319
|
+
type = Graphiti::Types[:"#{kind}_range"] = duped_hash
|
|
320
|
+
type[:canonical_name] = :"#{kind}_range"
|
|
321
|
+
Graphiti::Types[:"array_of_#{kind}_ranges"] = {
|
|
322
|
+
canonical_name: :"#{kind}_range",
|
|
323
|
+
params: Dry::Types["strict.array"].of(type[:params]),
|
|
324
|
+
read: Dry::Types["strict.array"].of(type[:read]),
|
|
325
|
+
write: Dry::Types["strict.array"].of(type[:write]),
|
|
326
|
+
kind: "array",
|
|
327
|
+
description: "Base Type."
|
|
328
|
+
}
|
|
329
|
+
end
|
|
330
|
+
|
|
279
331
|
module ActiveRecordAdapterExtras
|
|
280
332
|
extend ActiveSupport::Concern
|
|
281
333
|
|
|
@@ -375,6 +427,15 @@ module GraphitiGql
|
|
|
375
427
|
|
|
376
428
|
Graphiti::Query.send(:prepend, QueryExtras)
|
|
377
429
|
module ScopeExtras
|
|
430
|
+
def initialize(object, resource, query, opts = {})
|
|
431
|
+
if resource.value_object?
|
|
432
|
+
object = query.params[:parent]
|
|
433
|
+
super(object, resource, query, opts)
|
|
434
|
+
else
|
|
435
|
+
super
|
|
436
|
+
end
|
|
437
|
+
end
|
|
438
|
+
|
|
378
439
|
def resolve(*args)
|
|
379
440
|
results = super
|
|
380
441
|
results.reverse! if @query.hash[:reverse]
|
|
@@ -395,4 +456,48 @@ module GraphitiGql
|
|
|
395
456
|
::Graphiti::Adapters::ActiveRecord::ManyToManySideload
|
|
396
457
|
.send(:prepend, ActiveRecordManyToManyExtras)
|
|
397
458
|
end
|
|
459
|
+
end
|
|
460
|
+
|
|
461
|
+
class Graphiti::ValueObjectAssociation
|
|
462
|
+
attr_reader :name,
|
|
463
|
+
:parent_resource_class,
|
|
464
|
+
:alias,
|
|
465
|
+
:readable,
|
|
466
|
+
:null,
|
|
467
|
+
:deprecation_reason
|
|
468
|
+
|
|
469
|
+
def initialize(
|
|
470
|
+
name,
|
|
471
|
+
parent_resource_class:,
|
|
472
|
+
resource_class:,
|
|
473
|
+
is_array: false,
|
|
474
|
+
readable: nil,
|
|
475
|
+
null: true,
|
|
476
|
+
_alias: nil,
|
|
477
|
+
deprecation_reason: nil
|
|
478
|
+
)
|
|
479
|
+
@name = name
|
|
480
|
+
@parent_resource_class = parent_resource_class
|
|
481
|
+
@resource_class = resource_class
|
|
482
|
+
@readable = readable
|
|
483
|
+
@array = is_array
|
|
484
|
+
@alias = _alias
|
|
485
|
+
@null = null
|
|
486
|
+
@deprecation_reason = deprecation_reason
|
|
487
|
+
end
|
|
488
|
+
|
|
489
|
+
def array?
|
|
490
|
+
!!@array
|
|
491
|
+
end
|
|
492
|
+
|
|
493
|
+
def resource_class
|
|
494
|
+
@resource_class ||= Graphiti::Util::Class
|
|
495
|
+
.infer_resource_class(@parent_resource_class, name)
|
|
496
|
+
end
|
|
497
|
+
|
|
498
|
+
def build_resource(parent)
|
|
499
|
+
instance = resource_class.new
|
|
500
|
+
instance.parent = parent
|
|
501
|
+
instance
|
|
502
|
+
end
|
|
398
503
|
end
|
|
@@ -16,13 +16,15 @@ module GraphitiGql
|
|
|
16
16
|
|
|
17
17
|
private
|
|
18
18
|
|
|
19
|
+
def thru_model
|
|
20
|
+
thru = @sideload.foreign_key.keys.first
|
|
21
|
+
reflection = @sideload.parent_resource.model.reflect_on_association(thru)
|
|
22
|
+
reflection.klass
|
|
23
|
+
end
|
|
24
|
+
|
|
19
25
|
def add_join_table_magic(proxy)
|
|
20
26
|
return unless @sideload.edge_magic
|
|
21
27
|
if defined?(ActiveRecord) && proxy.resource.model.ancestors.include?(ActiveRecord::Base)
|
|
22
|
-
thru = @sideload.foreign_key.keys.first
|
|
23
|
-
reflection = @sideload.parent_resource.model.reflect_on_association(thru)
|
|
24
|
-
thru_model = reflection.klass
|
|
25
|
-
|
|
26
28
|
thru_table_name = @sideload.join_table_alias || thru_model.table_name
|
|
27
29
|
names = thru_model.column_names.map do |n|
|
|
28
30
|
next if n == :id
|
|
@@ -3,12 +3,11 @@ module GraphitiGql
|
|
|
3
3
|
module Fields
|
|
4
4
|
class Attribute
|
|
5
5
|
# If sideload is present, we're applying m2m metadata to an edge
|
|
6
|
-
def initialize(resource, name, config
|
|
6
|
+
def initialize(resource, name, config)
|
|
7
7
|
@resource = resource
|
|
8
8
|
@config = config
|
|
9
9
|
@name = name
|
|
10
10
|
@alias = config[:alias]
|
|
11
|
-
@sideload = sideload # is_edge: true
|
|
12
11
|
end
|
|
13
12
|
|
|
14
13
|
def apply(type)
|
|
@@ -16,13 +15,11 @@ module GraphitiGql
|
|
|
16
15
|
_config = @config
|
|
17
16
|
_name = @name
|
|
18
17
|
_alias = @alias
|
|
19
|
-
_sideload = @sideload
|
|
20
18
|
opts = @config.slice(:null, :deprecation_reason)
|
|
21
19
|
type.field(_name, field_type, **opts)
|
|
22
20
|
type.define_method _name do
|
|
23
21
|
if (readable = _config[:readable]).is_a?(Symbol)
|
|
24
22
|
obj = object
|
|
25
|
-
obj = object.node if _sideload
|
|
26
23
|
resource = obj.instance_variable_get(:@__graphiti_resource)
|
|
27
24
|
unless resource.send(readable)
|
|
28
25
|
path = Graphiti.context[:object][:current_path].join(".")
|
|
@@ -30,22 +27,11 @@ module GraphitiGql
|
|
|
30
27
|
end
|
|
31
28
|
end
|
|
32
29
|
|
|
33
|
-
edge_attrs = nil
|
|
34
|
-
if _sideload
|
|
35
|
-
edge_attrs = object.node.attributes
|
|
36
|
-
.select { |k, v| k.to_s.starts_with?("_edge_") }
|
|
37
|
-
edge_attrs.transform_keys! { |k| k.to_s.gsub("_edge_", "").to_sym }
|
|
38
|
-
end
|
|
39
|
-
|
|
40
30
|
value = if _config[:proc]
|
|
41
|
-
|
|
42
|
-
instance_exec(edge_attrs, object.node, &_config[:proc])
|
|
43
|
-
else
|
|
44
|
-
instance_eval(&_config[:proc])
|
|
45
|
-
end
|
|
31
|
+
instance_eval(&_config[:proc])
|
|
46
32
|
else
|
|
47
|
-
if
|
|
48
|
-
|
|
33
|
+
if object.is_a?(Hash)
|
|
34
|
+
object[_name] || object[_name.to_s]
|
|
49
35
|
else
|
|
50
36
|
object.send(_alias || _name)
|
|
51
37
|
end
|
|
@@ -35,7 +35,7 @@ module GraphitiGql
|
|
|
35
35
|
end
|
|
36
36
|
|
|
37
37
|
def customized_edge?
|
|
38
|
-
@sideload.type == :many_to_many && @sideload.
|
|
38
|
+
@sideload.type == :many_to_many && @sideload.edge_resource
|
|
39
39
|
end
|
|
40
40
|
|
|
41
41
|
def find_or_build_connection
|
|
@@ -59,21 +59,61 @@ module GraphitiGql
|
|
|
59
59
|
end
|
|
60
60
|
|
|
61
61
|
def build_edge_type_class(sideload_type)
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
62
|
+
klass = build_friendly_graphql_edge_type_class \
|
|
63
|
+
sideload_type.edge_type_class
|
|
64
|
+
name = edge_type_class_name(sideload_type)
|
|
65
|
+
klass.define_method(:graphql_name) { name }
|
|
66
|
+
klass.graphql_name(name)
|
|
67
|
+
edge_resource = @sideload.edge_resource
|
|
68
|
+
ResourceType.add_fields(klass, edge_resource, id: false)
|
|
69
|
+
ResourceType.add_relationships(edge_resource, klass)
|
|
70
|
+
ResourceType.add_value_objects(edge_resource, klass)
|
|
71
|
+
klass
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# Normally we reference 'object', but edges work differently
|
|
75
|
+
# This makes 'object' work everywhere
|
|
76
|
+
# Needed when evaluating fields/relationships for consistent interface
|
|
77
|
+
def build_friendly_graphql_edge_type_class(superklass)
|
|
78
|
+
klass = Class.new(superklass) do
|
|
79
|
+
alias :original_object :object
|
|
80
|
+
def object
|
|
81
|
+
return @_object if @_object # avoid conflict
|
|
82
|
+
|
|
83
|
+
node = original_object.node # the 'parent' record we joined with
|
|
84
|
+
edge_attrs = node.attributes.select { |k,v| k.to_s.starts_with?('_edge') }
|
|
85
|
+
edge_attrs.transform_keys! { |k| k.to_s.gsub('_edge_', '') }
|
|
86
|
+
edge_model = model.new(edge_attrs)
|
|
87
|
+
edge_model.instance_variable_set(:@__graphiti_resource, resource)
|
|
88
|
+
@_object = edge_model
|
|
89
|
+
@_object
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def cursor
|
|
93
|
+
original_object.cursor
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def node
|
|
97
|
+
original_object.node
|
|
98
|
+
end
|
|
68
99
|
end
|
|
69
|
-
|
|
100
|
+
|
|
101
|
+
# used in #object
|
|
102
|
+
thru = @sideload.foreign_key.keys.first
|
|
103
|
+
reflection = @sideload.parent_resource.model.reflect_on_association(thru)
|
|
104
|
+
thru_model = reflection.klass
|
|
105
|
+
edge_resource = @sideload.edge_resource.new
|
|
106
|
+
klass.define_method(:model) { thru_model }
|
|
107
|
+
klass.define_method(:resource) { edge_resource }
|
|
108
|
+
|
|
109
|
+
klass
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def edge_type_class_name(sideload_type)
|
|
113
|
+
registered_parent = Schema.registry.get \
|
|
114
|
+
@sideload.parent_resource.class
|
|
70
115
|
parent_name = registered_parent[:type].graphql_name
|
|
71
|
-
|
|
72
|
-
edge_type_class.define_method :graphql_name do
|
|
73
|
-
edge_type_class_name
|
|
74
|
-
end
|
|
75
|
-
edge_type_class.graphql_name(edge_type_class_name)
|
|
76
|
-
edge_type_class
|
|
116
|
+
"#{parent_name}To#{sideload_type.graphql_name}Edge"
|
|
77
117
|
end
|
|
78
118
|
end
|
|
79
119
|
end
|
|
@@ -10,6 +10,7 @@ module GraphitiGql
|
|
|
10
10
|
def build
|
|
11
11
|
@resources.each { |resource| ResourceType.new(resource).build }
|
|
12
12
|
define_entrypoints
|
|
13
|
+
add_value_objects
|
|
13
14
|
add_relationships
|
|
14
15
|
@query_class
|
|
15
16
|
end
|
|
@@ -30,30 +31,16 @@ module GraphitiGql
|
|
|
30
31
|
end
|
|
31
32
|
|
|
32
33
|
def add_relationships
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
else
|
|
37
|
-
Fields::ToOne.new(sideload, sideload_type).apply(type)
|
|
38
|
-
end
|
|
34
|
+
registry.resource_types.each do |registered|
|
|
35
|
+
resource, type = registered[:resource], registered[:type]
|
|
36
|
+
ResourceType.add_relationships(resource, type)
|
|
39
37
|
end
|
|
40
38
|
end
|
|
41
39
|
|
|
42
|
-
def
|
|
40
|
+
def add_value_objects
|
|
43
41
|
registry.resource_types.each do |registered|
|
|
44
|
-
registered[:resource]
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
registered_sl = if sl.type == :polymorphic_belongs_to
|
|
48
|
-
PolymorphicBelongsToInterface
|
|
49
|
-
.new(registered[:resource], sl)
|
|
50
|
-
.build
|
|
51
|
-
else
|
|
52
|
-
registry.get(sl.resource.class)
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
yield registered[:type], registered_sl[:type], sl
|
|
56
|
-
end
|
|
42
|
+
resource, type = registered[:resource], registered[:type]
|
|
43
|
+
ResourceType.add_value_objects(resource, type)
|
|
57
44
|
end
|
|
58
45
|
end
|
|
59
46
|
end
|
|
@@ -52,7 +52,8 @@ module GraphitiGql
|
|
|
52
52
|
# When polymorphic parent, returns the Interface not the Class
|
|
53
53
|
def resource_types
|
|
54
54
|
values
|
|
55
|
-
.select { |v| v.key?(:resource)
|
|
55
|
+
.select { |v| v.key?(:resource) }
|
|
56
|
+
.reject { |v| v[:interface] || v[:resource].value_object? }
|
|
56
57
|
.map { |registered| get(registered[:resource]) }
|
|
57
58
|
end
|
|
58
59
|
|
|
@@ -14,6 +14,69 @@ module GraphitiGql
|
|
|
14
14
|
end
|
|
15
15
|
end
|
|
16
16
|
|
|
17
|
+
def self.add_fields(type, resource, id: true) # id: false for edges
|
|
18
|
+
resource.attributes.each_pair do |name, config|
|
|
19
|
+
next if name == :id && id == false
|
|
20
|
+
if config[:readable]
|
|
21
|
+
Fields::Attribute.new(resource, name, config).apply(type)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def self.add_value_objects(resource, type)
|
|
27
|
+
resource.config[:value_objects].each_pair do |name, vo_association|
|
|
28
|
+
vo_resource_class = vo_association.resource_class
|
|
29
|
+
value_object_type = Schema.registry.get(vo_resource_class)[:type]
|
|
30
|
+
if vo_association.array?
|
|
31
|
+
value_object_type = [value_object_type]
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
_array = vo_association.array?
|
|
35
|
+
opts = { null: vo_association.null }
|
|
36
|
+
opts[:deprecation_reason] = vo_association.deprecation_reason if vo_association.deprecation_reason
|
|
37
|
+
type.field name, value_object_type, **opts
|
|
38
|
+
type.define_method name do
|
|
39
|
+
if (method_name = vo_association.readable)
|
|
40
|
+
unless vo_association.parent_resource_class.new.send(method_name)
|
|
41
|
+
raise ::Graphiti::Errors::UnreadableAttribute
|
|
42
|
+
.new(vo_association.parent_resource_class, name)
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
result = vo_resource_class.all({ parent: object }).to_a
|
|
47
|
+
if result.is_a?(Array) && !_array
|
|
48
|
+
result = result.first
|
|
49
|
+
end
|
|
50
|
+
if result == object || result == [object]
|
|
51
|
+
method_name = vo_association.alias.presence || name
|
|
52
|
+
result = object.send(method_name)
|
|
53
|
+
end
|
|
54
|
+
result
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def self.add_relationships(resource, type)
|
|
60
|
+
resource.sideloads.each do |name, sideload|
|
|
61
|
+
next unless sideload.readable?
|
|
62
|
+
|
|
63
|
+
registered_sl = if sideload.type == :polymorphic_belongs_to
|
|
64
|
+
PolymorphicBelongsToInterface
|
|
65
|
+
.new(resource, sideload)
|
|
66
|
+
.build
|
|
67
|
+
else
|
|
68
|
+
Schema.registry.get(sideload.resource.class)
|
|
69
|
+
end
|
|
70
|
+
sideload_type = registered_sl[:type]
|
|
71
|
+
|
|
72
|
+
if [:has_many, :many_to_many, :has_one].include?(sideload.type)
|
|
73
|
+
Fields::ToMany.new(sideload, sideload_type).apply(type)
|
|
74
|
+
else
|
|
75
|
+
Fields::ToOne.new(sideload, sideload_type).apply(type)
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
17
80
|
def initialize(resource, implements: nil)
|
|
18
81
|
@resource = resource
|
|
19
82
|
@implements = implements
|
|
@@ -86,14 +149,10 @@ module GraphitiGql
|
|
|
86
149
|
def name
|
|
87
150
|
registry.key_for(@resource)
|
|
88
151
|
end
|
|
89
|
-
|
|
152
|
+
|
|
90
153
|
def add_fields(type, resource)
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
Fields::Attribute.new(@resource, name, config).apply(type)
|
|
94
|
-
end
|
|
95
|
-
end
|
|
96
|
-
end
|
|
154
|
+
self.class.add_fields(type, resource)
|
|
155
|
+
end
|
|
97
156
|
|
|
98
157
|
def build_connection_class
|
|
99
158
|
klass = Class.new(GraphQL::Types::Relay::BaseConnection)
|
data/lib/graphiti_gql/schema.rb
CHANGED
|
@@ -4,6 +4,31 @@ module GraphitiGql
|
|
|
4
4
|
self.time_precision = 6
|
|
5
5
|
end
|
|
6
6
|
|
|
7
|
+
class DatetimeRange < GraphQL::Schema::Object
|
|
8
|
+
field :from, GraphQL::Types::ISO8601DateTime
|
|
9
|
+
field :to, GraphQL::Types::ISO8601DateTime
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
class PreciseDatetimeRange < GraphQL::Schema::Object
|
|
13
|
+
field :from, PreciseDatetime
|
|
14
|
+
field :to, PreciseDatetime
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
class StringRange < GraphQL::Schema::Object
|
|
18
|
+
field :from, String
|
|
19
|
+
field :to, String
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
class IntegerRange < GraphQL::Schema::Object
|
|
23
|
+
field :from, Integer
|
|
24
|
+
field :to, Integer
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
class FloatRange < GraphQL::Schema::Object
|
|
28
|
+
field :from, Float
|
|
29
|
+
field :to, Float
|
|
30
|
+
end
|
|
31
|
+
|
|
7
32
|
GQL_TYPE_MAP = {
|
|
8
33
|
integer_id: String,
|
|
9
34
|
string: String,
|
|
@@ -11,18 +36,28 @@ module GraphitiGql
|
|
|
11
36
|
integer: Integer,
|
|
12
37
|
big_integer: GraphQL::Types::BigInt,
|
|
13
38
|
float: Float,
|
|
14
|
-
boolean: GraphQL::
|
|
39
|
+
boolean: GraphQL::Types::Boolean,
|
|
15
40
|
date: GraphQL::Types::ISO8601Date,
|
|
16
41
|
datetime: GraphQL::Types::ISO8601DateTime,
|
|
17
42
|
precise_datetime: PreciseDatetime,
|
|
18
43
|
hash: GraphQL::Types::JSON,
|
|
44
|
+
string_range: StringRange,
|
|
45
|
+
integer_range: IntegerRange,
|
|
46
|
+
float_range: FloatRange,
|
|
47
|
+
datetime_range: DatetimeRange,
|
|
48
|
+
precise_datetime_range: PreciseDatetimeRange,
|
|
19
49
|
array: [GraphQL::Types::JSON],
|
|
20
50
|
array_of_strings: [String],
|
|
21
51
|
array_of_integers: [Integer],
|
|
22
52
|
array_of_floats: [Float],
|
|
23
53
|
array_of_dates: [GraphQL::Types::ISO8601Date],
|
|
24
54
|
array_of_datetimes: [GraphQL::Types::ISO8601DateTime],
|
|
25
|
-
array_of_precise_datetimes: [PreciseDatetime]
|
|
55
|
+
array_of_precise_datetimes: [PreciseDatetime],
|
|
56
|
+
array_of_string_ranges: [StringRange],
|
|
57
|
+
array_of_integer_ranges: [IntegerRange],
|
|
58
|
+
array_of_float_ranges: [FloatRange],
|
|
59
|
+
array_of_datetime_ranges: [DatetimeRange],
|
|
60
|
+
array_of_precise_datetime_ranges: [PreciseDatetimeRange]
|
|
26
61
|
}
|
|
27
62
|
|
|
28
63
|
class RelayConnectionExtension < GraphQL::Schema::Field::ConnectionExtension
|
data/lib/graphiti_gql/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: graphiti_gql
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.2.
|
|
4
|
+
version: 0.2.25
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Lee Richmond
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2022-08-
|
|
11
|
+
date: 2022-08-12 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: graphql
|