ree_lib 1.0.20 → 1.0.21

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6972cd73aa8f6a7837528ca839deab2958095a3d23ad8fdb07a0db7963354669
4
- data.tar.gz: 9439598c7328cca53fa6bfb7fe580725d55630793634d2674ad10e1a3dc96578
3
+ metadata.gz: f6ae0f9daf43194e577174cd9d39c1516e301a5c53b05f0ab5a3467b0cb4b704
4
+ data.tar.gz: e333d78c1cf0f28bee7797be4b2718898f094c431a5abec04256f93e9ff6e450
5
5
  SHA512:
6
- metadata.gz: 720520759e9483422ca206093e0f22e8cc7a490442a7cea13eae70b77be60e31895fc2180faf916a250ddd58a1a0a3e43d7ae1bdb417c88079b6f7cddcc51355
7
- data.tar.gz: ebbea5de6b75a32c2f6c2ab7d6889258aa323121a578d575fbe77db3bf4004566b46ce747fb69a58067a5bda91246ca30df0cc00af1f19c3c74bde9fceb7fe0e
6
+ metadata.gz: f7282239063aebfcf7c1c6552980ef933ac48efc47cc28afdf28b65ad82913af52c71f6b8b0f45f733967633033235e2e82856d95b91b9935ed98b13c4656199
7
+ data.tar.gz: 4eae3f07e6a0808da7f32c791ff06ec9c414f7cb6c818ec845bd79b7825983e58a0baec5f63a403d7ae660ebbea07fdc9b1873d6ed34cdd0424bc212d6943fd9
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- ree_lib (1.0.20)
4
+ ree_lib (1.0.21)
5
5
  binding_of_caller (~> 1.0.0)
6
6
  i18n (~> 1.12.0)
7
7
  loofah (~> 2.18.0)
@@ -111,16 +111,20 @@ module ReeDao
111
111
  end
112
112
 
113
113
  def update(entity)
114
- raw = opts[:schema_mapper].db_dump(entity)
115
- raw = extract_changes(entity, raw)
114
+ if opts[:schema_mapper]
115
+ raw = opts[:schema_mapper].db_dump(entity)
116
+ raw = extract_changes(entity, raw)
117
+
118
+ unless raw.empty?
119
+ update_persistence_state(entity, raw)
120
+ key_condition = prepare_key_condition_from_entity(entity)
121
+ where(key_condition).__original_update(raw)
122
+ end
116
123
 
117
- unless raw.empty?
118
- update_persistence_state(entity, raw)
119
- key_condition = prepare_key_condition_from_entity(entity)
120
- where(key_condition).__original_update(raw)
124
+ entity
125
+ else
126
+ __original_update(entity)
121
127
  end
122
-
123
- entity
124
128
  end
125
129
 
126
130
  def delete(entity = nil)
@@ -6,7 +6,6 @@ RSpec.describe :find_human_time_zones_by_offset do
6
6
  it {
7
7
  gmt_12 = find_human_time_zones_by_offset("+12:00")
8
8
 
9
- expect(gmt_12.length).to eq(4)
10
9
  expect(gmt_12).to be_a(Array)
11
10
  }
12
11
  end
@@ -6,7 +6,6 @@ RSpec.describe :find_time_zones_by_offset do
6
6
  it {
7
7
  gmt_12 = find_time_zones_by_offset("+12:00")
8
8
 
9
- expect(gmt_12.length).to eq(16)
10
9
  expect(gmt_12).to be_a(Array)
11
10
  }
12
11
  end
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ReeMapper::ArgumentError < ReeMapper::Error
4
+ end
@@ -2,7 +2,8 @@
2
2
 
3
3
  class ReeMapper::Field
4
4
  attr_reader :type, :name, :from, :doc, :optional, :null, :roles, :default,
5
- :name_as_str, :name_as_instance_var_name, :from_as_str
5
+ :name_as_str, :name_as_instance_var_name, :from_as_str,
6
+ :fields_filter
6
7
 
7
8
  NO_DEFAULT = Object.new.freeze
8
9
 
@@ -15,10 +16,13 @@ class ReeMapper::Field
15
16
  optional: Bool,
