foobara 0.6.4 → 0.7.0

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: 3417123e9edcf11d20e2d6355e1b63d7d25b33e957b42d32c64b4452d93f4463
4
- data.tar.gz: 8b94bd6c61857d89eda1bcf667a408536cad9f2a5845f9a51a57e931a64ae28c
3
+ metadata.gz: 55727f8ba357338d057069b782e94dc171a87ce95ae4d1865c5df1e46252559a
4
+ data.tar.gz: 5aa4e8a6535fdaf3bc1b3dd968b5b00348ef00c723d4728e313f9076b4a02b5c
5
5
  SHA512:
6
- metadata.gz: b57004203dabc6e0d305f17dfd470e7fe47878b0c1be28fb6ebd89b5c0cbf943e96b5efa8404ce929e7a59744e0a36385649448391830886a5042ec3d48ce822
7
- data.tar.gz: 77d265ecf8b8c9f2fa8dcc30f996df4f237fda07eee821f7d85c67963ab42732a5dec786e2f0a2c6e273d1077215dac22ef4ad44c2ca8dc410e56658417ec599
6
+ metadata.gz: 239417815a5ead7dd367120cb67b50fb20d0750dacdd3f8519d76f2bc1e69f565f6217d7dd8d194bd199e6dbf9e7f1d2fd8783e081461da8888ee675f1fc9e7a
7
+ data.tar.gz: c06a234449b4ee52855f153277fe2440111f14873cc03dc9cc8c4c3a2fe558f811800ca6db8b0714d1e1fc2a54223290fb278c13c854b49dc2b708a5687f5ca2
data/CHANGELOG.md CHANGED
@@ -1,3 +1,13 @@
1
+ # [0.7.0] - 2026-10-09
2
+
3
+ - Do not allow anything but domains (and orgs as a hack) to be children of orgs
4
+ - Eliminate NoContextTypeSetError and add default context type of {}
5
+
6
+ # [0.6.5] - 2026-10-04
7
+
8
+ - Fix a problem where some nested sugary types don't expand correctly when using attributes dsl
9
+ - Add command name to error message when a result can't be cast to the result type
10
+
1
11
  # [0.6.4] - 2026-09-11
2
12
 
3
13
  - Track which models instances ignore unsupported attributes to prevent various issues, including breaking domain mappers
@@ -4,7 +4,15 @@ module Foobara
4
4
  module Result
5
5
  include Concern
6
6
 
7
- class CouldNotProcessResult < Outcome::UnsuccessfulOutcomeError; end
7
+ class CouldNotProcessResult < Outcome::UnsuccessfulOutcomeError;
8
+ attr_accessor :command
9
+
10
+ def initialize(command, errors)
11
+ self.command = command
12
+
13
+ super(errors, prefix: command.class.full_command_name)
14
+ end
15
+ end
8
16
 
9
17
  private
10
18
 
@@ -16,7 +24,7 @@ module Foobara
16
24
  if outcome.success?
17
25
  outcome.result
18
26
  else
19
- raise CouldNotProcessResult, outcome.errors
27
+ raise CouldNotProcessResult.new(self, outcome.errors)
20
28
  end
21
29
  end
22
30
  end
@@ -11,6 +11,8 @@ module Foobara
11
11
  :result_transformers,
12
12
  :errors_transformers,
13
13
  :pre_commit_transformers,
14
+ # Should we have separate success and error serializers so that serializers can be
15
+ # more reusable?
14
16
  :serializers,
15
17
  :request_mutators,
16
18
  :response_mutators,
@@ -5,6 +5,7 @@ module Foobara
5
5
  module Serializers
6
6
  class SuccessSerializer < Serializer
7
7
  def always_applicable?
8
+ # Why is the serializer coupled to a request???
8
9
  request.outcome&.success?
9
10
  end
10
11
  end
@@ -1,6 +1,10 @@
1
1
  module Foobara
2
2
  module CommandConnectors
3
3
  module Serializers
4
+ # TODO: put an entity-free version of this in model_plumbing!
5
+ # TODO: can't this just inherit from Serializer??
6
+ # TODO: shouldn't this be a transformer? It's not really serializing anything
7
+ # just preparing the data for serialization.
4
8
  class AggregateSerializer < SuccessSerializer
5
9
  def serialize(object)
6
10
  case object
@@ -3,10 +3,12 @@ module Foobara
3
3
  class UnsuccessfulOutcomeError < StandardError
4
4
  attr_accessor :errors, :backtrace_when_raised
5
5
 
6
- def initialize(errors)
6
+ def initialize(errors, message: errors.map(&:message).join(", "), prefix: nil)
7
7
  self.errors = errors
8
8
 
9
- message = errors.map(&:message).join(", ")
9
+ if prefix
10
+ message = "#{prefix}: #{message}"
11
+ end
10
12
 
