ree_lib 1.0.60 → 1.0.62

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: 77d773db4104deb076fe0ea9d9aa6b8e0fd1218d71731e6d51a70a50be09d569
4
- data.tar.gz: ac943abd83280ff44db19e50991e1ca51aa92cd1f140ccaa9e82cf706fc9dc8e
3
+ metadata.gz: e69b23ef012a6748604d4b82d1d81c791902ee23bc6179d231a340e48289a5d7
4
+ data.tar.gz: 6233c958a32bfdeea0efaf5b5692d0e824a5e04d9d334bf002d519b0789d6cc3
5
5
  SHA512:
6
- metadata.gz: 6eb4b4567e977e12c59f5246f819dcba9702ccb77fb5e776584f193f6cff18c14d4e7e40d75c0377b0fc905720936f0feb888e2e953b288466f7d777ed7bd633
7
- data.tar.gz: 26ee7d50cf9e346c4cb9614832282d586d0ac767dcd0b65bdb056511ed2e3058f5d1186003e6f30b89a9a661768c7b7153e4d2a3f079185b441f9b7ca5582485
6
+ metadata.gz: eee96a99fe5217675f4ff9c3db4915571ae444c7af4a33ca763b786b51a07f77f55fe794aa004688ccfd0f6c00f478631ba100181625de5d5f8d503f62b85edb
7
+ data.tar.gz: 1abc64ad140c4901e52f62b9a74f30e16f9fd4364a5e066f5321597c4246b7c5d7e2a0cba0515396b1a18aacd27d786321b17fa29004ed7336fac22a8ee75b06
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- ree_lib (1.0.60)
4
+ ree_lib (1.0.62)
5
5
  binding_of_caller (~> 1.0.0)
6
6
  i18n (~> 1.12.0)
7
7
  loofah (~> 2.18.0)
@@ -2,16 +2,16 @@ module ReeDao
2
2
  class Association
3
3
  include Ree::LinkDSL
4
4
 
5
- link :demodulize, from: :ree_string
6
5
  link :group_by, from: :ree_array
7
6
  link :index_by, from: :ree_array
8
- link :underscore, from: :ree_string
7
+ link :transform_values, from: :ree_hash
9
8
 
10
- attr_reader :parent, :list, :global_opts
9
+ attr_reader :parent, :parent_dao_name, :list, :global_opts
11
10
 
12
- contract(ReeDao::Associations, Array, Ksplat[RestKeys => Any] => Any)
13
- def initialize(parent, list, **global_opts)
11
+ contract(ReeDao::Associations, Symbol, Array, Ksplat[RestKeys => Any] => Any)
12
+ def initialize(parent, parent_dao_name, list, **global_opts)
14
13
  @parent = parent
14
+ @parent_dao_name = parent_dao_name
15
15
  @list = list
16
16
  @global_opts = global_opts
17
17
  end
@@ -37,13 +37,18 @@ module ReeDao
37
37
  Optblock => Nilor[Array]
38
38
  )
39
39
  def load_association(assoc_type, assoc_name, **opts, &block)
40
+ opts[:autoload_children] ||= false
41
+
40
42
  assoc_index = load_association_by_type(
41
43
  assoc_type,
42
44
  assoc_name,
43
45
  **opts
44
46
  )
45
47
 
46
- process_block(assoc_index, opts[:autoload_children] ||= false, &block) if block_given?
48
+ dao = find_dao(assoc_name, parent, opts[:scope])
49
+ dao_name = dao.first_source_table
50
+
51
+ process_block(assoc_index, opts[:autoload_children], opts[:to_dto], dao_name, &block) if block_given?
47
52
 
48
53
  list
49
54
  end
@@ -57,6 +62,7 @@ module ReeDao
57
62
  case type
58
63
  when :belongs_to
59
64
  one_to_one(
65
+ parent_dao_name,
60
66
  assoc_name,
61
67
  list,
62
68
  scope: opts[:scope],
@@ -67,44 +73,46 @@ module ReeDao
67
73
  )
68
74
  when :has_one
