foobara 0.0.89 → 0.0.91

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: 424a065d4e4a0543f55ac9c3b7c0c87db4a5f334241c5b8e5a46b44a45907a55
4
- data.tar.gz: ec082f769eaae6bc5f9b4dd079722b044e417243ad1cf0cabcf0c21b9648efa6
3
+ metadata.gz: afa85ac4f9b3b8a144859108c7d4273fc290449bcf831cc6a3ff6c9445530f10
4
+ data.tar.gz: 918c40b8fd082cc4982d984716b7f7e0fbaac6f2110d445bc248d4985dfa2726
5
5
  SHA512:
6
- metadata.gz: 5b6b51362c480c26f1690c17874607a2bcf34d14b6d3882665798efe6511e3fc2f602214cae1b005dd788cf23f33a68a4c1781b631108248e2bb1baca0ed0204
7
- data.tar.gz: 2e910c95484b092eb2bfdef1eeed079f99794801a3bb345efc0291f51ca1b832301f3540e454b0bd749d9028b591bbc3b919a0301d03db965e576644c9c72284
6
+ metadata.gz: 2aca63aa3477913c4289896d64b62a53065951da6d7c24982fa7ec8569a97bfc490320ffa002a1f219b97ee205dc2230bd3c5a66def92932da42df133a600ced
7
+ data.tar.gz: 26546b93d55db31c3c88a322dcc1cd472ab2be4392b8410f1a1206a25f060f86b3be2db2628d2cf3897c0b461844acff52bd063a299ab917c0c05c22119cb4ac
data/CHANGELOG.md CHANGED
@@ -1,3 +1,12 @@
1
+ # [0.0.91] - 2025-03-31
2
+
3
+ - Fix bug that was including removed types in command manifest's inputs_types_depended_on
4
+ - Hoist authentication check up into command connector further from transformed command
5
+
6
+ # [0.0.90] - 2025-03-29
7
+
8
+ - Implement request mutator concept
9
+
1
10
  # [0.0.89] - 2025-03-29
2
11
 
3
12
  - Make attributes transformers work with either a from type or a to type
@@ -17,6 +17,7 @@ module Foobara
17
17
  # On exposed command? On the command registry? On the command connector?
18
18
  # This is the easiest place to implement them but feels awkward.
19
19
  :response_mutators,
20
+ :request_mutators,
20
21
  :allowed_rule,
21
22
  :requires_authentication,
22
23
  :authenticator
@@ -32,6 +33,7 @@ module Foobara
32
33
  pre_commit_transformers:,
33
34
  serializers:,
34
35
  response_mutators:,
36
+ request_mutators:,
35
37
  allowed_rule:,
36
38
  requires_authentication:,
37
39
  authenticator:,
@@ -64,6 +66,7 @@ module Foobara
64
66
  klass.pre_commit_transformers = Util.array(pre_commit_transformers)
65
67
  klass.serializers = Util.array(serializers)
66
68
  klass.response_mutators = Util.array(response_mutators)
69
+ klass.request_mutators = Util.array(request_mutators)
67
70
  klass.allowed_rule = allowed_rule
68
71
  klass.requires_authentication = requires_authentication
69
72
  klass.authenticator = authenticator
@@ -126,6 +129,18 @@ module Foobara
126
129
  @result_type_for_manifest = mutated_result_type
127
130
  end
128
131
 
132
+ def inputs_type_for_manifest
133
+ return @inputs_type_for_manifest if defined?(@inputs_type_for_manifest)
134
+
135
+ mutated_inputs_type = inputs_type
136
+
137
+ request_mutators&.each do |mutator|
138
+ mutated_inputs_type = mutator.instance.inputs_type_from(mutated_inputs_type)
139
+ end
140
+
141
+ @inputs_type_for_manifest = mutated_inputs_type
142
+ end
143
+
129
144
  def error_context_type_map
130
145
  @error_context_type_map ||= begin
131
146
  set = {}
@@ -165,6 +180,14 @@ module Foobara
165
180
  end.sort.to_h
166
181
  end
167
182
 
183
+ def inputs_types_depended_on
184
+ inputs_type&.types_depended_on || []
185
+ end
186
+
187
+ def result_types_depended_on(remove_sensitive: true)
188
+ result_type&.types_depended_on(remove_sensitive:) || []
189
+ end
190
+
168
191
  def types_depended_on(remove_sensitive: true)
169
192
  # TODO: memoize this
170
193
  # TODO: this should not delegate to command since transformers are in play
@@ -173,29 +196,29 @@ module Foobara
173
196
  type = inputs_type
174
197
 
175
198
  if type != command_class.inputs_type
176
- types |= if type.registered?
177
- # TODO: if we ever change from attributes-only inputs type
178
- # then this will be handy
179
- # :nocov:
180
- [type]
181
- # :nocov:
182
- else
183
- type.types_depended_on(remove_sensitive:)
184
- end
199
+ if type.registered?
200
+ # TODO: if we ever change from attributes-only inputs type
201
+ # then this will be handy
202
+ # :nocov:
203
+ types |= [type]
204
+ # :nocov:
205
+ end
206
+
207
+ types |= type.types_depended_on
185
208
  end
