hub_kernel-interface 0.3.0 → 0.5.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: 37c5ea275a8aaacc15d056ff35580688737ef2210a22e22846276404cf7b052b
4
- data.tar.gz: 8ca84328489427f9d5616ad4d93b620219bbb6bc550a5ec63ac0f7e54ec3e569
3
+ metadata.gz: b0fa91bb8d315c37de4f4d2aadb2c12e924b092b763b2d932eecf0a0adb161d8
4
+ data.tar.gz: bccf1208493a973a64cb76df47226cd638d375aa38e3dfa34f18e801a4fba94f
5
5
  SHA512:
6
- metadata.gz: ef4ee5d46d58f791c724fbaa24402cc3db861c05b1193a4a13d60a413aae415bdab29400cbf10c4fe5ae7580be660c6e3740012ad5c9cbe0a93733674f1b2c32
7
- data.tar.gz: 2410f02d15351de8a053741bd66c14a162d34ce4f60a910acaa13f2002cc63742716f2029ed02ff042d4aee2323123cb9fc9dff2ec1f07498fee4f9c166c634c
6
+ metadata.gz: 2114bad113c0a16a3f6a85b59a01f887928980fa69f334e32dcdb19f5ca7ac1397c234d67779d8c5ba275c794254cbb673a6fc3db5f5b2fb6c0d35858acc587c
7
+ data.tar.gz: 90e57ae0a730030c16c895f94d6011c99d371bb7443668e935c681b95f1a58b0de8440bc0bf011f6b5110583b173100bfae214241215afe5f9ad0b3783b75d7a
data/README.md CHANGED
@@ -55,6 +55,23 @@ HubKernel::Interface.served # => { "supplies" => Supplies, "money" =>
55
55
  The permission check is still asked about a hub served under a chosen name by its own name,
56
56
  such as `ledger:record_spend`.
57
57
 
58
+ An interface gem's boot check runs `HubKernel::Interface.check!`, which raises
59
+ `HubKernel::Interface::UnservableHubError` naming every problem in the served list at once:
60
+ an entry that exposes no methods, two entries that answer at the same name, and each
61
+ problem in a served hub's exposed list.
62
+
63
+ An interface gem checks a call's values before calling, and describes a record the call
64
+ named that does not exist, so every interface gives the same reasons:
65
+
66
+ ```ruby
67
+ HubKernel::Interface::CallReasons.refuse_unlisted_values(Supplies, "price_of", values: values, person: person, account: account)
68
+ HubKernel::Interface::CallReasons.missing_record(error) # => "No consumable has the id 7"
69
+ ```
70
+
71
+ `refuse_unlisted_values` raises `HubKernel::NotAllowed` when the permission check refuses the
72
+ call, whatever values it sends, and otherwise raises `HubKernel::Refused` naming the method and
73
+ every value it is not listed with. `missing_record` reads the error's `model` and `id`.
74
+
58
75
  `Supplies.exposure_problems` names each exposed method the hub has no method for, or lists
59
76
  with values it does not take. `HubKernel::Interface::ExposingHubs.list` holds every hub that
60
77
  declares an exposed method.
@@ -0,0 +1,16 @@
1
+ require "hub_kernel/exposes"
2
+
3
+ module HubKernel
4
+ module Interface
5
+ module CallReasons
6
+ def self.refuse_unlisted_values(hub, name, values:, person:, account:)
7
+ raise HubKernel::NotAllowed, "#{hub.name.demodulize} #{name}" unless hub.exposures_for(person: person, account: account).any? { |exposure| exposure.name.to_s == name.to_s }
8
+
9
+ unlisted = values.keys - hub.exposed(name).takes
10
+ raise HubKernel::Refused, "#{name} does not take #{unlisted.join(", ")}" if unlisted.any?
11
+ end
12
+
13
+ def self.missing_record(missing) = "No #{missing.model.demodulize.underscore.humanize(capitalize: false)} has the id #{missing.id}"
14
+ end
15
+ end
16
+ end
@@ -1,5 +1,5 @@
1
1
  module HubKernel
2
2
  module Interface
3
- VERSION = "0.3.0"
3
+ VERSION = "0.5.0"
4
4
  end
5
5
  end
@@ -1,14 +1,35 @@
1
1
  require "hub_kernel/interface/version"
2
2
  require "hub_kernel/exposes"
3
+ require "hub_kernel/interface/call_reasons"
3
4
 
4
5
  module HubKernel
5
6
  module Interface
7
+ class UnservableHubError < StandardError; end
8
+
6
9
  singleton_class.attr_writer :hubs
7
10
 
8
11
  def self.hubs = @hubs ||= []
9
12
 
10
13
  def self.find(name) = served[name]
11
14
 
12
- def self.served = hubs.flat_map { |entry| entry.is_a?(Hash) ? entry.to_a : [ [ entry.name.demodulize.underscore, entry ] ] }.to_h
15
+ def self.check!
16
+ problems = unexposed_hubs + shared_names + exposure_problems
17
+ raise UnservableHubError, problems.join("\n") if problems.any?
18
+ end
19
+
20
+ def self.unexposed_hubs = served.values.reject { |hub| hub.respond_to?(:exposures) && hub.exposures.any? }.map { |hub| "#{hub.name} exposes no methods to serve" }
21
+
22
+ def self.shared_names
23
+ served_pairs.group_by(&:first).select { |_name, pairs| pairs.size > 1 }.map do |name, pairs|
24
+ "#{pairs.map { |_name, hub| hub.name }.join(" and ")} both answer at #{name}"
25
+ end
26
+ end
27
+
28
+ def self.exposure_problems = served.values.select { |hub| hub.respond_to?(:exposure_problems) }.flat_map(&:exposure_problems)
29
+
30
+ def self.served_pairs = hubs.flat_map { |entry| entry.is_a?(Hash) ? entry.to_a : [ [ entry.name.demodulize.underscore, entry ] ] }
31
+ private_class_method :unexposed_hubs, :shared_names, :exposure_problems, :served_pairs
32
+
33
+ def self.served = served_pairs.to_h
13
34
  end
14
35
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hub_kernel-interface
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - tylercschneider
@@ -40,6 +40,7 @@ files:
40
40
  - lib/hub_kernel/context.rb
41
41
  - lib/hub_kernel/exposes.rb
42
42
  - lib/hub_kernel/interface.rb
43
+ - lib/hub_kernel/interface/call_reasons.rb
43
44
  - lib/hub_kernel/interface/exposing_hubs.rb
44
45
  - lib/hub_kernel/interface/version.rb
45
46
  homepage: https://github.com/DYB-Development/hub_kernel-interface