69
75
  one_to_one(
76
+ parent_dao_name,
70
77
  assoc_name,
71
78
  list,
72
79
  scope: opts[:scope],
73
80
  primary_key: opts[:primary_key],
74
81
  foreign_key: opts[:foreign_key],
82
+ to_dto: opts[:to_dto],
75
83
  setter: opts[:setter],
76
84
  reverse: true
77
85
  )
78
86
  when :has_many
79
87
  one_to_many(
88
+ parent_dao_name,
80
89
  assoc_name,
81
90
  list,
82
91
  scope: opts[:scope],
83
92
  primary_key: opts[:primary_key],
84
93
  foreign_key: opts[:foreign_key],
85
- setter: opts[:setter]
86
- )
87
- else
88
- one_to_many(
89
- assoc_name,
90
- list,
91
- scope: opts[:scope],
92
- primary_key: opts[:primary_key],
93
- foreign_key: opts[:foreign_key],
94
+ to_dto: opts[:to_dto],
94
95
  setter: opts[:setter]
95
96
  )
96
97
  end
97
98
  end
98
99
 
99
- contract(Or[Hash, Array], Bool, Block => Any)
100
- def process_block(assoc, autoload_children, &block)
100
+ contract(Or[Hash, Array], Bool, Nilor[Proc], Symbol, Block => Any)
101
+ def process_block(assoc, autoload_children, to_dto, parent_dao_name, &block)
101
102
  assoc_list = assoc.is_a?(Array) ? assoc : assoc.values.flatten
102
103
 
104
+ if to_dto
105
+ assoc_list = assoc_list.map do |item|
106
+ to_dto.call(item)
107
+ end
108
+ end
109
+
103
110
  if ReeDao::Associations.sync_mode?
104
111
  ReeDao::Associations.new(
105
112
  parent.agg_caller,
106
113
  assoc_list,
107
114
  parent.local_vars,
115
+ parent_dao_name,
108
116
  autoload_children,
109
117
  **global_opts
110
118
  ).instance_exec(assoc_list, &block)
@@ -113,6 +121,7 @@ module ReeDao
113
121
  parent.agg_caller,
114
122
  assoc_list,
115
123
  parent.local_vars,
124
+ parent_dao_name,
116
125
  autoload_children,
117
126
  **global_opts
118
127
  ).instance_exec(assoc_list, &block)
@@ -132,16 +141,18 @@ module ReeDao
132
141
 
133
142
  contract(
134
143
  Symbol,
135
- Array,
144
+ Symbol,
145
+ Array,
136
146
  Kwargs[
137
147
  primary_key: Nilor[Symbol],
138
148
  foreign_key: Nilor[Symbol],
139
149
  scope: Nilor[Sequel::Dataset, Array],
140
150
  setter: Nilor[Or[Symbol, Proc]],
151
+ to_dto: Nilor[Proc],
141
152
  reverse: Bool
142
153
  ] => Or[Hash, Array]
143
154
  )
144
- def one_to_one(assoc_name, list, scope: nil, primary_key: :id, foreign_key: nil, setter: nil, reverse: true)
155
+ def one_to_one(parent_assoc_name, assoc_name, list, scope: nil, primary_key: :id, foreign_key: nil, setter: nil, to_dto: nil, reverse: true)
145
156
  return {} if list.empty?
146
157
 
147
158
  primary_key ||= :id
@@ -150,13 +161,12 @@ module ReeDao
150
161
  items = scope
151
162
  else
152
163
  assoc_dao = find_dao(assoc_name, parent, scope)
153
-
164
+
154
165
  if reverse
155
166
  if !foreign_key
156
- name = underscore(demodulize(list.first.class.name))
157
- foreign_key = "#{name}_id".to_sym
167
+ foreign_key = "#{parent_assoc_name.to_s.gsub(/s$/,'')}_id".to_sym
158
168
  end
159
-
169
+
160
170
  root_ids = list.map(&:id).uniq
161
171
  else
162
172
  if !foreign_key
@@ -165,13 +175,14 @@ module ReeDao
165
175
 
166
176
  root_ids = list.map(&:"#{foreign_key}").compact
167
177
  end
168
-
178
+
169
179
  scope ||= assoc_dao
170
180
  scope = scope.where((reverse ? foreign_key : :id) => root_ids)
171
-
181
+
172
182
  items = add_scopes(scope, global_opts[assoc_name])
173
183
  end