186
209
 
187
210
  type = result_type
188
211
 
189
212
  if type != command_class.result_type
190
- types |= if type.registered?
191
- # TODO: if we ever change from attributes-only inputs type
192
- # then this will be handy
193
- # :nocov:
194
- [type]
195
- # :nocov:
196
- else
197
- type.types_depended_on(remove_sensitive:)
198
- end
213
+ if type.registered?
214
+ # TODO: if we ever change from attributes-only inputs type
215
+ # then this will be handy
216
+ # :nocov:
217
+ types |= [type]
218
+ # :nocov:
219
+ end
220
+
221
+ types |= type.types_depended_on(remove_sensitive:)
199
222
  end
200
223
 
201
224
  possible_errors.each do |possible_error|
@@ -226,11 +249,29 @@ module Foobara
226
249
  end
227
250
 
228
251
  response_mutators = self.response_mutators.map { |t| t.foobara_manifest(to_include:) }
252
+ request_mutators = self.request_mutators.map { |t| t.foobara_manifest(to_include:) }
253
+
254
+ authenticator_manifest = if authenticator
255
+ if authenticator.respond_to?(:foobara_manifest)
256
+ # TODO: test this path
257
+ # :nocov:
258
+ authenticator.foobara_manifest(to_include:)
259
+ # :nocov:
260
+ else
261
+ true
262
+ end
263
+ end
264
+
265
+ inputs_types_depended_on = self.inputs_types_depended_on.map(&:foobara_manifest_reference).sort
266
+ result_types_depended_on = self.result_types_depended_on(remove_sensitive:).map(&:foobara_manifest_reference)
267
+ result_types_depended_on = result_types_depended_on.sort
229
268
 
230
269
  command_class.foobara_manifest(to_include:, remove_sensitive:).merge(
231
270
  Util.remove_blank(
271
+ inputs_types_depended_on:,
272
+ result_types_depended_on:,
232
273
  types_depended_on: types,
233
- inputs_type: inputs_type&.reference_or_declaration_data,
274
+ inputs_type: inputs_type_for_manifest&.reference_or_declaration_data,
234
275
  result_type: result_type_for_manifest&.reference_or_declaration_data(remove_sensitive:),
235
276
  possible_errors: possible_errors_manifest(to_include:, remove_sensitive:),
236
277
  capture_unknown_error:,
@@ -240,8 +281,9 @@ module Foobara
240
281
  pre_commit_transformers:,
241
282
  serializers:,
242
283
  response_mutators:,
284
+ request_mutators:,
243
285
  requires_authentication:,
244
- authenticator: authenticator&.manifest
286
+ authenticator: authenticator_manifest
245
287
  )
246
288
  )
247
289
  end
@@ -285,6 +327,29 @@ module Foobara
285
327
  end
286
328
  end
287
329
 
330
+ def request_mutator
331
+ return @request_mutator if defined?(@request_mutator)
332
+
333
+ if request_mutators.empty?
334
+ @request_mutator = nil
335
+ return
336
+ end
337
+
338
+ @request_mutator = begin
339
+ transformers = transformers_to_processors(request_mutators, result_type, direction: :to)
340
+
341
+ if transformers.size == 1
342
+ transformers.first
343
+ else
344
+ Value::Processor::Pipeline.new(processors: transformers)
345
+ end
346
+ end
347
+ end
348
+
349
+ def mutate_request(request)
350
+ request_mutator&.process_value!(request)
351
+ end
352
+
288
353
  def result_transformer
289
354
  return @result_transformer if defined?(@result_transformer)
290
355
 
@@ -354,7 +419,6 @@ module Foobara
354
419
  to: :class
355
420
 
356
421
  def run
357
- authenticate if requires_authentication?
358
422
  apply_allowed_rule
359
423
  apply_pre_commit_transformers
360
424
  run_command
@@ -442,19 +506,6 @@ module Foobara
442
506
  self.command = command_class.new(transformed_inputs)
443
507
  end
444
508
 
445
- def authenticate
446
- command.after_load_records do |command:, **|
447
- self.authenticated_user = instance_eval(&:authenticator)
448
-
449
- unless authenticated_user
450
- self.outcome = Outcome.error(CommandConnector::UnauthenticatedError.new)
451
-
452
- command.state_machine.error!
453
- command.halt!
454
- end
455
- end
456
- end
457
-
458
509
  def apply_allowed_rule
459
510
  rule = allowed_rule
460
511
 
@@ -4,8 +4,7 @@ module Foobara
4
4
  include TruncatedInspect
5
5
 
6
6
  # TODO: this feels like a smell of some sort...
7
- attr_accessor :command_class,
8
- :command,
7
+ attr_accessor :command,
9
8
  :error,
10
9
  :command_connector,
11
10
  :serializers,
@@ -13,6 +12,8 @@ module Foobara
13
12
  :full_command_name,
14
13
  :action
15
14
 
15
+ attr_reader :command_class
16
+
16
17
  def initialize(**opts)
17
18
  valid_keys = %i[inputs full_command_name action]
18
19
 