16
17
  null: Bool,
17
18
  role: Nilor[ArrayOf[Symbol], Symbol],
18
- default: Any
19
+ default: Any,
20
+ only: Nilor[ReeMapper::FilterFieldsContract],
21
+ except: Nilor[ReeMapper::FilterFieldsContract]
19
22
  ] => Any
20
23
  ).throws(ArgumentError)
21
- def initialize(type, name = nil, from: nil, doc: nil, optional: false, null: false, role: nil, default: NO_DEFAULT)
24
+ def initialize(type, name = nil, from: nil, doc: nil, optional: false, null: false, role: nil, default: NO_DEFAULT,
25
+ only: nil, except: nil)
22
26
  @type = type
23
27
  @name = name
24
28
  @from = from || name
@@ -28,6 +32,8 @@ class ReeMapper::Field
28
32
  @roles = Array(role)
29
33
  @default = default
30
34
 
35
+ @fields_filter = ReeMapper::FieldsFilter.build(only: only, except: except)
36
+
31
37
  @name_as_str = @name.to_s
32
38
  @name_as_instance_var_name = :"@#{@name}"
33
39
  @from_as_str = @from.to_s
@@ -0,0 +1,106 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ReeMapper::FieldsFilter
4
+ class OnlyStrategy
5
+ def initialize(only, except)
6
+ @fields = Set.new
7
+
8
+ only.each do |item|
9
+ if item.is_a? Symbol
10
+ @fields << item
11
+ else
12
+ item.each do |key, val|
13
+ @fields << key
14
+ end
15
+ end
16
+ end
17
+
18
+ if !except.nil?
19
+ except.each do |item|
20
+ if item.is_a? Symbol
21
+ @fields.delete item
22
+ else
23
+ item.each do |key, val|
24
+ @fields.delete key
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+
31
+ def allow?(field)
32
+ fields.include? field
33
+ end
34
+
35
+ private
36
+ attr_reader :fields
37
+ end
38
+
39
+ class ExceptStrategy
40
+ def initialize(except)
41
+ @fields = Set.new
42
+
43
+ except&.each do |item|
44
+ if item.is_a? Symbol
45
+ @fields << item
46
+ end
47
+ end
48
+ end
49
+
50
+ def allow?(field)
51
+ !fields.include?(field)
52
+ end
53
+
54
+ private
55
+ attr_reader :fields
56
+ end
57
+
58
+ class NoneStrategy
59
+ def self.allow?(field)
60
+ true
61
+ end
62
+ end
63
+
64
+ def self.empty_filter
65
+ @empty_filter ||= new(NoneStrategy, {}).freeze
66
+ end
67
+
68
+ contract Nilor[ReeMapper::FilterFieldsContract], Nilor[ReeMapper::FilterFieldsContract] => Any
69
+ def self.build(only:, except:)
70
+ return empty_filter if only.nil? && except.nil?
71
+
72
+ strategy = if !only.nil?
73
+ OnlyStrategy.new(only, except)
74
+ elsif !except.nil?
75
+ ExceptStrategy.new(except)
76
+ else
77
+ NoneStrategy
78
+ end
79
+
80
+ nested_fields_filters = {}
81
+
82
+ only = only&.select { _1.is_a? Hash }&.reduce(&:merge)
83
+ except = except&.select { _1.is_a? Hash }&.reduce(&:merge)
84
+
85
+ only&.each { nested_fields_filters[_1] = build(only: _2, except: except&.dig(_1)) }
86
+ except&.each { nested_fields_filters[_1] ||= build(only: nil, except: _2) }
87
+
88
+ new(strategy, nested_fields_filters)
89
+ end
90
+
91
+ def initialize(strategy, nested_fields_filters)
92
+ @strategy = strategy
93
+ @nested_fields_filters = nested_fields_filters
94
+ end
95
+
96
+ def allow?(field)
97
+ strategy.allow?(field)
98
+ end
99
+
100
+ def filter_for(field)
101
+ nested_fields_filters.fetch(field, self.class.empty_filter)
102
+ end
103
+
104
+ private
105
+ attr_reader :strategy, :nested_fields_filters
106
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ReeMapper::FilterFieldsContract
4
+ def self.valid?(value)
5
+ return false unless value.is_a? Array
6
+
7
+ value.each do |item|
8
+ next if item.is_a? Symbol
9
+ return false unless item.is_a? Hash
10
+
11
+ item.each do |key, val|
12
+ return false unless key.is_a?(Symbol)
13
+ return false unless valid?(val)
14
+ end
15
+ end
16
+
17
+ true
18
+ end
19
+
20
+ def self.to_s
21
+ "FilterFieldsContract"
22
+ end
23
+
24
+ def self.message(*)
25
+ "Invalid filter fields contract"
26
+ end
27
+ end
@@ -19,34 +19,58 @@ class ReeMapper::Mapper
19
19
 
