hal_presenter 0.6.0 → 1.0.0
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 +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
|