ams_hal 0.2.2

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 77898f307f89b2c0e0817b60c5837161cbdb387d
4
+ data.tar.gz: 29abc151fe345ab914679e56e5dda53b3d77352d
5
+ SHA512:
6
+ metadata.gz: 4ebacd405a3634d4a3a9a1379e7efb20f446a6b313788f3735758675b659d2e8824cc45b02c9c4131faf2a7004f03000e4468b078a5d0ae0692e27742b57e00f
7
+ data.tar.gz: 768689cfd85cc23962255f5a00cd959d8f5df3a7212158c11c89064ffa098f53bd1303251510150271ee9708696092b35962be1b1f805985f3b4ddb15cfbad1a
data/lib/ams_hal.rb ADDED
@@ -0,0 +1,7 @@
1
+ require 'active_support/core_ext/hash/indifferent_access.rb'
2
+ require 'active_model_serializers'
3
+ require 'ams_hal/adapter'
4
+ require 'ams_hal/link'
5
+ require 'ams_hal/curies'
6
+ require 'ams_hal/embedded'
7
+ require 'ams_hal/embed'
@@ -0,0 +1,131 @@
1
+ module AmsHal
2
+ class Adapter < ActiveModelSerializers::Adapter::Base
3
+ def serializable_hash(options = nil)
4
+ options = serialization_options(options)
5
+ options[:fields] ||= instance_options[:fields]
6
+ serialized = if serializer.respond_to?(:each)
7
+ serializer.each_with_object([]) do |_serializer, array|
8
+ array << serialize_resource(_serializer, instance_options, options)
9
+ end
10
+ else
11
+ serialize_resource(serializer, instance_options, options)
12
+ end
13
+
14
+ self.class.transform_key_casing!(serialized, instance_options)
15
+ end
16
+
17
+ protected
18
+
19
+ def serialize_resource(serializer, adapter_options, options)
20
+ options[:include_directive] = {} # Don't include associations as attributes
21
+ serialized = serializer.serializable_hash(adapter_options, options, self)
22
+
23
+ if links = serialize_links(serializer)
24
+ serialized[:_links] = links if links.any?
25
+ end
26
+
27
+ if embedded = serialize_embedded(serializer)
28
+ serialized[:_embedded] = embedded if embedded.any?
29
+ end
30
+
31
+ if associations = serialize_associations(serializer)
32
+ serialized[:_embedded] = associations if associations.any?
33
+ end
34
+
35
+ serialized
36
+ end
37
+
38
+ def serialize_links(serializer)
39
+ return unless serializer.respond_to? :_links
40
+ links = serializer._links.each_with_object({}) do |(rel, value), hash|
41
+ link = Link.new(serializer, value).value
42
+ [link].flatten.each do |href|
43
+ next unless href
44
+ if hash.key? rel
45
+ hash[rel] = [hash[rel]] unless hash[rel].is_a? Array
46
+ hash[rel] << { href: href }
47
+ else
48
+ hash[rel] = { href: href }
49
+ end
50
+ end
51
+ end
52
+ curies = serialize_curies(serializer)
53
+ links[:curies] = curies if curies
54
+
55
+ links
56
+ end
57
+
58
+ def serialize_curies(serializer)
59
+ return unless serializer.respond_to? :curies
60
+ serializer.curies.each_with_object([]) do |(name, value), array|
61
+ href = Link.new(serializer, value).value
62
+ array << {
63
+ name: name,
64
+ href: href,
65
+ templated: true
66
+ }
67
+ end
68
+ end
69
+
70
+ def serialize_embedded(serializer)
71
+ return unless serializer.respond_to? :embedded
72
+ serializer.embedded.each_with_object({}) do |embed, embedded|
73
+ resource = embed.resource_for(serializer)
74
+
75
+ next unless resource
76
+
77
+ serialized_resources = [resource].flatten.map do |resrc|
78
+ serialize_embedded_resource(resrc)
79
+ end
80
+ embedded[embed.name] = if serialized_resources.size == 1
81
+ serialized_resources.first
82
+ else
83
+ serialized_resources
84
+ end
85
+ end
86
+ end
87
+
88
+ def serialize_associations(serializer)
89
+ serializer.associations.each_with_object({}) do |association, embedded|
90
+ object = serializer.object
91
+ if object&.respond_to? association.name
92
+ resource = object.public_send(association.name)
93
+ else
94
+ puts "WARN: Failed to get '#{association.name}' association from resource (#{object})"
95
+ end
96
+
97
+ next unless resource
98
+
99
+ if association.serializer.is_a? ActiveModel::Serializer::CollectionSerializer
100
+ # Not sure if this could happen and perhaps we should fail instead of create an array??
101
+ resource = [resource] unless resource.respond_to? :each
102
+
103
+ embedded[association.name] = resource.map do |resrc|
104
+ # FIXME: How to improve this?
105
+ serialize_embedded_resource(
106
+ resrc,
107
+ serializer: association.serializer.send(:options)[:serializer]
108
+ )
109
+ end
110
+ else
111
+ embedded[association.name] = serialize_embedded_resource(
112
+ resource,
113
+ serializer: association.serializer&.class
114
+ )
115
+ end
116
+ end
117
+ end
118
+
119
+ private
120
+
121
+ def serialize_embedded_resource(resource, serializer: nil)
122
+ serializable_resource = ActiveModelSerializers::SerializableResource.new(
123
+ resource,
124
+ serializer: serializer,
125
+ adapter: AmsHal::Adapter
126
+ )
127
+ serializable_resource.as_json
128
+ end
129
+
130
+ end
131
+ end
@@ -0,0 +1,28 @@
1
+ module AmsHal
2
+ module Curies
3
+
4
+ def self.included(base)
5
+ base.extend ClassMethods
6
+ base._curies = {}
7
+ end
8
+
9
+ module ClassMethods
10
+ attr_accessor :_curies
11
+
12
+ def inherited(subclass)
13
+ super
14
+ subclass._curies = _curies.dup
15
+ end
16
+
17
+ def curie(name, value = nil, &block)
18
+ _curies[name] = block || value
19
+ end
20
+ end
21
+
22
+ def curies
23
+ self.class._curies.dup
24
+ end
25
+
26
+ end
27
+ end
28
+
@@ -0,0 +1,38 @@
1
+ require 'active_model_serializers/serialization_context'
2
+
3
+ module AmsHal
4
+ class Embed
5
+ include ActiveModelSerializers::SerializationContext::UrlHelpers
6
+
7
+ attr_reader :name, :options
8
+
9
+ def initialize(serializer, name, options = {}, &block)
10
+ @name = name
11
+ @options = options
12
+ @block = block
13
+ end
14
+
15
+ def resource_for(serializer)
16
+ @object = serializer.object
17
+ @scope = serializer.scope
18
+
19
+ @self_before_instance_eval = nil
20
+ # Use the return value of the block unless it is nil.
21
+ if @block
22
+ @self_before_instance_eval = eval "self", @block.binding
23
+ @resource = instance_eval(&@block)
24
+ else
25
+ @resource = @object.public_send(name)
26
+ end
27
+ end
28
+
29
+ protected
30
+
31
+ def method_missing(method, *args, &block)
32
+ return super unless @self_before_instance_eval
33
+ @self_before_instance_eval.send method, *args, &block
34
+ end
35
+
36
+ attr_reader :object, :scope
37
+ end
38
+ end
@@ -0,0 +1,28 @@
1
+ module AmsHal
2
+ module Embedded
3
+
4
+ def self.included(base)
5
+ base.extend ClassMethods
6
+ base._embedded = []
7
+ end
8
+
9
+ module ClassMethods
10
+ attr_accessor :_embedded
11
+
12
+ def inherited(subclass)
13
+ super
14
+ subclass._embedded = _embedded.dup
15
+ end
16
+
17
+ def embed(name, options = {}, &block)
18
+ self._embedded << Embed.new(self, name, options, &block)
19
+ end
20
+ end
21
+
22
+ def embedded
23
+ self.class._embedded.dup
24
+ end
25
+
26
+ end
27
+ end
28
+
@@ -0,0 +1,31 @@
1
+ require 'active_model_serializers/serialization_context'
2
+
3
+ module AmsHal
4
+ class Link
5
+ include ActiveModelSerializers::SerializationContext::UrlHelpers
6
+
7
+ attr_reader :value
8
+
9
+ def initialize(serializer, value)
10
+ @object = serializer.object
11
+ @scope = serializer.scope
12
+ @self_before_instance_eval = nil
13
+ # Use the return value of the block unless it is nil.
14
+ if value.respond_to?(:call)
15
+ @self_before_instance_eval = eval "self", value.binding
16
+ @value = instance_eval(&value)
17
+ else
18
+ @value = value
19
+ end
20
+ end
21
+
22
+ protected
23
+
24
+ def method_missing(method, *args, &block)
25
+ return super unless @self_before_instance_eval
26
+ @self_before_instance_eval.send method, *args, &block
27
+ end
28
+
29
+ attr_reader :object, :scope
30
+ end
31
+ end
metadata ADDED
@@ -0,0 +1,94 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ams_hal
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.2
5
+ platform: ruby
6
+ authors:
7
+ - Sammy Henningsson
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-04-10 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: active_model_serializers
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 0.10.5
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 0.10.5
27
+ - !ruby/object:Gem::Dependency
28
+ name: activesupport
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '4.2'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '4.2'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: |
56
+ Provides an adapter to use with ActiveModel::Serializer
57
+ so that resources can be serializer according to
58
+ HypertextApplicationLanguage.
59
+ email: sammy.henningsson@gmail.com
60
+ executables: []
61
+ extensions: []
62
+ extra_rdoc_files: []
63
+ files:
64
+ - lib/ams_hal.rb
65
+ - lib/ams_hal/adapter.rb
66
+ - lib/ams_hal/curies.rb
67
+ - lib/ams_hal/embed.rb
68
+ - lib/ams_hal/embedded.rb
69
+ - lib/ams_hal/link.rb
70
+ homepage: https://github.com/sammyhenningsson/ams_hal
71
+ licenses:
72
+ - MIT
73
+ metadata: {}
74
+ post_install_message:
75
+ rdoc_options: []
76
+ require_paths:
77
+ - lib
78
+ required_ruby_version: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ required_rubygems_version: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - ">="
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ requirements: []
89
+ rubyforge_project:
90
+ rubygems_version: 2.6.8
91
+ signing_key:
92
+ specification_version: 4
93
+ summary: HAL adapter for active_model_serializers
94
+ test_files: []