deep_unrest 0.1.36 → 0.1.37

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 49fe70a86a480793222a007af3de245afc7d2bba795d3e42ba0f2e74a5791c3b
4
- data.tar.gz: 64ac3b1ffcb724b5bd5b8c15c37143da18241685cc36f76b3a7e63d9c568b461
3
+ metadata.gz: 81050e835a80fcd169a4bcfe4213d2378575ac6a87942bf07289e1b4b8c6722b
4
+ data.tar.gz: bdbbc8aa16a157a2103beb572173ea0018a251936dbe132a7e33adcb677afc77
5
5
  SHA512:
6
- metadata.gz: 5b824d05e3a002abd22057c337c6b5b948c9c54c92c148873bf4239aa47a5319bcf68dd212d9dbb3dc9093addda891a3e2bc17329677e8ae05fee5c9a245b451
7
- data.tar.gz: eb20d4d68c51fb7bb383f1e34996841195f1c44a880e2348f839c39968048032a1b2bccabfe3d1738af5e31a92f3e11a5ac84f39371182ac8d1116e1dc02ad62
6
+ metadata.gz: e02bc06a96e1bc77f6a28be4d334e847c66cce02fbe8cdc7312191f94467d8889abd734716b085c56ab9fc1ab91ecd1a0c58d3794d37fd15948407813521fb14
7
+ data.tar.gz: c85e21c88985ad241d8c571926357f1ada73a8dee802bdca4c4abebdedf8fe2a3e5469b9681623f171d40489d5b4e8a7aac7fd34141a04626e075143af9ce8db
@@ -36,7 +36,8 @@ module DeepUnrest
36
36
  destroyed << {
37
37
  type: self.class.to_s.pluralize.camelize(:lower),
38
38
  id: pk,
39
- destroyed: true
39
+ destroyed: true,
40
+ query_uuid: @deep_unrest_query_uuid
40
41
  }
41
42
  end
42
43
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DeepUnrest
4
- VERSION = '0.1.36'
4
+ VERSION = '0.1.37'
5
5
  end
@@ -6,37 +6,60 @@ module DeepUnrest
6
6
  return :destroy if item[:destroy]
7
7
  return :show if item[:readOnly] || item[:attributes].blank?
8
8
  return :create if item[:id] && DeepUnrest.temp_id?(item[:id].to_s)
9
+
9
10
  :update
10
11
  end
11
12
 
13
+ def self.create_write_mapping(k, v, addr, idx = nil)
14
+ path = k
15
+ path += '[]' if idx
16
+ resource_addr = [*addr, path]
17
+ resource_addr << idx if idx
18
+ uuid = SecureRandom.uuid
19
+ v[:uuid] = uuid
20
+ [{ klass: k.singularize.classify.constantize,
21
+ policy: "#{k.singularize.classify}Policy".constantize,
22
+ resource: "#{k.singularize.classify}Resource".constantize,
23
+ scope_type: get_scope_type(v),
24
+ addr: resource_addr,
25
+ key: k.camelize(:lower),
26
+ uuid: uuid,
27
+ query: v },
28
+ *create_write_mappings(v[:include], [*resource_addr, :include])]
29
+ end
30
+
31
+ def self.create_mapping_sequence(k, v, addr)
32
+ v.each_with_index.map do |item, idx|
33
+ create_write_mapping(k, item, addr, idx)
34
+ end
35
+ end
36
+
12
37
  def self.create_write_mappings(params, addr = [])
13
38
  return unless params
39
+
14
40
  params.map do |k, v|
15
- resource_addr = [*addr, k]
16
- uuid = SecureRandom.uuid
17
- v[:uuid] = uuid
18
- [{ klass: k.singularize.classify.constantize,
19
- policy: "#{k.singularize.classify}Policy".constantize,
20
- resource: "#{k.singularize.classify}Resource".constantize,
21
- scope_type: get_scope_type(v),
22
- addr: resource_addr,
23
- key: k.camelize(:lower),
24
- uuid: uuid,
25
- query: DeepUnrest.deep_underscore_keys(v) },
26
- *create_write_mappings(v[:included], [*resource_addr, :include])]
41
+ if v.is_a? Array
42
+ create_mapping_sequence(k, v, addr)
43
+ else
44
+ create_write_mapping(k, v, addr)
45
+ end
27
46
  end.flatten.compact
