foobara 0.0.126 → 0.0.127

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.
Files changed (19) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +8 -1
  3. data/projects/builtin_types/src/attributes/supported_transformers/defaults/type_declaration_extension/extend_attributes_type_declaration/desugarizers/move_defaults_from_element_types_to_root.rb +1 -1
  4. data/projects/builtin_types/src/attributes/supported_validators/required/type_declaration_extension/extend_attributes_type_declaration/desugarizers/move_required_from_element_types_to_root.rb +1 -1
  5. data/projects/builtin_types/src/duck/supported_validators/instance_of/type_declaration_extension/extend_registered_type_declaration/desugarizers/class_type_desugarizer.rb +32 -0
  6. data/projects/builtin_types/src/duck/supported_validators/instance_of.rb +10 -0
  7. data/projects/command/src/command_pattern_implementation/concerns/inputs.rb +0 -2
  8. data/projects/command/src/command_pattern_implementation/concerns/runtime.rb +2 -1
  9. data/projects/command_connectors/src/transformed_command.rb +25 -0
  10. data/projects/detached_entity/src/concerns/associations.rb +1 -1
  11. data/projects/domain_mapper/src/domain_mapper_lookups.rb +2 -2
  12. data/projects/model/src/extensions/type_declarations/handlers/extend_registered_model_type_declaration.rb +1 -0
  13. data/projects/nested_transactionable/lib/foobara/nested_transactionable.rb +27 -0
  14. data/projects/type_declarations/src/handlers/extend_attributes_type_declaration/hash_desugarizer.rb +2 -1
  15. data/projects/type_declarations/src/handlers/extend_attributes_type_declaration/to_type_transformer.rb +1 -1
  16. data/projects/type_declarations/src/handlers/registered_type_declaration.rb +3 -1
  17. data/projects/types/src/type.rb +23 -5
  18. data/projects/value/src/processor/casting.rb +3 -3
  19. metadata +3 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1d3daa4a78757b936511e8ed15cf5226c243d0fcb1c8cc28e7dafd466127bff0
4
- data.tar.gz: 7c58b71185cb2ccffed937aa922170f70186295933e65586f57b1c8429d0875f
3
+ metadata.gz: 531c75e332f6e7cc297b0b56689d91f59737040fe533814a8b780defc937b2aa
4
+ data.tar.gz: 16dd8725423abe9155c1fd5b89c752271ce568ec83cca52c7654204ee114f559
5
5
  SHA512:
6
- metadata.gz: f1a61199416081a65ae3dda56809859fc0d036818d817bdc2885f627742ec81db2f31c3b599e8aad0de4dbb7a139b027e51e3a77e897013c2d4e2ca2391267bb
7
- data.tar.gz: 6e245ef28b841f54e9f84353cf4b689fc29edee3b41ab997436788835676299bd6f78a9708643f1cab2293edfbb6a53bd6841bf5bfbe61668c5950c2229d23f0
6
+ metadata.gz: 9c97ed1f00a114ea3ff8e1932cb32a13e8e538b1a0dc694f542060febafcae9e515e4888695cdbeede192e490ea280e6bddf8bf54b64e6339fe7adeaaeaa42a1
7
+ data.tar.gz: 4e414afd9090bc83685ce1b2e30fb31948963f4d57cff4d77ba4aa698547e716fd5a562442845f60cd8e6affb06263797fcf0c539a7f5478fceb9dec6b1412de
data/CHANGELOG.md CHANGED
@@ -1,6 +1,13 @@
1
+ # [0.0.127] - 2025-05-25
2
+
3
+ - Add better support for using ruby classes as types
4
+ - Support using :attributes as a type directly
5
+ - Make TransformedCommand#inputs reflect actual received inputs not transformed inputs
6
+ - Add NestedTransactionable.with_needed_transactions_for_type
7
+
1
8
  # [0.0.126] - 2025-05-21
2
9
 
3
- - Fix bugs with transations, Command.depends_on
10
+ - Fix bugs with transactions, Command.depends_on
4
11
  - Allow anonymous commands
5
12
  - Add CommandConnector#all_exposed_type_names
6
13
 
@@ -8,7 +8,7 @@ module Foobara
8
8
  module Desugarizers
9
9
  class MoveDefaultsFromElementTypesToRoot < TypeDeclarations::Desugarizer
10
10
  def applicable?(value)
11
- value.is_a?(::Hash) && value[:type] == :attributes
11
+ value.is_a?(::Hash) && value[:type] == :attributes && value.key?(:element_type_declarations)
12
12
  end
13
13
 
14
14
  def desugarize(rawish_type_declaration)
@@ -8,7 +8,7 @@ module Foobara
8
8
  module Desugarizers
9
9
  class MoveRequiredFromElementTypesToRoot < TypeDeclarations::Desugarizer
10
10
  def applicable?(value)
11
- value.is_a?(::Hash) && value[:type] == :attributes
11
+ value.is_a?(::Hash) && value[:type] == :attributes && value.key?(:element_type_declarations)
12
12
  end
13
13
 
14
14
  def desugarize(rawish_type_declaration)
@@ -0,0 +1,32 @@
1
+ module Foobara
2
+ module BuiltinTypes
3
+ module Duck
4
+ module SupportedValidators
5
+ class InstanceOf < TypeDeclarations::Validator
6
+ module TypeDeclarationExtension
7
+ module ExtendRegisteredTypeDeclaration
8
+ module Desugarizers
9
+ class ClassTypeDesugarizer < TypeDeclarations::Desugarizer
10
+ def applicable?(rawish_type_declaration)
11
+ return false unless rawish_type_declaration.is_a?(::Hash)
12
+
13
+ rawish_type_declaration[:type].is_a?(::Class)
14
+ end
15
+
16
+ def desugarize(rawish_type_declaration)
17
+ klass = rawish_type_declaration[:type]
18
+ rawish_type_declaration.merge(type: :duck, instance_of: klass.name)
19
+ end
20
+
21
+ def priority
22
+ Priority::LOWEST + 1
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -14,6 +14,16 @@ module Foobara
14
14
  end
15
15
  end
16
16
 
17
+ class << self
18
+ def requires_parent_declaration_data?
19
+ true
20
+ end
21
+ end
22
+
23
+ def applicable?(value)
24
+ !value.nil? || !parent_declaration_data[:allow_nil]
25
+ end
26
+
17
27
  def expected_class_name
18
28
  declaration_data
19
29
  end
@@ -31,8 +31,6 @@ module Foobara
31
31
  inputs_type&.element_types&.key?(method_name)
32
32
  end
33
33
 
34
- foobara_delegate :inputs_type, to: :class
35
-
36
34
  def cast_and_validate_inputs
37
35
  if inputs_type.nil? && (raw_inputs.nil? || raw_inputs.empty?)
38
36
  @inputs = {}
@@ -67,7 +67,8 @@ module Foobara
67
67
  end
68
68
 
69
69
  def run_execute
70
- result = process_result_using_result_type(execute)
70
+ raw_result = execute
71
+ result = process_result_using_result_type(raw_result)
71
72
  @outcome = Outcome.success(result)
72
73
  end
73
74
 
@@ -578,6 +578,7 @@ module Foobara
578
578
  def run
579
579
  apply_allowed_rule
580
580
  apply_pre_commit_transformers
581
+ set_inputs
581
582
  run_command
582
583
  # this gives us primary keys
583
584
  flush_transactions
@@ -609,6 +610,22 @@ module Foobara
609
610
  end
610
611
  end
611
612
 
613
+ def inputs
614
+ return @inputs if defined?(@inputs)
615
+
616
+ @inputs = if inputs_type
617
+ outcome = inputs_type.process_value(untransformed_inputs)
618
+
619
+ if outcome.success?
620
+ outcome.result
621
+ else
622
+ untransformed_inputs
623
+ end
624
+ else
625
+ {}
626
+ end
627
+ end
628
+
612
629
  def transform_result
613
630
  if self.class.result_transformer
614
631
  self.outcome = Outcome.success(self.class.result_transformer.process_value!(result))
@@ -723,6 +740,14 @@ module Foobara
723
740
  end
724
741
  end
725
742
 
743
+ def set_inputs
744
+ if self.class.inputs_type
745
+ command.after_cast_and_validate_inputs do |**|
746
+ inputs
747
+ end
748
+ end
749
+ end
750
+
726
751
  def run_command
727
752
  outcome = command.run
728
753
  self.outcome = outcome if outcome
@@ -187,7 +187,7 @@ module Foobara
187
187
  construct_associations(element_type, path.append(:"#"), result, initial: false)
188
188
  end
189
189
  elsif type.extends?(BuiltinTypes[:attributes]) # TODO: matches attributes itself instead of only subtypes
190
- type.element_types.each_pair do |attribute_name, element_type|
190
+ type.element_types&.each_pair do |attribute_name, element_type|
191
191
  if remove_sensitive && element_type.sensitive?
192
192
  next
193
193
  end
@@ -89,9 +89,9 @@ module Foobara
89
89
 
90
90
  unless strict
91
91
  if from
92
- lookup_matching_domain_mapper(from: nil, to:)
92
+ lookup_matching_domain_mapper(from: nil, to:, criteria:)
93
93
  elsif to
94
- lookup_matching_domain_mapper(from:, to: nil)
94
+ lookup_matching_domain_mapper(from:, to: nil, criteria:)
95
95
  end
96
96
  end
97
97
  end
@@ -10,6 +10,7 @@ module Foobara
10
10
  type_symbol = strict_type_declaration[:type]
11
11
 
12
12
  return false if type_symbol == expected_type_symbol
13
+ return false unless type_symbol.is_a?(::Symbol) || type_symbol.is_a?(::String)
13
14
 
14
15
  if type_registered?(type_symbol)
15
16
  type = lookup_type!(type_symbol)
@@ -17,6 +17,33 @@ module Foobara
17
17
 
18
18
  entity_classes.uniq
19
19
  end
20
+
21
+ def with_needed_transactions_for_type(type, &)
22
+ relevant_entity_classes = relevant_entity_classes_for_type(type)
23
+
24
+ if relevant_entity_classes.empty?
25
+ return yield
26
+ end
27
+
28
+ tx_class = Class.new
29
+ tx_class.include NestedTransactionable
30
+
31
+ tx_class.define_method(:relevant_entity_classes) do
32
+ relevant_entity_classes
33
+ end
34
+
35
+ tx_instance = tx_class.new
36
+
37
+ begin
38
+ tx_instance.open_transaction
39
+ result = Persistence::EntityBase.using_transactions(tx_instance.transactions, &)
40
+ tx_instance.commit_transaction
41
+ result
42
+ rescue
43
+ tx_instance.rollback_transaction
44
+ raise
45
+ end
46
+ end
20
47
  end
21
48
 
22
49
  def relevant_entity_classes_for_type(type)
@@ -17,7 +17,8 @@ module Foobara
17
17
  type_symbol = sugary_type_declaration[:type]
18
18
 
19
19
  if [:attributes, "attributes"].include?(type_symbol)
20
- Util.all_symbolizable_keys?(sugary_type_declaration[:element_type_declarations])
20
+ sugary_type_declaration.key?(:element_type_declarations) &&
21
+ Util.all_symbolizable_keys?(sugary_type_declaration[:element_type_declarations])
21
22
  elsif type_symbol.is_a?(::Symbol)
22
23
  # Why is this done?
23
24
  !type_registered?(type_symbol)
@@ -9,7 +9,7 @@ module Foobara
9
9
  def transform(strict_type_declaration)
10
10
  super.tap do |type|
11
11
  type_declarations = type.declaration_data[:element_type_declarations]
12
- type.element_types = type_declarations.transform_values do |attribute_declaration|
12
+ type.element_types = type_declarations&.transform_values do |attribute_declaration|
13
13
  type_for_declaration(attribute_declaration)
14
14
  end
15
15
  end
@@ -13,7 +13,9 @@ module Foobara
13
13
  # we only handle case where it's a builtin type not an extension of one
14
14
  if strict_type_declaration.keys == [:type]
15
15
  type_symbol = strict_type_declaration[:type]
16
- type_registered?(type_symbol)
16
+ if type_symbol.is_a?(::Symbol) || type_symbol.is_a?(::String)
17
+ type_registered?(type_symbol)
18
+ end
17
19
  end
18
20
  end
19
21
 
@@ -35,7 +35,7 @@ module Foobara
35
35
  :element_type
36
36
 
37
37
  def initialize(
38
- *,
38
+ declaration_data,
39
39
  target_classes:,
40
40
  base_type:,
41
41
  description: nil,
@@ -52,10 +52,12 @@ module Foobara
52
52
  sensitive_exposed: nil,
53
53
  **opts
54
54
  )
55
+ self.declaration_data = declaration_data
55
56
  self.sensitive = sensitive
56
57
  self.sensitive_exposed = sensitive_exposed
57
58
  self.base_type = base_type
58
59
  self.description = description
60
+ self.name = name
59
61
  self.casters = [*casters, *base_type&.casters]
60
62
  self.transformers = [*transformers, *base_type&.transformers]
61
63
  self.validators = [*validators, *base_type&.validators]
@@ -65,11 +67,10 @@ module Foobara
65
67
  # TODO: combine these maybe with the term "children_types"?
66
68
  self.element_types = element_types
67
69
  self.element_type = element_type
68
- self.name = name
69
70
  self.target_classes = Util.array(target_classes)
70
71
  self.processor_classes_requiring_type = processor_classes_requiring_type
71
72
 
72
- super(*, **opts.merge(processors:, prioritize: false))
73
+ super(declaration_data, **opts.merge(processors:, prioritize: false))
73
74
 
74
75
  apply_all_processors_needing_type!
75
76
 
@@ -274,8 +275,25 @@ module Foobara
274
275
  end
275
276
 
276
277
  def value_caster
277
- # TODO: how can declaration_data be blank? That seems really strange...
278
- Value::Processor::Casting.new({ cast_to: declaration_data }, casters:, target_classes:)
278
+ # TODO: figure out what would be needed to successfully memoize this
279
+ # return @value_caster if defined?(@value_caster)
280
+
281
+ # We make this exception for :duck because it will match any instance of
282
+ # Object but AllowNil will match nil which is also an instance of Object.
283
+ # This results in two matching casters. Instead of figuring out a way to make one
284
+ # conditional on the other we will just turn off this unique enforcement for :duck
285
+ enforce_unique = if declaration_data.is_a?(::Hash)
286
+ declaration_data[:type] != :duck
287
+ else
288
+ true
289
+ end
290
+
291
+ Value::Processor::Casting.new(
292
+ { cast_to: declaration_data },
293
+ casters:,
294
+ target_classes:,
295
+ enforce_unique:
296
+ )
279
297
  end
280
298
 
281
299
  def applicable?(value)
@@ -39,7 +39,7 @@ module Foobara
39
39
 
40
40
  attr_accessor :target_classes
41
41
 
42
- def initialize(*, casters:, target_classes: nil)
42
+ def initialize(*, casters:, target_classes: nil, **)
43
43
  self.target_classes = Util.array(target_classes)
44
44
 
45
45
  processors = [
@@ -47,7 +47,7 @@ module Foobara
47
47
  *casters
48
48
  ]
49
49
 
50
- super(*, processors:)
50
+ super(*, processors:, **)
51
51
  end
52
52
 
53
53
  def needs_cast?(value)
@@ -113,7 +113,7 @@ module Foobara
113
113
  build_error(*args)
114
114
  elsif error_class == MoreThanOneApplicableProcessorError
115
115
  # :nocov:
116
- raise "Matched too many casters for #{args.inspect} with #{opts.inspect}"
116
+ raise "Matched too many casters for #{args.map(&:inspect).join(",")} with #{opts.inspect}"
117
117
  # :nocov:
118
118
  else
119
119
  super
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.126
4
+ version: 0.0.127
5
5
  platform: ruby
6
6
  authors:
7
7
  - Miles Georgi
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-05-21 00:00:00.000000000 Z
10
+ date: 2025-05-26 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: bigdecimal
@@ -116,6 +116,7 @@ files:
116
116
  - projects/builtin_types/src/duck/supported_casters/allow_nil.rb
117
117
  - projects/builtin_types/src/duck/supported_validators/instance_of.rb
118
118
  - projects/builtin_types/src/duck/supported_validators/instance_of/type_declaration_extension/extend_registered_type_declaration/desugarizers/class_desugarizer.rb
119
+ - projects/builtin_types/src/duck/supported_validators/instance_of/type_declaration_extension/extend_registered_type_declaration/desugarizers/class_type_desugarizer.rb
119
120
  - projects/builtin_types/src/duck/supported_validators/instance_of/type_declaration_extension/extend_registered_type_declaration/desugarizers/instance_of_class_desugarizer.rb
120
121
  - projects/builtin_types/src/duck/supported_validators/instance_of/type_declaration_extension/extend_registered_type_declaration/desugarizers/instance_of_symbol_desugarizer.rb
121
122
  - projects/builtin_types/src/duck/supported_validators/instance_of/type_declaration_extension/extend_registered_type_declaration/type_declaration_validators/is_valid_class.rb