foobara 0.2.5 → 0.2.7

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: e05617e8bea9b7a9ce861246a1a5c664ad3b525630dd1cd7362b80b4d6d809ea
4
- data.tar.gz: 10bd954f202f83aef9a20f0dec859212766a81e9682f6526ece70e3cd457b6a7
3
+ metadata.gz: 4f5b2b0f1316a7d5530778566c64df6cffafb44dfdb99e5fd4797de2fbe3b0a2
4
+ data.tar.gz: 9819421a3b7dafcb39ac4d3dadb3b7a8ee2967648abf9adad4cc2fd094769bf3
5
5
  SHA512:
6
- metadata.gz: 26fa0c9be295542f963963ac892405a315d5b6f004fadcdf23336bab09ad973cdae843186134c20c1e173be816506c37f2ad34e825c6d84f2c2ef42845262011
7
- data.tar.gz: efefbce7b11751d240a09ca34bc5e20a182c60daa00cc79399aceee55c74e33b8b1135aca706abd2a8d3e80c39414477a19d3fee05cc28bdd0e13b063d6fda77
6
+ metadata.gz: 388210bea30291de942b1b42b80c5105c31a8f74a039e33ac42700c85f8052e7f229390eb57214a15d7cda3ba76767fa4934cf8c8bb2dae187dbce22ee72a631
7
+ data.tar.gz: bfb8114f0b127c60389fa83d0d6145178a6b3e6e28418ec2a7faaf645c16ff31d5075688edcd6005ea33fb67e02a76155286dc0cc4a93b5ad710787b2d93ad4d
data/CHANGELOG.md CHANGED
@@ -1,3 +1,11 @@
1
+ # [0.2.7] - 2025-11-10
2
+
3
+ - Fix CommandConnector authorization bug that can fail to close transactions
4
+
5
+ # [0.2.6] - 2025-10-30
6
+
7
+ - Add a set inputs transformer
8
+
1
9
  # [0.2.5] - 2025-10-27
2
10
 
3
11
  - Do not allow commands to be connected multiple times via symbol/string
@@ -17,6 +17,7 @@ module Foobara
17
17
  CommandConnector.add_desugarizer Desugarizers.rename :response, :response_mutators
18
18
  CommandConnector.add_desugarizer Desugarizers::Attributes::OnlyInputs
19
19
  CommandConnector.add_desugarizer Desugarizers::Attributes::RejectInputs
20
+ CommandConnector.add_desugarizer Desugarizers::SetInputs
20
21
  CommandConnector.add_desugarizer Desugarizers::Attributes::OnlyResult
21
22
  CommandConnector.add_desugarizer Desugarizers::Attributes::RejectResult
22
23
  CommandConnector.add_desugarizer Desugarizers::Attributes::InputsFromYaml
@@ -443,12 +443,10 @@ module Foobara
443
443
  end
444
444
  end
445
445
  ensure
446
- request.use_transaction do
447
- if (request.response || request).outcome&.success?
448
- request.commit_transaction_if_open
449
- else
450
- request.rollback_transaction
451
- end
446
+ if (request.response || request).outcome&.success?
447
+ request.commit_transaction_if_open
448
+ else
449
+ request.rollback_transaction
452
450
  end
453
451
  end
454
452
 
@@ -0,0 +1,48 @@
1
+ require_relative "../desugarizer"
2
+
3
+ module Foobara
4
+ module CommandConnectors
5
+ module Desugarizers
6
+ class SetInputs < Desugarizer
7
+ def applicable?(args_and_opts)
8
+ _args, opts = args_and_opts
9
+
10
+ return false unless opts.key?(:inputs_transformers)
11
+
12
+ transformers = opts[:inputs_transformers]
13
+ transformers = Util.array(transformers)
14
+
15
+ transformers.any? do |transformer|
16
+ transformer.is_a?(::Hash) && transformer.key?(:set)
17
+ end
18
+ end
19
+
20
+ def desugarize(args_and_opts)
21
+ args, opts = args_and_opts
22
+
23
+ transformers = opts[:inputs_transformers]
24
+ is_array = transformers.is_a?(::Array)
25
+
26
+ transformers = Util.array(transformers)
27
+
28
+ transformers = transformers.map do |transformer|
29
+ if transformer.is_a?(::Hash) && transformer.key?(:set)
30
+ AttributesTransformers.set(transformer[:set])
31
+ else
32
+ # TODO: add a test for this
33
+ # :nocov:
34
+ transformer
35
+ # :nocov:
36
+ end
37
+ end
38
+
39
+ transformers = transformers.first unless is_array
40
+
41
+ opts = opts.merge(inputs_transformers: transformers)
42
+
43
+ [args, opts]
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -1,6 +1,14 @@
1
1
  module Foobara
2
2
  module CommandConnectors
3
3
  module Serializers
4
+ # This seems to interpret "Atomic" as load the first entity you hit but not deeper entities.
5
+ # Other interpretations it could have been:
6
+ # 1) If top-level is an entity, load it and convert all nested entities to primary keys,
7
+ # otherwise, convert all entities to primary keys
8
+ # 2) Once past the first model, all entities are cast to primary keys
9
+ #
10
+ # However, in the typescript-remote-command-generator, the logic is a little different...
11
+ # There, AtomModelGenerator always uses primary keys for all entities.
4
12
  class AtomicSerializer < SuccessSerializer
5
13
  def serialize(object)
6
14
  case object
@@ -13,6 +13,8 @@ module Foobara
13
13
 
14
14
  model = Namespace.global.foobara_lookup_type!(:model)
15
15
  BuiltinTypes.build_and_register!(:detached_entity, model, nil)
16
+
17
+ TypeDeclarations::RemoveSensitiveValuesTransformer.include(RemoveSensitiveValuesTransformerExtensions)
16
18
  end
17
19
 
18
20
  def reset_all
@@ -0,0 +1,64 @@
1
+ module Foobara
2
+ class DetachedEntity < Model
3
+ module RemoveSensitiveValuesTransformerExtensions
4
+ def from(...)
5
+ super.tap do
6
+ create_all_association_types_in_current_namespace(from_type)
7
+ end
8
+ end
9
+
10
+ def to(...)
11
+ super.tap do
12
+ create_all_association_types_in_current_namespace(to_type)
13
+ end
14
+ end
15
+
16
+ def create_all_association_types_in_current_namespace(type)
17
+ already_sanitized = Set.new
18
+
19
+ associations = Foobara::DetachedEntity.construct_deep_associations(type)
20
+
21
+ associations&.values&.reverse&.each do |entity_type|
22
+ next if already_sanitized.include?(entity_type)
23
+
24
+ next if entity_type.sensitive?
25
+
26
+ unless entity_type.has_sensitive_types?
27
+ already_sanitized << entity_type
28
+ next
29
+ end
30
+
31
+ ns = Namespace.current
32
+
33
+ declaration = entity_type.declaration_data
34
+ sanitized_type_declaration = TypeDeclarations.remove_sensitive_types(declaration)
35
+
36
+ existing_type = ns.foobara_lookup(
37
+ entity_type.full_type_symbol,
38
+ mode: Namespace::LookupMode::ABSOLUTE_SINGLE_NAMESPACE
39
+ )
40
+
41
+ if existing_type
42
+ if existing_type.declaration_data == sanitized_type_declaration
43
+ already_sanitized << entity_type
44
+ already_sanitized << existing_type
45
+ next
46
+ else
47
+ # :nocov:
48
+ raise "Did not expect to be re-sanitizing #{entity_type.full_type_symbol}"
49
+ # :nocov:
50
+ end
51
+
52
+ end
53
+
54
+ # We want to make sure that any types that change due to having sensitive types
55
+ # has a corresponding registered type in the command registry domain if needed
56
+ # TODO: this all feels so messy and brittle.
57
+ Domain.current.foobara_type_from_declaration(sanitized_type_declaration)
58
+
59
+ already_sanitized << entity_type
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
@@ -310,27 +310,6 @@ module Foobara
310
310
  type
311
311
  end
312
312
 
313
- def foobara_register_model(model_class)
314
- type = model_class.model_type
315
-
316
- full_name = type.scoped_full_name
317
-
318
- if model_class.full_model_name.size > full_name.size
319
- # TODO: why does this happen exactly??
320
- full_name = model_class.full_model_name
321
- end
322
-
323
- if type.scoped_path_set? && foobara_registered?(full_name, mode: Namespace::LookupMode::DIRECT)
324
- # :nocov:
325
- raise AlreadyRegisteredError, "Already registered: #{type.inspect}"
326
- # :nocov:
327
- end
328
-
329
- foobara_register(type)
330
-
331
- type.target_class
332
- end
333
-
334
313
  def foobara_register_and_deanonymize_entity(name, *, &)
335
314
  entity_class = foobara_register_entity(name, *, &)
336
315
  Foobara::Model.deanonymize_class(entity_class)
@@ -208,6 +208,7 @@ module Foobara
208
208
  delegates[attribute_name] = delegate_manifest
209
209
 
210
210
  delegated_type_declaration = model_type.type_at_path(data_path).reference_or_declaration_data
211
+ # TODO: add defaults and required for the delegated declaration!
211
212
  attributes(type: :attributes, element_type_declarations: { attribute_name => delegated_type_declaration })
212
213
 
213
214
  define_method attribute_name do
@@ -118,7 +118,7 @@ module Foobara
118
118
 
119
119
  model_class.description type.declaration_data[:description]
120
120
 
121
- domain.foobara_register_model(model_class)
121
+ domain.foobara_register(type)
122
122
 
123
123
  if type.declaration_data[:delegates]
124
124
  model_class.delegate_attributes type.declaration_data[:delegates]
@@ -8,6 +8,12 @@ module Foobara
8
8
  def register(scoped)
9
9
  short_name = scoped.scoped_short_name
10
10
  registry[short_name] ||= []
11
+ # This kind of error should only happen in test suites that need to unregister/reregister things
12
+ # with different object_ids but the same scoped full name. So will check it in commented out.
13
+ # if registry[short_name].map(&:scoped_full_name).include?(scoped.scoped_full_name)
14
+ # raise "Already registered: #{scoped.scoped_full_name}"
15
+ # end
16
+
11
17
  registry[short_name] |= [scoped]
12
18
  end
13
19
 
@@ -7,8 +7,6 @@ module Foobara
7
7
 
8
8
  module Concerns
9
9
  module StateTransitions
10
- foobara_delegate :close, to: :state_machine
11
-
12
10
  def currently_open?
13
11
  state_machine.currently_open?
14
12
  end
@@ -188,6 +188,7 @@ module Foobara
188
188
  if tx.currently_open? && !existing_transaction
189
189
  tx.commit!
190
190
  end
191
+
191
192
  result
192
193
  rescue Foobara::Persistence::EntityBase::Transaction::RolledBack # rubocop:disable Lint/SuppressedException
193
194
  rescue => e
@@ -46,8 +46,10 @@ module Foobara
46
46
  Namespace.global.foobara_register(scoped)
47
47
  end
48
48
 
49
+ children = Namespace.global.foobara_children
50
+
49
51
  @original_children.each do |child|
50
- Namespace.global.foobara_children << child
52
+ children.foobara_children << child unless children.include?(child)
51
53
  end
52
54
 
53
55
  GlobalOrganization.foobara_register(GlobalDomain)
@@ -0,0 +1,77 @@
1
+ module Foobara
2
+ class AttributesTransformers < TypeDeclarations::TypedTransformer
3
+ class << self
4
+ def next_index
5
+ @index ||= 0
6
+ @index += 1
7
+ end
8
+
9
+ def set(attribute_names_to_values)
10
+ if attribute_names_to_values.empty?
11
+ # :nocov:
12
+ raise ArgumentError, "You must specify at least one attribute name/value pair"
13
+ # :nocov:
14
+ end
15
+
16
+ symbol = symbol_for_attribute_names([*attribute_names_to_values.keys, next_index.to_s.to_sym])
17
+ existing = Set.foobara_lookup(symbol, mode: Namespace::LookupMode::DIRECT)
18
+
19
+ return existing if existing
20
+
21
+ transformer_class = Class.new(Set)
22
+ transformer_class.attribute_names_to_values = attribute_names_to_values
23
+
24
+ Namespace::NamespaceHelpers.foobara_autoset_scoped_path(transformer_class, set_namespace: true)
25
+ transformer_class.scoped_namespace.foobara_register(transformer_class)
26
+
27
+ transformer_class
28
+ end
29
+ end
30
+
31
+ class Set < AttributesTransformers
32
+ class << self
33
+ attr_accessor :attribute_names_to_values
34
+
35
+ def symbol
36
+ if attribute_names_to_values
37
+ symbol_for_attribute_names(attribute_names_to_values.keys)
38
+ end
39
+ end
40
+
41
+ def will_set_scoped_path?
42
+ true
43
+ end
44
+ end
45
+
46
+ def to_type_declaration
47
+ # TODO: test this
48
+ # :nocov:
49
+ if from_type
50
+ from_declaration = from_type.declaration_data
51
+ TypeDeclarations::Attributes.reject(from_declaration, *self.class.attribute_names_to_values.keys)
52
+ end
53
+ # :nocov:
54
+ end
55
+
56
+ def from_type_declaration
57
+ if to_type
58
+ to_declaration = to_type.declaration_data
59
+ TypeDeclarations::Attributes.reject(to_declaration, *self.class.attribute_names_to_values.keys)
60
+ end
61
+ end
62
+
63
+ def transform(inputs)
64
+ to_merge = {}
65
+
66
+ self.class.attribute_names_to_values.each_pair do |input_name, value|
67
+ if value.is_a?(::Proc)
68
+ value = value.call
69
+ end
70
+ to_merge[input_name] = value
71
+ end
72
+
73
+ inputs.merge(to_merge)
74
+ end
75
+ end
76
+ end
77
+ end
@@ -3,65 +3,6 @@ require_relative "typed_transformer"
3
3
  module Foobara
4
4
  module TypeDeclarations
5
5
  class RemoveSensitiveValuesTransformer < TypedTransformer
6
- def from(...)
7
- super.tap do
8
- create_all_association_types_in_current_namespace(from_type)
9
- end
10
- end
11
-
12
- def to(...)
13
- super.tap do
14
- create_all_association_types_in_current_namespace(to_type)
15
- end
16
- end
17
-
18
- def create_all_association_types_in_current_namespace(type)
19
- already_sanitized = Set.new
20
-
21
- associations = Foobara::DetachedEntity.construct_deep_associations(type)
22
-
23
- associations&.values&.reverse&.each do |entity_type|
24
- next if already_sanitized.include?(entity_type)
25
-
26
- next if entity_type.sensitive?
27
-
28
- unless entity_type.has_sensitive_types?
29
- already_sanitized << entity_type
30
- next
31
- end
32
-
33
- ns = Namespace.current
34
-
35
- declaration = entity_type.declaration_data
36
- sanitized_type_declaration = TypeDeclarations.remove_sensitive_types(declaration)
37
-
38
- existing_type = ns.foobara_lookup(
39
- entity_type.full_type_symbol,
40
- mode: Namespace::LookupMode::ABSOLUTE_SINGLE_NAMESPACE
41
- )
42
-
43
- if existing_type
44
- if existing_type.declaration_data == sanitized_type_declaration
45
- already_sanitized << entity_type
46
- already_sanitized << existing_type
47
- next
48
- else
49
- # :nocov:
50
- raise "Did not expect to be re-sanitizing #{entity_type.full_type_symbol}"
51
- # :nocov:
52
- end
53
-
54
- end
55
-
56
- # We want to make sure that any types that change due to having sensitive types
57
- # has a corresponding registered type in the command registry domain if needed
58
- # TODO: this all feels so messy and brittle.
59
- Domain.current.foobara_type_from_declaration(sanitized_type_declaration)
60
-
61
- already_sanitized << entity_type
62
- end
63
- end
64
-
65
6
  def to_type_declaration
66
7
  TypeDeclarations.remove_sensitive_types(from_type.declaration_data)
67
8
  end
data/version.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  module Foobara
2
2
  module Version
3
- VERSION = "0.2.5".freeze
3
+ VERSION = "0.2.7".freeze
4
4
  MINIMUM_RUBY_VERSION = ">= 3.4.0".freeze
5
5
  end
6
6
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: foobara
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.5
4
+ version: 0.2.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Miles Georgi
@@ -214,6 +214,7 @@ files:
214
214
  - projects/command_connectors/src/desugarizers/attributes/reject_result.rb
215
215
  - projects/command_connectors/src/desugarizers/auth.rb
216
216
  - projects/command_connectors/src/desugarizers/rename_key.rb
217
+ - projects/command_connectors/src/desugarizers/set_inputs.rb
217
218
  - projects/command_connectors/src/desugarizers/symbols_to_true.rb
218
219
  - projects/command_connectors/src/request_mutator.rb
219
220
  - projects/command_connectors/src/response_mutator.rb
@@ -273,6 +274,7 @@ files:
273
274
  - projects/detached_entity/src/extensions/type_declarations/handlers/extend_detached_entity_type_declaration/validate_primary_key_is_symbol.rb
274
275
  - projects/detached_entity/src/extensions/type_declarations/handlers/extend_detached_entity_type_declaration/validate_primary_key_present.rb
275
276
  - projects/detached_entity/src/extensions/type_declarations/handlers/extend_detached_entity_type_declaration/validate_primary_key_references_attribute.rb
277
+ - projects/detached_entity/src/remove_sensitive_values_transformer_extensions.rb
276
278
  - projects/detached_entity/src/sensitive_type_removers/detached_entity.rb
277
279
  - projects/detached_entity/src/sensitive_value_removers/detached_entity.rb
278
280
  - projects/domain/lib/foobara/domain.rb
@@ -422,6 +424,7 @@ files:
422
424
  - projects/type_declarations/src/attributes_transformers/from_yaml.rb
423
425
  - projects/type_declarations/src/attributes_transformers/only.rb
424
426
  - projects/type_declarations/src/attributes_transformers/reject.rb
427
+ - projects/type_declarations/src/attributes_transformers/set.rb
425
428
  - projects/type_declarations/src/caster.rb
426
429
  - projects/type_declarations/src/desugarizer.rb
427
430
  - projects/type_declarations/src/desugarizer_pipeline.rb