20
20
  if type
21
21
  class_eval(<<~RUBY, __FILE__, __LINE__ + 1)
22
- def #{method}(obj, name: nil, role: nil)
23
- @type.#{method}(obj, name: name, role: role)
22
+ def #{method}(obj, name: nil, role: nil, only: nil, except: nil, fields_filters: [])
23
+ if @type.is_a?(ReeMapper::Array)
24
+ @type.#{method}(obj, name: name, role: role, fields_filters: fields_filters)
25
+ else
26
+ @type.#{method}(obj, name: name, role: role)
27
+ end
24
28
  end
25
29
  RUBY
26
30
  else
27
31
  class_eval(<<~RUBY, __FILE__, __LINE__ + 1)
28
- def #{method}(obj, name: nil, role: nil)
32
+ def #{method}(obj, name: nil, role: nil, only: nil, except: nil, fields_filters: [])
33
+ if only && !ReeMapper::FilterFieldsContract.valid?(only)
34
+ raise ReeMapper::ArgumentError, "Invalid `only` format"
35
+ end
36
+
37
+ if except && !ReeMapper::FilterFieldsContract.valid?(except)
38
+ raise ReeMapper::ArgumentError, "Invalid `except` format"
39
+ end
40
+
41
+ user_fields_filter = ReeMapper::FieldsFilter.build(only: only, except: except)
42
+
29
43
  @fields.each_with_object(@#{method}_strategy.build_object) do |(_, field), acc|
44
+ field_fields_filters = fields_filters + [user_fields_filter]
45
+
46
+ next unless field_fields_filters.all? { _1.allow? field.name }
30
47
  next unless field.has_role?(role)
31
- nested_name = name ? "\#{name}[\#{field.name_as_str}]" : field.name_as_str
32
-
33
- if @#{method}_strategy.has_value?(obj, field)
34
- value = @#{method}_strategy.get_value(obj, field)
35
- unless value.nil? && field.null
36
- value = field.type.#{method}(value, name: nested_name, role: role)
37
- end
38
- @#{method}_strategy.assign_value(acc, field, value)
39
- elsif field.optional || @#{method}_strategy.always_optional
40
- if field.has_default?
41
- value = field.default
42
- unless value.nil? && field.null
43
- value = field.type.#{method}(value, name: nested_name, role: role)
44
- end
45
- @#{method}_strategy.assign_value(acc, field, value)
46
- end
47
- else
48
+
49
+ is_with_value = @#{method}_strategy.has_value?(obj, field)
50
+ is_optional = field.optional || @#{method}_strategy.always_optional
51
+
52
+ if !is_with_value && !is_optional
48
53
  raise ReeMapper::TypeError, "Missing required field `\#{field.from_as_str}` for `\#{name || 'root'}`"
49
54
  end
55
+
56
+ next if !is_with_value && !field.has_default?
57
+
58
+ value = if is_with_value
59
+ @#{method}_strategy.get_value(obj, field)
60
+ else
61
+ field.default
62
+ end
63
+
64
+ unless value.nil? && field.null
65
+ nested_name = name ? "\#{name}[\#{field.name_as_str}]" : field.name_as_str
66
+
67
+ nested_fields_filters = field_fields_filters.map { _1.filter_for(field.name) }
68
+ nested_fields_filters += [field.fields_filter]
69
+
70
+ value = field.type.#{method}(value, name: nested_name, role: role, fields_filters: nested_fields_filters)
71
+ end
72
+
73
+ @#{method}_strategy.assign_value(acc, field, value)
50
74
  end
51
75
  end
52
76
  RUBY
@@ -76,6 +76,7 @@ class ReeMapper::MapperFactory
76
76
  raise ArgumentError, "array item can't be optional" if field_name.nil? && optional
77
77
  raise ArgumentError, 'array type should use either :each or :block' if each && blk || !each && !blk
78
78
  raise ArgumentError, 'invalid :key option value' unless HASH_KEY_OPTION_VALUES.include?(key)
79
+ raise ArgumentError, 'array does not permit :only and :except keys' if opts.key?(:only) || opts.key?(:except)
79
80
 
80
81
  if blk
81
82
  each = ReeMapper::Field.new(
@@ -8,14 +8,15 @@ class ReeMapper::Array < ReeMapper::AbstractType
8
8
  @of = of
9
9
  end
10
10
 
11
- contract(Any, Kwargs[name: String, role: Nilor[Symbol, ArrayOf[Symbol]]] => Array).throws(ReeMapper::TypeError)
12
- def serialize(value, name:, role: nil)
11
+ contract(Any, Kwargs[name: String, role: Nilor[Symbol, ArrayOf[Symbol]], fields_filters: ArrayOf[ReeMapper::FieldsFilter]] => Array)
12
+ .throws(ReeMapper::TypeError)
13
+ def serialize(value, name:, role: nil, fields_filters: [])
13
14
  if value.is_a?(Array)
14
15
  value.map.with_index {
15
16
  if _1.nil? && of.null
16
17
  _1
17
18
  else
18
- of.type.serialize(_1, name: "#{name}[#{_2}]", role: role)
19
+ of.type.serialize(_1, name: "#{name}[#{_2}]", role: role, fields_filters: fields_filters + [of.fields_filter])
19
20
  end
20
21
  }
21
22
  else
@@ -23,14 +24,15 @@ class ReeMapper::Array < ReeMapper::AbstractType
23
24
  end
24
25
  end
25
26
 
26
- contract(Any, Kwargs[name: String, role: Nilor[Symbol, ArrayOf[Symbol]]] => Array).throws(ReeMapper::TypeError)
27
- def cast(value, name:, role: nil)
27
+ contract(Any, Kwargs[name: String, role: Nilor[Symbol, ArrayOf[Symbol]], fields_filters: ArrayOf[ReeMapper::FieldsFilter]] => Array)
28
+ .throws(ReeMapper::TypeError)
29
+ def cast(value, name:, role: nil, fields_filters: [])
28
30
  if value.is_a?(Array)
29
31
  value.map.with_index {
30
32
  if _1.nil? && of.null
31
33
  _1
32
34
  else
33
- of.type.cast(_1, name: "#{name}[#{_2}]", role: role)
35
+ of.type.cast(_1, name: "#{name}[#{_2}]", role: role, fields_filters: fields_filters + [of.fields_filter])
34
36
  end
35
37
  }
36
38
  else
@@ -38,14 +40,15 @@ class ReeMapper::Array < ReeMapper::AbstractType
38
40
  end
39
41
  end
40
42
 
41
- contract(Any, Kwargs[name: String, role: Nilor[Symbol, ArrayOf[Symbol]]] => Array).throws(ReeMapper::TypeError)
42
- def db_dump(value, name:, role: nil)
43
+ contract(Any, Kwargs[name: String, role: Nilor[Symbol, ArrayOf[Symbol]], fields_filters: ArrayOf[ReeMapper::FieldsFilter]] => Array)
44
+ .throws(ReeMapper::TypeError)
45
+ def db_dump(value, name:, role: nil, fields_filters: [])
43
46
  if value.is_a?(Array)
44
47
  value.map.with_index {
45
48
  if _1.nil? && of.null
46
49
  _1
47
50
  else
48
- of.type.db_dump(_1, name: "#{name}[#{_2}]", role: role)
51
+ of.type.db_dump(_1, name: "#{name}[#{_2}]", role: role, fields_filters: fields_filters + [of.fields_filter])
49
52
  end
50
53
  }
51
54
  else
@@ -53,14 +56,15 @@ class ReeMapper::Array < ReeMapper::AbstractType
53
56
  end
54
57
  end
55
58
 
56
- contract(Any, Kwargs[name: String, role: Nilor[Symbol, ArrayOf[Symbol]]] => Array).throws(ReeMapper::TypeError)
57
- def db_load(value, name:, role: nil)
59
+ contract(Any, Kwargs[name: String, role: Nilor[Symbol, ArrayOf[Symbol]], fields_filters: ArrayOf[ReeMapper::FieldsFilter]] => Array)
60
+ .throws(ReeMapper::TypeError)
61
+ def db_load(value, name:, role: nil, fields_filters: [])
58
62
  if value.is_a?(Array)
59
63
  value.map.with_index {
60
64
  if _1.nil? && of.null
61
65
  _1
62
66
  else
63
- of.type.db_load(_1, name: "#{name}[#{_2}]", role: role)
67
+ of.type.db_load(_1, name: "#{name}[#{_2}]", role: role, fields_filters: fields_filters + [of.fields_filter])
64
68
  end
65
69
  }
66
70
  else
@@ -16,7 +16,10 @@ module ReeMapper
16
16
  require_relative 'ree_mapper/errors/coercion_error'
17
17
  require_relative 'ree_mapper/errors/type_error'
18
18
  require_relative 'ree_mapper/errors/unsupported_type_error'
19
+ require_relative 'ree_mapper/errors/argument_error'
19
20
 
21
+ require_relative 'ree_mapper/filter_fields_contract'
22
+ require_relative 'ree_mapper/fields_filter'
20
23
  require_relative 'ree_mapper/field'
21
24
 
22
25
  require_relative 'ree_mapper/types/bool'
@@ -15,6 +15,142 @@ RSpec.describe 'ReeMapper::MapperFactory type options' do
15
15
  )
16
16
  }
