hal_presenter 0.6.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +3 -3
- data/lib/hal_presenter/attributes.rb +4 -4
- data/lib/hal_presenter/collection.rb +2 -2
- data/lib/hal_presenter/curies.rb +19 -6
- data/lib/hal_presenter/embedded.rb +4 -4
- data/lib/hal_presenter/lazy_evaluator.rb +44 -0
- data/lib/hal_presenter/links.rb +30 -10
- data/lib/hal_presenter/policy.rb +2 -2
- data/lib/hal_presenter/property.rb +11 -39
- data/lib/hal_presenter/serialize_hooks.rb +2 -2
- data/lib/hal_presenter/serializer.rb +38 -17
- data.tar.gz.sig +0 -0
- metadata +3 -2
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2fe4271a7912587144464a955caafd6d5391f34b6f2ed3a41f5daa5249a39eeb
|
4
|
+
data.tar.gz: c17ab721cbbd1ff37ae96fa921a3a3bb1d003f67943c13863058dfda60a42e4d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b0d7657cdb1609fe0a9e9a072be80ef61b9f9b8df31750575d9cbe007fdef6f86668b4a4c84431c1b94e04165195704eaced191443b8eaa7a3d91909f8b5bcc8
|
7
|
+
data.tar.gz: 9dac165e3f659f3e36c7d1e3f3ec8af60cb74e93152f5f68361b1b13037157fac157d0b5a40e92a60425a2b6c686f2c46a47a43a5da001bbe3efb8d022a4de28
|
checksums.yaml.gz.sig
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
Sp�gLP@b��ܘ��Lb���šד��y������6��n��K��B}���`V0���3�F�X:���}��� �tT�a���ݷ<C����#��@�t<�";�#�
|
2
|
+
PӦ���[@���ib ���z��1̢��>���L�
|
3
|
+
������ئ�R������-nv;:L};���c�({f���ІXɲ�
|
@@ -3,7 +3,7 @@ require 'hal_presenter/property'
|
|
3
3
|
module HALPresenter
|
4
4
|
module Attributes
|
5
5
|
def attribute(*args, **kw_args, &block)
|
6
|
-
@_attributes ||=
|
6
|
+
@_attributes ||= __init_attributes
|
7
7
|
@_attributes = @_attributes.reject { |attr| attr.name == args.first }
|
8
8
|
@_attributes << Property.new(*args, **kw_args, &block)
|
9
9
|
end
|
@@ -11,16 +11,16 @@ module HALPresenter
|
|
11
11
|
protected
|
12
12
|
|
13
13
|
def attributes
|
14
|
-
@_attributes ||=
|
14
|
+
@_attributes ||= __init_attributes
|
15
15
|
end
|
16
16
|
|
17
17
|
private
|
18
18
|
|
19
|
-
def
|
19
|
+
def __init_attributes
|
20
20
|
return [] unless Class === self
|
21
21
|
return [] unless superclass.respond_to?(:attributes, true)
|
22
22
|
superclass.attributes.each do |attr|
|
23
|
-
attr.
|
23
|
+
attr.change_context(self)
|
24
24
|
end
|
25
25
|
end
|
26
26
|
end
|
@@ -37,7 +37,7 @@ module HALPresenter
|
|
37
37
|
protected
|
38
38
|
|
39
39
|
def collection_properties
|
40
|
-
@_collection_properties ||=
|
40
|
+
@_collection_properties ||= __init_collection_params
|
41
41
|
end
|
42
42
|
|
43
43
|
def can_serialize_collection?
|
@@ -46,7 +46,7 @@ module HALPresenter
|
|
46
46
|
|
47
47
|
private
|
48
48
|
|
49
|
-
def
|
49
|
+
def __init_collection_params
|
50
50
|
return unless Class === self
|
51
51
|
if superclass.respond_to?(:collection_properties, true)
|
52
52
|
superclass.collection_properties
|
data/lib/hal_presenter/curies.rb
CHANGED
@@ -2,28 +2,41 @@ require 'hal_presenter/property'
|
|
2
2
|
|
3
3
|
module HALPresenter
|
4
4
|
module Curies
|
5
|
-
|
5
|
+
class Curie < HALPresenter::Property
|
6
|
+
def to_h(resource = nil, options = {})
|
7
|
+
href = value(resource, options)
|
8
|
+
return {} unless href
|
9
|
+
|
10
|
+
{
|
11
|
+
name: name,
|
12
|
+
href: HALPresenter.href(href),
|
13
|
+
templated: true
|
14
|
+
}
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def curie(rel, value = nil, embed_depth: nil, &block)
|
6
19
|
if value.nil? && !block_given?
|
7
20
|
raise 'curie must be called with non nil value or be given a block'
|
8
21
|
end
|
9
|
-
@_curies ||=
|
22
|
+
@_curies ||= __init_curies
|
10
23
|
@_curies = @_curies.reject { |curie| curie.name == rel }
|
11
|
-
@_curies <<
|
24
|
+
@_curies << Curie.new(rel, value, embed_depth: embed_depth, &block)
|
12
25
|
end
|
13
26
|
|
14
27
|
protected
|
15
28
|
|
16
29
|
def curies
|
17
|
-
@_curies ||=
|
30
|
+
@_curies ||= __init_curies
|
18
31
|
end
|
19
32
|
|
20
33
|
private
|
21
34
|
|
22
|
-
def
|
35
|
+
def __init_curies
|
23
36
|
return [] unless Class === self
|
24
37
|
return [] unless superclass.respond_to?(:curies, true)
|
25
38
|
superclass.curies.each do |curie|
|
26
|
-
curie.
|
39
|
+
curie.change_context(self)
|
27
40
|
end
|
28
41
|
end
|
29
42
|
end
|
@@ -12,7 +12,7 @@ module HALPresenter
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def embed(*args, **kw_args, &block)
|
15
|
-
@_embedded ||=
|
15
|
+
@_embedded ||= __init_embedded
|
16
16
|
@_embedded = @_embedded.reject { |embed| embed.name == args.first }
|
17
17
|
@_embedded << Embed.new(*args, **kw_args, &block)
|
18
18
|
end
|
@@ -20,16 +20,16 @@ module HALPresenter
|
|
20
20
|
protected
|
21
21
|
|
22
22
|
def embedded
|
23
|
-
@_embedded ||=
|
23
|
+
@_embedded ||= __init_embedded
|
24
24
|
end
|
25
25
|
|
26
26
|
private
|
27
27
|
|
28
|
-
def
|
28
|
+
def __init_embedded
|
29
29
|
return [] unless Class === self
|
30
30
|
return [] unless superclass.respond_to?(:embedded, true)
|
31
31
|
superclass.embedded.each do |embed|
|
32
|
-
embed.
|
32
|
+
embed.change_context(self)
|
33
33
|
end
|
34
34
|
end
|
35
35
|
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module HALPresenter
|
4
|
+
class LazyEvaluator
|
5
|
+
attr_reader :resource, :options
|
6
|
+
alias resources resource
|
7
|
+
|
8
|
+
def initialize(block)
|
9
|
+
@__context = eval 'self', block.binding
|
10
|
+
define_singleton_method(:evaluate_block, &block)
|
11
|
+
end
|
12
|
+
|
13
|
+
def update_context(context)
|
14
|
+
@__context = context
|
15
|
+
end
|
16
|
+
|
17
|
+
def evaluate(resource, options)
|
18
|
+
@resource = resource
|
19
|
+
@options = options || {}
|
20
|
+
evaluate_block
|
21
|
+
ensure
|
22
|
+
@resource = nil
|
23
|
+
@options = nil
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
attr_reader :__context
|
29
|
+
|
30
|
+
def method_missing(method, *args, &block)
|
31
|
+
return super unless __context.respond_to?(method)
|
32
|
+
|
33
|
+
define_singleton_method(method) do |*a, &b|
|
34
|
+
__context.public_send(method, *a, &b)
|
35
|
+
end
|
36
|
+
|
37
|
+
public_send(method, *args, &block)
|
38
|
+
end
|
39
|
+
|
40
|
+
def respond_to_missing?(method, _include_private = false)
|
41
|
+
__context.respond_to?(method) || super
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
data/lib/hal_presenter/links.rb
CHANGED
@@ -15,39 +15,59 @@ module HALPresenter
|
|
15
15
|
module Links
|
16
16
|
|
17
17
|
class Link < HALPresenter::Property
|
18
|
-
attr_reader :
|
19
|
-
|
18
|
+
attr_reader :type, :deprecation, :profile, :title
|
19
|
+
attr_accessor :templated
|
20
|
+
|
21
|
+
def initialize(rel, value = nil, **kwargs, &block)
|
20
22
|
if value.nil? && !block_given?
|
21
23
|
raise 'link must be called with non nil value or be given a block'
|
22
24
|
end
|
23
|
-
@
|
24
|
-
|
25
|
+
@type = kwargs[:type]
|
26
|
+
@deprecation = kwargs[:deprecation]
|
27
|
+
@profile = kwargs[:profile]
|
28
|
+
@title = kwargs[:title]
|
29
|
+
super(rel, value, embed_depth: kwargs[:embed_depth], &block)
|
25
30
|
end
|
26
31
|
|
27
32
|
def rel
|
28
33
|
name
|
29
34
|
end
|
35
|
+
|
36
|
+
def to_h(resource = nil, options = {})
|
37
|
+
href = value(resource, options)
|
38
|
+
return {} unless href
|
39
|
+
|
40
|
+
hash = {href: HALPresenter.href(href)}.tap do |h|
|
41
|
+
h[:type] = type if type
|
42
|
+
h[:deprecation] = deprecation if deprecation
|
43
|
+
h[:profile] = profile if profile
|
44
|
+
h[:title] = title if title
|
45
|
+
h[:templated] = templated if templated
|
46
|
+
end
|
47
|
+
|
48
|
+
{rel => hash}
|
49
|
+
end
|
30
50
|
end
|
31
51
|
|
32
|
-
def link(rel, value = nil, **
|
33
|
-
@_links ||=
|
52
|
+
def link(rel, value = nil, **kwargs, &block)
|
53
|
+
@_links ||= __init_links
|
34
54
|
@_links = @_links.reject { |link| link.rel == rel }
|
35
|
-
@_links << Link.new(rel, value, **
|
55
|
+
@_links << Link.new(rel, value, **kwargs, &block)
|
36
56
|
end
|
37
57
|
|
38
58
|
protected
|
39
59
|
|
40
60
|
def links
|
41
|
-
@_links ||=
|
61
|
+
@_links ||= __init_links
|
42
62
|
end
|
43
63
|
|
44
64
|
private
|
45
65
|
|
46
|
-
def
|
66
|
+
def __init_links
|
47
67
|
return [] unless Class === self
|
48
68
|
return [] unless superclass.respond_to?(:links, true)
|
49
69
|
superclass.links.each do |link|
|
50
|
-
link.
|
70
|
+
link.change_context(self)
|
51
71
|
end
|
52
72
|
end
|
53
73
|
end
|
data/lib/hal_presenter/policy.rb
CHANGED
@@ -8,12 +8,12 @@ module HALPresenter
|
|
8
8
|
protected
|
9
9
|
|
10
10
|
def policy_class
|
11
|
-
@_policy ||=
|
11
|
+
@_policy ||= __init_policy
|
12
12
|
end
|
13
13
|
|
14
14
|
private
|
15
15
|
|
16
|
-
def
|
16
|
+
def __init_policy
|
17
17
|
return unless Class === self
|
18
18
|
return unless superclass.respond_to?(:policy_class, true)
|
19
19
|
superclass.policy_class
|
@@ -1,58 +1,30 @@
|
|
1
|
+
require 'hal_presenter/lazy_evaluator'
|
2
|
+
|
1
3
|
module HALPresenter
|
2
4
|
class Property
|
3
|
-
attr_reader :name, :resource, :embed_depth, :options
|
4
5
|
|
5
|
-
|
6
|
+
attr_reader :name, :embed_depth
|
6
7
|
|
7
8
|
def initialize(name, value = nil, embed_depth: nil, &block)
|
8
|
-
@name = name
|
9
|
+
@name = name.to_sym
|
9
10
|
@value = value
|
10
11
|
@embed_depth = embed_depth
|
11
|
-
@
|
12
|
-
return unless block_given?
|
13
|
-
@scope = eval 'self', block.binding
|
14
|
-
define_singleton_method(:value_from_block, &block)
|
12
|
+
@lazy = block_given? && LazyEvaluator.new(block)
|
15
13
|
end
|
16
14
|
|
17
|
-
def value(resource = nil, options =
|
18
|
-
@
|
19
|
-
|
20
|
-
if scope
|
21
|
-
value_from_block
|
15
|
+
def value(resource = nil, options = nil)
|
16
|
+
if @lazy
|
17
|
+
@lazy.evaluate(resource, options)
|
22
18
|
elsif resource && @value.nil?
|
23
19
|
resource.public_send(name) if resource.respond_to?(name)
|
24
20
|
else
|
25
21
|
@value
|
26
22
|
end
|
27
|
-
ensure
|
28
|
-
reset
|
29
|
-
end
|
30
|
-
|
31
|
-
def change_scope(new_scope)
|
32
|
-
return unless scope
|
33
|
-
@scope = new_scope
|
34
|
-
end
|
35
|
-
|
36
|
-
def method_missing(method, *args, &block)
|
37
|
-
if scope&.respond_to? method
|
38
|
-
define_singleton_method(method) { |*a, &b| scope.public_send method, *a, &b }
|
39
|
-
return public_send(method, *args, &block)
|
40
|
-
end
|
41
|
-
super
|
42
|
-
end
|
43
|
-
|
44
|
-
def respond_to_missing?(method, include_private = false)
|
45
|
-
return true if scope&.respond_to? method
|
46
|
-
super
|
47
23
|
end
|
48
24
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
def reset
|
54
|
-
@resource = nil
|
55
|
-
@options = nil
|
25
|
+
def change_context(context)
|
26
|
+
return unless @lazy
|
27
|
+
@lazy.update_context(context)
|
56
28
|
end
|
57
29
|
end
|
58
30
|
end
|
@@ -27,12 +27,12 @@ module HALPresenter
|
|
27
27
|
protected
|
28
28
|
|
29
29
|
def post_serialize_hook
|
30
|
-
@_post_serialize_hook ||=
|
30
|
+
@_post_serialize_hook ||= __init_post_serialize_hook
|
31
31
|
end
|
32
32
|
|
33
33
|
private
|
34
34
|
|
35
|
-
def
|
35
|
+
def __init_post_serialize_hook
|
36
36
|
return unless Class === self
|
37
37
|
return unless superclass.respond_to?(:post_serialize_hook, true)
|
38
38
|
superclass.post_serialize_hook
|
@@ -26,6 +26,7 @@ module HALPresenter
|
|
26
26
|
def to_hal(resource = nil, options = {})
|
27
27
|
options[:_depth] ||= 0
|
28
28
|
hash = to_hash(resource, options)
|
29
|
+
move_curies_to_top! hash
|
29
30
|
JSON.generate(hash)
|
30
31
|
end
|
31
32
|
|
@@ -38,6 +39,7 @@ module HALPresenter
|
|
38
39
|
options[:paginate] = HALPresenter.paginate unless options.key? :paginate
|
39
40
|
options[:_depth] ||= 0
|
40
41
|
hash = to_collection_hash(resources, options)
|
42
|
+
move_curies_to_top! hash
|
41
43
|
JSON.generate(hash)
|
42
44
|
end
|
43
45
|
|
@@ -71,6 +73,7 @@ module HALPresenter
|
|
71
73
|
serialized[:_embedded] = embedded[:_embedded] || {}
|
72
74
|
|
73
75
|
# Embedded resources
|
76
|
+
options[:_depth] += 1
|
74
77
|
serialized_resources = resources.map { |resource| to_hash(resource, options) }
|
75
78
|
serialized[:_embedded].merge!({properties.name => serialized_resources })
|
76
79
|
end
|
@@ -85,20 +88,47 @@ module HALPresenter
|
|
85
88
|
end
|
86
89
|
|
87
90
|
def serialize_curies(resource, policy, options)
|
88
|
-
_serialize_curies(curies, resource,
|
91
|
+
_serialize_curies(curies, resource, options)
|
89
92
|
end
|
90
93
|
|
91
94
|
def serialize_embedded(resource, policy, options)
|
92
95
|
_serialize_embedded(embedded, resource, policy, options)
|
93
96
|
end
|
94
97
|
|
98
|
+
private
|
99
|
+
|
100
|
+
def move_curies_to_top!(hash)
|
101
|
+
curies = {}
|
102
|
+
find_curies(hash).each do |curie|
|
103
|
+
name = curie[:name]
|
104
|
+
curies[name] = curie
|
105
|
+
end
|
106
|
+
|
107
|
+
return if curies.empty?
|
108
|
+
|
109
|
+
hash[:_links] ||= {}
|
110
|
+
hash[:_links][:curies] = curies.values
|
111
|
+
end
|
112
|
+
|
113
|
+
def find_curies(hash)
|
114
|
+
return [] if Hash(hash).empty?
|
115
|
+
|
116
|
+
curies = hash[:_links].delete(:curies) if hash.key? :_links
|
117
|
+
curies ||= []
|
118
|
+
|
119
|
+
hash.fetch(:_embedded, {}).values.each do |embedded|
|
120
|
+
collection = embedded.is_a?(Array) ? embedded : [embedded]
|
121
|
+
collection.each { |resrc| curies += find_curies(resrc) }
|
122
|
+
end
|
123
|
+
|
124
|
+
curies
|
125
|
+
end
|
126
|
+
|
95
127
|
def run_post_serialize_hook!(resource, options, serialized)
|
96
128
|
hook = post_serialize_hook
|
97
129
|
hook&.run(resource, options, serialized)
|
98
130
|
end
|
99
131
|
|
100
|
-
private
|
101
|
-
|
102
132
|
def _serialize_attributes(attributes, resource, policy, options)
|
103
133
|
attributes.each_with_object({}) do |attribute, hash|
|
104
134
|
next unless nested_depth_ok?(attribute, options[:_depth])
|
@@ -111,26 +141,19 @@ module HALPresenter
|
|
111
141
|
serialized = links.each_with_object({}) do |link, hash|
|
112
142
|
next unless nested_depth_ok?(link, options[:_depth])
|
113
143
|
next if policy && !policy.link?(link.rel)
|
114
|
-
|
115
|
-
hash[link.rel] = { href: HALPresenter.href(href) }.tap do |s|
|
116
|
-
s[:method] = link.http_method if link.http_method
|
117
|
-
end
|
144
|
+
hash.merge! link.to_h(resource, options)
|
118
145
|
end
|
119
|
-
curies = _serialize_curies(curies, resource,
|
146
|
+
curies = _serialize_curies(curies, resource, options)
|
120
147
|
serialized[:curies] = curies if curies.any?
|
121
148
|
return {} if serialized.empty?
|
122
149
|
{ _links: serialized }
|
123
150
|
end
|
124
151
|
|
125
|
-
def _serialize_curies(curies, resource,
|
152
|
+
def _serialize_curies(curies, resource, options)
|
126
153
|
curies.each_with_object([]) do |curie, array|
|
127
154
|
next unless nested_depth_ok?(curie, options[:_depth])
|
128
|
-
|
129
|
-
array <<
|
130
|
-
name: curie.name,
|
131
|
-
href: HALPresenter.href(href),
|
132
|
-
templated: true
|
133
|
-
}
|
155
|
+
hash = curie.to_h(resource, options)
|
156
|
+
array << hash unless hash.empty?
|
134
157
|
end
|
135
158
|
end
|
136
159
|
|
@@ -179,5 +202,3 @@ module HALPresenter
|
|
179
202
|
end
|
180
203
|
end
|
181
204
|
end
|
182
|
-
|
183
|
-
|
data.tar.gz.sig
CHANGED
Binary file
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hal_presenter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sammy Henningsson
|
@@ -30,7 +30,7 @@ cert_chain:
|
|
30
30
|
ZMhjYR7sRczGJx+GxGU2EaR0bjRsPVlC4ywtFxoOfRG3WaJcpWGEoAoMJX6Z0bRv
|
31
31
|
M40=
|
32
32
|
-----END CERTIFICATE-----
|
33
|
-
date: 2019-
|
33
|
+
date: 2019-03-08 00:00:00.000000000 Z
|
34
34
|
dependencies:
|
35
35
|
- !ruby/object:Gem::Dependency
|
36
36
|
name: rake
|
@@ -166,6 +166,7 @@ files:
|
|
166
166
|
- lib/hal_presenter/curies.rb
|
167
167
|
- lib/hal_presenter/deserializer.rb
|
168
168
|
- lib/hal_presenter/embedded.rb
|
169
|
+
- lib/hal_presenter/lazy_evaluator.rb
|
169
170
|
- lib/hal_presenter/links.rb
|
170
171
|
- lib/hal_presenter/model.rb
|
171
172
|
- lib/hal_presenter/pagination.rb
|
metadata.gz.sig
CHANGED
Binary file
|