174
184
 
185
+
175
186
  assoc = index_by(items) { _1.send(reverse ? foreign_key : :id) }
176
187
 
177
188
  populate_association(
@@ -180,23 +191,26 @@ module ReeDao
180
191
  assoc_name,
181
192
  setter: setter,
182
193
  reverse: reverse,
183
- primary_key: primary_key
194
+ primary_key: primary_key,
195
+ to_dto: to_dto
184
196
  )
185
197
 
186
198
  assoc
187
199
  end
188
200
 
189
201
  contract(
202
+ Symbol,
190
203
  Symbol,
191
204
  Array,
192
205
  Kwargs[
193
206
  foreign_key: Nilor[Symbol],
194
207
  primary_key: Nilor[Symbol],
195
208
  scope: Nilor[Sequel::Dataset, Array],
196
- setter: Nilor[Or[Symbol, Proc]]
209
+ setter: Nilor[Or[Symbol, Proc]],
210
+ to_dto: Nilor[Proc]
197
211
  ] => Or[Hash, Array]
198
212
  )
199
- def one_to_many(assoc_name, list, primary_key: nil, foreign_key: nil, scope: nil, setter: nil)
213
+ def one_to_many(parent_assoc_name, assoc_name, list, primary_key: nil, foreign_key: nil, scope: nil, setter: nil, to_dto: nil)
200
214
  return {} if list.empty?
201
215
 
202
216
  primary_key ||= :id
@@ -206,14 +220,14 @@ module ReeDao
206
220
  else
207
221
  assoc_dao = nil
208
222
  assoc_dao = find_dao(assoc_name, parent, scope)
209
-
210
- foreign_key ||= "#{underscore(demodulize(list.first.class.name))}_id".to_sym
211
-
223
+
224
+ foreign_key ||= "#{parent_assoc_name.to_s.gsub(/s$/, '')}_id".to_sym
225
+
212
226
  root_ids = list.map(&:"#{primary_key}")
213
-
227
+
214
228
  scope ||= assoc_dao
215
229
  scope = scope.where(foreign_key => root_ids)
216
-
230
+
217
231
  items = add_scopes(scope, global_opts[assoc_name])
218
232
  end
219
233
 
@@ -229,6 +243,7 @@ module ReeDao
229
243
  assoc_name,
230
244
  setter: setter,
231
245
  primary_key: primary_key,
246
+ to_dto: to_dto,
232
247
  multiple: true
233
248
  )
234
249
 
@@ -243,10 +258,11 @@ module ReeDao
243
258
  primary_key: Nilor[Symbol],
244
259
  reverse: Nilor[Bool],
245
260
  setter: Nilor[Or[Symbol, Proc]],
261
+ to_dto: Nilor[Proc],
246
262
  multiple: Bool
247
263
  ] => Any
248
264
  )
249
- def populate_association(list, association_index, assoc_name, primary_key: nil, reverse: nil, setter: nil, multiple: false)
265
+ def populate_association(list, association_index, assoc_name, primary_key: nil, reverse: nil, setter: nil, to_dto: nil, multiple: false)
250
266
  assoc_setter = if setter
251
267
  setter
252
268
  else
@@ -255,16 +271,35 @@ module ReeDao
255
271
 
256
272
  list.each do |item|
257
273
  if setter && setter.is_a?(Proc)
258
- self.instance_exec(item, association_index, &assoc_setter)
274
+ if to_dto
275
+ assoc_index = transform_values(association_index) do |key, value|
276
+ to_dto.call(value)
277
+ end
278
+
279
+ self.instance_exec(item, assoc_index, &assoc_setter)
280
+ else
281
+ self.instance_exec(item, association_index, &assoc_setter)
282
+ end
259
283
  else
260
284
  key = if reverse.nil?
261
285
  primary_key
262
286
  else
263
287
  reverse ? primary_key : "#{assoc_name}_id"
264
288
  end
289
+
265
290
  value = association_index[item.send(key)]
266
291
 
267
- value = [] if value.nil? && multiple
292
+ if to_dto && !value.nil?
293
+ if value.is_a?(Array)
294
+ value = value.map { to_dto.call(_1) }
295
+ else
296
+ value = to_dto.call(value)
297
+ end
298
+ end
299
+
300
+ if value.nil? && multiple
301
+ value = []
302
+ end
268
303
 
