jsonapionify 0.12.2 → 0.12.3
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 +8 -8
- data/lib/jsonapionify/api/action/documentation.rb +5 -5
- data/lib/jsonapionify/api/base.rb +1 -0
- data/lib/jsonapionify/api/base/app_builder.rb +1 -1
- data/lib/jsonapionify/api/context.rb +3 -5
- data/lib/jsonapionify/api/relationship/many.rb +1 -0
- data/lib/jsonapionify/api/resource/callbacks.rb +3 -48
- data/lib/jsonapionify/api/resource/caller.rb +9 -3
- data/lib/jsonapionify/api/resource/definitions/contexts.rb +1 -0
- data/lib/jsonapionify/api/resource/definitions/scopes.rb +8 -7
- data/lib/jsonapionify/api/resource/error_handling.rb +1 -1
- data/lib/jsonapionify/api/response.rb +2 -6
- data/lib/jsonapionify/callbacks.rb +24 -13
- data/lib/jsonapionify/custom_rescue.rb +38 -0
- data/lib/jsonapionify/destructured_proc.rb +5 -3
- data/lib/jsonapionify/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
MWNlMTA2NTM0YmE2ODY1NjgxYzZkZDdkZWI1YTI5NTA5ZjA4YmM0OA==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
MjllZmNlOGU1NmU1Nzk1YjZlZDYxODMxNThiZWQyYzA5NTVhMDc2Yg==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
Y2RlOTA5MDI3MGQ5M2U2MjAwZGJjMTNiOGNjMjFiOTU2ZmM5YzFlOTRiMDc0
|
10
|
+
MGRjMGJiN2NhZDkyODI2Y2VmNmUxNzE2MThmNjcxOWIzZDE0YjllZTFkYTFj
|
11
|
+
N2Q0YTQ3NTQyY2FkMDQxN2Y2YTE3NTI2OTIwNThhNGVjNjk1YjE=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
Y2FmODhmNzdhOTAwNjVmNWMzNDU4MDdlNDZiNzQ3YzlkNDY2NjQyYzRjNmE0
|
14
|
+
NDEyNTU1MzRiN2FkMzZkNGE2NzAyODVkZjNlMDJmNDlmMzg4ODA2ZDUzYWRm
|
15
|
+
OTZkMmYxZjVmOTVkYjliYWZlOWMwNmEyZGYwNzRmODgxZjA4N2I=
|
@@ -61,11 +61,11 @@ module JSONAPIonify::Api
|
|
61
61
|
collection_context = proc do |context|
|
62
62
|
3.times.map { resource.example_instance_for_action(action.name, context) }
|
63
63
|
end
|
64
|
-
defs[:_is_example_] = Context.new(readonly: true) { true }
|
65
|
-
defs[:collection] = Context.new(&collection_context)
|
66
|
-
defs[:paginated_collection] = Context.new { |collection:| collection }
|
67
|
-
defs[:instance] = Context.new(readonly: true) { |collection:| collection.first }
|
68
|
-
defs[:owner_context] = Context.new(readonly: true) { ContextDelegate::Mock.new } if defs.has_key? :owner_context
|
64
|
+
defs[:_is_example_] = Context.new(:_is_example_, readonly: true) { true }
|
65
|
+
defs[:collection] = Context.new(:collection, &collection_context)
|
66
|
+
defs[:paginated_collection] = Context.new(:paginated_collection) { |collection:| collection }
|
67
|
+
defs[:instance] = Context.new(:instance, readonly: true) { |collection:| collection.first }
|
68
|
+
defs[:owner_context] = Context.new(:owner_context, readonly: true) { ContextDelegate::Mock.new } if defs.has_key? :owner_context
|
69
69
|
end
|
70
70
|
end
|
71
71
|
|
@@ -2,7 +2,8 @@ module JSONAPIonify::Api
|
|
2
2
|
class Context
|
3
3
|
using JSONAPIonify::DestructuredProc
|
4
4
|
|
5
|
-
def initialize(readonly: false, persisted: false, existing_context: nil, &block)
|
5
|
+
def initialize(name, readonly: false, persisted: false, existing_context: nil, &block)
|
6
|
+
@name = name.to_sym
|
6
7
|
@readonly = readonly
|
7
8
|
@persisted = persisted
|
8
9
|
@existing_context = existing_context
|
@@ -12,11 +13,8 @@ module JSONAPIonify::Api
|
|
12
13
|
def call(instance, delegate)
|
13
14
|
existing_context = @existing_context || proc {}
|
14
15
|
existing_block = proc { existing_context.call(instance, delegate) }
|
15
|
-
|
16
|
+
JSONAPIonify::CustomRescue.perform(remove: __FILE__, source: @block, formatter: ->(meta) { meta.source_location.join(':') + ":in context: `#{@name}''" }) do
|
16
17
|
instance.instance_exec(delegate, existing_block, &@block.destructure(0))
|
17
|
-
rescue => e
|
18
|
-
e.backtrace.unshift @block.source_location.join(':') + ":in (context)"
|
19
|
-
raise e
|
20
18
|
end
|
21
19
|
end
|
22
20
|
|
@@ -5,56 +5,11 @@ module JSONAPIonify::Api
|
|
5
5
|
extend ActiveSupport::Concern
|
6
6
|
using JSONAPIonify::DestructuredProc
|
7
7
|
included do
|
8
|
+
include JSONAPIonify::Callbacks
|
8
9
|
|
9
|
-
|
10
|
-
|
11
|
-
chains = {
|
12
|
-
main: "__#{name}_callback_chain",
|
13
|
-
before: "__#{name}_before_callback_chain",
|
14
|
-
after: "__#{name}_after_callback_chain"
|
15
|
-
}
|
16
|
-
define_method chains[:main] do |*args, &block|
|
17
|
-
block ||= proc {}
|
18
|
-
if send(chains[:before], *args) != false
|
19
|
-
value = begin
|
20
|
-
instance_exec(*args, @__context, &block&.destructure)
|
21
|
-
rescue => e
|
22
|
-
e.backtrace.unshift block.source_location.join(':') + ":in `(callback)`"
|
23
|
-
raise e
|
24
|
-
end
|
25
|
-
value if send(chains[:after], *args) != false
|
26
|
-
end
|
27
|
-
end unless method_defined? chains[:main]
|
28
|
-
|
29
|
-
# Define before and after chains
|
30
|
-
%i{after before}.each do |timing|
|
31
|
-
define_method chains[timing] { |*| } unless method_defined? chains[timing]
|
32
|
-
callback_name = "#{timing}_#{name}"
|
33
|
-
define_singleton_method callback_name do |sym = nil, &outer_block|
|
34
|
-
outer_block = (outer_block || sym).to_proc
|
35
|
-
prev_chain = instance_method(chains[timing])
|
36
|
-
define_method chains[timing] do |*args, &block|
|
37
|
-
begin
|
38
|
-
if prev_chain.bind(self).call(*args, @__context, &block&.destructure) != false
|
39
|
-
instance_exec(*args, @__context, &outer_block&.destructure)
|
40
|
-
end
|
41
|
-
rescue => e
|
42
|
-
e.backtrace.unshift outer_block.source_location.join(':') + ":in `(callback) #{callback_name}`"
|
43
|
-
raise e
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
private(*chains.values)
|
50
|
-
|
51
|
-
end
|
10
|
+
define_callback_strategy do |*args, &block|
|
11
|
+
instance_exec(*args, @__context, &block.destructure)
|
52
12
|
end
|
53
13
|
end
|
54
|
-
|
55
|
-
def run_callbacks(name, *args, &block)
|
56
|
-
send("__#{name}_callback_chain", *args, &block)
|
57
|
-
end
|
58
|
-
|
59
14
|
end
|
60
15
|
end
|
@@ -19,9 +19,15 @@ module JSONAPIonify::Api
|
|
19
19
|
end
|
20
20
|
|
21
21
|
def response_definition
|
22
|
-
|
23
|
-
|
24
|
-
|
22
|
+
extension = @__context.request.extension
|
23
|
+
responses = action.responses
|
24
|
+
response = nil
|
25
|
+
@__context.request.accept.each do |accept|
|
26
|
+
response = responses.find { |r| r.accept_with_matcher? @__context } ||
|
27
|
+
responses.find { |r| r.accept_with_header? accept: accept, extension: extension }
|
28
|
+
break if response
|
29
|
+
end
|
30
|
+
response || error_now(:not_acceptable)
|
25
31
|
end
|
26
32
|
|
27
33
|
private
|
@@ -1,12 +1,13 @@
|
|
1
1
|
module JSONAPIonify::Api
|
2
2
|
module Resource::Definitions::Scopes
|
3
|
+
using JSONAPIonify::DestructuredProc
|
3
4
|
|
4
5
|
def scope(&block)
|
5
6
|
define_singleton_method(:current_scope) do
|
6
|
-
instance_exec(OpenStruct.new, &block)
|
7
|
+
instance_exec(OpenStruct.new, &block.destructure)
|
7
8
|
end
|
8
9
|
context :scope do |context|
|
9
|
-
instance_exec(context, &block)
|
10
|
+
instance_exec(context, &block.destructure)
|
10
11
|
end
|
11
12
|
end
|
12
13
|
|
@@ -14,16 +15,16 @@ module JSONAPIonify::Api
|
|
14
15
|
|
15
16
|
def instance(&block)
|
16
17
|
define_singleton_method(:find_instance) do |id|
|
17
|
-
instance_exec(current_scope, id, OpenStruct.new, &block)
|
18
|
+
instance_exec(current_scope, id, OpenStruct.new, &block.destructure)
|
18
19
|
end
|
19
20
|
context :instance, persisted: true do |context, scope:, id:|
|
20
|
-
instance_exec(scope, id, context, &block)
|
21
|
+
instance_exec(scope, id, context, &block.destructure)
|
21
22
|
end
|
22
23
|
end
|
23
24
|
|
24
25
|
def collection(&block)
|
25
26
|
context :collection do |context, scope:, includes:|
|
26
|
-
collection =
|
27
|
+
collection = instance_exec(scope, context, &block.destructure)
|
27
28
|
|
28
29
|
# Compute includes manipulations
|
29
30
|
self.class.include_definitions.select do |relationship, _|
|
@@ -40,10 +41,10 @@ module JSONAPIonify::Api
|
|
40
41
|
|
41
42
|
def new_instance(&block)
|
42
43
|
define_singleton_method(:build_instance) do
|
43
|
-
Object.new.instance_exec(current_scope, &block)
|
44
|
+
Object.new.instance_exec(current_scope, &block.destructure)
|
44
45
|
end
|
45
46
|
context :new_instance, persisted: true, readonly: true do |context, scope:|
|
46
|
-
Object.new.instance_exec(scope, context, &block)
|
47
|
+
Object.new.instance_exec(scope, context, &block.destructure)
|
47
48
|
end
|
48
49
|
end
|
49
50
|
end
|
@@ -65,12 +65,8 @@ module JSONAPIonify::Api
|
|
65
65
|
end
|
66
66
|
end
|
67
67
|
|
68
|
-
def accept_with_header?(
|
69
|
-
|
70
|
-
self.accept == accept ||
|
71
|
-
(self.accept == '*/*' && !context.request.extension) ||
|
72
|
-
(accept == '*/*' && !context.request.extension)
|
73
|
-
end
|
68
|
+
def accept_with_header?(accept:, extension:)
|
69
|
+
self.accept == accept || (self.accept == '*/*' && !extension) || (accept == '*/*' && !extension)
|
74
70
|
end
|
75
71
|
|
76
72
|
def accept_with_matcher?(context)
|
@@ -1,11 +1,16 @@
|
|
1
1
|
require 'active_support/concern'
|
2
|
+
require 'unstrict_proc'
|
2
3
|
|
3
4
|
module JSONAPIonify
|
4
5
|
module Callbacks
|
5
6
|
extend ActiveSupport::Concern
|
6
|
-
included do
|
7
7
|
|
8
|
-
|
8
|
+
module ClassMethods
|
9
|
+
def define_callback_strategy(&strategy)
|
10
|
+
define_method(:__callback_strategy, &strategy)
|
11
|
+
end
|
12
|
+
|
13
|
+
def define_callbacks(*names)
|
9
14
|
names.each do |name|
|
10
15
|
chains = {
|
11
16
|
main: "__#{name}_callback_chain",
|
@@ -14,10 +19,12 @@ module JSONAPIonify
|
|
14
19
|
}
|
15
20
|
define_method chains[:main] do |*args, **, &block|
|
16
21
|
block ||= proc {}
|
17
|
-
|
18
|
-
value =
|
19
|
-
|
20
|
-
|
22
|
+
false != send(chains[:before], *args) &&
|
23
|
+
(value = JSONAPIonify::CustomRescue.perform(remove: __FILE__, source: block, formatter: ->(meta) { meta.source_location.join(':') + ":in callback: `run'" }) do
|
24
|
+
__callback_strategy(*args, &block) || true
|
25
|
+
end) &&
|
26
|
+
false != send(chains[:after], *args) &&
|
27
|
+
value
|
21
28
|
end unless method_defined? chains[:main]
|
22
29
|
|
23
30
|
# Define before and after chains
|
@@ -27,13 +34,11 @@ module JSONAPIonify
|
|
27
34
|
define_singleton_method callback_name do |sym = nil, &outer_block|
|
28
35
|
outer_block = (outer_block || sym).to_proc
|
29
36
|
prev_chain = instance_method(chains[timing])
|
30
|
-
define_method chains[timing] do |*args,
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
raise e
|
36
|
-
end
|
37
|
+
define_method chains[timing] do |*args, &block|
|
38
|
+
false != prev_chain.bind(self).call(*args, &block) &&
|
39
|
+
JSONAPIonify::CustomRescue.perform(remove: __FILE__, source: outer_block, formatter: ->(meta) { meta.source_location.join(':') + ":in callback: `#{timing}_#{name}'" }) do
|
40
|
+
__callback_strategy(*args, &outer_block)
|
41
|
+
end
|
37
42
|
end
|
38
43
|
end
|
39
44
|
end
|
@@ -44,6 +49,12 @@ module JSONAPIonify
|
|
44
49
|
end
|
45
50
|
end
|
46
51
|
|
52
|
+
included do
|
53
|
+
define_callback_strategy do |*args, &block|
|
54
|
+
instance_exec(*args, &block)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
47
58
|
def run_callbacks(name, *args, &block)
|
48
59
|
send("__#{name}_callback_chain", *args, &block)
|
49
60
|
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'unstrict_proc'
|
2
|
+
|
3
|
+
class JSONAPIonify::CustomRescue
|
4
|
+
using UnstrictProc
|
5
|
+
|
6
|
+
def self.perform(**opts, &block)
|
7
|
+
new(**opts, &block).perform
|
8
|
+
end
|
9
|
+
|
10
|
+
def initialize(remove: [], source: nil, formatter:, &block)
|
11
|
+
@block = block
|
12
|
+
@formatter = formatter
|
13
|
+
@source = source || block
|
14
|
+
@locs = Array.wrap remove
|
15
|
+
f, l = self.class.method(:perform).source_location
|
16
|
+
@locs << [f, l+1].join(':')
|
17
|
+
end
|
18
|
+
|
19
|
+
def source_location
|
20
|
+
source.source_location
|
21
|
+
end
|
22
|
+
|
23
|
+
def perform
|
24
|
+
@block.call
|
25
|
+
rescue => e
|
26
|
+
loc = [__FILE__, __LINE__-2].join(':')
|
27
|
+
formatted_value = @formatter.unstrict.call(Error.new(e, @source))
|
28
|
+
index = e.backtrace.index { |l| l.include? loc }
|
29
|
+
e.backtrace[index] = formatted_value if index && formatted_value
|
30
|
+
e.backtrace.delete_if { |l| @locs.any? { |rl| l.include? rl } }
|
31
|
+
raise e
|
32
|
+
end
|
33
|
+
|
34
|
+
class Error < Struct.new :error, :source
|
35
|
+
delegate :source_location, to: :source
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
@@ -5,16 +5,18 @@ module JSONAPIonify::DestructuredProc
|
|
5
5
|
original = self
|
6
6
|
Proc.new do |*args|
|
7
7
|
kwargs = original.kwargs_destructured(args[at_index])
|
8
|
-
|
8
|
+
JSONAPIonify::CustomRescue.perform(remove: __FILE__, source: original, formatter: ->(meta) { meta.source_location.join(':') + ":in `block (destructured)'" }) do
|
9
|
+
instance_exec(*args, **kwargs, &original)
|
10
|
+
end
|
9
11
|
end
|
10
12
|
end
|
11
13
|
|
12
14
|
def kwargs
|
13
|
-
parameters.select { |t, k| t.to_s.start_with?
|
15
|
+
parameters.select { |t, k| t.to_s.start_with?('key') && !t.to_s.end_with?('rest') }
|
14
16
|
end
|
15
17
|
|
16
18
|
def arguments
|
17
|
-
parameters.reject { |t, k| t.to_s.start_with?
|
19
|
+
parameters.reject { |t, k| t.to_s.start_with?('key') || t.to_s.end_with?('rest') }
|
18
20
|
end
|
19
21
|
|
20
22
|
def kwargs_destructured(target)
|
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.12.
|
4
|
+
version: 0.12.3
|
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-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -608,6 +608,7 @@ files:
|
|
608
608
|
- lib/jsonapionify/callbacks.rb
|
609
609
|
- lib/jsonapionify/character_range.rb
|
610
610
|
- lib/jsonapionify/continuation.rb
|
611
|
+
- lib/jsonapionify/custom_rescue.rb
|
611
612
|
- lib/jsonapionify/deep_sort_collection.rb
|
612
613
|
- lib/jsonapionify/destructured_proc.rb
|
613
614
|
- lib/jsonapionify/documentation.rb
|