hub_kernel-api 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: 86e1e73789993ac38e72f3707d5ff990ad680a180ea5c9b49afb8dbccc4ad2e0
4
- data.tar.gz: '02937a7e3d0b5eb5979c316a32cb7dede99749b0d559b5846ff090a5c700fc64'
3
+ metadata.gz: 005a2ef443ca851aa60b1e07bbf00d20f36ad682a7dcba572fcb2c5847181831
4
+ data.tar.gz: 3da76e3b5993936cc999d4641e2d4b70476a8fb7d86451294a7a5f583b85fb0c
5
5
  SHA512:
6
- metadata.gz: b8c5ba3ed71d2dbb8690ac63f7bded2b1cc9a3d9ef7e3592f65fe533402a6cbf8da8a7193e93e184bea3b6fa2bfa304e421ea16c9601bbbe8382c3524801fd29
7
- data.tar.gz: 1ff6097cfa70e00947054dc7b3c788923f94ef5e11ec731869f42f30c08f315d2ba498b3452808f5cba9a021cb3336b07aae9849b930f57c8a43293226391430
6
+ metadata.gz: 36883d22bb606c36eca8c7e80620d1a8c07105254f41152a87e28c4317f91ff23ec58f5a6aa17971d106577695f25f2e8c5e3aa8b329108303a0ca8f341326fb
7
+ data.tar.gz: 78348ad9a3c18cffff53beadc24f99a15a5d0b4524a592da883e807966648bef9f550945bd059cacc60e03d60084bed3c0d8a8ead26c7d702baaca0c43eabaeb
data/README.md CHANGED
@@ -17,9 +17,15 @@ HubKernel::Api.account_method = :current_account
17
17
 
18
18
  Rails.application.config.to_prepare do
19
19
  HubKernel::Api.hubs = [ Supplies ]
20
+ HubKernel::Api.check!
20
21
  end