269
304
  begin
270
305
  item.send(assoc_setter, value)
@@ -2,15 +2,16 @@ module ReeDao
2
2
  class Associations
3
3
  include Ree::LinkDSL
4
4
 
5
- attr_reader :agg_caller, :list, :local_vars, :only, :except, :autoload_children, :global_opts
5
+ attr_reader :agg_caller, :list, :local_vars, :only, :except, :parent_dao_name, :autoload_children, :global_opts
6
6
 
7
- def initialize(agg_caller, list, local_vars, autoload_children = false, **opts)
7
+ def initialize(agg_caller, list, local_vars, parent_dao_name, autoload_children = false, **opts)
8
8
  @agg_caller = agg_caller
9
9
  @list = list
10
10
  @local_vars = local_vars
11
11
  @global_opts = opts || {}
12
12
  @only = opts[:only] if opts[:only]
13
13
  @except = opts[:except] if opts[:except]
14
+ @parent_dao_name = parent_dao_name
14
15
  @autoload_children = autoload_children
15
16
 
16
17
  raise ArgumentError.new("you can't use both :only and :except arguments at the same time") if @only && @except
@@ -83,7 +84,7 @@ module ReeDao
83
84
  if self.class.sync_mode?
84
85
  return if association_is_not_included?(assoc_name) || list.empty?
85
86
 
86
- association = Association.new(self, list, **global_opts)
87
+ association = Association.new(self, parent_dao_name, list, **global_opts)
87
88
  if assoc_type == :field
88
89
  association.handle_field(assoc_name, opts)
89
90
  else
@@ -94,7 +95,7 @@ module ReeDao
94
95
  return { association_threads: @assoc_threads, field_threads: @field_threads }
95
96
  end
96
97
 
97
- association = Association.new(self, list, **global_opts)
98
+ association = Association.new(self, parent_dao_name, list, **global_opts)
98
99
 
99
100
  if assoc_type == :field
100
101
  field_proc = opts
@@ -4,6 +4,8 @@ class ReeDao::LoadAgg
4
4
  include Ree::FnDSL
5
5
 
6
6
  fn :load_agg do
7
+ link :demodulize, from: :ree_string
8
+ link :underscore, from: :ree_string
7
9
  link "ree_dao/associations", -> { Associations }
8
10
  link "ree_dao/contract/dao_dataset_contract", -> { DaoDatasetContract }
9
11
  link "ree_dao/contract/entity_contract", -> { EntityContract }
@@ -34,6 +36,12 @@ class ReeDao::LoadAgg
34
36
  ids_or_scope
35
37
  end
36
38
 
39
+ if dao
40
+ dao_name = dao.first_source_table
41
+ else
42
+ dao_name = underscore(demodulize(scope.first.class.name)).to_sym
43
+ end
44
+
37
45
  list = scope.is_a?(Sequel::Dataset) ? scope.all : scope
38
46
 
39
47
  if opts[:to_dto]
@@ -42,7 +50,7 @@ class ReeDao::LoadAgg
42
50
  end
43
51
  end
44
52
 
45
- load_associations(list, **opts, &block) if block_given?
53
+ load_associations(dao_name, list, **opts, &block) if block_given?
46
54
 
47
55
  if ids_or_scope.is_a?(Array)
48
56
  list.sort_by { ids_or_scope.index(_1.id) }
@@ -53,7 +61,7 @@ class ReeDao::LoadAgg
53
61
 
54
62
  private
55
63
 
56
- def load_associations(list, **opts, &block)
64
+ def load_associations(dao_name, list, **opts, &block)
57
65
  return if list.empty?
58
66
 
59
67
  local_vars = block.binding.eval(<<-CODE, __FILE__, __LINE__ + 1)
@@ -63,7 +71,7 @@ class ReeDao::LoadAgg
63
71
 
64
72
  agg_caller = block.binding.eval("self")
65
73
 
66
- associations = Associations.new(agg_caller, list, local_vars, **opts).instance_exec(list, &block)
74
+ associations = Associations.new(agg_caller, list, local_vars, dao_name, **opts).instance_exec(list, &block)
67
75
 