28
47
  end
29
48
 
30
49
  def self.append_ar_paths(mappings)
31
50
  mappings.each do |item|
32
51
  item[:ar_addr] = []
33
- item[:addr].each_with_index do |segment, i|
34
- next if segment == :include
35
- item[:ar_addr] << if item[:addr][i - 1] == :include
36
- "#{segment}_attributes".to_sym
37
- else
38
- segment
39
- end
52
+ addr = [*item[:addr]]
53
+ until addr.empty?
54
+ segment = addr.shift
55
+ item[:ar_addr] << segment if item[:ar_addr].empty?
56
+ next unless segment == :include
57
+
58
+ next_segment = "#{addr.shift.gsub('[]', '')}_attributes"
59
+ idx = addr.shift if addr[0].is_a? Integer
60
+ next_segment += '[]' if idx
61
+ item[:ar_addr] << next_segment
62
+ item[:ar_addr] << idx if idx
40
63
  end
41
64
  end
42
65
  end
@@ -73,18 +96,19 @@ module DeepUnrest
73
96
  end
74
97
 
75
98
  def self.build_mutation_bodies(mappings)
76
- mappings.reject { |m| m[:scope_type] == :show }
77
- .each_with_object({}) do |item, memo|
99
+ mappings.each_with_object({}) do |item, memo|
78
100
  # TODO: use pkey instead of "id"
79
- next_attrs = item.dig(:query, :attributes || {})
80
- .deep_symbolize_keys
101
+ next_attrs = (item.dig(:query, :attributes) || {})
102
+ .deep_symbolize_keys
81
103
  update_body = { id: item.dig(:query, :id),
82
104
  deep_unrest_query_uuid: item.dig(:query, :uuid),
83
- **next_attrs }
105
+ **DeepUnrest.deep_underscore_keys(next_attrs) }
84
106
  update_body[:_destroy] = true if item[:scope_type] == :destroy
85
107
  DeepUnrest.set_attr(memo, item[:ar_addr].clone, update_body)
86
-
87
- item[:mutate] = memo.fetch(*item[:ar_addr]) if item[:ar_addr].size == 1
108
+ if item[:ar_addr].size == 1
109
+ item[:mutate] = memo.fetch(*item[:ar_addr])
110
+ item[:scope_type] = :update if item[:scope_type] == :show
111
+ end
88
112
  end
89
113
  end
90
114
 
@@ -119,6 +143,7 @@ module DeepUnrest
119
143
  end
120
144
  end
121
145
 
146
+ item[:record] = record
122
147
  result = { record: record }
123
148
  if item[:temp_id]
124
149
  result[:temp_ids] = {}
@@ -141,6 +166,28 @@ module DeepUnrest
141
166
  end
142
167
  end
143
168
 
169
+ def self.addr_to_lodash_path(path_arr)
170
+ lodash_path = []
171
+ until path_arr.empty?
172
+ segment = path_arr.shift
173
+ if segment.match(/\[\]$/)
174
+ idx = path_arr.shift
175
+ segment = "#{segment.gsub('[]', '')}[#{idx}]"
176
+ end
177
+ lodash_path << segment
178
+ end
179
+ lodash_path.join('.')
180
+ end
181
+
182
+ def self.serialize_destroyed(_ctx, mappings, destroyed)
183
+ destroyed.select { |d| d[:query_uuid] }
184
+ .map do |d|
185
+ mapping = mappings.find { |m| m.dig(:query, :uuid) == d[:query_uuid] }
186
+ lodash_path = addr_to_lodash_path(mapping[:addr])
187
+ { id: d[:id], path: lodash_path, type: mapping[:key].pluralize }
188
+ end
189
+ end
190
+
144
191
  def self.serialize_errors(mappings)
