graphiti_gql 0.2.5 → 0.2.6
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/graphiti_gql/active_resource.rb +60 -12
- data/lib/graphiti_gql/graphiti_hax.rb +28 -9
- data/lib/graphiti_gql/loaders/belongs_to.rb +1 -0
- data/lib/graphiti_gql/loaders/many_to_many.rb +4 -1
- data/lib/graphiti_gql/schema/fields/attribute.rb +1 -1
- data/lib/graphiti_gql/schema/fields/to_many.rb +28 -11
- data/lib/graphiti_gql/schema/resource_type.rb +8 -3
- data/lib/graphiti_gql/spec_helper.rb +15 -17
- 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: a0558a0d0edaf2e03b09fe28ce603afb10eb0cbd02e8aa56be43cfd1044bebab
|
4
|
+
data.tar.gz: 69660d61a4191bd6428a2ad33d2f9e3e6a4227c31d4be636a6b886af543f35f3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 892b44992e36645282bd7003218067d248e04ac6f440feaac137afa1449f9b01017d7bcb577bbaf3bd8dc7f1c808b7f9b6eaf6e0c4474b4f1d6910dabb49ad3e
|
7
|
+
data.tar.gz: 3d29b975b6748e292e4420707c2f8e4825a8e743c197f70126863c230a22ad75f0efece663a2400704716d2c7621d8cdd90732185ee7540c317c23708004a4d0
|
@@ -1,17 +1,24 @@
|
|
1
|
+
# TODO: Rushing here so tests are in app and code is gross
|
1
2
|
module GraphitiGql
|
2
3
|
module ActiveResource
|
3
4
|
extend ActiveSupport::Concern
|
4
5
|
|
5
6
|
class Node < OpenStruct
|
6
|
-
def initialize(
|
7
|
+
def initialize(hash, resource = nil)
|
7
8
|
@resource = resource
|
9
|
+
@edges = {}
|
10
|
+
@node_id = hash.delete(:node_id)
|
8
11
|
hash.each_pair do |key, value|
|
9
12
|
if value.is_a?(Hash)
|
10
13
|
if (sideload = resource.sideload(key))
|
11
14
|
if value.key?(:edges)
|
12
|
-
|
15
|
+
@edges[key] = value[:edges].map do |edge|
|
16
|
+
node_id = edge[:node][:id]
|
17
|
+
Node.new(edge.except(:node).merge(node_id: node_id))
|
18
|
+
end
|
19
|
+
hash[key] = value[:edges].map { |v| Node.new(v[:node], sideload.resource.class) }
|
13
20
|
else
|
14
|
-
hash[key] = Node.new(sideload.resource.class
|
21
|
+
hash[key] = Node.new(value, sideload.resource.class)
|
15
22
|
end
|
16
23
|
end
|
17
24
|
end
|
@@ -19,6 +26,15 @@ module GraphitiGql
|
|
19
26
|
super(hash)
|
20
27
|
end
|
21
28
|
|
29
|
+
def edge(name, node_id)
|
30
|
+
found = @edges[name].empty? ? nil : @edges[name]
|
31
|
+
if found && node_id
|
32
|
+
found.find { |f| f.instance_variable_get(:@node_id) == node_id.to_s }
|
33
|
+
else
|
34
|
+
found
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
22
38
|
def decoded_id
|
23
39
|
Base64.decode64(self.id)
|
24
40
|
end
|
@@ -29,7 +45,8 @@ module GraphitiGql
|
|
29
45
|
end
|
30
46
|
|
31
47
|
class Proxy
|
32
|
-
def initialize(resource, params, ctx)
|
48
|
+
def initialize(resource, params, ctx, query)
|
49
|
+
@query = query
|
33
50
|
@resource = resource
|
34
51
|
@ctx = ctx
|
35
52
|
@params = params.deep_transform_keys { |key| key.to_s.camelize(:lower).to_sym }
|
@@ -46,10 +63,18 @@ module GraphitiGql
|
|
46
63
|
result
|
47
64
|
end
|
48
65
|
|
66
|
+
def node(id)
|
67
|
+
nodes.find { |n| n.id == id.to_s }
|
68
|
+
end
|
69
|
+
|
49
70
|
def nodes
|
50
71
|
return [] unless data
|
51
|
-
|
52
|
-
|
72
|
+
elements = if edges
|
73
|
+
edges.map { |e| e[:node] }
|
74
|
+
else
|
75
|
+
data[data.keys.first][:nodes] || []
|
76
|
+
end
|
77
|
+
elements.map { |n| Node.new(underscore(n), @resource) }
|
53
78
|
end
|
54
79
|
alias :to_a :nodes
|
55
80
|
|
@@ -85,7 +110,10 @@ module GraphitiGql
|
|
85
110
|
underscore(data[data.keys.first][:pageInfo])
|
86
111
|
end
|
87
112
|
|
113
|
+
# barf
|
88
114
|
def query
|
115
|
+
return @query if @query
|
116
|
+
|
89
117
|
name = Schema.registry.key_for(@resource)
|
90
118
|
filter_bang = "!" if @resource.filters.values.any? { |f| f[:required] }
|
91
119
|
sortvar = "$sort: [#{name}Sort!]," if @resource.sorts.any?
|
@@ -118,6 +146,7 @@ module GraphitiGql
|
|
118
146
|
node {|
|
119
147
|
|
120
148
|
fields.each do |name|
|
149
|
+
next if name.is_a?(Hash)
|
121
150
|
q << %|
|
122
151
|
#{name.to_s.camelize(:lower)}|
|
123
152
|
end
|
@@ -129,17 +158,36 @@ module GraphitiGql
|
|
129
158
|
sideload = @resource.sideload(inc.to_sym)
|
130
159
|
to_one = [:belongs_to, :has_one, :polymorphic_belongs_to].include?(sideload.type)
|
131
160
|
indent = " " if !to_one
|
161
|
+
|
162
|
+
edge_fields = []
|
163
|
+
runtime_sideload_fields = @params[:fields].find { |f| f.is_a?(Hash) && f.key?(inc.to_sym) }
|
164
|
+
if runtime_sideload_fields
|
165
|
+
runtime_sideload_fields = runtime_sideload_fields.values
|
166
|
+
edge_fields = runtime_sideload_fields.find { |f| f.is_a?(Hash) && f.key?(:edge) }
|
167
|
+
runtime_sideload_fields = runtime_sideload_fields.reject { |f| f.is_a?(Hash) }
|
168
|
+
edge_fields = edge_fields[:edge] if edge_fields
|
169
|
+
end
|
170
|
+
|
132
171
|
q << %|
|
133
172
|
#{inc.to_s.camelize(:lower)} {|
|
134
173
|
if !to_one
|
135
174
|
q << %|
|
136
|
-
edges {
|
175
|
+
edges {|
|
176
|
+
|
177
|
+
edge_fields.each do |ef|
|
178
|
+
q << %|
|
179
|
+
#{ef.to_s.camelize(:lower)}|
|
180
|
+
end
|
181
|
+
|
182
|
+
q << %|
|
137
183
|
node {|
|
138
184
|
end
|
139
185
|
|
140
|
-
|
141
|
-
|
142
|
-
|
186
|
+
sideload_fields = runtime_sideload_fields
|
187
|
+
if sideload_fields.blank?
|
188
|
+
sideload_fields = @resource.sideload(inc.to_sym).resource.attributes.select { |_, config| config[:readable] }.map(&:first)
|
189
|
+
end
|
190
|
+
sideload_fields.each do |name|
|
143
191
|
q << %|
|
144
192
|
#{indent}#{name.to_s.camelize(:lower)}|
|
145
193
|
end
|
@@ -200,8 +248,8 @@ module GraphitiGql
|
|
200
248
|
end
|
201
249
|
|
202
250
|
class_methods do
|
203
|
-
def gql(params = {}, ctx = {})
|
204
|
-
Proxy.new(self, params, ctx)
|
251
|
+
def gql(params = {}, ctx = {}, query = nil)
|
252
|
+
Proxy.new(self, params, ctx, query)
|
205
253
|
end
|
206
254
|
end
|
207
255
|
end
|
@@ -143,22 +143,41 @@ module GraphitiGql
|
|
143
143
|
Graphiti::Scoping::Paginate.send(:prepend, PaginateExtras)
|
144
144
|
|
145
145
|
module ManyToManyExtras
|
146
|
-
|
146
|
+
def self.prepended(klass)
|
147
|
+
klass.class_eval do
|
148
|
+
class << self
|
149
|
+
attr_accessor :edge_resource
|
147
150
|
|
148
|
-
|
149
|
-
|
151
|
+
def attribute(*args, &blk)
|
152
|
+
@edge_resource ||= Class.new(Graphiti::Resource) do
|
153
|
+
def self.abstract_class?
|
154
|
+
true
|
155
|
+
end
|
156
|
+
end
|
157
|
+
@edge_resource.attribute(*args, &blk)
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
def apply_belongs_to_many_filter
|
164
|
+
super
|
165
|
+
self_ref = self
|
166
|
+
fk_type = parent_resource_class.attributes[:id][:type]
|
167
|
+
fk_type = :hash if polymorphic?
|
168
|
+
filters = resource_class.config[:filters]
|
150
169
|
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
170
|
+
# Keep the options, apply the eq proc
|
171
|
+
if (filter = filters[inverse_filter.to_sym])
|
172
|
+
if filter[:operators][:eq].nil?
|
173
|
+
filter[:operators][:eq] = proc do |scope, value|
|
174
|
+
self_ref.belongs_to_many_filter(scope, value)
|
155
175
|
end
|
156
176
|
end
|
157
|
-
@edge_resource.attribute(*args, &blk)
|
158
177
|
end
|
159
178
|
end
|
160
179
|
end
|
161
|
-
Graphiti::Sideload::ManyToMany.send(:
|
180
|
+
Graphiti::Sideload::ManyToMany.send(:prepend, ManyToManyExtras)
|
162
181
|
|
163
182
|
module StatsExtras
|
164
183
|
def calculate_stat(name, function)
|
@@ -19,8 +19,11 @@ module GraphitiGql
|
|
19
19
|
def add_join_table_magic(proxy)
|
20
20
|
if defined?(ActiveRecord) && proxy.resource.model.ancestors.include?(ActiveRecord::Base)
|
21
21
|
thru = @sideload.foreign_key.keys.first
|
22
|
-
|
22
|
+
reflection = @sideload.parent_resource.model.reflect_on_association(thru)
|
23
|
+
thru_model = reflection.klass
|
24
|
+
|
23
25
|
names = thru_model.column_names.map do |n|
|
26
|
+
next if n == :id
|
24
27
|
"#{thru_model.table_name}.#{n} as _edge_#{n}"
|
25
28
|
end
|
26
29
|
scope = proxy.scope.object
|
@@ -42,24 +42,41 @@ module GraphitiGql
|
|
42
42
|
end
|
43
43
|
|
44
44
|
def build_customized_edge_type(sideload_type)
|
45
|
-
|
46
|
-
|
47
|
-
|
45
|
+
edge_type_class = build_edge_type_class(sideload_type)
|
46
|
+
|
47
|
+
# Build the sideload type with new edge class applied
|
48
|
+
if sideload_type.is_a?(Module)
|
49
|
+
klass = sideload_type
|
50
|
+
# There's some magic that happens when subclassing, but modules
|
51
|
+
# don't subclass. This is the kind of resetting we need to happen.
|
52
|
+
# Might be a graphql-ruby issue.
|
53
|
+
klass.instance_variable_set(:@connection_type, nil)
|
54
|
+
klass.instance_variable_set(:@edge_type, nil)
|
55
|
+
klass.edge_type_class(edge_type_class)
|
56
|
+
klass
|
57
|
+
else
|
58
|
+
klass = Class.new(sideload_type)
|
59
|
+
klass.edge_type_class(edge_class)
|
60
|
+
klass
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def build_edge_type_class(sideload_type)
|
65
|
+
prior_edge_type_class = sideload_type.edge_type_class
|
66
|
+
edge_type_class = Class.new(prior_edge_type_class)
|
48
67
|
edge_resource = @sideload.class.edge_resource
|
49
68
|
edge_resource.attributes.each_pair do |name, config|
|
50
69
|
next if name == :id
|
51
|
-
Schema::Fields::Attribute.new(name, config, @sideload).apply(
|
70
|
+
Schema::Fields::Attribute.new(name, config, @sideload).apply(edge_type_class)
|
52
71
|
end
|
53
72
|
registered_parent = Schema.registry.get(@sideload.parent_resource.class)
|
54
73
|
parent_name = registered_parent[:type].graphql_name
|
55
|
-
|
56
|
-
|
74
|
+
edge_type_class_name = "#{parent_name}To#{sideload_type.graphql_name}Edge"
|
75
|
+
edge_type_class.define_method :graphql_name do
|
76
|
+
edge_type_class_name
|
57
77
|
end
|
58
|
-
|
59
|
-
|
60
|
-
klass = Class.new(sideload_type)
|
61
|
-
klass.edge_type_class(edge_class)
|
62
|
-
klass
|
78
|
+
edge_type_class.graphql_name(edge_type_class_name)
|
79
|
+
edge_type_class
|
63
80
|
end
|
64
81
|
end
|
65
82
|
end
|
@@ -34,14 +34,19 @@ module GraphitiGql
|
|
34
34
|
|
35
35
|
private
|
36
36
|
|
37
|
-
def process_polymorphic_parent(
|
37
|
+
def process_polymorphic_parent(interface_type)
|
38
|
+
registry_name = registry.key_for(@resource, interface: false)
|
39
|
+
type = Class.new(Schema.base_object)
|
40
|
+
type.graphql_name(registry_name)
|
41
|
+
type.implements(interface_type)
|
42
|
+
|
38
43
|
# Define the actual class that implements the interface
|
39
44
|
registry.set(@resource, type, interface: false)
|
40
45
|
@resource.children.each do |child|
|
41
46
|
if (registered = registry.get(child))
|
42
|
-
registered[:type].implements(
|
47
|
+
registered[:type].implements(interface_type)
|
43
48
|
else
|
44
|
-
self.class.new(child, implements:
|
49
|
+
self.class.new(child, implements: interface_type).build
|
45
50
|
end
|
46
51
|
end
|
47
52
|
end
|
@@ -24,6 +24,7 @@ module GraphitiGql
|
|
24
24
|
:errors,
|
25
25
|
:error_messages,
|
26
26
|
:nodes,
|
27
|
+
:node,
|
27
28
|
:stats
|
28
29
|
|
29
30
|
Graphiti::Resource.send(:prepend, ScopeTrackable)
|
@@ -42,20 +43,20 @@ module GraphitiGql
|
|
42
43
|
def self.except_fields(*fields)
|
43
44
|
let(:except_fields) { fields }
|
44
45
|
end
|
45
|
-
end
|
46
|
-
end
|
47
46
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
47
|
+
let(:fields) do
|
48
|
+
fields = []
|
49
|
+
resource.attributes.each_pair do |name, config|
|
50
|
+
(fields << name) if config[:readable]
|
51
|
+
end
|
52
|
+
if respond_to?(:only_fields) && only_fields.present?
|
53
|
+
fields.select! { |f| only_fields.include?(f) }
|
54
|
+
elsif respond_to?(:except_fields) && except_fields.present?
|
55
|
+
fields.reject! { |f| except_fields.include?(f) }
|
56
|
+
end
|
57
|
+
fields
|
58
|
+
end
|
57
59
|
end
|
58
|
-
fields
|
59
60
|
end
|
60
61
|
|
61
62
|
def gql_datetime(timestamp, precise = false)
|
@@ -67,11 +68,8 @@ module GraphitiGql
|
|
67
68
|
end
|
68
69
|
|
69
70
|
def proxy
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
def query
|
74
|
-
proxy.query
|
71
|
+
q = defined?(query) ? query : nil
|
72
|
+
resource.gql(params.merge(fields: fields), ctx, q)
|
75
73
|
end
|
76
74
|
|
77
75
|
def run
|
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.6
|
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-07-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: graphql
|