thalamus 0.0.2 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +12 -0
- data/README.md +53 -19
- data/TODO.md +3 -0
- data/lib/thalamus.rb +3 -4
- data/lib/thalamus/interactor.rb +32 -24
- data/lib/thalamus/policy.rb +3 -3
- data/lib/thalamus/result.rb +55 -0
- data/lib/thalamus/version.rb +12 -1
- data/thalamus.gemspec +3 -9
- metadata +4 -88
- data/bin/setup +0 -8
- data/lib/thalamus/interactor/result.rb +0 -64
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dbbccc5279014f01d693e7dd49bb79d5af7d9a3c
|
4
|
+
data.tar.gz: f7001941bd457f0f7dfa8da64c33c725fd2d644b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cb17a44901fe0258c7322c916ca6d57bdf63cf4c244deff6baf761eeecd6ad7bb02496fbbd5ef0fdf0d05b62a56549d09395aa9cbdf7c8de2bb39a553cc3fa94
|
7
|
+
data.tar.gz: a6aae1401cbc2b69e0685023b4f2d06bac17d7f0035f8b85400ef1f00a7bcd93ef256ee7ec2feec44641bb83f75b25c210fc0abb71183e645e84a0a67f0e1fe4
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,20 +1,26 @@
|
|
1
1
|
# Thalamus
|
2
2
|
|
3
|
-
|
3
|
+
[![Gem Version](https://badge.fury.io/rb/thalamus.svg)](https://badge.fury.io/rb/thalamus)
|
4
4
|
|
5
|
-
Thalamus is
|
5
|
+
**Thalamus** is a simple implementation of the interactor pattern. It encourages separating business logic from implementation concerns. Thalamus provides the glue between your endpoints and your problem domain, and is especially useful for keeping logic consistent in apps with multiple interfaces.
|
6
6
|
|
7
7
|
## Installation
|
8
8
|
|
9
|
-
Come on now
|
9
|
+
Come on now:
|
10
10
|
|
11
11
|
```ruby
|
12
|
-
gem 'thalamus'
|
12
|
+
gem 'thalamus'
|
13
13
|
```
|
14
14
|
```bash
|
15
15
|
bundle install
|
16
16
|
```
|
17
17
|
|
18
|
+
Or:
|
19
|
+
|
20
|
+
```bash
|
21
|
+
gem install thalamus
|
22
|
+
```
|
23
|
+
|
18
24
|
## Usage
|
19
25
|
|
20
26
|
```ruby
|
@@ -30,7 +36,7 @@ class DoSomething < Thalamus::Interactor
|
|
30
36
|
end
|
31
37
|
```
|
32
38
|
|
33
|
-
Call `DoSomething.call(payload)` from anywhere - a controller, an API endpoint, a task or job, the command line, another interactor, etc. This is the _only_ entry point from your app's implementation details
|
39
|
+
Call `DoSomething.call(payload)` from anywhere - a controller, an API endpoint, a task or job, the command line, another interactor, etc. This is the _only_ entry point from your app's implementation details into the business logic.
|
34
40
|
|
35
41
|
Note that you invoke with `Interactor.call` but define behaviour with `Interactor#call`.
|
36
42
|
|
@@ -38,26 +44,44 @@ Note that you invoke with `Interactor.call` but define behaviour with `Interacto
|
|
38
44
|
|
39
45
|
The input payload must be a hash and is immutable. Symbolized keys are preferred. The hash content may take two forms:
|
40
46
|
|
41
|
-
- `{params: {foo: 'bar'}, current_user: User.new}` is recommended.
|
47
|
+
- `{params: {foo: 'bar'}, current_user: User.new}` is recommended. Often, implementation in the controller will look like `Interactor.call(params: http_request_params_hash, current_user: authenticated_user)`.
|
42
48
|
- `{foo: 'bar', current_user: User.new}` is also accepted. Special fields will be extracted and will _not_ be passed to `:params`. Special fields include:
|
43
49
|
+ `:current_user` (see Authorization)
|
44
50
|
|
45
51
|
### Authorization
|
46
52
|
|
47
53
|
```ruby
|
54
|
+
class MyPolicy < Thalamus::Policy
|
55
|
+
def eat?
|
56
|
+
# boolean expression
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
48
60
|
class EatCheese < Thalamus::Interactor
|
49
|
-
policy
|
61
|
+
policy MyPolicy, :eat?
|
50
62
|
def call
|
51
63
|
# ...
|
52
64
|
end
|
53
65
|
end
|
54
66
|
```
|
55
67
|
|
56
|
-
If a policy is defined
|
68
|
+
If a policy is defined on the interactor, `Interactor.call` provides its payload to the policy. If the policy fails, the interactor will fail immediately.
|
69
|
+
|
70
|
+
Policies have access to `#current_user` and `#params` getters.
|
71
|
+
|
72
|
+
In your policy, you may need to define a way to transform your data from raw inputs to rich domain objects:
|
73
|
+
|
74
|
+
```ruby
|
75
|
+
class ApplicationPolicy < Thalamus::Policy
|
76
|
+
def model
|
77
|
+
params[:type].constantize.find(params[:id])
|
78
|
+
end
|
79
|
+
end
|
80
|
+
```
|
57
81
|
|
58
82
|
### Validation
|
59
83
|
|
60
|
-
Thalamus depends on [dry-rb](http://dry-rb.org/gems/dry-validation)
|
84
|
+
Thalamus depends on [dry-rb](http://dry-rb.org/gems/dry-validation) via [Hanami::Validations](https://github.com/hanami/validations):
|
61
85
|
|
62
86
|
```ruby
|
63
87
|
class Blah < Thalamus::Interactor
|
@@ -88,23 +112,26 @@ end
|
|
88
112
|
|
89
113
|
### Execution
|
90
114
|
|
91
|
-
This is where you work with domain entities - and as a best practice, this should be the outermost layer _in your entire application_ where you work with them. (User
|
115
|
+
This is where you work with domain entities - and as a best practice, this should be the outermost layer _in your entire application_ where you work with them. (User _authentication_ in the router or controller is the only exception, and even then you should only be exposing credentials outside of the business domain.) `#call` will only be run if the interactor is both authorized and valid, enforcing permitted access and changes.
|
92
116
|
|
93
117
|
`#error!(message)` triggers a failure and aborts the interactor.
|
94
118
|
|
95
|
-
`#params` provides a copy of the sanitized input after it has been processed by the validator. It cannot be modified - see
|
119
|
+
`#current_user` and `#params` access the payload. `#params` provides a copy of the sanitized input after it has been processed by the validator. It cannot be modified - see Output to mutate return data.
|
96
120
|
|
97
121
|
### Output
|
98
122
|
|
99
|
-
An interactor returns an instance of Thalamus::Result
|
123
|
+
An interactor returns an instance of `Thalamus::Result`. It responds to the following instance methods:
|
100
124
|
|
101
125
|
- `status` => Symbol in `[:success, :unauthorized, :invalid, :failure]`
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
- `errors` =>
|
107
|
-
|
126
|
+
+ `success?` => Boolean, results are successful if no errors are raised
|
127
|
+
+ `unauthorized?` => Boolean
|
128
|
+
+ `invalid?` => Boolean
|
129
|
+
+ `failure?` => Boolean, equivalent of `!success?`
|
130
|
+
- `errors` => Enumerable of error messages, depending on status
|
131
|
+
+ success: Empty array: `[]`
|
132
|
+
+ unauthorized: `['Unauthorized']`
|
133
|
+
+ invalid: Hash of arrays from dry-validation: `{param: [errors]}`
|
134
|
+
+ failure: `[error!(message)]`
|
108
135
|
|
109
136
|
Any other name starting with a lowercase letter can be exposed to the result object:
|
110
137
|
|
@@ -120,4 +147,11 @@ end
|
|
120
147
|
|
121
148
|
Whatever is at `@book` is now available at `Result#book`.
|
122
149
|
|
123
|
-
It is up to the developer to enforce boundaries appropriately. You must decide which data to expose outside of the interactor, and which layer is responsible for converting it. For example, you may wish to convert an entity to JSON for an API response, but when calling an interactor from somewhere else you may find it more useful to return a richer object. You may decide to handle JSON conversions in the controller - the interactor is the layer that modifies data, but there is no conversion mechanism because it is agnostic to how it is
|
150
|
+
It is up to the developer to enforce boundaries appropriately. You must decide which data to expose outside of the interactor, and which layer is responsible for converting it. For example, you may wish to convert an entity to JSON for an API response, but when calling an interactor from somewhere else you may find it more useful to return a richer object. You may decide to handle JSON conversions in the controller - the interactor is the layer that modifies data, but there is no conversion mechanism because it is agnostic to how it is used.
|
151
|
+
|
152
|
+
For your convenience, `Result#response` provides a JSON-friendly hash of appropriate information:
|
153
|
+
|
154
|
+
- success: all exposures
|
155
|
+
- unauthorized: `{messages: ['Unauthorized']}`
|
156
|
+
- invalid: errors hash
|
157
|
+
- failure: `{messages: [error_message]}`
|
data/TODO.md
ADDED
data/lib/thalamus.rb
CHANGED
data/lib/thalamus/interactor.rb
CHANGED
@@ -1,27 +1,28 @@
|
|
1
1
|
require 'hanami/validations/form'
|
2
|
-
require 'thalamus/
|
2
|
+
require 'thalamus/result'
|
3
3
|
|
4
4
|
module Thalamus
|
5
5
|
class Interactor
|
6
6
|
include Hanami::Validations::Form
|
7
7
|
|
8
|
+
attr_reader :current_user
|
9
|
+
|
8
10
|
def initialize(payload = {})
|
9
11
|
@current_user = payload.delete(:current_user)
|
10
12
|
@_params = payload.delete(:params) || payload
|
11
13
|
@_errors = []
|
12
14
|
end
|
13
|
-
attr_reader :current_user, :model
|
14
15
|
|
15
16
|
def params
|
16
17
|
@_params.dup
|
17
18
|
end
|
18
19
|
|
19
20
|
def _call
|
20
|
-
|
21
|
+
status = catch :status do
|
21
22
|
# Authorization
|
22
23
|
if tuple = self.class._policy
|
23
24
|
klass, policy = tuple
|
24
|
-
fail!(:unauthorized) unless klass.new(current_user,
|
25
|
+
fail!(:unauthorized) unless klass.new(current_user, params).send(policy)
|
25
26
|
end
|
26
27
|
|
27
28
|
# Validation
|
@@ -31,29 +32,30 @@ module Thalamus
|
|
31
32
|
call
|
32
33
|
:success
|
33
34
|
end
|
34
|
-
result = Result.new
|
35
|
-
.finish!(status, @_errors, @_validation_errors)
|
35
|
+
result = Result.new(status, @_errors, _exposures)
|
36
36
|
yield result if block_given? && result.success?
|
37
37
|
result
|
38
38
|
end
|
39
39
|
|
40
40
|
private
|
41
41
|
|
42
|
+
# Throw an error from the business logic, and abort
|
42
43
|
def error!(msg = '')
|
43
|
-
@_errors
|
44
|
+
@_errors = [msg]
|
44
45
|
fail!
|
45
46
|
end
|
46
47
|
|
48
|
+
# Internal methods
|
47
49
|
def fail!(status = :failure)
|
48
50
|
throw :status, status
|
49
51
|
end
|
50
52
|
|
51
53
|
def valid?
|
52
54
|
if schema = self.class.schema
|
53
|
-
|
54
|
-
@_params =
|
55
|
-
@
|
56
|
-
|
55
|
+
validation = schema.call(@_params)
|
56
|
+
@_params = validation.output
|
57
|
+
@_errors = validation.errors
|
58
|
+
validation.success?
|
57
59
|
else
|
58
60
|
true
|
59
61
|
end
|
@@ -66,36 +68,42 @@ module Thalamus
|
|
66
68
|
end.to_h
|
67
69
|
end
|
68
70
|
|
71
|
+
# Class methods
|
69
72
|
class << self
|
70
73
|
private :new
|
71
74
|
|
72
|
-
|
75
|
+
attr_reader :_policy, :exposures
|
76
|
+
|
77
|
+
# Public entry point
|
78
|
+
def call(payload = {}, &block)
|
73
79
|
new(payload)._call(&block)
|
74
80
|
end
|
75
81
|
|
76
|
-
attr_reader :_policy, :exposures
|
77
|
-
|
78
82
|
private # Class-level DSL
|
79
83
|
|
84
|
+
# Example:
|
85
|
+
# policy UserPolicy, :edit?
|
80
86
|
def policy(klass, policy)
|
81
87
|
@_policy = [klass, policy]
|
82
88
|
end
|
83
89
|
|
84
|
-
|
85
|
-
|
86
|
-
end
|
87
|
-
|
88
|
-
def _schema_type
|
89
|
-
@_schema_type || super
|
90
|
-
end
|
91
|
-
|
90
|
+
# Example:
|
91
|
+
# expose :foo, :bar
|
92
92
|
def expose(*ivars)
|
93
93
|
ivars.each do |ivar|
|
94
94
|
@exposures ||= []
|
95
95
|
@exposures << ivar.to_sym
|
96
96
|
end
|
97
97
|
end
|
98
|
-
end
|
99
98
|
|
100
|
-
|
99
|
+
# TODO: Document this
|
100
|
+
# def schema_type(type)
|
101
|
+
# @_schema_type = type
|
102
|
+
# end
|
103
|
+
|
104
|
+
# def _schema_type
|
105
|
+
# @_schema_type || super
|
106
|
+
# end
|
107
|
+
end # class << self
|
108
|
+
end # class Interactor
|
101
109
|
end
|
data/lib/thalamus/policy.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
module Thalamus
|
2
2
|
class Policy
|
3
|
-
attr_reader :
|
3
|
+
attr_reader :current_user, :params
|
4
4
|
|
5
|
-
def initialize(
|
6
|
-
@
|
5
|
+
def initialize(current_user, params)
|
6
|
+
@current_user, @params = current_user, params
|
7
7
|
end
|
8
8
|
|
9
9
|
def method_missing(m, *args, &block)
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module Thalamus
|
2
|
+
class Result
|
3
|
+
def initialize(status, errors, exposures)
|
4
|
+
@status = status
|
5
|
+
@errors = errors || []
|
6
|
+
@exposures = exposures || {}
|
7
|
+
end
|
8
|
+
|
9
|
+
attr_reader :status, :errors
|
10
|
+
|
11
|
+
def success?
|
12
|
+
status == :success && errors.empty?
|
13
|
+
end
|
14
|
+
|
15
|
+
def unauthorized?
|
16
|
+
status == :unauthorized
|
17
|
+
end
|
18
|
+
|
19
|
+
def invalid?
|
20
|
+
status == :invalid
|
21
|
+
end
|
22
|
+
|
23
|
+
def failure?
|
24
|
+
!success?
|
25
|
+
end
|
26
|
+
|
27
|
+
def response
|
28
|
+
if success?
|
29
|
+
@exposures
|
30
|
+
elsif unauthorized?
|
31
|
+
{messages: ['Unauthorized']}
|
32
|
+
elsif invalid?
|
33
|
+
errors
|
34
|
+
elsif failure?
|
35
|
+
{messages: errors}
|
36
|
+
else
|
37
|
+
raise "[Thalamus] Invalid result status: #{status}"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
protected
|
42
|
+
|
43
|
+
def method_missing(m, *args, &block)
|
44
|
+
if m.to_s =~ /^[a-z]/
|
45
|
+
@exposures.fetch(m) { super }
|
46
|
+
else
|
47
|
+
super
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def respond_to_missing?(m, include_private = false)
|
52
|
+
m.to_s =~ /^[a-z]/ && @exposures.key?(m)
|
53
|
+
end
|
54
|
+
end # class Result
|
55
|
+
end
|
data/lib/thalamus/version.rb
CHANGED
data/thalamus.gemspec
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
lib = File.expand_path("../lib", __FILE__)
|
3
|
-
|
3
|
+
$:.unshift(lib) unless $:.include?(lib)
|
4
4
|
require "thalamus/version"
|
5
5
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
7
|
spec.name = "thalamus"
|
8
|
-
spec.version = Thalamus
|
8
|
+
spec.version = Thalamus.version
|
9
9
|
spec.authors = ["Josh Greenberg"]
|
10
10
|
spec.email = ["joshgreenberg91@gmail.com"]
|
11
11
|
|
@@ -22,12 +22,6 @@ Gem::Specification.new do |spec|
|
|
22
22
|
|
23
23
|
spec.add_development_dependency "bundler", "~> 1.15"
|
24
24
|
spec.add_development_dependency "rake", "~> 10.0"
|
25
|
-
|
26
|
-
spec.add_development_dependency "minitest-reporters"
|
27
|
-
spec.add_development_dependency "pry"
|
28
|
-
spec.add_development_dependency "guard"
|
29
|
-
spec.add_development_dependency "guard-minitest"
|
30
|
-
spec.add_development_dependency "rake-notes"
|
31
|
-
|
25
|
+
|
32
26
|
spec.add_dependency "hanami-validations", "~> 1.0"
|
33
27
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: thalamus
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Josh Greenberg
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-09-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -38,90 +38,6 @@ dependencies:
|
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '10.0'
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: minitest
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - "~>"
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: '5.0'
|
48
|
-
type: :development
|
49
|
-
prerelease: false
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - "~>"
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: '5.0'
|
55
|
-
- !ruby/object:Gem::Dependency
|
56
|
-
name: minitest-reporters
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
58
|
-
requirements:
|
59
|
-
- - ">="
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: '0'
|
62
|
-
type: :development
|
63
|
-
prerelease: false
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
65
|
-
requirements:
|
66
|
-
- - ">="
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
version: '0'
|
69
|
-
- !ruby/object:Gem::Dependency
|
70
|
-
name: pry
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
72
|
-
requirements:
|
73
|
-
- - ">="
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
version: '0'
|
76
|
-
type: :development
|
77
|
-
prerelease: false
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
79
|
-
requirements:
|
80
|
-
- - ">="
|
81
|
-
- !ruby/object:Gem::Version
|
82
|
-
version: '0'
|
83
|
-
- !ruby/object:Gem::Dependency
|
84
|
-
name: guard
|
85
|
-
requirement: !ruby/object:Gem::Requirement
|
86
|
-
requirements:
|
87
|
-
- - ">="
|
88
|
-
- !ruby/object:Gem::Version
|
89
|
-
version: '0'
|
90
|
-
type: :development
|
91
|
-
prerelease: false
|
92
|
-
version_requirements: !ruby/object:Gem::Requirement
|
93
|
-
requirements:
|
94
|
-
- - ">="
|
95
|
-
- !ruby/object:Gem::Version
|
96
|
-
version: '0'
|
97
|
-
- !ruby/object:Gem::Dependency
|
98
|
-
name: guard-minitest
|
99
|
-
requirement: !ruby/object:Gem::Requirement
|
100
|
-
requirements:
|
101
|
-
- - ">="
|
102
|
-
- !ruby/object:Gem::Version
|
103
|
-
version: '0'
|
104
|
-
type: :development
|
105
|
-
prerelease: false
|
106
|
-
version_requirements: !ruby/object:Gem::Requirement
|
107
|
-
requirements:
|
108
|
-
- - ">="
|
109
|
-
- !ruby/object:Gem::Version
|
110
|
-
version: '0'
|
111
|
-
- !ruby/object:Gem::Dependency
|
112
|
-
name: rake-notes
|
113
|
-
requirement: !ruby/object:Gem::Requirement
|
114
|
-
requirements:
|
115
|
-
- - ">="
|
116
|
-
- !ruby/object:Gem::Version
|
117
|
-
version: '0'
|
118
|
-
type: :development
|
119
|
-
prerelease: false
|
120
|
-
version_requirements: !ruby/object:Gem::Requirement
|
121
|
-
requirements:
|
122
|
-
- - ">="
|
123
|
-
- !ruby/object:Gem::Version
|
124
|
-
version: '0'
|
125
41
|
- !ruby/object:Gem::Dependency
|
126
42
|
name: hanami-validations
|
127
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -150,12 +66,12 @@ files:
|
|
150
66
|
- LICENSE.txt
|
151
67
|
- README.md
|
152
68
|
- Rakefile
|
69
|
+
- TODO.md
|
153
70
|
- bin/console
|
154
|
-
- bin/setup
|
155
71
|
- lib/thalamus.rb
|
156
72
|
- lib/thalamus/interactor.rb
|
157
|
-
- lib/thalamus/interactor/result.rb
|
158
73
|
- lib/thalamus/policy.rb
|
74
|
+
- lib/thalamus/result.rb
|
159
75
|
- lib/thalamus/version.rb
|
160
76
|
- thalamus.gemspec
|
161
77
|
homepage:
|
data/bin/setup
DELETED
@@ -1,64 +0,0 @@
|
|
1
|
-
module Thalamus
|
2
|
-
class Interactor
|
3
|
-
class Result
|
4
|
-
|
5
|
-
def expose!(exposures)
|
6
|
-
@exposures = exposures
|
7
|
-
self
|
8
|
-
end
|
9
|
-
|
10
|
-
def finish!(status, errors = [], validation_errors = {})
|
11
|
-
@status = status
|
12
|
-
@errors = errors
|
13
|
-
@validation_errors = validation_errors
|
14
|
-
self
|
15
|
-
end
|
16
|
-
attr_reader :status, :errors, :validation_errors
|
17
|
-
|
18
|
-
def success? # 200 or 201
|
19
|
-
@status == :success && errors.empty?
|
20
|
-
end
|
21
|
-
|
22
|
-
def unauthorized? # 403
|
23
|
-
@status == :unauthorized
|
24
|
-
end
|
25
|
-
|
26
|
-
def invalid? # 422
|
27
|
-
@status == :invalid
|
28
|
-
end
|
29
|
-
|
30
|
-
def failure? # catch-all
|
31
|
-
!success?
|
32
|
-
end
|
33
|
-
|
34
|
-
def response
|
35
|
-
if success?
|
36
|
-
@exposures
|
37
|
-
elsif unauthorized?
|
38
|
-
{errors: ["UNAUTHORIZED"]}
|
39
|
-
elsif invalid?
|
40
|
-
validation_errors
|
41
|
-
elsif failure?
|
42
|
-
{errors: errors}
|
43
|
-
else
|
44
|
-
raise "[Thalamus] Invalid result status: #{status}"
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
protected
|
49
|
-
|
50
|
-
def method_missing(m, *args, &block)
|
51
|
-
if m.to_s =~ /^[a-z]/
|
52
|
-
(@exposures || {}).fetch(m) { super }
|
53
|
-
else
|
54
|
-
super
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
def respond_to_missing?(m, include_private = false)
|
59
|
-
m.to_s =~ /^[a-z]/ && @exposures.key?(m)
|
60
|
-
end
|
61
|
-
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|