foobara 0.0.91 → 0.0.93
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 +15 -2
- data/projects/builtin_types/src/email/validator_base.rb +1 -1
- data/projects/command/src/command_pattern_implementation/concerns/reflection.rb +39 -18
- data/projects/command/src/transformed_command.rb +85 -40
- data/projects/command_connectors/src/command_connector/commands/describe.rb +1 -5
- data/projects/command_connectors/src/command_connector.rb +65 -55
- data/projects/command_connectors/src/command_registry/exposed_command.rb +2 -2
- data/projects/command_connectors/src/command_registry/exposed_domain.rb +10 -3
- data/projects/command_connectors/src/command_registry/exposed_organization.rb +2 -2
- data/projects/command_connectors/src/command_registry.rb +9 -0
- data/projects/command_connectors/src/serializers/atomic_serializer.rb +1 -1
- data/projects/command_connectors/src/transformers/load_delegated_attributes_entities_pre_commit_transformer.rb +40 -0
- data/projects/common/src/data_path.rb +16 -0
- data/projects/common/src/error.rb +35 -5
- data/projects/common/src/outcome.rb +11 -5
- data/projects/common/src/possible_error.rb +9 -3
- data/projects/detached_entity/src/concerns/associations.rb +26 -20
- data/projects/detached_entity/src/concerns/reflection.rb +3 -3
- data/projects/detached_entity/src/detached_entity_type.rb +8 -3
- data/projects/detached_entity/src/extensions/builtin_types/detached_entity/validators/{attributes_declaration.rb → model_instance_is_valid.rb} +1 -1
- data/projects/domain/src/domain_module_extension.rb +12 -4
- data/projects/domain/src/extensions/foobara.rb +31 -28
- data/projects/domain/src/is_manifestable.rb +6 -2
- data/projects/domain/src/organization_module_extension.rb +6 -2
- data/projects/entity/src/concerns/queries.rb +29 -31
- data/projects/entity/src/extensions/builtin_types/entity/validators/{attributes_declaration.rb → model_instance_is_valid.rb} +1 -1
- data/projects/model/src/concerns/reflection.rb +8 -2
- data/projects/model/src/concerns/types.rb +121 -23
- data/projects/model/src/extensions/builtin_types/model/supported_transformers/mutable.rb +1 -2
- data/projects/model/src/extensions/builtin_types/model/validators/{attributes_declaration.rb → model_instance_is_valid.rb} +1 -1
- data/projects/model/src/extensions/type_declarations/handlers/extend_model_type_declaration/array_with_symbolic_elements.rb +29 -0
- data/projects/model/src/extensions/type_declarations/handlers/extend_model_type_declaration/delegates_desugarizer.rb +39 -0
- data/projects/model/src/extensions/type_declarations/handlers/extend_model_type_declaration/delegates_validator.rb +44 -0
- data/projects/model/src/extensions/type_declarations/handlers/extend_model_type_declaration/move_private_from_element_types_to_root.rb +48 -0
- data/projects/model/src/extensions/type_declarations/handlers/extend_model_type_declaration/symbolize_private.rb +34 -0
- data/projects/model/src/extensions/type_declarations/handlers/extend_model_type_declaration/to_type_transformer.rb +34 -2
- data/projects/model/src/extensions/type_declarations/handlers/extend_model_type_declaration/valid_attribute_names.rb +54 -0
- data/projects/model/src/model.rb +9 -0
- data/projects/model_attribute_helpers/src/attribute_helpers.rb +25 -4
- data/projects/namespace/src/is_namespace.rb +34 -15
- data/projects/persistence/src/entity_attributes_crud_driver.rb +25 -1
- data/projects/persistence/src/entity_base/transaction_table.rb +28 -3
- data/projects/type_declarations/src/desugarizer.rb +1 -1
- data/projects/type_declarations/src/remove_sensitive_values_transformer.rb +6 -0
- data/projects/type_declarations/src/type_builder.rb +42 -39
- data/projects/type_declarations/src/type_declaration_handler.rb +1 -1
- data/projects/type_declarations/src/type_declaration_handler_registry.rb +1 -1
- data/projects/type_declarations/src/type_declaration_validator.rb +1 -1
- data/projects/type_declarations/src/type_declarations.rb +39 -10
- data/projects/types/src/extensions/error.rb +3 -3
- data/projects/types/src/type/concerns/reflection.rb +79 -4
- data/projects/types/src/type.rb +42 -17
- data/projects/value/src/caster.rb +1 -1
- data/projects/value/src/mutator.rb +1 -1
- data/projects/value/src/processor/casting.rb +1 -1
- data/projects/value/src/processor/pipeline.rb +1 -1
- data/projects/value/src/processor/selection.rb +1 -1
- data/projects/value/src/processor.rb +13 -5
- data/projects/value/src/transformer.rb +1 -1
- data/projects/value/src/validator.rb +1 -1
- metadata +12 -5
@@ -98,28 +98,29 @@ module Foobara
|
|
98
98
|
path,
|
99
99
|
filter: nil,
|
100
100
|
mode: LookupMode::GENERAL,
|
101
|
-
visited: Set.new
|
101
|
+
visited: Set.new,
|
102
|
+
initial: true
|
102
103
|
)
|
103
|
-
|
104
|
+
path = Namespace.to_registry_path(path)
|
105
|
+
visited_key = [path, mode, initial, self]
|
104
106
|
return nil if visited.include?(visited_key)
|
105
107
|
|
106
108
|
visited << visited_key
|
107
109
|
|
108
110
|
LookupMode.validate!(mode)
|
109
111
|
|
110
|
-
path = Namespace.to_registry_path(path)
|
111
|
-
|
112
112
|
if mode == LookupMode::RELAXED
|
113
113
|
scoped = foobara_lookup(
|
114
114
|
path,
|
115
115
|
filter:,
|
116
116
|
mode: LookupMode::GENERAL,
|
117
|
-
visited
|
117
|
+
visited:,
|
118
|
+
initial: false
|
118
119
|
)
|
119
120
|
return scoped if scoped
|
120
121
|
|
121
122
|
candidates = foobara_children.map do |namespace|
|
122
|
-
namespace.foobara_lookup(path, filter:, mode:, visited:)
|
123
|
+
namespace.foobara_lookup(path, filter:, mode:, visited:, initial: false)
|
123
124
|
end.compact
|
124
125
|
|
125
126
|
if candidates.size > 1
|
@@ -129,7 +130,8 @@ module Foobara
|
|
129
130
|
# :nocov:
|
130
131
|
end
|
131
132
|
|
132
|
-
return candidates.first ||
|
133
|
+
return candidates.first ||
|
134
|
+
foobara_parent_namespace&.foobara_lookup(path, filter:, mode:, visited:, initial: false)
|
133
135
|
end
|
134
136
|
|
135
137
|
if path[0] == ""
|
@@ -141,7 +143,7 @@ module Foobara
|
|
141
143
|
path = path[(foobara_root_namespace.scoped_path.size + 1)..]
|
142
144
|
end
|
143
145
|
|
144
|
-
return foobara_root_namespace.foobara_lookup(path, filter:, mode: LookupMode::ABSOLUTE)
|
146
|
+
return foobara_root_namespace.foobara_lookup(path, filter:, mode: LookupMode::ABSOLUTE, initial: true)
|
145
147
|
end
|
146
148
|
|
147
149
|
partial = foobara_registry.lookup(path, filter)
|
@@ -166,12 +168,16 @@ module Foobara
|
|
166
168
|
return scoped if scoped
|
167
169
|
|
168
170
|
if [LookupMode::GENERAL, LookupMode::STRICT].include?(mode) && foobara_parent_namespace
|
169
|
-
scoped = foobara_parent_namespace.foobara_lookup(
|
171
|
+
scoped = foobara_parent_namespace.foobara_lookup(
|
172
|
+
path, filter:, mode: LookupMode::STRICT, visited:, initial: false
|
173
|
+
)
|
170
174
|
return scoped if scoped
|
171
175
|
end
|
172
176
|
|
173
|
-
|
174
|
-
|
177
|
+
if mode == LookupMode::GENERAL
|
178
|
+
scoped = _lookup_in(path, foobara_depends_on_namespaces, filter:, visited:)
|
179
|
+
return scoped if scoped
|
180
|
+
end
|
175
181
|
|
176
182
|
to_consider = case mode
|
177
183
|
when LookupMode::GENERAL
|
@@ -181,7 +187,7 @@ module Foobara
|
|
181
187
|
end
|
182
188
|
|
183
189
|
candidates = to_consider.map do |namespace|
|
184
|
-
namespace.foobara_lookup(path, filter:, mode:, visited:)
|
190
|
+
namespace.foobara_lookup(path, filter:, mode:, visited:, initial: false)
|
185
191
|
end.compact
|
186
192
|
|
187
193
|
if candidates.size > 1
|
@@ -190,7 +196,19 @@ module Foobara
|
|
190
196
|
# :nocov:
|
191
197
|
end
|
192
198
|
|
193
|
-
candidates.first || partial
|
199
|
+
scoped = candidates.first || partial
|
200
|
+
return scoped if scoped
|
201
|
+
|
202
|
+
# As a last resort we'll see if we're trying to fetch a builtin type from a different namespace
|
203
|
+
# TODO: these lookup modes are really confusing and were designed prior to having multiple root
|
204
|
+
# namespaces playing a role in command connectors.
|
205
|
+
if initial
|
206
|
+
scoped = Namespace.global.foobara_lookup(path, filter:, mode: LookupMode::ABSOLUTE, visited:, initial: false)
|
207
|
+
|
208
|
+
if scoped.is_a?(Types::Type) && scoped.builtin?
|
209
|
+
scoped
|
210
|
+
end
|
211
|
+
end
|
194
212
|
end
|
195
213
|
|
196
214
|
def foobara_parent_namespace
|
@@ -330,14 +348,15 @@ module Foobara
|
|
330
348
|
path[matching_child_score..],
|
331
349
|
mode: LookupMode::ABSOLUTE,
|
332
350
|
filter:,
|
333
|
-
visited
|
351
|
+
visited:,
|
352
|
+
initial: false
|
334
353
|
)
|
335
354
|
|
336
355
|
return scoped if scoped
|
337
356
|
end
|
338
357
|
|
339
358
|
last_resort.uniq.each do |namespace|
|
340
|
-
scoped = namespace.foobara_lookup(path, filter:, mode: LookupMode::ABSOLUTE, visited:)
|
359
|
+
scoped = namespace.foobara_lookup(path, filter:, mode: LookupMode::ABSOLUTE, visited:, initial: false)
|
341
360
|
return scoped if scoped
|
342
361
|
end
|
343
362
|
|
@@ -155,7 +155,31 @@ module Foobara
|
|
155
155
|
end
|
156
156
|
|
157
157
|
def matches_attributes_filter?(attributes, attributes_filter)
|
158
|
-
attributes_filter.all?
|
158
|
+
attributes_filter.all? do |attribute_name_or_path, value|
|
159
|
+
type = nil
|
160
|
+
|
161
|
+
if attribute_name_or_path.is_a?(::Array)
|
162
|
+
values = DataPath.values_at(attribute_name_or_path, attributes)
|
163
|
+
|
164
|
+
if values.include?(value)
|
165
|
+
true
|
166
|
+
else
|
167
|
+
type ||= entity_class.model_type.type_at_path(attribute_name_or_path)
|
168
|
+
if type.extends?(:detached_entity)
|
169
|
+
values.any? do |v|
|
170
|
+
value.primary_key == v
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
elsif attributes[attribute_name_or_path] == value
|
175
|
+
true
|
176
|
+
else
|
177
|
+
type ||= entity_class.model_type.type_at_path(attribute_name_or_path)
|
178
|
+
if type.extends?(:detached_entity)
|
179
|
+
value.primary_key == attributes[attribute_name_or_path]
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
159
183
|
end
|
160
184
|
|
161
185
|
def insert(_attributes)
|
@@ -225,8 +225,8 @@ module Foobara
|
|
225
225
|
find_by(attribute_name => value)
|
226
226
|
end
|
227
227
|
|
228
|
-
def find_all_by_attribute(
|
229
|
-
find_many_by(
|
228
|
+
def find_all_by_attribute(attribute_name_or_path, value)
|
229
|
+
find_many_by(attribute_name_or_path => value)
|
230
230
|
end
|
231
231
|
|
232
232
|
def find_by_attribute_containing(attribute_name, value)
|
@@ -283,13 +283,38 @@ module Foobara
|
|
283
283
|
|
284
284
|
def find_many_by(attributes_filter)
|
285
285
|
find_by_type = entity_class.domain.foobara_type_from_declaration(entity_class.attributes_for_find_by)
|
286
|
-
|
286
|
+
|
287
|
+
path_filters = {}
|
288
|
+
regular_filters = {}
|
289
|
+
|
290
|
+
attributes_filter.each_pair do |attribute_name_or_path, value|
|
291
|
+
case attribute_name_or_path
|
292
|
+
when ::Symbol, ::String
|
293
|
+
regular_filters[attribute_name_or_path] = value
|
294
|
+
when ::Array, Value::DataPath
|
295
|
+
path_filters[attribute_name_or_path] = value
|
296
|
+
else
|
297
|
+
# :nocov:
|
298
|
+
raise "Unexpected filter type: #{attribute_name_or_path.class}"
|
299
|
+
# :nocov:
|
300
|
+
end
|
301
|
+
end
|
302
|
+
|
303
|
+
regular_filters = find_by_type.process_value!(regular_filters)
|
304
|
+
|
305
|
+
path_filters.keys.each do |path|
|
306
|
+
type = entity_class.deep_associations[DataPath.for(path).to_s]
|
307
|
+
path_filters[path] = type.process_value!(path_filters[path])
|
308
|
+
end
|
309
|
+
|
310
|
+
attributes_filter = regular_filters.merge(path_filters)
|
287
311
|
|
288
312
|
yielded_ids = Set.new
|
289
313
|
|
290
314
|
Enumerator.new do |yielder|
|
291
315
|
tracked_records.each do |record|
|
292
316
|
next if hard_deleted?(record)
|
317
|
+
next unless record.loaded? || record.built? || record.created?
|
293
318
|
|
294
319
|
if entity_attributes_crud_driver_table.matches_attributes_filter?(record.attributes, attributes_filter)
|
295
320
|
yielded_ids << record.primary_key
|
@@ -8,9 +8,15 @@ module Foobara
|
|
8
8
|
associations = Foobara::DetachedEntity.construct_deep_associations(from_type)
|
9
9
|
|
10
10
|
associations&.values&.reverse&.each do |entity_type|
|
11
|
+
next if entity_type.sensitive?
|
12
|
+
next unless entity_type.has_sensitive_types?
|
13
|
+
|
11
14
|
declaration = entity_type.declaration_data
|
12
15
|
sanitized_type_declaration = TypeDeclarations.remove_sensitive_types(declaration)
|
13
16
|
|
17
|
+
# We want to make sure that any types that change due to having sensitive types
|
18
|
+
# has a corresponding registered type in the command registry domain if needed
|
19
|
+
# TODO: this all feels so messy and brittle.
|
14
20
|
Domain.current.foobara_type_from_declaration(sanitized_type_declaration)
|
15
21
|
end
|
16
22
|
end
|
@@ -2,6 +2,46 @@ require "foobara/lru_cache"
|
|
2
2
|
|
3
3
|
module Foobara
|
4
4
|
module TypeDeclarations
|
5
|
+
class << self
|
6
|
+
# TODO: relocate these to a different file
|
7
|
+
def args_to_type_declaration(*args, &block)
|
8
|
+
if block
|
9
|
+
unless args.empty?
|
10
|
+
# :nocov:
|
11
|
+
raise ArgumentError, "Cannot provide both block and declaration"
|
12
|
+
# :nocov:
|
13
|
+
end
|
14
|
+
|
15
|
+
block
|
16
|
+
else
|
17
|
+
case args.size
|
18
|
+
when 0
|
19
|
+
# :nocov:
|
20
|
+
raise ArgumentError, "expected 1 argument or a block but got 0 arguments and no block"
|
21
|
+
# :nocov:
|
22
|
+
when 1
|
23
|
+
args.first
|
24
|
+
else
|
25
|
+
type, *symbolic_processors, processor_data = args
|
26
|
+
|
27
|
+
if !symbolic_processors.empty?
|
28
|
+
symbolic_processors = symbolic_processors.to_h { |symbol| [symbol, true] }
|
29
|
+
|
30
|
+
if processor_data.is_a?(::Hash) && !processor_data.empty?
|
31
|
+
processor_data.merge(symbolic_processors)
|
32
|
+
else
|
33
|
+
symbolic_processors
|
34
|
+
end
|
35
|
+
elsif processor_data.is_a?(::Hash)
|
36
|
+
processor_data
|
37
|
+
else
|
38
|
+
{ processor_data.to_sym => true }
|
39
|
+
end.merge(type:)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
5
45
|
class TypeBuilder
|
6
46
|
class NoTypeDeclarationHandlerFoundError < StandardError; end
|
7
47
|
|
@@ -70,27 +110,8 @@ module Foobara
|
|
70
110
|
end
|
71
111
|
end
|
72
112
|
|
73
|
-
def type_for_declaration_without_cache(*type_declaration_bits, &
|
74
|
-
type_declaration =
|
75
|
-
unless type_declaration_bits.empty?
|
76
|
-
# :nocov:
|
77
|
-
raise ArgumentError, "Cannot provide both block and declaration"
|
78
|
-
# :nocov:
|
79
|
-
end
|
80
|
-
|
81
|
-
block
|
82
|
-
else
|
83
|
-
case type_declaration_bits.size
|
84
|
-
when 0
|
85
|
-
# :nocov:
|
86
|
-
raise ArgumentError, "expected 1 argument or a block but got 0 arguments and no block"
|
87
|
-
# :nocov:
|
88
|
-
when 1
|
89
|
-
type_declaration_bits.first
|
90
|
-
else
|
91
|
-
type_declaration_bits_to_type_declaration(type_declaration_bits)
|
92
|
-
end
|
93
|
-
end
|
113
|
+
def type_for_declaration_without_cache(*type_declaration_bits, &)
|
114
|
+
type_declaration = TypeDeclarations.args_to_type_declaration(*type_declaration_bits, &)
|
94
115
|
|
95
116
|
handler = type_declaration_handler_for(type_declaration)
|
96
117
|
handler.process_value!(type_declaration)
|
@@ -107,24 +128,6 @@ module Foobara
|
|
107
128
|
def lru_cache
|
108
129
|
@lru_cache ||= Foobara::LruCache.new(100)
|
109
130
|
end
|
110
|
-
|
111
|
-
def type_declaration_bits_to_type_declaration(type_declaration_bits)
|
112
|
-
type, *symbolic_processors, processor_data = type_declaration_bits
|
113
|
-
|
114
|
-
if !symbolic_processors.empty?
|
115
|
-
symbolic_processors = symbolic_processors.to_h { |symbol| [symbol, true] }
|
116
|
-
|
117
|
-
if processor_data.is_a?(::Hash) && !processor_data.empty?
|
118
|
-
processor_data.merge(symbolic_processors)
|
119
|
-
else
|
120
|
-
symbolic_processors
|
121
|
-
end
|
122
|
-
elsif processor_data.is_a?(::Hash)
|
123
|
-
processor_data
|
124
|
-
else
|
125
|
-
{ processor_data.to_sym => true }
|
126
|
-
end.merge(type:)
|
127
|
-
end
|
128
131
|
end
|
129
132
|
end
|
130
133
|
end
|
@@ -4,7 +4,7 @@ module Foobara
|
|
4
4
|
module TypeDeclarations
|
5
5
|
class TypeDeclarationHandler < Value::Processor::Pipeline
|
6
6
|
class << self
|
7
|
-
def foobara_manifest
|
7
|
+
def foobara_manifest
|
8
8
|
# :nocov:
|
9
9
|
super.merge(processor_type: :type_declaration_handler)
|
10
10
|
# :nocov:
|
@@ -2,7 +2,7 @@ module Foobara
|
|
2
2
|
module TypeDeclarations
|
3
3
|
class TypeDeclarationHandlerRegistry < Value::Processor::Selection
|
4
4
|
class << self
|
5
|
-
def foobara_manifest
|
5
|
+
def foobara_manifest
|
6
6
|
# :nocov:
|
7
7
|
super.merge(processor_type: :type_declaration_handler_registry)
|
8
8
|
# :nocov:
|
@@ -68,22 +68,17 @@ module Foobara
|
|
68
68
|
using_mode(Mode::STRICT_STRINGIFIED, &)
|
69
69
|
end
|
70
70
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
Thread.foobara_var_set(:foobara_type_declarations_mode, new_mode)
|
75
|
-
yield
|
76
|
-
ensure
|
77
|
-
Thread.foobara_var_set(:foobara_type_declarations_mode, old_mode)
|
78
|
-
end
|
71
|
+
# TODO: use manifest context instead
|
72
|
+
def using_mode(new_mode, &)
|
73
|
+
with_manifest_context(mode: new_mode, &)
|
79
74
|
end
|
80
75
|
|
81
76
|
def strict?
|
82
|
-
|
77
|
+
foobara_manifest_context_mode == Mode::STRICT
|
83
78
|
end
|
84
79
|
|
85
80
|
def strict_stringified?
|
86
|
-
|
81
|
+
foobara_manifest_context_mode == Mode::STRICT_STRINGIFIED
|
87
82
|
end
|
88
83
|
|
89
84
|
# TODO: we should desugarize these but can't because of a bug where desugarizing entities results in creating the
|
@@ -94,6 +89,40 @@ module Foobara
|
|
94
89
|
|
95
90
|
declaration1 == declaration2
|
96
91
|
end
|
92
|
+
|
93
|
+
def foobara_manifest_context
|
94
|
+
Thread.foobara_var_get("foobara_manifest_context")
|
95
|
+
end
|
96
|
+
|
97
|
+
allowed_context_keys = %i[detached to_include mode remove_sensitive]
|
98
|
+
booleans = %i[detached remove_sensitive]
|
99
|
+
|
100
|
+
booleans.each do |context_item|
|
101
|
+
define_method "foobara_manifest_context_#{context_item}?" do
|
102
|
+
!!foobara_manifest_context&.[](context_item)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
(allowed_context_keys - booleans).each do |context_item|
|
107
|
+
define_method "foobara_manifest_context_#{context_item}" do
|
108
|
+
foobara_manifest_context&.[](context_item)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def manifest_context_set?(context_item)
|
113
|
+
foobara_manifest_context&.key?(context_item)
|
114
|
+
end
|
115
|
+
|
116
|
+
def with_manifest_context(context)
|
117
|
+
old_context = foobara_manifest_context
|
118
|
+
begin
|
119
|
+
new_context = (old_context || {}).merge(context)
|
120
|
+
Thread.foobara_var_set("foobara_manifest_context", new_context)
|
121
|
+
yield
|
122
|
+
ensure
|
123
|
+
Thread.foobara_var_set("foobara_manifest_context", old_context)
|
124
|
+
end
|
125
|
+
end
|
97
126
|
end
|
98
127
|
end
|
99
128
|
end
|
@@ -1,13 +1,13 @@
|
|
1
1
|
module Foobara
|
2
2
|
class Error
|
3
3
|
class << self
|
4
|
-
def types_depended_on(*args
|
4
|
+
def types_depended_on(*args)
|
5
5
|
if args.size == 1
|
6
|
-
context_type.types_depended_on(args.first
|
6
|
+
context_type.types_depended_on(args.first)
|
7
7
|
elsif args.empty?
|
8
8
|
begin
|
9
9
|
if context_type
|
10
|
-
context_type.types_depended_on
|
10
|
+
context_type.types_depended_on
|
11
11
|
else
|
12
12
|
raise Foobara::TypeDeclarations::ErrorExtension::NoContextTypeSetError
|
13
13
|
end
|
@@ -6,7 +6,9 @@ module Foobara
|
|
6
6
|
include Concern
|
7
7
|
|
8
8
|
# as soon as we hit a registered type, don't go further down that path
|
9
|
-
def types_depended_on(result = nil
|
9
|
+
def types_depended_on(result = nil)
|
10
|
+
remove_sensitive = TypeDeclarations.foobara_manifest_context_remove_sensitive?
|
11
|
+
|
10
12
|
start = result.nil?
|
11
13
|
result ||= Set.new
|
12
14
|
return if result.include?(self)
|
@@ -15,7 +17,7 @@ module Foobara
|
|
15
17
|
|
16
18
|
return if !start && registered?
|
17
19
|
|
18
|
-
to_process = types_to_add_to_manifest
|
20
|
+
to_process = types_to_add_to_manifest
|
19
21
|
|
20
22
|
if element_types
|
21
23
|
to_process += case element_types
|
@@ -48,7 +50,7 @@ module Foobara
|
|
48
50
|
end
|
49
51
|
|
50
52
|
to_process.each do |type|
|
51
|
-
type.types_depended_on(result
|
53
|
+
type.types_depended_on(result)
|
52
54
|
end
|
53
55
|
|
54
56
|
if start
|
@@ -58,7 +60,9 @@ module Foobara
|
|
58
60
|
result
|
59
61
|
end
|
60
62
|
|
61
|
-
def types_to_add_to_manifest
|
63
|
+
def types_to_add_to_manifest
|
64
|
+
remove_sensitive = TypeDeclarations.foobara_manifest_context_remove_sensitive?
|
65
|
+
|
62
66
|
types = [*base_type, *possible_errors.map(&:error_class)]
|
63
67
|
|
64
68
|
if element_type && (!remove_sensitive || !element_type.sensitive?)
|
@@ -86,6 +90,77 @@ module Foobara
|
|
86
90
|
result.select(&:registered?)
|
87
91
|
end
|
88
92
|
|
93
|
+
def type_at_path(data_path)
|
94
|
+
path_parts = DataPath.for(data_path).path
|
95
|
+
|
96
|
+
path_part, *path_parts = path_parts
|
97
|
+
|
98
|
+
next_type = case path_part
|
99
|
+
when :"#"
|
100
|
+
unless element_type
|
101
|
+
# :nocov:
|
102
|
+
raise "Expected element_type to be set but is not"
|
103
|
+
# :nocov:
|
104
|
+
end
|
105
|
+
|
106
|
+
element_type
|
107
|
+
when Symbol
|
108
|
+
case element_types
|
109
|
+
when ::Hash
|
110
|
+
unless element_types.key?(path_part)
|
111
|
+
# :nocov:
|
112
|
+
raise "Expected element type to have key #{path_part} but does not"
|
113
|
+
# :nocov:
|
114
|
+
end
|
115
|
+
|
116
|
+
element_types[path_part]
|
117
|
+
when Types::Type
|
118
|
+
unless element_types.extends?(BuiltinTypes[:attributes])
|
119
|
+
# :nocov:
|
120
|
+
raise "Expected element type to be a Type but is not"
|
121
|
+
# :nocov:
|
122
|
+
end
|
123
|
+
|
124
|
+
# TODO: We assume it's attributes here but maybe we should assert that
|
125
|
+
element_types.element_types[path_part]
|
126
|
+
when nil
|
127
|
+
# :nocov:
|
128
|
+
raise "Expected element_types to be set but is not"
|
129
|
+
# :nocov:
|
130
|
+
else
|
131
|
+
# :nocov:
|
132
|
+
raise "Unsure how to handle path part #{path_part}"
|
133
|
+
# :nocov:
|
134
|
+
end
|
135
|
+
when Integer
|
136
|
+
if extends?(BuiltinTypes[:tuple])
|
137
|
+
element_types[path_part]
|
138
|
+
elsif extends?(BuiltinTypes[:array])
|
139
|
+
element_type
|
140
|
+
else
|
141
|
+
# :nocov:
|
142
|
+
raise "Unsure how to handle path part #{path_part}"
|
143
|
+
# :nocov:
|
144
|
+
end
|
145
|
+
else
|
146
|
+
# :nocov:
|
147
|
+
raise "Bad path part #{path_part}"
|
148
|
+
# :nocov:
|
149
|
+
end
|
150
|
+
|
151
|
+
unless next_type
|
152
|
+
# :nocov:
|
153
|
+
raise "Expected to find a type at #{path_part}"
|
154
|
+
# :nocov:
|
155
|
+
end
|
156
|
+
|
157
|
+
if path_parts.empty?
|
158
|
+
next_type
|
159
|
+
else
|
160
|
+
next_type.type_at_path(path_parts)
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
89
164
|
def inspect
|
90
165
|
# :nocov:
|
91
166
|
name = if scoped_path_set?
|