68
76
  if ReeDao.load_sync_associations_enabled?
69
77
  associations
@@ -38,6 +38,21 @@
38
38
  }
39
39
  ],
40
40
  "links": [
41
+ {
42
+ "target": "demodulize",
43
+ "package_name": "ree_string",
44
+ "as": "demodulize",
45
+ "imports": [
46
+
47
+ ]
48
+ },
49
+ {
50
+ "target": "underscore",
51
+ "package_name": "ree_string",
52
+ "as": "underscore",
53
+ "imports": [
41
54
 
55
+ ]
56
+ }
42
57
  ]
43
58
  }
@@ -129,7 +129,7 @@ RSpec.describe :load_agg do
129
129
  end
130
130
 
131
131
  def call(ids_or_scope)
132
- load_agg(ids_or_scope, users) do
132
+ load_agg(users, ids_or_scope) do
133
133
  belongs_to :organization
134
134
 
135
135
  has_many :books
@@ -141,7 +141,7 @@ RSpec.describe :load_agg do
141
141
  has_many :skills
142
142
  has_many :dreams
143
143
 
144
- has_one :passport, foreign_key: :user_id, scope: user_passports
144
+ has_one :passport, -> { {foreign_key: :user_id, scope: user_passports} }
145
145
  end
146
146
  end
147
147
  end
@@ -251,7 +251,7 @@ RSpec.describe :load_agg do
251
251
 
252
252
  _users = []
253
253
  st_time = Time.now
254
- puts "Starting to seed #{NUM_OF_USERS} users..."
254
+ puts "Seeding #{NUM_OF_USERS} users..."
255
255
  NUM_OF_USERS.times do
256
256
  u = ReeDaoLoadAggTest::User.new(
257
257
  name: Faker::Name.name,
@@ -104,7 +104,7 @@ RSpec.describe :load_agg do
104
104
  has_many :books do |books_list|
105
105
  has_one :author
106
106
  has_many :chapters
107
-
107
+
108
108
  has_many :reviews do |reviews_list|
109
109
  has_one :review_author
110
110
 
@@ -113,7 +113,7 @@ RSpec.describe :load_agg do
113
113
 
114
114
  field :book_calculatetable_field, -> { change_book_titles(books_list) }
115
115
  end
116
-
116
+
117
117
  has_one :passport, -> { passport_opts }
118
118
  has_one :custom_field, -> { custom_field_opts }
119
119
 
@@ -153,6 +153,9 @@ RSpec.describe :load_agg do
153
153
 
154
154
  aggregate :users_agg_with_dto do
155
155
  link :users, from: :ree_dao_load_agg_test
156
+ link :books, from: :ree_dao_load_agg_test
157
+ link :authors, from: :ree_dao_load_agg_test
158
+ link :chapters, from: :ree_dao_load_agg_test
156
159
  link :organizations, from: :ree_dao_load_agg_test
157
160
  link :load_agg, from: :ree_dao
158
161
  end
@@ -160,8 +163,32 @@ RSpec.describe :load_agg do
160
163
  def call(ids_or_scope, **opts)
161
164
  load_agg(users, ids_or_scope, **opts) do
162
165
  belongs_to :organization
166
+
167
+ has_many :books, -> { books_opts } do
168
+ has_one :author, -> { author_opts }
169
+ has_many :chapters, -> { chapters_opts }
170
+ end
163
171
  end
164
172
  end
173
+
174
+ private
175
+
176
+ def books_opts
177
+ {
178
+ to_dto: -> (book) { ReeDaoLoadAggTest::BookDto.new(book) },
179
+ setter: -> (item, child_index) {
180
+ item.set_books(child_index[item.id] || [])
181
+ }
182
+ }
183
+ end
184
+
185
+ def author_opts
186
+ { to_dto: -> (author) { ReeDaoLoadAggTest::AuthorDto.new(author) }}
187
+ end
188
+
189
+ def chapters_opts
190
+ { to_dto: -> (chapter) { ReeDaoLoadAggTest::ChapterDto.new(chapter) }}
191
+ end
165
192
  end
166
193
 
167
194
  class ReeDaoLoadAggTest::UsersAggAutoloadBooksChildren
@@ -183,7 +210,7 @@ RSpec.describe :load_agg do
183
210
  has_many :books, -> { books_opts } do
184
211
  has_one :author
185
212
  has_many :chapters
186
-
213
+
187
214
  has_many :reviews do
188
215
  has_one :review_author
189
216
  end
@@ -192,7 +219,7 @@ RSpec.describe :load_agg do
192
219
  end
193
220
 
194
221
  private
195
-
222
+
196
223
  def books_opts
197
224
  { autoload_children: true }
198
225
  end
@@ -217,7 +244,7 @@ RSpec.describe :load_agg do
217
244
  has_many :books do
218
245
  has_one :author
219
246
  has_many :chapters
220
-
247
+
221
248
  has_many :reviews, -> { { autoload_children: true } } do
222
249
  has_one :review_author
223
250
  end
@@ -370,6 +397,12 @@ RSpec.describe :load_agg do
370
397
  users.put(user_1)
371
398
  users.put(user_2)
372
399
 
400
+ book_1 = ReeDaoLoadAggTest::Book.new(user_id: user_1.id, title: "1984")
401
+ books.put(book_1)
402
+
403
+ authors.put(ReeDaoLoadAggTest::Author.new(book_id: book_1.id, name: "George Orwell"))
404
+ chapters.put(ReeDaoLoadAggTest::Chapter.new(book_id: book_1.id, title: "interlude"))
405
+
373
406
  res = users_agg_with_dto.call(
374
407
  users.all,
375
408
  to_dto: -> (user) {
@@ -382,7 +415,12 @@ RSpec.describe :load_agg do
382
415
  }
383
416
  )
384
417
 
418
+ book = res.first.books.first
419
+
385
420
  expect(res.first.class).to eq(ReeDaoLoadAggTest::UserDto)
421
+ expect(book.class).to eq(ReeDaoLoadAggTest::BookDto)
422
+ expect(book.author.class).to eq(ReeDaoLoadAggTest::AuthorDto)
423
+ expect(book.chapters.first.class).to eq(ReeDaoLoadAggTest::ChapterDto)
386
424
  }