11
13
  super(message)
12
14
  end
@@ -234,12 +234,23 @@ module Foobara
234
234
  domain.foobara_manifest_reference
235
235
  end.sort
236
236
 
237
- types = foobara_all_type(mode: Namespace::LookupMode::DIRECT).map do |type|
238
- if to_include
239
- to_include << type
237
+ types = []
238
+
239
+ # Using this to support deprecated Foobara.manifest without risking
240
+ # breakage elsewhere
241
+ if TypeDeclarations.foobara_manifest_context_include_unreachable?
242
+ foobara_all(mode: Namespace::LookupMode::DIRECT).each do |scoped|
243
+ to_include << scoped if to_include
244
+ types << scoped.foobara_manifest_reference if scoped.scoped_category == :type
240
245
  end
241
- type.foobara_manifest_reference
242
- end.sort
246
+ else
247
+ foobara_all_type(mode: Namespace::LookupMode::DIRECT).each do |scoped|
248
+ to_include << scoped if to_include
249
+ types << scoped.foobara_manifest_reference
250
+ end
251
+ end
252
+
253
+ types.sort!
243
254
 
244
255
  manifest = super.merge(types:)
245
256
 
@@ -11,7 +11,7 @@ module Foobara
11
11
  private def debug_manifest
12
12
  to_include = Namespace.global.foobara_all_organization.to_set
13
13
 
14
- TypeDeclarations.with_manifest_context(to_include:) do
14
+ TypeDeclarations.with_manifest_context(to_include:, include_unreachable: true) do
15
15
  included = {}
16
16
 
17
17
  h = {}
@@ -17,6 +17,8 @@ module Foobara
17
17
  # simplecov:enable
18
18
  end
19
19
 
20
+ include DomainModuleExtension
21
+
20
22
  unless is_a?(Namespace::IsNamespace)
21
23
  foobara_namespace!
22
24
  foobara_autoset_namespace!(default_namespace: Foobara::GlobalOrganization)
@@ -24,8 +26,6 @@ module Foobara
24
26
 
25
27
  foobara_parent_namespace.foobara_register(self)
26
28
  end
27
-
28
- include(DomainModuleExtension)
29
29
  end
30
30
 
31
31
  def foobara_organization!
@@ -155,11 +155,15 @@ module Foobara
155
155
 
156
156
  while parent_mod
157
157
  if parent_mod.is_a?(Foobara::Namespace::IsNamespace)
158
- mod.scoped_namespace = parent_mod
159
- return
160
- else
161
- parent_mod = Util.module_for(parent_mod)
158
+ # Only domains can have an org as its parent
159
+ # Important that Foobara::GlobalOrganization's parent is Foobara or it breaks categories
160
+ if mod.foobara_organization? || mod.foobara_domain? || !parent_mod.foobara_organization?
161
+ mod.scoped_namespace = parent_mod
162
+ return
163
+ end
162
164
  end
165
+
166
+ parent_mod = Util.module_for(parent_mod)
163
167
  end
164
168
 
165
169
  mod.scoped_namespace = default_namespace if default_namespace
@@ -216,6 +220,13 @@ module Foobara
216
220
  adjusted_scoped_path << path_part unless mod.scoped_namespace&.scoped_ignore_module?(next_mod)
217
221
  end
218
222
 
223
+ if parent&.foobara_organization?
224
+ if !mod.foobara_domain? && !mod.foobara_organization?
225
+ parent = Foobara::GlobalDomain
226
+ adjusted_scoped_path = mod_name.split("::")
227
+ end
228
+ end
229
+
219
230
  mod.scoped_path_autoset = true
220
231
  mod.scoped_path = adjusted_scoped_path
221
232
 
@@ -101,11 +101,15 @@ module Foobara
101
101
  }
102
102
  end
103
103
 
104
- Value::DataError.singleton_class.define_method :context_type_declaration do
105
- {
106
- attribute_name: :symbol,
107
- value: :duck
108
- }
104
+ ::Foobara::Value::DataError.instance_exec do
105
+ class << self
106
+ def context_type_declaration
107
+ {
108
+ attribute_name: :symbol,
109
+ value: :duck
110
+ }.freeze
111
+ end
112
+ end
109
113
  end
110
114
  end
111
115
 
@@ -83,6 +83,17 @@ module Foobara
83
83
  end
84
84
  end
85
85
 
86
+ if type && !type.is_a?(::Symbol)
87
+ type = Domain.current.foobara_type_from_declaration(type)
88
+
89
+ type = if type.registered?
90
+ type.reference_symbol
91
+ else
92
+ declaration = type.declaration_data.merge(declaration)
93
+ declaration[:type]
94
+ end
95
+ end
96
+
86
97
  processor_symbols.each do |processor_symbol|
87
98
  case processor_symbol
88
99
  when ::String