@@ -29,6 +30,15 @@ module Foobara
29
30
  self.full_command_name = opts[:full_command_name] if opts.key?(:full_command_name)
30
31
  end
31
32
 
33
+ def command_class=(klass)
34
+ @command_class = klass
35
+
36
+ # TODO: we really need to revisit these interfaces. Something is wrong.
37
+ if command_class.respond_to?(:mutate_request)
38
+ command_class.mutate_request(self)
39
+ end
40
+ end
41
+
32
42
  def serializer
33
43
  return @serializer if defined?(@serializer)
34
44
 
@@ -338,6 +338,10 @@ module Foobara
338
338
  # TODO: feels like a smell
339
339
  request.command_connector = self
340
340
 
341
+ if command.respond_to?(:requires_authentication?) && command.requires_authentication?
342
+ authenticate(request)
343
+ end
344
+
341
345
  if command
342
346
  command.run
343
347
  # :nocov:
@@ -349,6 +353,23 @@ module Foobara
349
353
  build_response(request)
350
354
  end
351
355
 
356
+ def authenticate(request)
357
+ request_command = request.command
358
+
359
+ request_command.after_load_records do |command:, **|
360
+ authenticated_user = request.instance_eval(&authenticator)
361
+
362
+ request_command.authenticated_user = authenticated_user
363
+
364
+ unless authenticated_user
365
+ request_command.outcome = Outcome.error(CommandConnector::UnauthenticatedError.new)
366
+
367
+ command.state_machine.error!
368
+ command.halt!
369
+ end
370
+ end
371
+ end
372
+
352
373
  def build_request_and_command(...)
353
374
  request = build_request(...)
354
375
 
@@ -12,6 +12,7 @@ module Foobara
12
12
  :errors_transformers,
13
13
  :pre_commit_transformers,
14
14
  :serializers,
15
+ :request_mutators,
15
16
  :response_mutators,
16
17
  :allowed_rule,
17
18
  :requires_authentication,
@@ -29,6 +30,7 @@ module Foobara
29
30
  errors_transformers: nil,
30
31
  pre_commit_transformers: nil,
31
32
  response_mutators: nil,
33
+ request_mutators: nil,
32
34
  serializers: nil,
33
35
  allowed_rule: nil,
34
36
  requires_authentication: nil,
@@ -79,6 +81,7 @@ module Foobara
79
81
  self.errors_transformers = errors_transformers
80
82
  self.pre_commit_transformers = pre_commit_transformers
81
83
  self.response_mutators = response_mutators
84
+ self.request_mutators = request_mutators
82
85
  self.serializers = serializers
83
86
  self.allowed_rule = allowed_rule
84
87
  self.requires_authentication = requires_authentication
@@ -115,6 +118,7 @@ module Foobara
115
118
  errors_transformers,
116
119
  pre_commit_transformers,
117
120
  response_mutators,
121
+ request_mutators,
118
122
  serializers,
119
123
  allowed_rule,
120
124
  requires_authentication,
@@ -135,6 +139,7 @@ module Foobara
135
139
  errors_transformers:,
136
140
  pre_commit_transformers:,
137
141
  response_mutators:,
142
+ request_mutators:,
138
143
  serializers:,
139
144
  allowed_rule:,
140
145
  requires_authentication:,
@@ -0,0 +1,24 @@
1
+ module Foobara
2
+ module CommandConnectors
3
+ class RequestMutator < Foobara::Value::Mutator
4
+ def inputs_type_declaration_from(_inputs_type)
5
+ # :nocov:
6
+ raise "subclass responsibility"
7
+ # :nocov:
8
+ end
9
+
10
+ def inputs_type_from(inputs_type)
11
+ declaration = inputs_type_declaration_from(inputs_type)
12
+ Foobara::Domain.current.foobara_type_from_declaration(declaration)
13
+ end
14
+
15
+ def mutate
16
+ # :nocov:
17
+ raise "subclass responsibility"
18
+ # :nocov:
19
+ end
20
+
21
+ alias request declaration_data
22
+ end
23
+ end
24
+ end
@@ -3,6 +3,10 @@ module Foobara
3
3
  class Command < BaseManifest
4
4
  self.category_symbol = :command
5
5
 
6
+ def requires_authentication?
7
+ !!self[:requires_authentication]
8
+ end
9
+
6
10
  def command_manifest
7
11
  relevant_manifest
8
12
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: foobara
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.89
4
+ version: 0.0.91
5
5
  platform: ruby
6
6
  authors:
7
7
  - Miles Georgi
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-03-29 00:00:00.000000000 Z
10
+ date: 2025-03-31 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: bigdecimal
@@ -179,6 +179,7 @@ files:
179
179
  - projects/command_connectors/src/command_registry/exposed_command.rb
180
180
  - projects/command_connectors/src/command_registry/exposed_domain.rb
181
181
  - projects/command_connectors/src/command_registry/exposed_organization.rb
182
+ - projects/command_connectors/src/request_mutator.rb
182
183
  - projects/command_connectors/src/response_mutator.rb
183
184
  - projects/command_connectors/src/serializer.rb
184
185
  - projects/command_connectors/src/serializers/aggregate_serializer.rb