simple_ams 0.2.1 → 0.2.6
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
- data/.github/workflows/ruby.yml +28 -0
- data/.rubocop.yml +56 -0
- data/CHANGELOG.md +22 -0
- data/Gemfile +2 -2
- data/README.md +665 -116
- data/Rakefile +3 -3
- data/bin/console +3 -3
- data/lib/simple_ams.rb +34 -33
- data/lib/simple_ams/adapters/ams.rb +26 -32
- data/lib/simple_ams/adapters/jsonapi.rb +47 -64
- data/lib/simple_ams/document.rb +38 -37
- data/lib/simple_ams/document/fields.rb +36 -37
- data/lib/simple_ams/document/forms.rb +7 -9
- data/lib/simple_ams/document/generics.rb +35 -37
- data/lib/simple_ams/document/links.rb +7 -9
- data/lib/simple_ams/document/metas.rb +7 -11
- data/lib/simple_ams/document/primary_id.rb +14 -17
- data/lib/simple_ams/document/relations.rb +99 -109
- data/lib/simple_ams/dsl.rb +73 -71
- data/lib/simple_ams/methy.rb +2 -2
- data/lib/simple_ams/options.rb +267 -265
- data/lib/simple_ams/options/adapter.rb +2 -2
- data/lib/simple_ams/options/concerns/filterable.rb +29 -34
- data/lib/simple_ams/options/concerns/mod.rb +4 -0
- data/lib/simple_ams/options/concerns/name_value_hash.rb +25 -26
- data/lib/simple_ams/options/concerns/tracked_properties.rb +15 -17
- data/lib/simple_ams/options/concerns/value_hash.rb +25 -26
- data/lib/simple_ams/options/fields.rb +1 -1
- data/lib/simple_ams/options/forms.rb +1 -2
- data/lib/simple_ams/options/generics.rb +2 -4
- data/lib/simple_ams/options/includes.rb +1 -1
- data/lib/simple_ams/options/links.rb +1 -1
- data/lib/simple_ams/options/metas.rb +1 -1
- data/lib/simple_ams/options/primary_id.rb +1 -1
- data/lib/simple_ams/options/relations.rb +9 -7
- data/lib/simple_ams/options/type.rb +1 -2
- data/lib/simple_ams/renderer.rb +43 -41
- data/lib/simple_ams/version.rb +1 -1
- data/simple_ams.gemspec +17 -17
- metadata +30 -27
- data/.travis.yml +0 -5
data/lib/simple_ams/document.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require 'simple_ams'
|
2
2
|
|
3
3
|
class SimpleAMS::Document
|
4
4
|
attr_reader :options, :embedded_options, :serializer, :resource
|
@@ -17,12 +17,14 @@ class SimpleAMS::Document
|
|
17
17
|
def fields
|
18
18
|
return @fields if defined?(@fields)
|
19
19
|
return @fields = [] if options.fields.empty?
|
20
|
-
|
20
|
+
|
21
|
+
@fields ||= self.class::Fields.new(options)
|
21
22
|
end
|
22
23
|
|
23
24
|
def relations
|
24
25
|
return @relations if defined?(@relations)
|
25
|
-
|
26
|
+
|
27
|
+
@relations ||= self.class::Relations.new(
|
26
28
|
options, options.relations
|
27
29
|
)
|
28
30
|
end
|
@@ -42,30 +44,36 @@ class SimpleAMS::Document
|
|
42
44
|
def links
|
43
45
|
return @links if defined?(@links)
|
44
46
|
return @links = {} if options.links.empty?
|
45
|
-
|
47
|
+
|
48
|
+
@links ||= self.class::Links.new(options)
|
46
49
|
end
|
47
50
|
|
48
51
|
def metas
|
49
52
|
return @metas if defined?(@metas)
|
50
53
|
return @metas = {} if options.metas.empty?
|
51
|
-
|
54
|
+
|
55
|
+
@metas ||= self.class::Metas.new(options)
|
52
56
|
end
|
53
57
|
|
54
58
|
def forms
|
55
59
|
return @forms if defined?(@forms)
|
56
60
|
return @forms = {} if options.forms.empty?
|
57
|
-
|
61
|
+
|
62
|
+
@forms ||= self.class::Forms.new(options)
|
58
63
|
end
|
59
64
|
|
60
65
|
def generics
|
61
66
|
return @generics if defined?(@generics)
|
62
67
|
return @generics = {} if options.generics.empty?
|
63
|
-
|
68
|
+
|
69
|
+
@generics ||= self.class::Generics.new(options)
|
64
70
|
end
|
65
71
|
|
72
|
+
# rubocop:disable Naming/MemoizedInstanceVariableName
|
66
73
|
def folder?
|
67
|
-
@is_folder ||=
|
74
|
+
@is_folder ||= is_a?(self.class::Folder)
|
68
75
|
end
|
76
|
+
# rubocop:enable Naming/MemoizedInstanceVariableName
|
69
77
|
|
70
78
|
def document?
|
71
79
|
!folder?
|
@@ -91,7 +99,7 @@ class SimpleAMS::Document
|
|
91
99
|
@resource = options.resource
|
92
100
|
end
|
93
101
|
|
94
|
-
def each
|
102
|
+
def each
|
95
103
|
return enum_for(:each) unless block_given?
|
96
104
|
|
97
105
|
members.each do |resource|
|
@@ -101,7 +109,7 @@ class SimpleAMS::Document
|
|
101
109
|
self
|
102
110
|
end
|
103
111
|
|
104
|
-
#do we really need this method ?
|
112
|
+
# do we really need this method ?
|
105
113
|
def documents
|
106
114
|
each.map
|
107
115
|
end
|
@@ -111,35 +119,28 @@ class SimpleAMS::Document
|
|
111
119
|
end
|
112
120
|
|
113
121
|
private
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
})
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
SimpleAMS::Options.new(resource, {
|
129
|
-
injected_options: resource_options.injected_options.merge({
|
130
|
-
serializer: serializer_for(resource)
|
131
|
-
}),
|
132
|
-
allowed_options: serializer_for(resource).options
|
133
|
-
})
|
134
|
-
=end
|
135
|
-
end
|
122
|
+
|
123
|
+
attr_reader :_options
|
124
|
+
|
125
|
+
def options_for(resource)
|
126
|
+
if resource_options.serializer_class.respond_to?(:call)
|
127
|
+
SimpleAMS::Options.new(
|
128
|
+
resource,
|
129
|
+
injected_options: resource_options.injected_options.merge({
|
130
|
+
serializer: serializer_for(resource)
|
131
|
+
}),
|
132
|
+
allowed_options: serializer_for(resource).options
|
133
|
+
)
|
134
|
+
else
|
135
|
+
resource_options.with_resource(resource)
|
136
136
|
end
|
137
|
+
end
|
137
138
|
|
138
|
-
|
139
|
-
|
140
|
-
|
139
|
+
def serializer_for(resource)
|
140
|
+
serializer = resource_options.serializer_class
|
141
|
+
serializer = serializer.call(resource) if serializer.respond_to?(:call)
|
141
142
|
|
142
|
-
|
143
|
-
|
143
|
+
serializer
|
144
|
+
end
|
144
145
|
end
|
145
146
|
end
|
@@ -1,51 +1,50 @@
|
|
1
|
-
require
|
1
|
+
require 'simple_ams'
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
include Enumerable
|
3
|
+
class SimpleAMS::Document::Fields
|
4
|
+
include Enumerable
|
6
5
|
|
7
|
-
|
6
|
+
Field = Struct.new(:key, :value)
|
8
7
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
def [](key)
|
15
|
-
found = members.find{|field| field == key}
|
16
|
-
return nil unless found
|
8
|
+
def initialize(options)
|
9
|
+
@options = options
|
10
|
+
@members = options.fields # [:field1, :field2]
|
11
|
+
end
|
17
12
|
|
18
|
-
|
19
|
-
|
13
|
+
def [](key)
|
14
|
+
found = members.find { |field| field == key }
|
15
|
+
return nil unless found
|
20
16
|
|
21
|
-
|
22
|
-
|
23
|
-
return enum_for(:each) unless block_given?
|
17
|
+
value_of(found)
|
18
|
+
end
|
24
19
|
|
25
|
-
|
26
|
-
|
27
|
-
|
20
|
+
# TODO: Can we make this faster?
|
21
|
+
def each
|
22
|
+
return enum_for(:each) unless block_given?
|
28
23
|
|
29
|
-
|
24
|
+
members.each do |key|
|
25
|
+
yield value_of(key)
|
30
26
|
end
|
31
27
|
|
32
|
-
|
33
|
-
|
34
|
-
end
|
28
|
+
self
|
29
|
+
end
|
35
30
|
|
36
|
-
|
37
|
-
|
38
|
-
|
31
|
+
def any?
|
32
|
+
members.any?
|
33
|
+
end
|
34
|
+
|
35
|
+
def empty?
|
36
|
+
members.empty?
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
39
40
|
|
40
|
-
|
41
|
-
attr_reader :members, :options
|
41
|
+
attr_reader :members, :options
|
42
42
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
end
|
43
|
+
def value_of(key)
|
44
|
+
if options.serializer.respond_to?(key)
|
45
|
+
Field.new(key, options.serializer.send(key))
|
46
|
+
else
|
47
|
+
Field.new(key, options.resource.send(key))
|
48
|
+
end
|
50
49
|
end
|
51
50
|
end
|
@@ -1,13 +1,11 @@
|
|
1
|
-
require
|
1
|
+
require 'simple_ams'
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
end
|
3
|
+
class SimpleAMS::Document::Forms < SimpleAMS::Document::Generics
|
4
|
+
def initialize(options)
|
5
|
+
@options = options
|
6
|
+
@members = options.forms
|
7
|
+
end
|
9
8
|
|
10
|
-
|
11
|
-
end
|
9
|
+
class Form < SimpleAMS::Document::Generics::Generic
|
12
10
|
end
|
13
11
|
end
|
@@ -1,51 +1,49 @@
|
|
1
|
-
require
|
1
|
+
require 'simple_ams'
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
include Enumerable
|
3
|
+
class SimpleAMS::Document::Generics
|
4
|
+
include Enumerable
|
6
5
|
|
7
|
-
|
6
|
+
Generic = Struct.new(:name, :value, :options)
|
8
7
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
def [](key)
|
15
|
-
found = members.find{|generic| generic.name == key}
|
16
|
-
return nil unless found
|
8
|
+
def initialize(options)
|
9
|
+
@options = options
|
10
|
+
@members = options.generics
|
11
|
+
end
|
17
12
|
|
18
|
-
|
19
|
-
|
13
|
+
def [](key)
|
14
|
+
found = members.find { |generic| generic.name == key }
|
15
|
+
return nil unless found
|
20
16
|
|
21
|
-
|
22
|
-
|
17
|
+
with_decorator(found)
|
18
|
+
end
|
23
19
|
|
24
|
-
|
25
|
-
|
26
|
-
}
|
20
|
+
def each
|
21
|
+
return enum_for(:each) unless block_given?
|
27
22
|
|
28
|
-
|
23
|
+
members.each do |member|
|
24
|
+
yield with_decorator(member)
|
29
25
|
end
|
30
26
|
|
31
|
-
|
32
|
-
|
33
|
-
end
|
27
|
+
self
|
28
|
+
end
|
34
29
|
|
35
|
-
|
36
|
-
|
37
|
-
|
30
|
+
def any?
|
31
|
+
members.any?
|
32
|
+
end
|
33
|
+
|
34
|
+
def empty?
|
35
|
+
members.empty?
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
38
39
|
|
39
|
-
|
40
|
-
attr_reader :members, :options
|
40
|
+
attr_reader :members, :options
|
41
41
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
end
|
42
|
+
def with_decorator(generic)
|
43
|
+
Generic.new(
|
44
|
+
generic.name,
|
45
|
+
generic.respond_to?(:call) ? generic.value.call : generic.value,
|
46
|
+
generic.options
|
47
|
+
)
|
49
48
|
end
|
50
49
|
end
|
51
|
-
|
@@ -1,13 +1,11 @@
|
|
1
|
-
require
|
1
|
+
require 'simple_ams'
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
end
|
3
|
+
class SimpleAMS::Document::Links < SimpleAMS::Document::Generics
|
4
|
+
def initialize(options)
|
5
|
+
@options = options
|
6
|
+
@members = options.links
|
7
|
+
end
|
9
8
|
|
10
|
-
|
11
|
-
end
|
9
|
+
class Generic < SimpleAMS::Document::Generics::Generic
|
12
10
|
end
|
13
11
|
end
|
@@ -1,15 +1,11 @@
|
|
1
|
-
require
|
1
|
+
require 'simple_ams'
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
end
|
3
|
+
class SimpleAMS::Document::Metas < SimpleAMS::Document::Generics
|
4
|
+
def initialize(options)
|
5
|
+
@options = options
|
6
|
+
@members = options.metas
|
7
|
+
end
|
9
8
|
|
10
|
-
|
11
|
-
end
|
9
|
+
class Meta < SimpleAMS::Document::Generics::Generic
|
12
10
|
end
|
13
11
|
end
|
14
|
-
|
15
|
-
|
@@ -1,23 +1,20 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
attr_reader :name
|
1
|
+
class SimpleAMS::Document::PrimaryId
|
2
|
+
attr_reader :name
|
4
3
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
4
|
+
def initialize(options)
|
5
|
+
@options = options
|
6
|
+
@name = options.primary_id.name
|
7
|
+
end
|
9
8
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
end
|
9
|
+
def value
|
10
|
+
if @options.serializer.respond_to?(name)
|
11
|
+
@options.serializer.send(name)
|
12
|
+
else
|
13
|
+
@options.resource.send(name)
|
16
14
|
end
|
15
|
+
end
|
17
16
|
|
18
|
-
|
19
|
-
|
20
|
-
end
|
17
|
+
def options
|
18
|
+
@options.primary_id.options
|
21
19
|
end
|
22
20
|
end
|
23
|
-
|
@@ -1,125 +1,115 @@
|
|
1
|
-
require
|
2
|
-
|
3
|
-
#TODO: Add memoization for the relations object (iteration + access)
|
4
|
-
module SimpleAMS
|
5
|
-
class Document::Relations
|
6
|
-
include Enumerable
|
7
|
-
|
8
|
-
def initialize(options, relations)
|
9
|
-
@options = options
|
10
|
-
@relations = relations
|
11
|
-
@serializer = options.serializer
|
12
|
-
@resource = options.resource
|
13
|
-
end
|
1
|
+
require 'simple_ams'
|
14
2
|
|
15
|
-
|
16
|
-
|
17
|
-
|
3
|
+
# TODO: Add memoization for the relations object (iteration + access)
|
4
|
+
class SimpleAMS::Document::Relations
|
5
|
+
include Enumerable
|
18
6
|
|
19
|
-
|
20
|
-
|
7
|
+
def initialize(options, relations)
|
8
|
+
@options = options
|
9
|
+
@relations = relations
|
10
|
+
@serializer = options.serializer
|
11
|
+
@resource = options.resource
|
12
|
+
end
|
21
13
|
|
22
|
-
|
23
|
-
|
14
|
+
def [](key)
|
15
|
+
found = relations.find { |relation| relation.name == key }
|
16
|
+
return nil unless found
|
24
17
|
|
25
|
-
|
26
|
-
|
27
|
-
}
|
18
|
+
relation_for(found)
|
19
|
+
end
|
28
20
|
|
29
|
-
|
30
|
-
|
21
|
+
def each
|
22
|
+
return enum_for(:each) unless block_given?
|
31
23
|
|
32
|
-
|
33
|
-
|
24
|
+
relations.each do |relation|
|
25
|
+
yield relation_for(relation)
|
34
26
|
end
|
35
27
|
|
36
|
-
|
37
|
-
|
28
|
+
self
|
29
|
+
end
|
30
|
+
|
31
|
+
def empty?
|
32
|
+
relations.length.zero?
|
33
|
+
end
|
34
|
+
|
35
|
+
def available
|
36
|
+
return @available ||= [] if relations.available.empty?
|
37
|
+
|
38
|
+
@available ||= self.class.new(options, relations.available)
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
attr_reader :options, :relations, :serializer, :resource
|
44
|
+
|
45
|
+
def relation_for(relation)
|
46
|
+
relation_value = relation_value_for(relation.name)
|
47
|
+
|
48
|
+
renderer_klass_for(relation, relation_value).new(
|
49
|
+
SimpleAMS::Options.new(
|
50
|
+
relation_value, **relation_options_for(relation, relation_value)
|
51
|
+
),
|
52
|
+
SimpleAMS::Options.new(
|
53
|
+
resource,
|
54
|
+
injected_options: {
|
55
|
+
serializer: relation.embedded
|
56
|
+
},
|
57
|
+
allowed_options: relation.embedded.options
|
58
|
+
)
|
59
|
+
)
|
60
|
+
end
|
38
61
|
|
39
|
-
|
62
|
+
# TODO: rename that to relation and existing relation to relationship
|
63
|
+
def relation_value_for(name)
|
64
|
+
if serializer.respond_to?(name)
|
65
|
+
serializer.send(name)
|
66
|
+
else
|
67
|
+
resource.send(name)
|
40
68
|
end
|
69
|
+
end
|
41
70
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
injected_options: {
|
55
|
-
serializer: relation.embedded
|
56
|
-
},
|
57
|
-
allowed_options: relation.embedded.options
|
58
|
-
}
|
59
|
-
)
|
71
|
+
# 3 options are merged:
|
72
|
+
# *user injected when instantiating the SimpleAMS class
|
73
|
+
# *relation options injected from parent serializer
|
74
|
+
# *serializer class options
|
75
|
+
# rubocop:disable Lint/UnderscorePrefixedVariableName
|
76
|
+
def relation_options_for(relation, relation_value)
|
77
|
+
_relation_options = {
|
78
|
+
injected_options: (relation.options || {}).merge(
|
79
|
+
options.relation_options_for(
|
80
|
+
relation.name
|
81
|
+
).reject { |_k, v| v.nil? }.merge(
|
82
|
+
expose: options.expose
|
60
83
|
)
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
def relation_value_for(name)
|
65
|
-
if serializer.respond_to?(name)
|
66
|
-
serializer.send(name)
|
67
|
-
else
|
68
|
-
resource.send(name)
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
#4 options are merged:
|
73
|
-
# *user injected when instantiating the SimpleAMS class
|
74
|
-
# *relation options injected from parent serializer
|
75
|
-
# *serializer class options
|
76
|
-
def relation_options_for(relation, relation_value)
|
77
|
-
_relation_options = {
|
78
|
-
injected_options: (relation.options || {}).merge(
|
79
|
-
options.relation_options_for(
|
80
|
-
relation.name
|
81
|
-
).select{|k, v| !v.nil?}.merge(
|
82
|
-
expose: options.expose
|
83
|
-
)
|
84
|
-
).merge(
|
85
|
-
_internal: {
|
86
|
-
module: serializer.class.to_s.rpartition('::')[0]
|
87
|
-
}
|
88
|
-
)
|
84
|
+
).merge(
|
85
|
+
_internal: {
|
86
|
+
module: serializer.class.to_s.rpartition('::')[0]
|
89
87
|
}
|
88
|
+
)
|
89
|
+
}
|
90
|
+
|
91
|
+
if relation.collection? || relation_value.respond_to?(:each)
|
92
|
+
# TODO: deep merge, can we automate this somehow ?
|
93
|
+
_relation_options[:injected_options][:collection] = {
|
94
|
+
name: relation.name
|
95
|
+
}.merge(_relation_options[:injected_options][:collection] || {})
|
96
|
+
else
|
97
|
+
_relation_options[:injected_options][:name] = relation.name
|
98
|
+
end
|
90
99
|
|
91
|
-
|
92
|
-
#TODO: deep merge, can we automate this somehow ?
|
93
|
-
_relation_options[:injected_options][:collection] = {
|
94
|
-
name: relation.name
|
95
|
-
}.merge(_relation_options[:injected_options][:collection] || {})
|
96
|
-
else
|
97
|
-
_relation_options[:injected_options][:name] = relation.name
|
98
|
-
end
|
99
|
-
|
100
|
-
return _relation_options
|
101
|
-
end
|
102
|
-
=begin
|
103
|
-
def embedded_relation_options_for(relation)
|
104
|
-
_relation_options = relation_options_for(relation).merge(
|
105
|
-
allowed_options: relation.embedded.options
|
106
|
-
)
|
107
|
-
_relation_options[:injected_options][:serializer] = relation.embedded
|
108
|
-
|
109
|
-
return _relation_options
|
110
|
-
end
|
111
|
-
=end
|
112
|
-
|
113
|
-
def renderer_klass_for(relation, relation_value)
|
114
|
-
return SimpleAMS::Document::Folder if relation.collection?
|
115
|
-
return SimpleAMS::Document::Folder if relation_value.respond_to?(:each)
|
116
|
-
return SimpleAMS::Document
|
117
|
-
end
|
118
|
-
|
119
|
-
=begin TODO: Add that as public method, should help performance in edge cases
|
120
|
-
def relationship_info_for(name)
|
121
|
-
relations.find{|i| i.name == name}
|
122
|
-
end
|
123
|
-
=end
|
100
|
+
_relation_options
|
124
101
|
end
|
102
|
+
# rubocop:enable Lint/UnderscorePrefixedVariableName
|
103
|
+
|
104
|
+
def renderer_klass_for(relation, relation_value)
|
105
|
+
return SimpleAMS::Document::Folder if relation.collection?
|
106
|
+
return SimpleAMS::Document::Folder if relation_value.respond_to?(:each)
|
107
|
+
|
108
|
+
SimpleAMS::Document
|
109
|
+
end
|
110
|
+
|
111
|
+
# TODO: Add that as public method, should help performance in edge cases
|
112
|
+
# def relationship_info_for(name)
|
113
|
+
# relations.find{|i| i.name == name}
|
114
|
+
# end
|
125
115
|
end
|