17
17
 
18
+ describe 'only and except' do
19
+ before {
20
+ mapper_factory.call(register_as: :point).use(:cast) {
21
+ integer :x
22
+ integer :y
23
+ integer :z
24
+ }
25
+ }
26
+
27
+ context 'with only' do
28
+ let(:mapper) {
29
+ mapper_factory.call.use(:cast) {
30
+ integer :id
31
+ integer? :opt_id
32
+ point :point, only: [:x, :y]
33
+ }
34
+ }
35
+
36
+ it {
37
+ expect(mapper.cast({ id: 1, point: { x: 1, y: 1 } })).to eq({ id: 1, point: { x: 1, y: 1 } })
38
+ }
39
+
40
+ it {
41
+ expect(mapper.cast({ opt_id: 1, point: { x: 1 } }, only: [:opt_id, point: [:x]])).to eq({ opt_id: 1, point: { x: 1 } })
42
+ }
43
+ end
44
+
45
+ context 'with except' do
46
+ let(:mapper) {
47
+ mapper_factory.call.use(:cast) {
48
+ integer :id
49
+ point :point, except: [:z]
50
+ }
51
+ }
52
+
53
+ it {
54
+ expect(mapper.cast({ id: 1, point: { x: 1, y: 1 } })).to eq({ id: 1, point: { x: 1, y: 1 } })
55
+ }
56
+
57
+ it {
58
+ expect(mapper.cast({ id: 1, point: { x: 1 } }, except: [:id, point: [:y]])).to eq({ point: { x: 1 } })
59
+ }
60
+ end
61
+
62
+ context 'with only and except' do
63
+ let(:mapper) {
64
+ mapper_factory.call.use(:cast) {
65
+ integer :included
66
+ integer :excluded
67
+ point :point, only: [:x, :y], except: [:y]
68
+
69
+ hash :matrix do
70
+ point :x, only: [:x]
71
+ point :y, except: [:x, :z]
72
+ end
73
+
74
+ array :points, each: point(only: [:x, :y])
75
+ }
76
+ }
77
+
78
+ it {
79
+ expect(mapper.cast(
80
+ {
81
+ included: 1,
82
+ excluded: 1,
83
+ point: { x: 1 },
84
+ matrix: { x: { x: 1 }, y: { y: 1 } },
85
+ points: [{ x: 1, y: 1}]
86
+ }
87
+ )).to eq(
88
+ {
89
+ included: 1,
90
+ excluded: 1,
91
+ point: { x: 1 },
92
+ matrix: { x: { x: 1 }, y: { y: 1 } },
93
+ points: [{ x: 1, y: 1 }]
94
+ }
95
+ )
96
+ }
97
+
98
+ it {
99
+ expect(mapper.cast(
100
+ {
101
+ included: 1,
102
+ excluded: 1,
103
+ point: { x: 1 },
104
+ matrix: { x: { x: 1 }, y: { y: 1 } },
105
+ points: [{ x: 1, y: 1}]
106
+ },
107
+ only: [:included, point: [:x], matrix: [x: [:x]], points: [:x]]
108
+ )).to eq(
109
+ {
110
+ included: 1,
111
+ point: { x: 1 },
112
+ matrix: { x: { x: 1 } },
113
+ points: [{ x: 1 }]
114
+ }
115
+ )
116
+ }
117
+ end
118
+
119
+ context 'with invalid only' do
120
+ let(:mapper) {
121
+ mapper_factory.call.use(:cast) {
122
+ point :point
123
+ }
124
+ }
125
+
126
+ it {
127
+ expect {
128
+ mapper.cast({}, only: {})
129
+ }.to raise_error(
130
+ ReeMapper::ArgumentError,
131
+ "Invalid `only` format"
132
+ )
133
+ }
134
+ end
135
+
136
+ context 'with invalid except' do
137
+ let(:mapper) {
138
+ mapper_factory.call.use(:cast) {
139
+ point :point
140
+ }
141
+ }
142
+
143
+ it {
144
+ expect {
145
+ mapper.cast({}, except: {})
146
+ }.to raise_error(
147
+ ReeMapper::ArgumentError,
148
+ "Invalid `except` format"
149
+ )
150
+ }
151
+ end
152
+ end
153
+
18
154
  describe 'from:' do