@@ -22,36 +22,20 @@ module Foobara
22
22
  self.validate_error_context_enabled = true
23
23
 
24
24
  module ErrorExtension
25
- class NoContextTypeSetError < StandardError
26
- def initialize
27
- super("No context type declaration set. Either set it or mark the error as abstract")
28
- end
29
- end
30
-
31
25
  include Concern
32
26
  # TODO: replace this with some kind of Foobara::TypeBuilder version
33
27
  include WithRegistries
34
28
 
35
29
  module ClassMethods
36
30
  def context_type
37
- @context_type ||= begin
38
- Foobara::Domain.foobara_type_from_declaration(self, context_type_declaration)
39
- rescue NoContextTypeSetError
40
- if abstract?
41
- nil
42
- else
43
- # simplecov:disable
44
- raise
45
- # simplecov:enable
46
- end
47
- end
48
- end
31
+ return @context_type if defined?(@context_type)
49
32
 
50
- def context_type_declaration
51
- # simplecov:disable
52
- raise NoContextTypeSetError
53
- # simplecov:enable
33
+ @context_type = unless abstract?
34
+ Foobara::Domain.foobara_type_from_declaration(self, context_type_declaration)
35
+ end
54
36
  end
37
+
38
+ def context_type_declaration = {}.freeze
55
39
  end
56
40
 
57
41
  def initialize(...)
@@ -82,7 +82,6 @@ module Foobara
82
82
  using_mode(Mode::STRINGIFIED, &)
83
83
  end
84
84
 
85
- # TODO: use manifest context instead
86
85
  def using_mode(new_mode, &)
87
86
  with_manifest_context(mode: new_mode, &)
88
87
  end
@@ -116,8 +115,17 @@ module Foobara
116
115
  Thread.inheritable_thread_local_var_get("foobara_manifest_context")
117
116
  end
118
117
 
119
- allowed_context_keys = [:detached, :to_include, :mode, :remove_sensitive, :include_processors]
120
- booleans = [:detached, :remove_sensitive, :include_processors]
118
+ allowed_context_keys = [
119
+ :detached,
120
+ :to_include,
121
+ :mode,
122
+ :remove_sensitive,
123
+ :include_processors,
124
+ # This is just a flag to allow the deprecated Foobara.manifest to include
125
+ # everything without risk of breaking something in command connector manifests
126
+ :include_unreachable
127
+ ]
128
+ booleans = [:detached, :remove_sensitive, :include_processors, :include_unreachable]
121
129
 
122
130
  booleans.each do |context_item|
123
131
  define_method "foobara_manifest_context_#{context_item}?" do
@@ -5,22 +5,11 @@ module Foobara
5
5
  if args.size == 1
6
6
  context_type.types_depended_on(args[0])
7
7
  elsif args.empty?
8
- begin
9
- if context_type
10
- context_type.types_depended_on
11
- else
12
- raise Foobara::TypeDeclarations::ErrorExtension::NoContextTypeSetError
13
- end
14
- rescue Foobara::TypeDeclarations::ErrorExtension::NoContextTypeSetError
15
- if abstract?
16
- []
17
- else
18
- # simplecov:disable
19
- raise
20
- # simplecov:enable
21
- end
8
+ if abstract?
9
+ []
10
+ else
11
+ context_type.types_depended_on
22
12
  end
23
-
24
13
  else
25
14
  # simplecov:disable
26
15
  raise ArgumentError, "Too many arguments #{args}"
@@ -428,12 +428,7 @@ module Foobara
428
428
  remove_sensitive = TypeDeclarations.foobara_manifest_context_remove_sensitive?
429
429
 
430
430
  if registered?
431
- # TODO: we should just use the symbol and nothing else in this context instead of a hash with 1 element.
432
- if scoped_unregistered?
433
- unregistered_foobara_manifest_reference.to_sym
434
- else
435
- foobara_manifest_reference.to_sym
436
- end
431
+ reference_symbol
437
432
  elsif remove_sensitive
438
433
  TypeDeclarations.remove_sensitive_types(declaration_data)
439
434
  else
@@ -441,6 +436,16 @@ module Foobara
441
436
  end
442
437
  end
443
438
 
439
+ def reference_symbol
440
+ raise "Not registered so no reference symbol" unless registered?
441
+
442
+ if scoped_unregistered?
443
+ unregistered_foobara_manifest_reference.to_sym
444
+ else
445
+ foobara_manifest_reference.to_sym
446
+ end
447
+ end
448
+
444
449
  def declaration_data_for_manifest
445
450
  data = declaration_data
446
451
 
data/version.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  module Foobara
2
2
  module Version
3
- VERSION = "0.6.4".freeze
3
+ VERSION = "0.7.0".freeze
4
4
  MINIMUM_RUBY_VERSION = [">= 3.4.0", "< 4.1"].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.6.4
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Miles Georgi