eco-helpers 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (123) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +1 -0
  3. data/.rspec +3 -0
  4. data/README.md +20 -0
  5. data/eco-helpers.gemspec +34 -0
  6. data/lib/eco-helpers.rb +15 -0
  7. data/lib/eco/api.rb +13 -0
  8. data/lib/eco/api/common.rb +10 -0
  9. data/lib/eco/api/common/people.rb +17 -0
  10. data/lib/eco/api/common/people/base_parser.rb +16 -0
  11. data/lib/eco/api/common/people/default_parsers.rb +40 -0
  12. data/lib/eco/api/common/people/default_parsers/boolean_parser.rb +28 -0
  13. data/lib/eco/api/common/people/default_parsers/date_parser.rb +33 -0
  14. data/lib/eco/api/common/people/default_parsers/multi_parser.rb +33 -0
  15. data/lib/eco/api/common/people/default_parsers/numeric_parser.rb +23 -0
  16. data/lib/eco/api/common/people/default_parsers/select_parser.rb +29 -0
  17. data/lib/eco/api/common/people/entries.rb +120 -0
  18. data/lib/eco/api/common/people/person_entry.rb +380 -0
  19. data/lib/eco/api/common/people/person_factory.rb +114 -0
  20. data/lib/eco/api/common/people/person_modifier.rb +62 -0
  21. data/lib/eco/api/common/people/person_parser.rb +140 -0
  22. data/lib/eco/api/common/people/types.rb +47 -0
  23. data/lib/eco/api/common/session.rb +15 -0
  24. data/lib/eco/api/common/session/base_session.rb +46 -0
  25. data/lib/eco/api/common/session/environment.rb +47 -0
  26. data/lib/eco/api/common/session/file_manager.rb +90 -0
  27. data/lib/eco/api/common/session/logger.rb +105 -0
  28. data/lib/eco/api/common/session/mailer.rb +92 -0
  29. data/lib/eco/api/common/session/s3_uploader.rb +110 -0
  30. data/lib/eco/api/common/version_patches.rb +11 -0
  31. data/lib/eco/api/common/version_patches/external_person.rb +11 -0
  32. data/lib/eco/api/eco_faker.rb +59 -0
  33. data/lib/eco/api/organization.rb +13 -0
  34. data/lib/eco/api/organization/account.rb +23 -0
  35. data/lib/eco/api/organization/people.rb +118 -0
  36. data/lib/eco/api/organization/policy_groups.rb +51 -0
  37. data/lib/eco/api/organization/preferences.rb +28 -0
  38. data/lib/eco/api/organization/preferences_reference.json +23 -0
  39. data/lib/eco/api/organization/presets.rb +138 -0
  40. data/lib/eco/api/organization/presets_backup.rb +220 -0
  41. data/lib/eco/api/organization/presets_values.json +10 -0
  42. data/lib/eco/api/organization/tag_tree.rb +134 -0
  43. data/lib/eco/api/organization_old.rb +73 -0
  44. data/lib/eco/api/session.rb +180 -0
  45. data/lib/eco/api/session/batch.rb +132 -0
  46. data/lib/eco/api/session/batch_job.rb +152 -0
  47. data/lib/eco/api/session/batch_jobs.rb +131 -0
  48. data/lib/eco/api/session/batch_status.rb +138 -0
  49. data/lib/eco/api/session/task.rb +92 -0
  50. data/lib/eco/api/session_config.rb +179 -0
  51. data/lib/eco/api/session_config/api.rb +47 -0
  52. data/lib/eco/api/session_config/apis.rb +78 -0
  53. data/lib/eco/api/session_config/files.rb +30 -0
  54. data/lib/eco/api/session_config/logger.rb +54 -0
  55. data/lib/eco/api/session_config/mailer.rb +65 -0
  56. data/lib/eco/api/session_config/people.rb +89 -0
  57. data/lib/eco/api/session_config/s3_bucket.rb +62 -0
  58. data/lib/eco/api/session_config/use_cases.rb +30 -0
  59. data/lib/eco/api/usecases.rb +12 -0
  60. data/lib/eco/api/usecases/base_case.rb +14 -0
  61. data/lib/eco/api/usecases/case_data.rb +13 -0
  62. data/lib/eco/api/usecases/default_cases.rb +53 -0
  63. data/lib/eco/api/usecases/default_cases/change_email_case.rb +47 -0
  64. data/lib/eco/api/usecases/default_cases/create_details_case.rb +29 -0
  65. data/lib/eco/api/usecases/default_cases/create_details_with_supervisor_case.rb +49 -0
  66. data/lib/eco/api/usecases/default_cases/delete_case.rb +20 -0
  67. data/lib/eco/api/usecases/default_cases/email_as_id_case.rb +24 -0
  68. data/lib/eco/api/usecases/default_cases/hris_case.rb +67 -0
  69. data/lib/eco/api/usecases/default_cases/new_email_case.rb +26 -0
  70. data/lib/eco/api/usecases/default_cases/new_id_case.rb +26 -0
  71. data/lib/eco/api/usecases/default_cases/refresh_presets.rb +25 -0
  72. data/lib/eco/api/usecases/default_cases/reinvite_case.rb +22 -0
  73. data/lib/eco/api/usecases/default_cases/remove_account_case.rb +36 -0
  74. data/lib/eco/api/usecases/default_cases/reset_landing_page_case.rb +24 -0
  75. data/lib/eco/api/usecases/default_cases/set_default_tag_case.rb +44 -0
  76. data/lib/eco/api/usecases/default_cases/set_supervisor_case.rb +39 -0
  77. data/lib/eco/api/usecases/default_cases/to_csv_case.rb +36 -0
  78. data/lib/eco/api/usecases/default_cases/update_details_case.rb +30 -0
  79. data/lib/eco/api/usecases/default_cases/upsert_account_case.rb +35 -0
  80. data/lib/eco/api/usecases/use_case.rb +177 -0
  81. data/lib/eco/api/usecases/use_group.rb +104 -0
  82. data/lib/eco/cli.rb +9 -0
  83. data/lib/eco/cli/input.rb +109 -0
  84. data/lib/eco/cli/input_multi.rb +137 -0
  85. data/lib/eco/cli/root.rb +8 -0
  86. data/lib/eco/cli/session.rb +9 -0
  87. data/lib/eco/cli/session/batch.rb +9 -0
  88. data/lib/eco/common.rb +7 -0
  89. data/lib/eco/common/base_cli.rb +116 -0
  90. data/lib/eco/common/language.rb +9 -0
  91. data/lib/eco/data.rb +9 -0
  92. data/lib/eco/data/crypto.rb +7 -0
  93. data/lib/eco/data/crypto/encryption.rb +318 -0
  94. data/lib/eco/data/files.rb +10 -0
  95. data/lib/eco/data/files/directory.rb +93 -0
  96. data/lib/eco/data/files/file_pattern.rb +32 -0
  97. data/lib/eco/data/files/helpers.rb +90 -0
  98. data/lib/eco/data/mapper.rb +54 -0
  99. data/lib/eco/data/random.rb +10 -0
  100. data/lib/eco/data/random/distribution.rb +133 -0
  101. data/lib/eco/data/random/fake.rb +320 -0
  102. data/lib/eco/data/random/values.rb +80 -0
  103. data/lib/eco/language.rb +12 -0
  104. data/lib/eco/language/curry.rb +28 -0
  105. data/lib/eco/language/hash_transform.rb +68 -0
  106. data/lib/eco/language/hash_transform_modifier.rb +114 -0
  107. data/lib/eco/language/match.rb +30 -0
  108. data/lib/eco/language/match_modifier.rb +190 -0
  109. data/lib/eco/language/models.rb +11 -0
  110. data/lib/eco/language/models/attribute_parser.rb +38 -0
  111. data/lib/eco/language/models/collection.rb +181 -0
  112. data/lib/eco/language/models/modifier.rb +68 -0
  113. data/lib/eco/language/models/wrap.rb +114 -0
  114. data/lib/eco/language/values_at.rb +159 -0
  115. data/lib/eco/lexic/dictionary.rb +33 -0
  116. data/lib/eco/lexic/dictionary/dictionary.txt +355484 -0
  117. data/lib/eco/lexic/dictionary/tags.json +38 -0
  118. data/lib/eco/scripting.rb +30 -0
  119. data/lib/eco/scripting/README.md +11 -0
  120. data/lib/eco/scripting/arguments.rb +40 -0
  121. data/lib/eco/tester.rb +97 -0
  122. data/lib/eco/version.rb +3 -0
  123. metadata +325 -0
@@ -0,0 +1,380 @@
1
+ module Eco
2
+ module API
3
+ module Common
4
+ module People
5
+ class PersonEntry
6
+ @@cached_warnings = {}
7
+
8
+ def initialize(data, parser:, mapper:, dependencies: {}, logger: ::Logger.new(IO::NULL))
9
+ raise "Constructor needs a PersonParser. Given: #{parser}" if !parser.is_a?(Eco::API::Common::People::PersonParser)
10
+ raise "Expecting Mapper object. Given: #{mapper}" if mapper && !mapper.is_a?(Eco::Data::Mapper)
11
+
12
+ @source = data
13
+ @parser = parser
14
+ @mapper = mapper
15
+ @deps = dependencies
16
+ @logger = logger
17
+
18
+ if parsing?
19
+ # PARSING
20
+ @raw_entry = data
21
+ init_attr_trackers
22
+ @aliased_entry = mapped_entry(@raw_entry)
23
+ @int_row = internal_entry(@aliased_entry)
24
+
25
+ # internally named attrs scoped by mapper and parser against the current row
26
+ @int_attrs = @int_row.keys
27
+ else
28
+ # SERIALIZING
29
+ @person = data
30
+ @int_row = internal_entry(@person)
31
+ @aliased_entry = mapped_entry(@int_row)
32
+ @int_attrs = @parser.all_attrs
33
+ end
34
+
35
+ @core_attrs = @parser.target_attrs_core(@int_attrs)
36
+ @details_attrs = @parser.target_attrs_details(@int_attrs)
37
+ @account_attrs = @parser.target_attrs_account(@int_attrs)
38
+ end
39
+
40
+ def parsing?
41
+ !is_person?(@source)
42
+ end
43
+
44
+ def serializing?
45
+ !parsing?
46
+ end
47
+
48
+ # SHORTCUTS
49
+
50
+ def id
51
+ @int_row["id"]
52
+ end
53
+
54
+ def external_id
55
+ @int_row["external_id"]
56
+ end
57
+
58
+ def name
59
+ @int_row["name"]
60
+ end
61
+
62
+ def email
63
+ @int_row["email"]
64
+ end
65
+
66
+ def supervisor_id
67
+ @int_row["supervisor_id"]
68
+ end
69
+
70
+ def supervisor_id=(value)
71
+ @int_row["supervisor_id"] = value
72
+ end
73
+
74
+ def to_s(options)
75
+ options = into_a(options)
76
+ case
77
+ when options.include?(:identify)
78
+ "'#{name}' ('#{external_id}': '#{email}')"
79
+ else
80
+ @int_row.each.map do |k, v|
81
+ "'#{k}': '#{v.to_json}'"
82
+ end.join(" | ")
83
+ end
84
+ end
85
+
86
+ # SETTERS
87
+ def set_core(person, exclude: nil)
88
+ scoped_attrs = @core_attrs - into_a(exclude)
89
+ @int_row.slice(*scoped_attrs).each do |attr, value|
90
+ set_to_core(person, attr, value)
91
+ end
92
+ end
93
+
94
+ def set_details(person, exclude: nil)
95
+ person.add_details(@parser.schema) if !person.details || !person.details.schema_id
96
+ scoped_attrs = @details_attrs - into_a(exclude)
97
+ @int_row.slice(*scoped_attrs).each do |attr, value|
98
+ set_to_details(person, attr, value)
99
+ end
100
+ end
101
+
102
+ def set_account(person, exclude: nil)
103
+ person.account = {} if !person.account
104
+ person.account.permissions_preset = nil unless person.account.permissions_preset = "custom"
105
+ scoped_attrs = @account_attrs - into_a(exclude)
106
+ @int_row.slice(*scoped_attrs).each do |attr, value|
107
+ set_to_account(person, attr, value)
108
+ end
109
+ end
110
+
111
+ # GETTERS
112
+ def entry(klass: nil)
113
+ return klass.new(to_hash) if klass
114
+ to_hash
115
+ end
116
+
117
+ def to_hash
118
+ @aliased_entry.each.map do |int_attr, v|
119
+ [to_external(int_attr), v || ""] if to_external(int_attr)
120
+ end.compact.to_h
121
+ end
122
+
123
+ private
124
+
125
+ def set_to_core (person, attr, value)
126
+ value = value&.downcase if attr == "email"
127
+ person.send("#{attr}=", value&.strip)
128
+ end
129
+
130
+ def set_to_account (person, attr, value)
131
+ return if !person.account
132
+ multiple = ["policy_group_ids", "filter_tags"].include?(attr)
133
+ if multiple
134
+ value = @parser.parse(:multiple, value)
135
+ value = value.map { |v| v&.upcase } if attr == "filter_tags"
136
+ # preserve previous order
137
+ current = into_a(person.account.send(attr))
138
+ value = (current & value) + (value - current)
139
+ end
140
+
141
+ person.account.send("#{attr}=", value)
142
+ end
143
+
144
+ def set_to_details (person, attr, value)
145
+ return if !person.details
146
+ field = person.details.get_field(attr)
147
+ fatal("Field '#{attr}' does not exist in details of schema: '#{person.details.schema_id}'") if !field
148
+ value = @parser.parse(:multiple, value) if field.multiple
149
+
150
+ if @parser.defined?(field.type.to_sym)
151
+ value = @parser.parse(field.type.to_sym, value, deps: {"attr" => attr})
152
+ end
153
+
154
+ person.details[attr] = value
155
+ end
156
+
157
+ def get_from_core (person, attr)
158
+ person.send(attr)
159
+ end
160
+
161
+ def get_from_account (person, attr)
162
+ return "-" if !person.account
163
+ multiple = ["policy_group_ids", "filter_tags"].include?(attr)
164
+ value = person.account.send(attr)
165
+ @parser.serialize(:multiple, value) if multiple
166
+ end
167
+
168
+ def get_from_details (person, attr)
169
+ return "-" if !person.details || !person&.details&.schema_id
170
+ field = person.details.get_field(attr)
171
+ fatal("Field '#{attr}' does not exist in details of schema: '#{person.details.schema_id}'") if !field
172
+ value = person.details[attr]
173
+ value = @parser.serialize(:date, value) if field.type == "date"
174
+ value = @parser.serialize(:multiple, value) if field.multiple
175
+ value
176
+ end
177
+
178
+ # INIT
179
+
180
+ # when parsing:
181
+ def init_attr_trackers
182
+ # internal <-> external attributes
183
+ int_aliased = @parser.all_attrs.select { |attr| to_external(attr) }
184
+ ext_alias = int_aliased.map { |attr| to_external(attr) }
185
+
186
+ # virtual attrs (non native internal attr that require aliasing):
187
+ ext_vi_aliased = attributes(@raw_entry).select do |attr|
188
+ !ext_alias.include?(attr) && @mapper.external?(attr)
189
+ end
190
+
191
+ int_vi_aliased = ext_vi_aliased.map { |attr| @mapper.to_internal(attr) }
192
+ @aliased_attrs = int_aliased + int_vi_aliased
193
+
194
+ int_unlinked = @parser.undefined_attrs.select { |attr| !to_external(attr) }
195
+ # those with parser or alias:
196
+ int_linked = @parser.all_attrs - int_unlinked
197
+
198
+ ext_aliased = ext_alias + ext_vi_aliased
199
+ # those that are direct external to internal:
200
+ ext_direct = attributes(@raw_entry) - ext_aliased
201
+ # to avoid collisions between internal names:
202
+ @direct_attrs = ext_direct - int_linked
203
+ end
204
+
205
+ # MAPPED ENTRY (when and where applicable)
206
+ # return entry with internal names and external values
207
+ def mapped_entry(data)
208
+ return aliased_entry(data) if parsing?
209
+ serialized_entry(data)
210
+ end
211
+
212
+ # parse: here we aliase attribute names
213
+ def aliased_entry(raw_data)
214
+ aliased_hash = @aliased_attrs.map do |attr|
215
+ [attr, raw_data[to_external(attr)]]
216
+ end.to_h
217
+
218
+ direct_hash = @direct_attrs.map do |attr|
219
+ [attr, raw_data[attr]]
220
+ end.to_h
221
+
222
+ aliased_hash.merge!(direct_hash)
223
+ end
224
+
225
+ def hash_attr(attr, value)
226
+ return value if value.is_a?(Hash)
227
+ { attr => value }
228
+ end
229
+
230
+ # serializing: run serializers (overrides existing keys)
231
+ def serialized_entry(unserialized_entry)
232
+ serial_attrs = @parser.defined_attrs.reduce({}) do |serial_hash, attr|
233
+ deps = @deps[attr] || {}
234
+ serial_attr = @parser.serialize(attr, @person, deps: deps)
235
+ serial_hash.merge(hash_attr(attr, serial_attr))
236
+ end
237
+ unserialized_entry.merge(serial_attrs)
238
+ end
239
+
240
+ # returns entry with interal names and values
241
+ def internal_entry(data)
242
+ return parsed_entry(data) if parsing?
243
+ unserialized_entry(data)
244
+ end
245
+
246
+ # parse: to internal entry (parse values)
247
+ def parsed_entry(aliased_entry)
248
+ parsed = @parser.defined_attrs.map do |attr|
249
+ value = @parser.parse(attr, aliased_entry)
250
+ [attr, value]
251
+ end.to_h
252
+ aliased_entry.merge(parsed)
253
+ end
254
+
255
+ # serializing: to internal entry (create the internal entry out of a person)
256
+ def unserialized_entry(person)
257
+ core_hash = @parser.target_attrs_core.reduce({}) do |hash, attr|
258
+ value = get_from_core(person, attr)
259
+ hash.merge(hash_attr(attr, value))
260
+ end
261
+
262
+ details_hash = @parser.target_attrs_details.reduce({}) do |hash, attr|
263
+ value = get_from_details(person, attr)
264
+ hash.merge(hash_attr(attr, value))
265
+ end
266
+
267
+ account_hash = @parser.target_attrs_account.reduce({}) do |hash, attr|
268
+ value = get_from_account(person, attr)
269
+ hash.merge(hash_attr(attr, value))
270
+ end
271
+
272
+ details_hash.merge(account_hash).merge(core_hash)
273
+ #core_hash.merge(account_hash).merge(details_hash)
274
+ end
275
+
276
+
277
+ def to_internal(value)
278
+ return value if !@mapper
279
+ attr = value
280
+ case value
281
+ when Array
282
+ return value.map do |v|
283
+ to_internal(v)
284
+ end.compact
285
+ when String
286
+ case
287
+ when @mapper.external?(value)
288
+ attr = @mapper.to_internal(value)
289
+ when @mapper.external?(value.strip)
290
+ unless cached_warning("external", "spaces", value)
291
+ logger.warn("The external person field name '#{value}' contains additional spaces in the reference file")
292
+ end
293
+ attr = @mapper.to_internal(value.strip)
294
+ when @mapper.internal?(value) || @mapper.internal?(value.strip) || @mapper.internal?(value.strip.downcase)
295
+ unless cached_warning("external", "reversed", value)
296
+ logger.warn("The mapper [external, internal] attribute names may be declared reversedly for EXTERNAL attribute: '#{value}'")
297
+ end
298
+ end
299
+ end
300
+
301
+ return nil unless @parser.all_attrs.include?(attr)
302
+ end
303
+
304
+ def to_external(value)
305
+ return value if !@mapper
306
+ attr = value
307
+ case value
308
+ when Array
309
+ return value.map do |v|
310
+ to_external(v)
311
+ end.compact
312
+ when String
313
+ case
314
+ when @mapper.internal?(value)
315
+ attr = @mapper.to_external(value)
316
+ when @mapper.internal?(value.strip)
317
+ unless cached_warning("internal", "spaces", value)
318
+ logger.warn("The internal person field name '#{value}' contains additional spaces in the reference file")
319
+ end
320
+ attr = @mapper.to_external(value.strip)
321
+ when @mapper.external?(value) || @mapper.external?(value.strip) || @mapper.external?(value.strip.downcase)
322
+ unless cached_warning("internal", "reversed", value)
323
+ logger.warn("The mapper [external, internal] attribute names may be declared reversedly for INTERNAL attribute: '#{value}'")
324
+ end
325
+ end
326
+ end
327
+
328
+ return nil unless !@raw_entry || attributes(@raw_entry).include?(attr)
329
+ attr
330
+ end
331
+
332
+ # LOGGER
333
+ def logger
334
+ @logger || ::Logger.new(IO::NULL)
335
+ end
336
+
337
+ def cached_warning(*args)
338
+ unless exists = !!@@cached_warnings.dig(*args)
339
+ args.reduce(@@cached_warnings) do |cache, level|
340
+ cache[level] = {} if !cache.key?(level)
341
+ cache[level]
342
+ end
343
+ end
344
+ exists
345
+ end
346
+
347
+ def fatal(msg)
348
+ logger.fatal(msg)
349
+ exit
350
+ end
351
+
352
+ # HELPERS
353
+ def into_a(value)
354
+ value = [] if value == nil
355
+ value = [].push(value) unless value.is_a?(Array)
356
+ value
357
+ end
358
+
359
+ def attributes(value)
360
+ case value
361
+ when CSV::Row
362
+ value&.headers
363
+ when Hash
364
+ value&.keys
365
+ when PersonEntry
366
+ @parser.target_attrs_core
367
+ else
368
+ []
369
+ end
370
+ end
371
+
372
+ def is_person?(value)
373
+ value.is_a?(Ecoportal::API::Internal::Person)
374
+ end
375
+
376
+ end
377
+ end
378
+ end
379
+ end
380
+ end
@@ -0,0 +1,114 @@
1
+ module Eco
2
+ module API
3
+ module Common
4
+ module People
5
+ class PersonFactory
6
+
7
+ include Common::People
8
+
9
+ attr_reader :schema_attrs
10
+
11
+ def initialize(person: {}, schema: {}, account: {}, modifier: Common::People::PersonModifier.new)
12
+ @modifier = Common::People::PersonModifier.new(modifier)
13
+ @person = person
14
+ @account = account
15
+ @schema = schema
16
+ @schema_attrs = @schema&.fields&.map { |fld| fld.alt_id }
17
+ end
18
+
19
+ def new(person: nil)
20
+ in_raw_modifier = Common::People::PersonModifier.new.no_details
21
+ return PersonFactory.new(person: person, schema: @schema, modifier: in_raw_modifier).new unless !person
22
+ person = klass.new(person_hash(@person))
23
+ person.account = account_hash(@account) if @modifier.add_account? && @modifier.internal?
24
+ person.details = details_hash(@schema) unless @modifier.no_details?
25
+ person
26
+ end
27
+
28
+ def new_contact(schema)
29
+ factory = self.class.new(@modifier.reset_account, person: @person, schema: @schema, account: @account)
30
+ factory.new
31
+ end
32
+
33
+ def new_doc
34
+ new_hash(@modifier)
35
+ end
36
+
37
+ def schema_id
38
+ nil if !@schema
39
+ @schema['schema_id'] || @schema['id']
40
+ end
41
+
42
+ private
43
+
44
+ def klass
45
+ if @modifier.external?
46
+ EXTERNAL::Person
47
+ else
48
+ INTERNAL::Person
49
+ end
50
+ end
51
+
52
+ def new_hash(modifier)
53
+ modifier = Common::People::PersonModifier.new(modifier)
54
+ doc = person_hash(@person)
55
+ doc = add_account(doc, @account) if modifier.add_account? && modifier.internal?
56
+ doc = add_details(doc, @schema) unless modifier.no_details?
57
+ end
58
+
59
+ def add_details(doc, details)
60
+ return nil if !doc
61
+ doc_det = details_hash(details)
62
+ doc.merge({ "details" => doc_det })
63
+ end
64
+
65
+ def add_account(doc, account)
66
+ return nil if !doc
67
+ doc_acc = account_hash(account)
68
+ doc.merge({ "account" => doc_acc })
69
+ end
70
+
71
+ def person_hash(person)
72
+ case
73
+ when is_person?(person)
74
+ JSON.parse(person.doc.to_json)
75
+ when person.is_a?(Hash)
76
+ JSON.parse(person.to_json)
77
+ else
78
+ {}
79
+ end
80
+ end
81
+
82
+ def details_hash(details)
83
+ case
84
+ when details.is_a?(EXTERNAL::PersonDetails)
85
+ doc = JSON.parse(details.doc.to_json)
86
+ when details.is_a?(EXTERNAL::PersonSchema)
87
+ doc =JSON.parse(details.doc.to_json)
88
+ when details.is_a?(Hash)
89
+ doc = JSON.parse(details.to_json)
90
+ doc = doc["details"] if doc.key?("details")
91
+ else
92
+ doc = {}
93
+ end
94
+ doc["schema_id"] = doc.delete("id") if doc&.key?("id")
95
+ doc
96
+ end
97
+
98
+ def account_hash(account)
99
+ case
100
+ when account.is_a?(INTERNAL::Account)
101
+ JSON.parse(account.doc.to_json)
102
+ when account.is_a?(Hash)
103
+ doc = JSON.parse(account.to_json)
104
+ doc["account"] if doc.key?("account")
105
+ else
106
+ {}
107
+ end
108
+ end
109
+
110
+ end
111
+ end
112
+ end
113
+ end
114
+ end