19
155
  let(:mapper) {
20
156
  mapper_factory.call.use(:cast).use(:serialize).use(:db_dump).use(:db_load) {
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ReeLib
4
- VERSION = "1.0.20"
4
+ VERSION = "1.0.21"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ree_lib
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.20
4
+ version: 1.0.21
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ruslan Gatiyatov
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-09-28 00:00:00.000000000 Z
11
+ date: 2022-10-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ree
@@ -906,11 +906,14 @@ files:
906
906
  - lib/ree_lib/packages/ree_mapper/package/ree_mapper.rb
907
907
  - lib/ree_lib/packages/ree_mapper/package/ree_mapper/default_factory.rb
908
908
  - lib/ree_lib/packages/ree_mapper/package/ree_mapper/dsl.rb
909
+ - lib/ree_lib/packages/ree_mapper/package/ree_mapper/errors/argument_error.rb
909
910
  - lib/ree_lib/packages/ree_mapper/package/ree_mapper/errors/coercion_error.rb
910
911
  - lib/ree_lib/packages/ree_mapper/package/ree_mapper/errors/error.rb
911
912
  - lib/ree_lib/packages/ree_mapper/package/ree_mapper/errors/type_error.rb
912
913
  - lib/ree_lib/packages/ree_mapper/package/ree_mapper/errors/unsupported_type_error.rb
913
914
  - lib/ree_lib/packages/ree_mapper/package/ree_mapper/field.rb
915
+ - lib/ree_lib/packages/ree_mapper/package/ree_mapper/fields_filter.rb
916
+ - lib/ree_lib/packages/ree_mapper/package/ree_mapper/filter_fields_contract.rb
914
917
  - lib/ree_lib/packages/ree_mapper/package/ree_mapper/functions/build_mapper_factory.rb
915
918
  - lib/ree_lib/packages/ree_mapper/package/ree_mapper/functions/build_mapper_strategy.rb
916
919
  - lib/ree_lib/packages/ree_mapper/package/ree_mapper/mapper.rb