145
192
  { errors: mappings.each_with_object({}) do |item, memo|
146
193
  err = {
@@ -152,10 +199,36 @@ module DeepUnrest
152
199
  end }.to_json
153
200
  end
154
201
 
202
+ def self.format_ar_error_path(base, ar_path)
203
+ path_arr = ar_path.gsub(/\.(?!\w+$)/, '.included.')
204
+ .gsub(/\.(?=\w+$)/, '.attributes.\1')
205
+ .gsub(/\[(\d+)\]/, '[].\1')
206
+ .split('.')
207
+
208
+ if path_arr.size == 1
209
+ path_arr.unshift('attributes')
210
+ elsif path_arr.size > 1
211
+ path_arr.unshift('included')
212
+ end
213
+
214
+ [*base, *path_arr]
215
+ end
216
+
217
+ def self.map_ar_errors_to_param_keys(mappings)
218
+ mappings
219
+ .each_with_object({}) do |item, memo|
220
+ item[:record]&.errors&.messages&.each do |ar_path, msg|
221
+ err_path = format_ar_error_path(item[:addr], ar_path.to_s)
222
+ DeepUnrest.set_attr(memo, err_path, msg)
223
+ end
224
+ end
225
+ end
226
+
155
227
  def self.write(ctx, params, user)
156
228
  temp_id_map = DeepUnrest::ApplicationController.class_variable_get(
157
229
  '@@temp_ids'
158
230
  )
231
+ temp_id_map[ctx[:uuid]] ||= {}
159
232
 
160
233
  # create mappings for assembly / disassembly
161
234
  mappings = create_write_mappings(params.to_unsafe_h)
@@ -173,7 +246,7 @@ module DeepUnrest
173
246
  build_mutation_bodies(mappings)
174
247
 
175
248
  # convert temp_ids from ids to non-activerecord attributes
176
- DeepUnrest.convert_temp_ids!(ctx[:uuid], mappings)
249
+ DeepUnrest.convert_temp_ids!(ctx[:uuid], mappings.select { |m| m[:mutate] })
177
250
 
178
251
  # save data, run callbaks
179
252
  results = execute_queries(mappings, ctx)
@@ -195,13 +268,13 @@ module DeepUnrest
195
268
 
196
269
  return {
197
270
  temp_ids: temp_id_map[ctx[:uuid]],
198
- destroyed: destroyed,
271
+ destroyed: serialize_destroyed(ctx, mappings, destroyed),
199
272
  changed: serialize_changes(ctx, mappings, changed)
200
273
  }
201
274
  end
202
275
 
203
276
  # map errors to their sources
204
- formatted_errors = { errors: map_errors_to_param_keys(scopes, errors) }
277
+ formatted_errors = { errors: map_ar_errors_to_param_keys(mappings) }
205
278
 
206
279
  # raise error if there are any errors
207
280
  raise DeepUnrest::Conflict, formatted_errors.to_json
data/lib/deep_unrest.rb CHANGED
@@ -319,6 +319,8 @@ module DeepUnrest
319
319
  mutations.map { |val| convert_temp_ids!(ctx, val) }
320
320
  end
321
321
  mutations
322
+ rescue Exception => e
323
+ binding.pry
322
324
  end
323
325
 
324
326
  def self.build_mutation_fragment(op, scopes, user, err_path_memo, rest = nil, memo = nil, cursor = nil, type = nil)
@@ -373,11 +375,12 @@ module DeepUnrest
373
375
  def self.set_attr(hash, path, val, cursor = nil)
374
376
  cursor ||= hash
375
377
  key = path.shift
378
+ key = key.to_i if cursor.is_a? Array
376
379
 
377
380
  if path.empty?
378
381
  case cursor
379
382
  when Array
380
- cursor << val
383
+ cursor[key] = val
381
384
  when Hash
382
385
  cursor[key] = val
383
386
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: deep_unrest
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.36
4
+ version: 0.1.37
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lynn Hurley
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-08-14 00:00:00.000000000 Z
11
+ date: 2019-08-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails