graphiti 1.0.alpha.1 → 1.0.alpha.4

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.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +0 -8
  3. data/README.md +2 -72
  4. data/bin/console +1 -1
  5. data/exe/graphiti +5 -0
  6. data/graphiti.gemspec +2 -2
  7. data/lib/generators/jsonapi/resource_generator.rb +1 -1
  8. data/lib/generators/jsonapi/templates/application_resource.rb.erb +0 -2
  9. data/lib/graphiti.rb +17 -1
  10. data/lib/graphiti/adapters/abstract.rb +32 -0
  11. data/lib/graphiti/adapters/active_record/base.rb +8 -0
  12. data/lib/graphiti/adapters/active_record/many_to_many_sideload.rb +2 -9
  13. data/lib/graphiti/cli.rb +45 -0
  14. data/lib/graphiti/configuration.rb +12 -0
  15. data/lib/graphiti/context.rb +1 -0
  16. data/lib/graphiti/errors.rb +105 -3
  17. data/lib/graphiti/filter_operators.rb +13 -3
  18. data/lib/graphiti/query.rb +8 -0
  19. data/lib/graphiti/rails.rb +1 -1
  20. data/lib/graphiti/railtie.rb +21 -2
  21. data/lib/graphiti/renderer.rb +2 -1
  22. data/lib/graphiti/resource.rb +11 -2
  23. data/lib/graphiti/resource/configuration.rb +1 -0
  24. data/lib/graphiti/resource/dsl.rb +4 -3
  25. data/lib/graphiti/resource/interface.rb +15 -0
  26. data/lib/graphiti/resource/links.rb +92 -0
  27. data/lib/graphiti/resource/polymorphism.rb +1 -0
  28. data/lib/graphiti/resource/sideloading.rb +13 -5
  29. data/lib/graphiti/resource_proxy.rb +1 -1
  30. data/lib/graphiti/schema.rb +169 -0
  31. data/lib/graphiti/schema_diff.rb +174 -0
  32. data/lib/graphiti/scoping/filter.rb +1 -1
  33. data/lib/graphiti/sideload.rb +47 -18
  34. data/lib/graphiti/sideload/belongs_to.rb +5 -1
  35. data/lib/graphiti/sideload/has_many.rb +5 -1
  36. data/lib/graphiti/sideload/many_to_many.rb +6 -2
  37. data/lib/graphiti/sideload/polymorphic_belongs_to.rb +3 -1
  38. data/lib/graphiti/types.rb +39 -17
  39. data/lib/graphiti/util/class.rb +22 -0
  40. data/lib/graphiti/util/hash.rb +16 -0
  41. data/lib/graphiti/util/hooks.rb +2 -2
  42. data/lib/graphiti/util/link.rb +48 -0
  43. data/lib/graphiti/util/serializer_relationships.rb +94 -0
  44. data/lib/graphiti/version.rb +1 -1
  45. 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
@@ -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
@@ -11,12 +11,12 @@ module Graphiti
11
11
  end
12
12
 
13
13
  def self._hooks
14
- Thread.current[:_compliable_hooks] ||= []
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[:_compliable_hooks] = val
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
@@ -1,3 +1,3 @@
1
1
  module Graphiti
2
- VERSION = "1.0.alpha.1"
2
+ VERSION = "1.0.alpha.4"
3
3
  end
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.1
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-31 00:00:00.000000000 Z
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: jsonapi_errorable
42
+ name: graphiti_errors
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '0.9'
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: '0.9'
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: jsonapi_spec_helpers
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