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 +4 -4
- data/CHANGELOG.md +8 -0
- data/projects/command_connectors/lib/foobara/command_connectors.rb +1 -0
- data/projects/command_connectors/src/command_connector.rb +4 -6
- data/projects/command_connectors/src/desugarizers/set_inputs.rb +48 -0
- data/projects/command_connectors/src/serializers/atomic_serializer.rb +8 -0
- data/projects/detached_entity/lib/foobara/detached_entity.rb +2 -0
- data/projects/detached_entity/src/remove_sensitive_values_transformer_extensions.rb +64 -0
- data/projects/domain/src/domain_module_extension.rb +0 -21
- data/projects/model/src/concerns/types.rb +1 -0
- data/projects/model/src/extensions/type_declarations/handlers/extend_model_type_declaration/to_type_transformer.rb +1 -1
- data/projects/namespace/src/ambiguous_registry.rb +6 -0
- data/projects/persistence/src/entity_base/transaction/concerns/state_transitions.rb +0 -2
- data/projects/persistence/src/entity_base.rb +1 -0
- data/projects/type_declarations/lib/foobara/type_declarations.rb +3 -1
- data/projects/type_declarations/src/attributes_transformers/set.rb +77 -0
- data/projects/type_declarations/src/remove_sensitive_values_transformer.rb +0 -59
- data/version.rb +1 -1
- metadata +4 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4f5b2b0f1316a7d5530778566c64df6cffafb44dfdb99e5fd4797de2fbe3b0a2
|
|
4
|
+
data.tar.gz: 9819421a3b7dafcb39ac4d3dadb3b7a8ee2967648abf9adad4cc2fd094769bf3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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.
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
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.
|
|
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
|
|
|
@@ -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
|
-
|
|
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
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.
|
|
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
|