jsonapionify 0.11.11 → 0.12.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/README.md +3 -0
- data/examples/example_api.rb +80 -0
- data/jsonapionify.gemspec +1 -0
- data/lib/jsonapionify/api/action/documentation.rb +2 -2
- data/lib/jsonapionify/api/attribute.rb +3 -2
- data/lib/jsonapionify/api/context.rb +8 -3
- data/lib/jsonapionify/api/context_delegate.rb +6 -0
- data/lib/jsonapionify/api/relationship.rb +5 -10
- data/lib/jsonapionify/api/relationship/many.rb +46 -14
- data/lib/jsonapionify/api/relationship/one.rb +31 -8
- data/lib/jsonapionify/api/resource.rb +3 -6
- data/lib/jsonapionify/api/resource/builders/fields_builder.rb +2 -2
- data/lib/jsonapionify/api/resource/builders/relationship_builder.rb +3 -2
- data/lib/jsonapionify/api/resource/builders/relationships_builder.rb +3 -2
- data/lib/jsonapionify/api/resource/caching.rb +1 -4
- data/lib/jsonapionify/api/resource/callbacks.rb +60 -0
- data/lib/jsonapionify/api/resource/caller.rb +8 -7
- data/lib/jsonapionify/api/resource/defaults/actions.rb +15 -12
- data/lib/jsonapionify/api/resource/defaults/hooks.rb +10 -57
- data/lib/jsonapionify/api/resource/defaults/options.rb +3 -8
- data/lib/jsonapionify/api/resource/defaults/params.rb +0 -2
- data/lib/jsonapionify/api/resource/defaults/request_contexts.rb +24 -29
- data/lib/jsonapionify/api/resource/defaults/response_contexts.rb +11 -18
- data/lib/jsonapionify/api/resource/definitions/actions.rb +38 -22
- data/lib/jsonapionify/api/resource/definitions/attributes.rb +2 -2
- data/lib/jsonapionify/api/resource/definitions/helpers.rb +1 -1
- data/lib/jsonapionify/api/resource/definitions/includes.rb +16 -0
- data/lib/jsonapionify/api/resource/definitions/pagination.rb +7 -11
- data/lib/jsonapionify/api/resource/definitions/params.rb +19 -26
- data/lib/jsonapionify/api/resource/definitions/relationships.rb +3 -3
- data/lib/jsonapionify/api/resource/definitions/request_headers.rb +14 -16
- data/lib/jsonapionify/api/resource/definitions/response_headers.rb +2 -1
- data/lib/jsonapionify/api/resource/definitions/scopes.rb +17 -6
- data/lib/jsonapionify/api/resource/definitions/sorting.rb +8 -7
- data/lib/jsonapionify/api/resource/error_handling.rb +3 -2
- data/lib/jsonapionify/api/resource/exec.rb +3 -1
- data/lib/jsonapionify/api/resource/includer.rb +20 -51
- data/lib/jsonapionify/api/response.rb +3 -1
- data/lib/jsonapionify/callbacks.rb +10 -7
- data/lib/jsonapionify/destructured_proc.rb +27 -0
- data/lib/jsonapionify/structure/collections/base.rb +20 -8
- data/lib/jsonapionify/structure/objects/base.rb +11 -2
- data/lib/jsonapionify/structure/objects/resource_identifier.rb +9 -14
- data/lib/jsonapionify/version.rb +1 -1
- metadata +20 -2
@@ -1,5 +1,7 @@
|
|
1
1
|
module JSONAPIonify::Api
|
2
2
|
class Response
|
3
|
+
using JSONAPIonify::DestructuredProc
|
4
|
+
|
3
5
|
attr_reader :action, :accept, :response_block, :status,
|
4
6
|
:matcher, :content_type, :extension, :example_accept
|
5
7
|
|
@@ -39,7 +41,7 @@ module JSONAPIonify::Api
|
|
39
41
|
status ||= self.status
|
40
42
|
response = self
|
41
43
|
instance.instance_eval do
|
42
|
-
body = instance_exec(context, &response.response_block)
|
44
|
+
body = instance_exec(context, &response.response_block.destructure)
|
43
45
|
Rack::Response.new.tap do |rack_response|
|
44
46
|
rack_response.status = status
|
45
47
|
response_headers.each do |k, v|
|
@@ -12,7 +12,7 @@ module JSONAPIonify
|
|
12
12
|
before: "__#{name}_before_callback_chain",
|
13
13
|
after: "__#{name}_after_callback_chain"
|
14
14
|
}
|
15
|
-
define_method chains[:main] do |*args, &block|
|
15
|
+
define_method chains[:main] do |*args, **, &block|
|
16
16
|
block ||= proc {}
|
17
17
|
if send(chains[:before], *args) != false
|
18
18
|
value = instance_exec(*args, &block)
|
@@ -23,19 +23,22 @@ module JSONAPIonify
|
|
23
23
|
# Define before and after chains
|
24
24
|
%i{after before}.each do |timing|
|
25
25
|
define_method chains[timing] { |*| } unless method_defined? chains[timing]
|
26
|
-
|
27
|
-
define_singleton_method
|
26
|
+
callback_name = "#{timing}_#{name}"
|
27
|
+
define_singleton_method callback_name do |sym = nil, &outer_block|
|
28
28
|
outer_block = (outer_block || sym).to_proc
|
29
29
|
prev_chain = instance_method(chains[timing])
|
30
|
-
define_method chains[timing] do |*args, &block|
|
31
|
-
|
32
|
-
instance_exec(*args, &outer_block)
|
30
|
+
define_method chains[timing] do |*args, **, &block|
|
31
|
+
begin
|
32
|
+
instance_exec(*args, &outer_block) if prev_chain.bind(self).call(*args, &block) != false
|
33
|
+
rescue => e
|
34
|
+
e.backtrace.unshift outer_block.source_location.join(':') + ":in `(callback) #{callback_name}`"
|
35
|
+
raise e
|
33
36
|
end
|
34
37
|
end
|
35
38
|
end
|
36
39
|
end
|
37
40
|
|
38
|
-
private
|
41
|
+
private(*chains.values)
|
39
42
|
|
40
43
|
end
|
41
44
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module JSONAPIonify::DestructuredProc
|
2
|
+
refine Proc do
|
3
|
+
def destructure(at_index = arguments.length-1)
|
4
|
+
return self unless kwargs.present?
|
5
|
+
original = self
|
6
|
+
Proc.new do |*args|
|
7
|
+
kwargs = original.kwargs_destructured(args[at_index])
|
8
|
+
instance_exec(*args, **kwargs, &original)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def kwargs
|
13
|
+
parameters.select { |t, k| t.to_s.start_with? 'key' }
|
14
|
+
end
|
15
|
+
|
16
|
+
def arguments
|
17
|
+
parameters.reject { |t, k| t.to_s.start_with? 'key' }
|
18
|
+
end
|
19
|
+
|
20
|
+
def kwargs_destructured(target)
|
21
|
+
kwargs.each_with_object({}) do |(_, key), kw|
|
22
|
+
next unless target.respond_to? key
|
23
|
+
kw[key] = target.public_send(key)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -4,8 +4,7 @@ require 'concurrent'
|
|
4
4
|
|
5
5
|
module JSONAPIonify::Structure
|
6
6
|
module Collections
|
7
|
-
class Base <
|
8
|
-
include EnumerableObserver
|
7
|
+
class Base < Array
|
9
8
|
include Helpers::InheritsOrigin
|
10
9
|
attr_reader :parent
|
11
10
|
|
@@ -20,11 +19,6 @@ module JSONAPIonify::Structure
|
|
20
19
|
value_is Objects::Base
|
21
20
|
|
22
21
|
def initialize(array = [])
|
23
|
-
observe.added do |items|
|
24
|
-
items.each do |item|
|
25
|
-
item.instance_variable_set(:@parent, self) unless item.frozen?
|
26
|
-
end
|
27
|
-
end
|
28
22
|
array.each do |instance|
|
29
23
|
self << instance
|
30
24
|
end
|
@@ -82,7 +76,25 @@ module JSONAPIonify::Structure
|
|
82
76
|
)
|
83
77
|
end
|
84
78
|
end
|
85
|
-
|
79
|
+
self[length] = new_instance
|
80
|
+
end
|
81
|
+
|
82
|
+
def [] k
|
83
|
+
v = super
|
84
|
+
v.nil? || v.instance_variable_get(:@parent) == self ? v : self[k] = v
|
85
|
+
end
|
86
|
+
|
87
|
+
def []= k, v
|
88
|
+
unless v.nil? || v.instance_variable_get(:@parent) == self
|
89
|
+
v = v.dup.tap { |obj| obj.instance_variable_set :@parent, self}
|
90
|
+
end
|
91
|
+
super(k, v)
|
92
|
+
end
|
93
|
+
|
94
|
+
def each
|
95
|
+
length.times do |i|
|
96
|
+
yield self[i]
|
97
|
+
end
|
86
98
|
end
|
87
99
|
|
88
100
|
def errors
|
@@ -54,7 +54,7 @@ module JSONAPIonify::Structure
|
|
54
54
|
|
55
55
|
# Initialize the object
|
56
56
|
def initialize(**attributes)
|
57
|
-
@object =
|
57
|
+
@object = Hash.new
|
58
58
|
run_callbacks :initialize do
|
59
59
|
attributes.each do |k, v|
|
60
60
|
self[k] = v
|
@@ -90,7 +90,7 @@ module JSONAPIonify::Structure
|
|
90
90
|
end
|
91
91
|
|
92
92
|
def to_json(**opts)
|
93
|
-
Oj.dump(
|
93
|
+
Oj.dump as_json(**opts)
|
94
94
|
end
|
95
95
|
|
96
96
|
def signature
|
@@ -155,6 +155,15 @@ module JSONAPIonify::Structure
|
|
155
155
|
JSON.pretty_generate as_json
|
156
156
|
end
|
157
157
|
|
158
|
+
def inspect
|
159
|
+
hash_inspect = to_h.to_s.gsub(
|
160
|
+
/\:([a-zA-Z_-]+)=>/, '\\1: '
|
161
|
+
)[1..-2].gsub(
|
162
|
+
/\{([^\s])/, '{ \\1').gsub(/([^\s])\}/, '\\1 }'
|
163
|
+
)
|
164
|
+
to_s.sub(/>$/, " #{hash_inspect}>")
|
165
|
+
end
|
166
|
+
|
158
167
|
private
|
159
168
|
|
160
169
|
def collect_child_errors
|
@@ -1,7 +1,8 @@
|
|
1
1
|
module JSONAPIonify::Structure
|
2
2
|
module Objects
|
3
3
|
class ResourceIdentifier < Base
|
4
|
-
|
4
|
+
|
5
|
+
define_order :type, :id
|
5
6
|
|
6
7
|
# A resource object **MUST** contain at least the following top-level members:
|
7
8
|
must_contain! :id, :type # Describes ResourceObjects that share common attributes and relationships.
|
@@ -22,25 +23,19 @@ module JSONAPIonify::Structure
|
|
22
23
|
|
23
24
|
def duplicate_exists?
|
24
25
|
return false unless parent.is_a?(Array)
|
25
|
-
|
26
|
-
!!peers.index(self)
|
27
|
-
end
|
28
|
-
|
29
|
-
def ==(other)
|
30
|
-
same_as? other
|
26
|
+
parent.select { |peer| peer.eql? self }.length > 1
|
31
27
|
end
|
32
28
|
|
33
29
|
def duplicate_does_not_exist?
|
34
30
|
!duplicate_exists?
|
35
31
|
end
|
36
32
|
|
37
|
-
def
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
other_id == local_id
|
33
|
+
def hash
|
34
|
+
{ type: self[:type], id: self[:id] }.hash
|
35
|
+
end
|
36
|
+
|
37
|
+
def eql?(other)
|
38
|
+
other.hash == self.hash
|
44
39
|
end
|
45
40
|
|
46
41
|
end
|
data/lib/jsonapionify/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jsonapionify
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.12.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jason Waldrip
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-07-
|
11
|
+
date: 2016-07-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -206,6 +206,20 @@ dependencies:
|
|
206
206
|
- - ! '>='
|
207
207
|
- !ruby/object:Gem::Version
|
208
208
|
version: '0'
|
209
|
+
- !ruby/object:Gem::Dependency
|
210
|
+
name: yard
|
211
|
+
requirement: !ruby/object:Gem::Requirement
|
212
|
+
requirements:
|
213
|
+
- - ! '>='
|
214
|
+
- !ruby/object:Gem::Version
|
215
|
+
version: '0'
|
216
|
+
type: :development
|
217
|
+
prerelease: false
|
218
|
+
version_requirements: !ruby/object:Gem::Requirement
|
219
|
+
requirements:
|
220
|
+
- - ! '>='
|
221
|
+
- !ruby/object:Gem::Version
|
222
|
+
version: '0'
|
209
223
|
- !ruby/object:Gem::Dependency
|
210
224
|
name: pry-byebug
|
211
225
|
requirement: !ruby/object:Gem::Requirement
|
@@ -511,6 +525,7 @@ files:
|
|
511
525
|
- bin/console
|
512
526
|
- bin/setup
|
513
527
|
- config.ru
|
528
|
+
- examples/example_api.rb
|
514
529
|
- index.html
|
515
530
|
- jsonapionify.gemspec
|
516
531
|
- lib/core_ext/boolean.rb
|
@@ -552,6 +567,7 @@ files:
|
|
552
567
|
- lib/jsonapionify/api/resource/builders/resource_builder.rb
|
553
568
|
- lib/jsonapionify/api/resource/builders/resource_identifer_builder.rb
|
554
569
|
- lib/jsonapionify/api/resource/caching.rb
|
570
|
+
- lib/jsonapionify/api/resource/callbacks.rb
|
555
571
|
- lib/jsonapionify/api/resource/caller.rb
|
556
572
|
- lib/jsonapionify/api/resource/class_methods.rb
|
557
573
|
- lib/jsonapionify/api/resource/defaults.rb
|
@@ -567,6 +583,7 @@ files:
|
|
567
583
|
- lib/jsonapionify/api/resource/definitions/attributes.rb
|
568
584
|
- lib/jsonapionify/api/resource/definitions/contexts.rb
|
569
585
|
- lib/jsonapionify/api/resource/definitions/helpers.rb
|
586
|
+
- lib/jsonapionify/api/resource/definitions/includes.rb
|
570
587
|
- lib/jsonapionify/api/resource/definitions/pagination.rb
|
571
588
|
- lib/jsonapionify/api/resource/definitions/params.rb
|
572
589
|
- lib/jsonapionify/api/resource/definitions/relationships.rb
|
@@ -591,6 +608,7 @@ files:
|
|
591
608
|
- lib/jsonapionify/character_range.rb
|
592
609
|
- lib/jsonapionify/continuation.rb
|
593
610
|
- lib/jsonapionify/deep_sort_collection.rb
|
611
|
+
- lib/jsonapionify/destructured_proc.rb
|
594
612
|
- lib/jsonapionify/documentation.rb
|
595
613
|
- lib/jsonapionify/documentation/template.erb
|
596
614
|
- lib/jsonapionify/indented_string.rb
|