387
425
 
388
426
  it {
@@ -402,7 +440,7 @@ RSpec.describe :load_agg do
402
440
  books.put(book_1)
403
441
  books.put(book_2)
404
442
  books.put(book_3)
405
-
443
+
406
444
  res = users_agg_only_dataset.call(users.where(name: "John"))
407
445
 
408
446
  user = res[0]
@@ -75,6 +75,9 @@ class ReeDaoLoadAggTest::Book
75
75
  attr_accessor :title, :user_id
76
76
  end
77
77
 
78
+ class ReeDaoLoadAggTest::BookDto < SimpleDelegator
79
+ end
80
+
78
81
  class ReeDaoLoadAggTest::User
79
82
  include ReeDto::EntityDSL
80
83
 
@@ -159,6 +162,14 @@ class ReeDaoLoadAggTest::UserDto
159
162
  def organization
160
163
  @organization
161
164
  end
165
+
166
+ def set_books(books)
167
+ @books = books; nil
168
+ end
169
+
170
+ def books
171
+ @books
172
+ end
162
173
  end
163
174
 
164
175
  class ReeDaoLoadAggTest::Organization
@@ -276,6 +287,9 @@ class ReeDaoLoadAggTest::Chapter
276
287
  attr_accessor :title, :book_id
277
288
  end
278
289
 
290
+ class ReeDaoLoadAggTest::ChapterDto < SimpleDelegator
291
+ end
292
+
279
293
  class ReeDaoLoadAggTest::Author
280
294
  include ReeDto::EntityDSL
281
295
 
@@ -288,6 +302,9 @@ class ReeDaoLoadAggTest::Author
288
302
  attr_accessor :name, :book_id
289
303
  end
290
304
 
305
+ class ReeDaoLoadAggTest::AuthorDto < SimpleDelegator
306
+ end
307
+
291
308
  class ReeDaoLoadAggTest::Review
292
309
  include ReeDto::EntityDSL
293
310
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ReeLib
4
- VERSION = "1.0.60"
4
+ VERSION = "1.0.62"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ree_lib
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.60
4
+ version: 1.0.62
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ruslan Gatiyatov