graphiti 1.0.alpha.1 → 1.0.alpha.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +0 -8
- data/README.md +2 -72
- data/bin/console +1 -1
- data/exe/graphiti +5 -0
- data/graphiti.gemspec +2 -2
- data/lib/generators/jsonapi/resource_generator.rb +1 -1
- data/lib/generators/jsonapi/templates/application_resource.rb.erb +0 -2
- data/lib/graphiti.rb +17 -1
- data/lib/graphiti/adapters/abstract.rb +32 -0
- data/lib/graphiti/adapters/active_record/base.rb +8 -0
- data/lib/graphiti/adapters/active_record/many_to_many_sideload.rb +2 -9
- data/lib/graphiti/cli.rb +45 -0
- data/lib/graphiti/configuration.rb +12 -0
- data/lib/graphiti/context.rb +1 -0
- data/lib/graphiti/errors.rb +105 -3
- data/lib/graphiti/filter_operators.rb +13 -3
- data/lib/graphiti/query.rb +8 -0
- data/lib/graphiti/rails.rb +1 -1
- data/lib/graphiti/railtie.rb +21 -2
- data/lib/graphiti/renderer.rb +2 -1
- data/lib/graphiti/resource.rb +11 -2
- data/lib/graphiti/resource/configuration.rb +1 -0
- data/lib/graphiti/resource/dsl.rb +4 -3
- data/lib/graphiti/resource/interface.rb +15 -0
- data/lib/graphiti/resource/links.rb +92 -0
- data/lib/graphiti/resource/polymorphism.rb +1 -0
- data/lib/graphiti/resource/sideloading.rb +13 -5
- data/lib/graphiti/resource_proxy.rb +1 -1
- data/lib/graphiti/schema.rb +169 -0
- data/lib/graphiti/schema_diff.rb +174 -0
- data/lib/graphiti/scoping/filter.rb +1 -1
- data/lib/graphiti/sideload.rb +47 -18
- data/lib/graphiti/sideload/belongs_to.rb +5 -1
- data/lib/graphiti/sideload/has_many.rb +5 -1
- data/lib/graphiti/sideload/many_to_many.rb +6 -2
- data/lib/graphiti/sideload/polymorphic_belongs_to.rb +3 -1
- data/lib/graphiti/types.rb +39 -17
- data/lib/graphiti/util/class.rb +22 -0
- data/lib/graphiti/util/hash.rb +16 -0
- data/lib/graphiti/util/hooks.rb +2 -2
- data/lib/graphiti/util/link.rb +48 -0
- data/lib/graphiti/util/serializer_relationships.rb +94 -0
- data/lib/graphiti/version.rb +1 -1
- metadata +16 -7
@@ -0,0 +1,22 @@
|
|
1
|
+
module Graphiti
|
2
|
+
module Util
|
3
|
+
class Class
|
4
|
+
def self.infer_resource_class(parent_resource_class, sideload_name)
|
5
|
+
namespace = namespace_for(parent_resource_class)
|
6
|
+
inferred_name = "#{sideload_name.to_s.singularize.classify}Resource"
|
7
|
+
klass = "#{namespace}::#{inferred_name}".safe_constantize
|
8
|
+
klass ||= inferred_name.safe_constantize
|
9
|
+
unless klass
|
10
|
+
raise Errors::ResourceNotFound.new(parent_resource_class, sideload_name)
|
11
|
+
end
|
12
|
+
klass
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.namespace_for(klass)
|
16
|
+
namespace = klass.name
|
17
|
+
split = namespace.split('::')
|
18
|
+
split[0,split.length-1].join('::')
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/graphiti/util/hash.rb
CHANGED
@@ -23,6 +23,22 @@ module Graphiti
|
|
23
23
|
collection
|
24
24
|
end
|
25
25
|
|
26
|
+
def self.include_removed?(new, old)
|
27
|
+
new = JSONAPI::IncludeDirective.new(new).to_hash
|
28
|
+
old = JSONAPI::IncludeDirective.new(old).to_hash
|
29
|
+
|
30
|
+
old.each_pair do |k, v|
|
31
|
+
if new[k]
|
32
|
+
if include_removed?(new[k], v)
|
33
|
+
return true
|
34
|
+
end
|
35
|
+
else
|
36
|
+
return true
|
37
|
+
end
|
38
|
+
end
|
39
|
+
false
|
40
|
+
end
|
41
|
+
|
26
42
|
# Like ActiveSupport's #deep_merge
|
27
43
|
# @return [Hash] the merged hash
|
28
44
|
# @api private
|
data/lib/graphiti/util/hooks.rb
CHANGED
@@ -11,12 +11,12 @@ module Graphiti
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def self._hooks
|
14
|
-
Thread.current[:
|
14
|
+
Thread.current[:_graphiti_hooks] ||= []
|
15
15
|
end
|
16
16
|
private_class_method :_hooks
|
17
17
|
|
18
18
|
def self.hooks=(val)
|
19
|
-
Thread.current[:
|
19
|
+
Thread.current[:_graphiti_hooks] = val
|
20
20
|
end
|
21
21
|
|
22
22
|
# Because hooks will be added from the outer edges of
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Graphiti
|
2
|
+
module Util
|
3
|
+
class Link
|
4
|
+
def initialize(sideload, model)
|
5
|
+
@sideload = sideload
|
6
|
+
@model = model
|
7
|
+
|
8
|
+
if @sideload.type == :polymorphic_belongs_to
|
9
|
+
type = @model.send(@sideload.grouper.field_name)
|
10
|
+
@sideload = @sideload.children.values.find do |c|
|
11
|
+
c.group_name == type.to_sym
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def generate
|
17
|
+
if params.empty?
|
18
|
+
path
|
19
|
+
else
|
20
|
+
"#{path}?#{URI.unescape(params.to_query)}"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def params
|
27
|
+
@params ||= {}.tap do |params|
|
28
|
+
if @sideload.type != :belongs_to
|
29
|
+
params[:filter] = @sideload.base_filter([@model])
|
30
|
+
end
|
31
|
+
|
32
|
+
if @sideload.params_proc
|
33
|
+
@sideload.params_proc.call(params, [@model])
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def path
|
39
|
+
@path ||=
|
40
|
+
path = @sideload.resource.endpoint[:url].to_s
|
41
|
+
if @sideload.type == :belongs_to
|
42
|
+
path = "#{path}/#{@model.send(@sideload.foreign_key)}"
|
43
|
+
end
|
44
|
+
path
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
module Graphiti
|
2
|
+
module Util
|
3
|
+
class SerializerRelationships
|
4
|
+
def initialize(resource_class, sideloads)
|
5
|
+
@resource_class = resource_class
|
6
|
+
@serializer = @resource_class.serializer
|
7
|
+
@sideloads = sideloads
|
8
|
+
end
|
9
|
+
|
10
|
+
def apply
|
11
|
+
@sideloads.each_pair do |name, sideload|
|
12
|
+
if apply?(sideload)
|
13
|
+
SerializerRelationship
|
14
|
+
.new(@resource_class, @serializer, sideload).apply
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def apply?(sideload)
|
22
|
+
@serializer.relationship_blocks[sideload.name].nil? &&
|
23
|
+
sideload.readable?
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class SerializerRelationship
|
28
|
+
def initialize(resource_class, serializer, sideload)
|
29
|
+
@resource_class = resource_class
|
30
|
+
@serializer = serializer
|
31
|
+
@sideload = sideload
|
32
|
+
end
|
33
|
+
|
34
|
+
def apply
|
35
|
+
@serializer.relationship(@sideload.name, &block)
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def block
|
41
|
+
if link?
|
42
|
+
validate_link! unless @sideload.link_proc
|
43
|
+
sl = @sideload
|
44
|
+
proc do
|
45
|
+
if @proxy.query.links?
|
46
|
+
link(:related) do
|
47
|
+
if prc = sl.link_proc
|
48
|
+
prc.call(@object)
|
49
|
+
else
|
50
|
+
::Graphiti::Util::Link.new(sl, @object).generate
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
else
|
56
|
+
proc { }
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def validate_link!
|
61
|
+
unless Graphiti.config.context_for_endpoint
|
62
|
+
raise Errors::Unlinkable.new(@resource_class, @sideload)
|
63
|
+
end
|
64
|
+
|
65
|
+
if @sideload.type == :polymorphic_belongs_to
|
66
|
+
@sideload.children.each_pair do |name, sideload|
|
67
|
+
_validate_link!(sideload)
|
68
|
+
end
|
69
|
+
else
|
70
|
+
_validate_link!(@sideload)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def _validate_link!(sideload)
|
75
|
+
action = sideload.type == :belongs_to ? :show : :index
|
76
|
+
prc = Graphiti.config.context_for_endpoint
|
77
|
+
unless prc.call(sideload.resource.endpoint[:full_path], action)
|
78
|
+
raise Errors::InvalidLink.new(@resource_class, sideload)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def link?
|
83
|
+
return true if @sideload.link_proc
|
84
|
+
|
85
|
+
if @sideload.respond_to?(:children)
|
86
|
+
@sideload.link? &&
|
87
|
+
@sideload.children.values.all? { |c| !c.resource.endpoint.nil? }
|
88
|
+
else
|
89
|
+
@sideload.link? && @sideload.resource.endpoint
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
data/lib/graphiti/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: graphiti
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.alpha.
|
4
|
+
version: 1.0.alpha.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lee Richmond
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-07
|
11
|
+
date: 2018-08-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: jsonapi-serializable
|
@@ -39,19 +39,19 @@ dependencies:
|
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0.13'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: graphiti_errors
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
47
|
+
version: 1.0.alpha.2
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
54
|
+
version: 1.0.alpha.2
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: concurrent-ruby
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -177,7 +177,7 @@ dependencies:
|
|
177
177
|
- !ruby/object:Gem::Version
|
178
178
|
version: '6'
|
179
179
|
- !ruby/object:Gem::Dependency
|
180
|
-
name:
|
180
|
+
name: graphiti_spec_helpers
|
181
181
|
requirement: !ruby/object:Gem::Requirement
|
182
182
|
requirements:
|
183
183
|
- - ">="
|
@@ -193,7 +193,8 @@ dependencies:
|
|
193
193
|
description:
|
194
194
|
email:
|
195
195
|
- richmolj@gmail.com
|
196
|
-
executables:
|
196
|
+
executables:
|
197
|
+
- graphiti
|
197
198
|
extensions: []
|
198
199
|
extra_rdoc_files: []
|
199
200
|
files:
|
@@ -213,6 +214,7 @@ files:
|
|
213
214
|
- bin/console
|
214
215
|
- bin/rspec
|
215
216
|
- bin/setup
|
217
|
+
- exe/graphiti
|
216
218
|
- gemfiles/rails_4.gemfile
|
217
219
|
- gemfiles/rails_5.gemfile
|
218
220
|
- graphiti.gemspec
|
@@ -238,6 +240,7 @@ files:
|
|
238
240
|
- lib/graphiti/adapters/active_record/many_to_many_sideload.rb
|
239
241
|
- lib/graphiti/adapters/null.rb
|
240
242
|
- lib/graphiti/base.rb
|
243
|
+
- lib/graphiti/cli.rb
|
241
244
|
- lib/graphiti/configuration.rb
|
242
245
|
- lib/graphiti/context.rb
|
243
246
|
- lib/graphiti/deserializer.rb
|
@@ -256,11 +259,14 @@ files:
|
|
256
259
|
- lib/graphiti/resource/configuration.rb
|
257
260
|
- lib/graphiti/resource/dsl.rb
|
258
261
|
- lib/graphiti/resource/interface.rb
|
262
|
+
- lib/graphiti/resource/links.rb
|
259
263
|
- lib/graphiti/resource/polymorphism.rb
|
260
264
|
- lib/graphiti/resource/sideloading.rb
|
261
265
|
- lib/graphiti/resource_proxy.rb
|
262
266
|
- lib/graphiti/responders.rb
|
263
267
|
- lib/graphiti/runner.rb
|
268
|
+
- lib/graphiti/schema.rb
|
269
|
+
- lib/graphiti/schema_diff.rb
|
264
270
|
- lib/graphiti/scope.rb
|
265
271
|
- lib/graphiti/scoping/base.rb
|
266
272
|
- lib/graphiti/scoping/default_filter.rb
|
@@ -279,13 +285,16 @@ files:
|
|
279
285
|
- lib/graphiti/stats/payload.rb
|
280
286
|
- lib/graphiti/types.rb
|
281
287
|
- lib/graphiti/util/attribute_check.rb
|
288
|
+
- lib/graphiti/util/class.rb
|
282
289
|
- lib/graphiti/util/field_params.rb
|
283
290
|
- lib/graphiti/util/hash.rb
|
284
291
|
- lib/graphiti/util/hooks.rb
|
285
292
|
- lib/graphiti/util/include_params.rb
|
293
|
+
- lib/graphiti/util/link.rb
|
286
294
|
- lib/graphiti/util/persistence.rb
|
287
295
|
- lib/graphiti/util/relationship_payload.rb
|
288
296
|
- lib/graphiti/util/serializer_attributes.rb
|
297
|
+
- lib/graphiti/util/serializer_relationships.rb
|
289
298
|
- lib/graphiti/util/sideload.rb
|
290
299
|
- lib/graphiti/util/validation_response.rb
|
291
300
|
- lib/graphiti/version.rb
|