graphiti_gql 0.2.29 → 0.2.32
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/.gitignore +2 -0
- data/lib/graphiti_gql/active_resource.rb +10 -8
- data/lib/graphiti_gql/graphiti_hax.rb +65 -8
- data/lib/graphiti_gql/loaders/belongs_to.rb +24 -11
- data/lib/graphiti_gql/loaders/many.rb +8 -4
- data/lib/graphiti_gql/log_subscriber.rb +8 -2
- data/lib/graphiti_gql/schema/fields/attribute.rb +10 -2
- data/lib/graphiti_gql/schema/fields/show.rb +1 -1
- data/lib/graphiti_gql/schema/list_arguments.rb +0 -1
- data/lib/graphiti_gql/schema/query.rb +1 -1
- data/lib/graphiti_gql/schema/registry.rb +4 -4
- data/lib/graphiti_gql/schema/resource_type.rb +54 -32
- data/lib/graphiti_gql/schema.rb +4 -0
- data/lib/graphiti_gql/spec_helper.rb +3 -0
- data/lib/graphiti_gql/version.rb +1 -1
- metadata +2 -3
- data/Gemfile.lock +0 -94
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e8d0cda6314cfd3485283ae277bdaa56494a4b8eae9c62f9037b5b78f17b2825
|
|
4
|
+
data.tar.gz: 28fcbab36f65c81bb8a673aefaefe7bd54888f02ca741fcf5a889f2f858e094a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 864e7b0fbd88fb01f3aa8bc0490ce144a4d62e02c9d9ce30dc032f6209b91cf9e5766b06bf85113cbdb9d4603dd397b8b831fcbc8f76ff123ff12307e82a4815
|
|
7
|
+
data.tar.gz: 61304ca30da99696a76c625c3737037429182df25ca6271c9f779bbbfa96740e2d1b3c792cbaaea560a31b52edc90f342b49a8aab12d607ece04804415e3d1e1
|
data/.gitignore
CHANGED
|
@@ -37,18 +37,20 @@ module GraphitiGql
|
|
|
37
37
|
def edge(name, node_id)
|
|
38
38
|
found = @edges[name].empty? ? nil : @edges[name]
|
|
39
39
|
if found && node_id
|
|
40
|
-
found.find
|
|
40
|
+
found.find do |f|
|
|
41
|
+
gql_node_id = f.instance_variable_get(:@node_id)
|
|
42
|
+
gql_node_id == node_id ||
|
|
43
|
+
gql_node_id == node_id.to_s ||
|
|
44
|
+
gql_node_id == @resource.gid(node_id)
|
|
45
|
+
end
|
|
41
46
|
else
|
|
42
47
|
found
|
|
43
48
|
end
|
|
44
49
|
end
|
|
45
50
|
|
|
46
|
-
def
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
def int_id
|
|
51
|
-
decoded_id.to_i
|
|
51
|
+
def _id
|
|
52
|
+
deserialized = @resource.deserialize_gid(id)
|
|
53
|
+
deserialized.to_i.to_s == deserialized ? deserialized.to_i : deserialized
|
|
52
54
|
end
|
|
53
55
|
end
|
|
54
56
|
|
|
@@ -77,7 +79,7 @@ module GraphitiGql
|
|
|
77
79
|
data # fire query
|
|
78
80
|
Node.new(underscore(data[data.keys.first]), @resource)
|
|
79
81
|
else
|
|
80
|
-
nodes.find { |n| n.id == id.to_s }
|
|
82
|
+
nodes.find { |n| n.id == id.to_s || n.id == @resource.gid(id) }
|
|
81
83
|
end
|
|
82
84
|
end
|
|
83
85
|
|
|
@@ -71,13 +71,46 @@ module GraphitiGql
|
|
|
71
71
|
end
|
|
72
72
|
|
|
73
73
|
class_methods do
|
|
74
|
+
def gid(*ids)
|
|
75
|
+
ids = ids[0] if ids[0].is_a?(Array) && ids.length == 1
|
|
76
|
+
gids = ids.map { |id| serialize_gid(id) }
|
|
77
|
+
ids.length == 1 ? gids.first : gids
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def serialize_gid(id)
|
|
81
|
+
Base64.encode64("#{graphql_name}/#{id}")
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def deserialize_gid(gid, integer = true)
|
|
85
|
+
id = Base64.decode64(gid).split("/").last
|
|
86
|
+
id.to_i.to_s == id ? id.to_i : id
|
|
87
|
+
end
|
|
88
|
+
|
|
74
89
|
def config
|
|
75
90
|
return @config if @config
|
|
76
91
|
super
|
|
77
92
|
@config = @config.merge(value_objects: {}, is_value_object: false)
|
|
78
93
|
end
|
|
79
94
|
|
|
95
|
+
def graphql_name
|
|
96
|
+
@graphql_name ||= begin
|
|
97
|
+
if name.nil?
|
|
98
|
+
'Unknown'
|
|
99
|
+
else
|
|
100
|
+
name.gsub('Resource', '').gsub('::', '')
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
80
105
|
def attribute(*args)
|
|
106
|
+
# new default is :gid, not integer_id
|
|
107
|
+
if args[0] == :id && args[1] == :integer_id
|
|
108
|
+
args[1] = :gid
|
|
109
|
+
opts = args.extract_options!
|
|
110
|
+
opts[:null] = false
|
|
111
|
+
args << opts
|
|
112
|
+
end
|
|
113
|
+
|
|
81
114
|
super(*args).tap do
|
|
82
115
|
opts = args.extract_options!
|
|
83
116
|
att = config[:attributes][args[0]]
|
|
@@ -116,6 +149,7 @@ module GraphitiGql
|
|
|
116
149
|
|
|
117
150
|
def value_object!
|
|
118
151
|
config[:is_value_object] = true
|
|
152
|
+
self.graphql_entrypoint = false
|
|
119
153
|
self.adapter = ::Graphiti::Adapters::Null
|
|
120
154
|
config[:filters] = {}
|
|
121
155
|
config[:stats] = {}
|
|
@@ -320,6 +354,7 @@ module GraphitiGql
|
|
|
320
354
|
description: 'Datetime with milliseconds'
|
|
321
355
|
}
|
|
322
356
|
|
|
357
|
+
# Support ranges
|
|
323
358
|
[:string, :integer, :float, :datetime, :precise_datetime].each do |kind|
|
|
324
359
|
duped_hash = Graphiti::Util::Hash.deep_dup(Graphiti::Types[:hash])
|
|
325
360
|
type = Graphiti::Types[:"#{kind}_range"] = duped_hash
|
|
@@ -334,6 +369,29 @@ module GraphitiGql
|
|
|
334
369
|
}
|
|
335
370
|
end
|
|
336
371
|
|
|
372
|
+
# Support gid
|
|
373
|
+
gid_going_out = ->(id) {
|
|
374
|
+
resource.gid(id)
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
gid_coming_in = definition.constructor do |input|
|
|
378
|
+
if defined?(ApplicationResource)
|
|
379
|
+
ApplicationResource.deserialize_gid(input)
|
|
380
|
+
else
|
|
381
|
+
Graphiti::Resource.deserialize_gid(input)
|
|
382
|
+
end
|
|
383
|
+
end
|
|
384
|
+
|
|
385
|
+
# Register it with Graphiti
|
|
386
|
+
Graphiti::Types[:gid] = {
|
|
387
|
+
params: gid_coming_in,
|
|
388
|
+
read: gid_going_out,
|
|
389
|
+
write: gid_coming_in,
|
|
390
|
+
kind: 'scalar',
|
|
391
|
+
canonical_name: :gid,
|
|
392
|
+
description: 'Globally-unique identifier',
|
|
393
|
+
}
|
|
394
|
+
|
|
337
395
|
module ActiveRecordAdapterExtras
|
|
338
396
|
extend ActiveSupport::Concern
|
|
339
397
|
|
|
@@ -344,6 +402,8 @@ module GraphitiGql
|
|
|
344
402
|
alias_method :filter_precise_datetime_gte, :filter_gte
|
|
345
403
|
alias_method :filter_precise_datetime_eq, :filter_eq
|
|
346
404
|
alias_method :filter_precise_datetime_not_eq, :filter_not_eq
|
|
405
|
+
alias_method :filter_gid_eq, :filter_eq
|
|
406
|
+
alias_method :filter_gid_not_eq, :filter_not_eq
|
|
347
407
|
end
|
|
348
408
|
|
|
349
409
|
# TODO: integration specs mysql vs postgres for case sensitivity
|
|
@@ -393,11 +453,14 @@ module GraphitiGql
|
|
|
393
453
|
class << self
|
|
394
454
|
alias :old_default_operators :default_operators
|
|
395
455
|
def default_operators
|
|
396
|
-
old_default_operators.merge({
|
|
397
|
-
precise_datetime: numerical_operators,
|
|
456
|
+
ops = old_default_operators.merge({
|
|
457
|
+
precise_datetime: numerical_operators - [:not_eq],
|
|
398
458
|
string_enum: [:eq, :not_eq],
|
|
399
459
|
integer_enum: [:eq, :not_eq],
|
|
460
|
+
gid: [:eq, :not_eq]
|
|
400
461
|
})
|
|
462
|
+
ops[:datetime] = ops[:datetime] - [:not_eq]
|
|
463
|
+
ops
|
|
401
464
|
end
|
|
402
465
|
end
|
|
403
466
|
end
|
|
@@ -519,12 +582,6 @@ class Graphiti::ValueObjectAssociation
|
|
|
519
582
|
@resource_class ||= Graphiti::Util::Class
|
|
520
583
|
.infer_resource_class(@parent_resource_class, name)
|
|
521
584
|
end
|
|
522
|
-
|
|
523
|
-
def build_resource(parent)
|
|
524
|
-
instance = resource_class.new
|
|
525
|
-
instance.parent = parent
|
|
526
|
-
instance
|
|
527
|
-
end
|
|
528
585
|
end
|
|
529
586
|
|
|
530
587
|
module Graphiti
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
module GraphitiGql
|
|
2
2
|
module Loaders
|
|
3
|
-
class FakeRecord < Struct.new(:id, :type)
|
|
3
|
+
class FakeRecord < Struct.new(:id, :type, :graphiti_resource)
|
|
4
|
+
def initialize(*args)
|
|
5
|
+
super
|
|
6
|
+
@__graphiti_resource = graphiti_resource
|
|
7
|
+
end
|
|
4
8
|
end
|
|
5
9
|
|
|
6
10
|
class BelongsTo < GraphQL::Batch::Loader
|
|
@@ -16,16 +20,16 @@ module GraphitiGql
|
|
|
16
20
|
ids.compact!
|
|
17
21
|
return if ids.empty?
|
|
18
22
|
|
|
19
|
-
if @params[:simpleid]
|
|
23
|
+
if @params[:simpleid] && !to_polymorphic_resource?
|
|
20
24
|
if @sideload.type == :polymorphic_belongs_to
|
|
21
25
|
ids.each do |id|
|
|
22
26
|
child = @sideload.children.values.find { |c| c.group_name == id[:type].to_sym }
|
|
23
27
|
type = Schema::Registry.instance.get(child.resource.class, interface: false)[:type]
|
|
24
|
-
fulfill(id, FakeRecord.new(id[:id], type))
|
|
28
|
+
fulfill(id, FakeRecord.new(id[:id], type, child.resource))
|
|
25
29
|
end
|
|
26
30
|
else
|
|
27
31
|
type = Schema::Registry.instance.get(@sideload.resource.class)[:type]
|
|
28
|
-
ids.each { |id| fulfill(id, FakeRecord.new(id, type)) }
|
|
32
|
+
ids.each { |id| fulfill(id, FakeRecord.new(id, type, @sideload.resource)) }
|
|
29
33
|
end
|
|
30
34
|
return
|
|
31
35
|
end
|
|
@@ -40,9 +44,10 @@ module GraphitiGql
|
|
|
40
44
|
payload.each_pair do |key, value|
|
|
41
45
|
params = { filter: {} }
|
|
42
46
|
klass = @sideload.children.values.find { |c| c.group_name == key.to_sym }
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
47
|
+
filter_ids = value.map { |id| @sideload.resource.class.gid(id.to_s) }
|
|
48
|
+
params = @params.merge({
|
|
49
|
+
filter: { id: { eq: filter_ids } }
|
|
50
|
+
})
|
|
46
51
|
|
|
47
52
|
futures << Concurrent::Future.execute do
|
|
48
53
|
{ type: key, data: klass.resource.class.all(params).data }
|
|
@@ -50,14 +55,16 @@ module GraphitiGql
|
|
|
50
55
|
end
|
|
51
56
|
values = futures.map(&:value)
|
|
52
57
|
ids.each do |id|
|
|
53
|
-
|
|
54
|
-
|
|
58
|
+
records_for_type = values.find { |v| v[:type] == id[:type] }
|
|
59
|
+
corresponding = records_for_type[:data].find { |r| r.id == id[:id] }
|
|
60
|
+
fulfill(id, corresponding)
|
|
55
61
|
end
|
|
56
62
|
else
|
|
57
63
|
resource = Schema.registry.get(@sideload.resource.class)[:resource]
|
|
58
|
-
params =
|
|
64
|
+
params = @params.deep_dup
|
|
59
65
|
unless resource.singular
|
|
60
|
-
|
|
66
|
+
filter_ids = ids.map { |id| @sideload.resource.class.gid(id.to_s) }
|
|
67
|
+
params[:filter] = {id: { eq: filter_ids } }
|
|
61
68
|
end
|
|
62
69
|
records = resource.all(params).data
|
|
63
70
|
if resource.singular
|
|
@@ -68,6 +75,12 @@ module GraphitiGql
|
|
|
68
75
|
end
|
|
69
76
|
end
|
|
70
77
|
end
|
|
78
|
+
|
|
79
|
+
private
|
|
80
|
+
|
|
81
|
+
def to_polymorphic_resource?
|
|
82
|
+
@sideload.resource.polymorphic? && @sideload.type != :polymorphic_belongs_to
|
|
83
|
+
end
|
|
71
84
|
end
|
|
72
85
|
end
|
|
73
86
|
end
|
|
@@ -15,7 +15,7 @@ module GraphitiGql
|
|
|
15
15
|
|
|
16
16
|
def initialize(sideload, params)
|
|
17
17
|
@sideload = sideload
|
|
18
|
-
@params = params
|
|
18
|
+
@params = params.merge(typecast_filters: false)
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
def perform(parent_records)
|
|
@@ -34,6 +34,7 @@ module GraphitiGql
|
|
|
34
34
|
pk
|
|
35
35
|
end
|
|
36
36
|
end
|
|
37
|
+
ids.compact!
|
|
37
38
|
|
|
38
39
|
build_params(ids, parent_records)
|
|
39
40
|
resource = Schema.registry.get(@sideload.resource.class)[:resource]
|
|
@@ -53,13 +54,16 @@ module GraphitiGql
|
|
|
53
54
|
if @sideload.polymorphic_as
|
|
54
55
|
type = ids[0][:"#{@sideload.polymorphic_as}_type"]
|
|
55
56
|
foreign_keys = ids.map { |id| id[@sideload.foreign_key] }
|
|
57
|
+
foreign_keys.map! { |id| @sideload.parent_resource.class.gid(id) }
|
|
56
58
|
@params[:filter][:"#{@sideload.polymorphic_as}_type"] = type
|
|
57
|
-
@params[:filter][@sideload.foreign_key] = foreign_keys
|
|
59
|
+
@params[:filter][@sideload.foreign_key] = foreign_keys
|
|
58
60
|
elsif @sideload.type == :many_to_many
|
|
61
|
+
filter_ids = ids.map { |id| @sideload.parent_resource.class.gid(id) }
|
|
59
62
|
fk = @sideload.foreign_key.values.first
|
|
60
|
-
@params[:filter].merge!(fk => { eq:
|
|
63
|
+
@params[:filter].merge!(fk => { eq: filter_ids })
|
|
61
64
|
elsif !@sideload.parent_resource.class.singular
|
|
62
|
-
|
|
65
|
+
filter_ids = ids.map { |id| @sideload.parent_resource.class.gid(id) }
|
|
66
|
+
@params[:filter].merge!(@sideload.foreign_key => { eq: filter_ids })
|
|
63
67
|
end
|
|
64
68
|
|
|
65
69
|
if @params[:stats]
|
|
@@ -76,8 +76,14 @@ end|, :white, true)
|
|
|
76
76
|
if response_errors
|
|
77
77
|
Graphiti.info("❌🚨 Response contained errors!", :red, true)
|
|
78
78
|
response_errors.each do |err|
|
|
79
|
-
|
|
80
|
-
|
|
79
|
+
if err['extensions']
|
|
80
|
+
Graphiti.info("#{err['extensions']['code']} - #{err['message']}", :red, true)
|
|
81
|
+
else
|
|
82
|
+
Graphiti.info(err['message'], :red, true)
|
|
83
|
+
end
|
|
84
|
+
if err['path']
|
|
85
|
+
Graphiti.info("#{err['path'].join(".")}", :red, false) if err['path']
|
|
86
|
+
end
|
|
81
87
|
end
|
|
82
88
|
end
|
|
83
89
|
else
|
|
@@ -37,7 +37,16 @@ module GraphitiGql
|
|
|
37
37
|
end
|
|
38
38
|
end
|
|
39
39
|
return if value.nil?
|
|
40
|
-
|
|
40
|
+
|
|
41
|
+
caster = Graphiti::Types[_config[:type]][:read]
|
|
42
|
+
# Dry::Types can't be instance_exec'd
|
|
43
|
+
# This dependency has probably served it's purpose and can be
|
|
44
|
+
# refactored away
|
|
45
|
+
if caster.is_a?(Proc)
|
|
46
|
+
instance_exec(value, &caster)
|
|
47
|
+
else
|
|
48
|
+
caster.call(value)
|
|
49
|
+
end
|
|
41
50
|
end
|
|
42
51
|
end
|
|
43
52
|
|
|
@@ -51,7 +60,6 @@ module GraphitiGql
|
|
|
51
60
|
if !field_type
|
|
52
61
|
canonical_graphiti_type = Graphiti::Types.name_for(@config[:type])
|
|
53
62
|
field_type = GQL_TYPE_MAP[canonical_graphiti_type.to_sym]
|
|
54
|
-
field_type = String if @name == :id
|
|
55
63
|
end
|
|
56
64
|
field_type = [field_type] if @config[:type].to_s.starts_with?("array_of")
|
|
57
65
|
field_type
|
|
@@ -12,7 +12,7 @@ module GraphitiGql
|
|
|
12
12
|
null: true,
|
|
13
13
|
extras: [:lookahead]
|
|
14
14
|
unless @registered[:resource].singular
|
|
15
|
-
field.argument(:id,
|
|
15
|
+
field.argument(:id, GraphQL::Types::ID, required: true)
|
|
16
16
|
end
|
|
17
17
|
_registered = @registered
|
|
18
18
|
query.define_method name do |**arguments|
|
|
@@ -38,7 +38,7 @@ module GraphitiGql
|
|
|
38
38
|
end
|
|
39
39
|
|
|
40
40
|
def add_value_objects
|
|
41
|
-
registry.resource_types.each do |registered|
|
|
41
|
+
registry.resource_types(value_objects: false).each do |registered|
|
|
42
42
|
resource, type = registered[:resource], registered[:type]
|
|
43
43
|
ResourceType.add_value_objects(resource, type)
|
|
44
44
|
end
|
|
@@ -50,18 +50,18 @@ module GraphitiGql
|
|
|
50
50
|
end
|
|
51
51
|
|
|
52
52
|
# When polymorphic parent, returns the Interface not the Class
|
|
53
|
-
def resource_types
|
|
53
|
+
def resource_types(value_objects: true)
|
|
54
54
|
values
|
|
55
55
|
.select { |v| v.key?(:resource) }
|
|
56
|
-
.reject { |v| v[:interface]
|
|
56
|
+
.reject { |v| v[:interface] }
|
|
57
|
+
.reject { |v| !value_objects && v[:resource].value_object? }
|
|
57
58
|
.map { |registered| get(registered[:resource]) }
|
|
58
59
|
end
|
|
59
60
|
|
|
60
61
|
private
|
|
61
62
|
|
|
62
63
|
def key_for_resource(resource)
|
|
63
|
-
resource.graphql_name
|
|
64
|
-
resource.name.gsub('Resource', '').gsub('::', '')
|
|
64
|
+
resource.graphql_name
|
|
65
65
|
end
|
|
66
66
|
end
|
|
67
67
|
end
|
|
@@ -6,8 +6,9 @@ module GraphitiGql
|
|
|
6
6
|
|
|
7
7
|
definition_methods do
|
|
8
8
|
# Optional: if this method is defined, it overrides `Schema.resolve_type`
|
|
9
|
-
def resolve_type(object,
|
|
9
|
+
def resolve_type(object, _context)
|
|
10
10
|
return object.type if object.is_a?(Loaders::FakeRecord)
|
|
11
|
+
|
|
11
12
|
resource = object.instance_variable_get(:@__graphiti_resource)
|
|
12
13
|
Registry.instance.get(resource.class)[:type]
|
|
13
14
|
end
|
|
@@ -17,9 +18,8 @@ module GraphitiGql
|
|
|
17
18
|
def self.add_fields(type, resource, id: true) # id: false for edges
|
|
18
19
|
resource.attributes.each_pair do |name, config|
|
|
19
20
|
next if name == :id && id == false
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
end
|
|
21
|
+
|
|
22
|
+
Fields::Attribute.new(resource, name, config).apply(type) if config[:readable]
|
|
23
23
|
end
|
|
24
24
|
end
|
|
25
25
|
|
|
@@ -27,31 +27,31 @@ module GraphitiGql
|
|
|
27
27
|
resource.config[:value_objects].each_pair do |name, vo_association|
|
|
28
28
|
vo_resource_class = vo_association.resource_class
|
|
29
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
|
|
30
|
+
value_object_type = [value_object_type] if vo_association.array?
|
|
33
31
|
|
|
34
32
|
_array = vo_association.array?
|
|
35
33
|
opts = { null: vo_association.null }
|
|
36
34
|
opts[:deprecation_reason] = vo_association.deprecation_reason if vo_association.deprecation_reason
|
|
37
35
|
type.field name, value_object_type, **opts
|
|
38
36
|
type.define_method name do
|
|
39
|
-
if (method_name = vo_association.readable)
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
.new(vo_association.parent_resource_class, name)
|
|
43
|
-
end
|
|
37
|
+
if (method_name = vo_association.readable) && !vo_association.parent_resource_class.new.send(method_name)
|
|
38
|
+
raise ::Graphiti::Errors::UnreadableAttribute
|
|
39
|
+
.new(vo_association.parent_resource_class, name)
|
|
44
40
|
end
|
|
45
41
|
|
|
46
42
|
result = vo_resource_class.all({ parent: object }).to_a
|
|
47
43
|
default_behavior = result == [object]
|
|
48
|
-
result = result.first
|
|
44
|
+
result = result.first unless _array
|
|
49
45
|
if default_behavior
|
|
50
46
|
method_name = vo_association.alias.presence || name
|
|
51
47
|
result = object.send(method_name)
|
|
52
|
-
if _array && !result.is_a?(Array)
|
|
53
|
-
|
|
54
|
-
|
|
48
|
+
raise Graphiti::Errors::InvalidValueObject.new(resource, name, result) if _array && !result.is_a?(Array)
|
|
49
|
+
end
|
|
50
|
+
# For polymorphic value objects
|
|
51
|
+
if result.is_a?(Array)
|
|
52
|
+
result.each { |r| r.instance_variable_set(:@__parent, object) }
|
|
53
|
+
else
|
|
54
|
+
result.instance_variable_set(:@__parent, object) if result
|
|
55
55
|
end
|
|
56
56
|
result
|
|
57
57
|
end
|
|
@@ -59,19 +59,19 @@ module GraphitiGql
|
|
|
59
59
|
end
|
|
60
60
|
|
|
61
61
|
def self.add_relationships(resource, type)
|
|
62
|
-
resource.sideloads.each do |
|
|
62
|
+
resource.sideloads.each do |_name, sideload|
|
|
63
63
|
next unless sideload.readable?
|
|
64
64
|
|
|
65
65
|
registered_sl = if sideload.type == :polymorphic_belongs_to
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
66
|
+
PolymorphicBelongsToInterface
|
|
67
|
+
.new(resource, sideload)
|
|
68
|
+
.build
|
|
69
|
+
else
|
|
70
|
+
Schema.registry.get(sideload.resource.class)
|
|
71
|
+
end
|
|
72
72
|
sideload_type = registered_sl[:type]
|
|
73
73
|
|
|
74
|
-
if [
|
|
74
|
+
if %i[has_many many_to_many has_one].include?(sideload.type)
|
|
75
75
|
Fields::ToMany.new(sideload, sideload_type).apply(type)
|
|
76
76
|
else
|
|
77
77
|
Fields::ToOne.new(sideload, sideload_type).apply(type)
|
|
@@ -86,6 +86,7 @@ module GraphitiGql
|
|
|
86
86
|
|
|
87
87
|
def build
|
|
88
88
|
return registry.get(@resource)[:type] if registry.get(@resource)
|
|
89
|
+
|
|
89
90
|
type = build_base_type
|
|
90
91
|
registry_name = registry.key_for(@resource, interface: poly_parent?)
|
|
91
92
|
type.connection_type_class(build_connection_class)
|
|
@@ -108,6 +109,7 @@ module GraphitiGql
|
|
|
108
109
|
# Define the actual class that implements the interface
|
|
109
110
|
registry.set(@resource, type, interface: false)
|
|
110
111
|
@resource.children.each do |child|
|
|
112
|
+
registry.get(child)
|
|
111
113
|
if (registered = registry.get(child))
|
|
112
114
|
registered[:type].implements(interface_type)
|
|
113
115
|
else
|
|
@@ -128,12 +130,14 @@ module GraphitiGql
|
|
|
128
130
|
klass.send(:include, BaseInterface)
|
|
129
131
|
ctx = nil
|
|
130
132
|
klass.definition_methods { ctx = self }
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
registry_name = Registry.instance.key_for(
|
|
134
|
-
if
|
|
135
|
-
|
|
136
|
-
|
|
133
|
+
_resource = @resource
|
|
134
|
+
ctx.define_method :resolve_type do |object, _context|
|
|
135
|
+
registry_name = Registry.instance.key_for(_resource)
|
|
136
|
+
if _resource.polymorphic?
|
|
137
|
+
parent = object.instance_variable_get(:@__parent)
|
|
138
|
+
# pass parent for polymorphic value objects
|
|
139
|
+
_resource = _resource.resource_for_model(parent || object)
|
|
140
|
+
registry_name = Registry.instance.key_for(_resource)
|
|
137
141
|
end
|
|
138
142
|
Registry.instance[registry_name][:type]
|
|
139
143
|
end
|
|
@@ -141,6 +145,24 @@ module GraphitiGql
|
|
|
141
145
|
klass = Class.new(Schema.base_object)
|
|
142
146
|
end
|
|
143
147
|
|
|
148
|
+
if @resource.value_object?
|
|
149
|
+
klass.define_method :parent do
|
|
150
|
+
object.instance_variable_get(:@__parent)
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
klass.define_method :resource do
|
|
155
|
+
return @resource if @resource
|
|
156
|
+
|
|
157
|
+
resource = object.instance_variable_get(:@__graphiti_resource)
|
|
158
|
+
resource_class = resource.class
|
|
159
|
+
if resource_class.polymorphic? && !resource_class.polymorphic_child?
|
|
160
|
+
resource_class = resource_class.resource_for_model(object)
|
|
161
|
+
end
|
|
162
|
+
@resource = resource_class
|
|
163
|
+
resource_class
|
|
164
|
+
end
|
|
165
|
+
|
|
144
166
|
klass
|
|
145
167
|
end
|
|
146
168
|
|
|
@@ -154,7 +176,7 @@ module GraphitiGql
|
|
|
154
176
|
|
|
155
177
|
def add_fields(type, resource)
|
|
156
178
|
self.class.add_fields(type, resource)
|
|
157
|
-
end
|
|
179
|
+
end
|
|
158
180
|
|
|
159
181
|
def build_connection_class
|
|
160
182
|
klass = Class.new(GraphQL::Types::Relay::BaseConnection)
|
|
@@ -163,4 +185,4 @@ module GraphitiGql
|
|
|
163
185
|
end
|
|
164
186
|
end
|
|
165
187
|
end
|
|
166
|
-
end
|
|
188
|
+
end
|
data/lib/graphiti_gql/schema.rb
CHANGED
|
@@ -33,6 +33,7 @@ module GraphitiGql
|
|
|
33
33
|
integer_id: String,
|
|
34
34
|
string: String,
|
|
35
35
|
uuid: String,
|
|
36
|
+
gid: GraphQL::Types::ID,
|
|
36
37
|
integer: Integer,
|
|
37
38
|
big_integer: GraphQL::Types::BigInt,
|
|
38
39
|
float: Float,
|
|
@@ -68,7 +69,9 @@ module GraphitiGql
|
|
|
68
69
|
end
|
|
69
70
|
|
|
70
71
|
def self.base_object
|
|
72
|
+
return @base_object if @base_object
|
|
71
73
|
klass = Class.new(GraphQL::Schema::Object)
|
|
74
|
+
|
|
72
75
|
# TODO make this config maybe
|
|
73
76
|
if defined?(ActionView)
|
|
74
77
|
klass.send(:include, ActionView::Helpers::TranslationHelper)
|
|
@@ -79,6 +82,7 @@ module GraphitiGql
|
|
|
79
82
|
end
|
|
80
83
|
end
|
|
81
84
|
end
|
|
85
|
+
@base_object = klass
|
|
82
86
|
klass
|
|
83
87
|
end
|
|
84
88
|
|
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.32
|
|
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-
|
|
11
|
+
date: 2022-09-02 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: graphql
|
|
@@ -126,7 +126,6 @@ files:
|
|
|
126
126
|
- ".rspec"
|
|
127
127
|
- ".travis.yml"
|
|
128
128
|
- Gemfile
|
|
129
|
-
- Gemfile.lock
|
|
130
129
|
- LICENSE.txt
|
|
131
130
|
- README.md
|
|
132
131
|
- Rakefile
|
data/Gemfile.lock
DELETED
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
PATH
|
|
2
|
-
remote: .
|
|
3
|
-
specs:
|
|
4
|
-
graphiti_gql (0.2.29)
|
|
5
|
-
activemodel (> 6.0, < 8.0)
|
|
6
|
-
graphiti (~> 1.3.9)
|
|
7
|
-
graphql (~> 2.0)
|
|
8
|
-
graphql-batch (~> 0.5)
|
|
9
|
-
|
|
10
|
-
GEM
|
|
11
|
-
remote: https://rubygems.org/
|
|
12
|
-
specs:
|
|
13
|
-
activemodel (7.0.3)
|
|
14
|
-
activesupport (= 7.0.3)
|
|
15
|
-
activesupport (7.0.3)
|
|
16
|
-
concurrent-ruby (~> 1.0, >= 1.0.2)
|
|
17
|
-
i18n (>= 1.6, < 2)
|
|
18
|
-
minitest (>= 5.1)
|
|
19
|
-
tzinfo (~> 2.0)
|
|
20
|
-
byebug (11.1.3)
|
|
21
|
-
coderay (1.1.3)
|
|
22
|
-
concurrent-ruby (1.1.10)
|
|
23
|
-
diff-lcs (1.5.0)
|
|
24
|
-
dry-container (0.10.1)
|
|
25
|
-
concurrent-ruby (~> 1.0)
|
|
26
|
-
dry-core (0.8.1)
|
|
27
|
-
concurrent-ruby (~> 1.0)
|
|
28
|
-
dry-inflector (0.3.0)
|
|
29
|
-
dry-logic (1.2.0)
|
|
30
|
-
concurrent-ruby (~> 1.0)
|
|
31
|
-
dry-core (~> 0.5, >= 0.5)
|
|
32
|
-
dry-types (1.5.1)
|
|
33
|
-
concurrent-ruby (~> 1.0)
|
|
34
|
-
dry-container (~> 0.3)
|
|
35
|
-
dry-core (~> 0.5, >= 0.5)
|
|
36
|
-
dry-inflector (~> 0.1, >= 0.1.2)
|
|
37
|
-
dry-logic (~> 1.0, >= 1.0.2)
|
|
38
|
-
graphiti (1.3.9)
|
|
39
|
-
activesupport (>= 5.2)
|
|
40
|
-
concurrent-ruby (~> 1.0)
|
|
41
|
-
dry-types (>= 0.15.0, < 2.0)
|
|
42
|
-
graphiti_errors (~> 1.1.0)
|
|
43
|
-
jsonapi-renderer (~> 0.2, >= 0.2.2)
|
|
44
|
-
jsonapi-serializable (~> 0.3.0)
|
|
45
|
-
graphiti_errors (1.1.2)
|
|
46
|
-
jsonapi-serializable (~> 0.1)
|
|
47
|
-
graphql (2.0.12)
|
|
48
|
-
graphql-batch (0.5.1)
|
|
49
|
-
graphql (>= 1.10, < 3)
|
|
50
|
-
promise.rb (~> 0.7.2)
|
|
51
|
-
i18n (1.12.0)
|
|
52
|
-
concurrent-ruby (~> 1.0)
|
|
53
|
-
jsonapi-renderer (0.2.2)
|
|
54
|
-
jsonapi-serializable (0.3.1)
|
|
55
|
-
jsonapi-renderer (~> 0.2.0)
|
|
56
|
-
method_source (1.0.0)
|
|
57
|
-
minitest (5.16.2)
|
|
58
|
-
promise.rb (0.7.4)
|
|
59
|
-
pry (0.13.1)
|
|
60
|
-
coderay (~> 1.1)
|
|
61
|
-
method_source (~> 1.0)
|
|
62
|
-
pry-byebug (3.9.0)
|
|
63
|
-
byebug (~> 11.0)
|
|
64
|
-
pry (~> 0.13.0)
|
|
65
|
-
rake (10.5.0)
|
|
66
|
-
rspec (3.11.0)
|
|
67
|
-
rspec-core (~> 3.11.0)
|
|
68
|
-
rspec-expectations (~> 3.11.0)
|
|
69
|
-
rspec-mocks (~> 3.11.0)
|
|
70
|
-
rspec-core (3.11.0)
|
|
71
|
-
rspec-support (~> 3.11.0)
|
|
72
|
-
rspec-expectations (3.11.0)
|
|
73
|
-
diff-lcs (>= 1.2.0, < 2.0)
|
|
74
|
-
rspec-support (~> 3.11.0)
|
|
75
|
-
rspec-mocks (3.11.1)
|
|
76
|
-
diff-lcs (>= 1.2.0, < 2.0)
|
|
77
|
-
rspec-support (~> 3.11.0)
|
|
78
|
-
rspec-support (3.11.0)
|
|
79
|
-
tzinfo (2.0.5)
|
|
80
|
-
concurrent-ruby (~> 1.0)
|
|
81
|
-
|
|
82
|
-
PLATFORMS
|
|
83
|
-
arm64-darwin-21
|
|
84
|
-
|
|
85
|
-
DEPENDENCIES
|
|
86
|
-
bundler (~> 2.3)
|
|
87
|
-
graphiti_gql!
|
|
88
|
-
pry
|
|
89
|
-
pry-byebug
|
|
90
|
-
rake (~> 10.0)
|
|
91
|
-
rspec (~> 3.0)
|
|
92
|
-
|
|
93
|
-
BUNDLED WITH
|
|
94
|
-
2.3.12
|