21
22
  ```
22
23
 
24
+ `HubKernel::Api.check!` raises `HubKernel::Api::UnservableHubError` when a served entry
25
+ exposes no methods, when two served hubs answer at the same address, or when a served
26
+ hub's exposed list has a problem, naming each. Inside `to_prepare` it runs again after
27
+ every code reload.
28
+
23
29
  The base controller's own sign-in runs before every call. hub_kernel's permission check
24
30
  and account scope must also be set, as hub_kernel's readme describes. Mount the engine:
25
31
 
@@ -38,6 +44,16 @@ A hub listed this way answers only at the name given, and the permission check i
38
44
  asked about it by its own name, such as `ledger:record_spend`. A read answers GET and a write answers POST, and the answer is the method's
39
45
  return value under `answer`.
40
46
 
47
+ A GET at a served hub's own address, `/<hub>`, lists the methods the caller may call on
48
+ the account the host names, each with its name, the values it takes and its verb:
49
+
50
+ ```json
51
+ [{ "name": "price_of", "takes": ["item"], "verb": "GET" }]
52
+ ```
53
+
54
+ A hub that is not served is answered as not found, and a caller the host's sign-in refuses
55
+ is shown nothing.
56
+
41
57
  | Case | Status | Body |
42
58
  | --- | --- | --- |
43
59
  | The method answers | 200 | `{"answer": ...}` |
@@ -1,9 +1,8 @@
1
1
  module HubKernel
2
2
  module Api
3
- class HubCallsController < HubKernel::Api.base_controller.constantize
3
+ class HubCallsController < HubController
4
4
  wrap_parameters false
5
5
 
6
- rescue_from ActionController::RoutingError, HubKernel::NotAllowed, with: :not_found
7
6
  rescue_from HubKernel::Refused, HubKernel::MissingArgumentError, with: :refused
8
7
  rescue_from ActiveRecord::RecordNotFound, with: :missing_record
9
8
 
@@ -16,8 +15,6 @@ module HubKernel
16
15
 
17
16
  private
18
17
 
19
- def hub = @hub ||= HubKernel::Api.find(params[:hub]) || raise(ActionController::RoutingError, "Not found")
20
-
21
18
  def asked_with_the_right_verb? = hub.exposed(params[:name])&.writes == request.post?
22
19
 
23
20
  def refuse_unlisted_values
@@ -32,12 +29,6 @@ module HubKernel
32
29
 
33
30
  def values = request.query_parameters.merge(request.request_parameters).deep_symbolize_keys
34
31
 
35
- def caller_person = send(HubKernel::Api.person_method)
36
-
37
- def caller_account = send(HubKernel::Api.account_method)
38
-
39
- def not_found = render(json: { error: "Not found" }, status: :not_found)
40
-
41
32
  def refused(refusal) = render(json: { error: refusal.message }, status: :unprocessable_content)
42
33
 
43
34
  def missing_record(missing)
@@ -0,0 +1,17 @@
1
+ module HubKernel
2
+ module Api
3
+ class HubController < HubKernel::Api.base_controller.constantize
4
+ rescue_from ActionController::RoutingError, HubKernel::NotAllowed, with: :not_found
5
+
6
+ private
7
+
8
+ def hub = @hub ||= HubKernel::Api.find(params[:hub]) || raise(ActionController::RoutingError, "Not found")
9
+
10
+ def caller_person = send(HubKernel::Api.person_method)
11
+
12
+ def caller_account = send(HubKernel::Api.account_method)
13
+
14
+ def not_found = render(json: { error: "Not found" }, status: :not_found)
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,13 @@
1
+ module HubKernel
2
+ module Api
3
+ class HubsController < HubController
4
+ def show
5
+ render json: hub.exposures_for(person: caller_person, account: caller_account).map { |exposure| listed(exposure) }
6
+ end
7
+
8
+ private
9
+
10
+ def listed(exposure) = { name: exposure.name, takes: exposure.takes, verb: exposure.writes ? "POST" : "GET" }
11
+ end
12
+ end
13
+ end
data/config/routes.rb CHANGED
@@ -1,3 +1,4 @@
1
1
  HubKernel::Api::Engine.routes.draw do
2
+ get ":hub", to: "hubs#show"
2
3
  match ":hub/:name", to: "hub_calls#answer", via: [ :get, :post ]
3
4
  end
@@ -1,5 +1,5 @@
1
1
  module HubKernel
2
2
  module Api
3
- VERSION = "0.3.0"
3
+ VERSION = "0.5.0"
4
4
  end
5
5
  end
@@ -4,6 +4,8 @@ require "hub_kernel/api/engine"
4
4
 
5
5
  module HubKernel
6
6
  module Api
7
+ class UnservableHubError < StandardError; end
8
+
7
9
  mattr_accessor :hubs, default: []
8
10
  mattr_accessor :base_controller, default: "ActionController::API"
9
11
  mattr_accessor :person_method
@@ -11,6 +13,24 @@ module HubKernel
11
13
 
12
14
  def self.find(name) = addresses[name]
13
15
 
14
- def self.addresses = hubs.reduce({}) { |found, entry| found.merge(entry.is_a?(Hash) ? entry : { entry.name.demodulize.underscore => entry }) }
16
+ def self.check!
17
+ problems = unexposed_hubs + shared_addresses + exposure_problems
18
+ raise UnservableHubError, problems.join("\n") if problems.any?
19
+ end
20
+
21
+ def self.addresses = served.to_h
22
+
23
+ def self.served = hubs.flat_map { |entry| entry.is_a?(Hash) ? entry.to_a : [ [ entry.name.demodulize.underscore, entry ] ] }
24
+
25
+ def self.unexposed_hubs = served.map(&:last).reject { |hub| hub.respond_to?(:exposures) }.map { |hub| "#{hub.name} exposes no methods to serve" }
26
+
27
+ def self.shared_addresses
28
+ served.group_by(&:first).select { |_address, entries| entries.size > 1 }.map do |address, entries|
29
+ "#{entries.map { |_address, hub| hub.name }.join(" and ")} both answer at #{address}"
30
+ end
31
+ end
32
+
33
+ def self.exposure_problems = served.map(&:last).select { |hub| hub.respond_to?(:exposure_problems) }.flat_map(&:exposure_problems)
34
+ private_class_method :served, :unexposed_hubs, :shared_addresses, :exposure_problems
15
35
  end
16
36
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hub_kernel-api
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
@@ -50,6 +50,8 @@ files:
50
50
  - README.md
51
51
  - Rakefile
52
52
  - app/controllers/hub_kernel/api/hub_calls_controller.rb
53
+ - app/controllers/hub_kernel/api/hub_controller.rb
54
+ - app/controllers/hub_kernel/api/hubs_controller.rb
53
55
  - config/routes.rb
54
56
  - lib/hub_kernel-api.rb
55
57
  - lib/hub_kernel/api.rb