opie 1.0.0 → 1.1.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 +4 -4
- data/.rubocop.yml +1 -0
- data/.vscode/settings.json +6 -0
- data/CHANGELOG.md +12 -0
- data/README.md +42 -21
- data/lib/opie/operation.rb +14 -9
- data/lib/opie/version.rb +1 -1
- data/opie.gemspec +2 -4
- metadata +20 -33
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9f6c49cd8b64674b706842336d7efb1972825655
|
4
|
+
data.tar.gz: 1624b5f8578aadee872bfd6cedfd44072dbc68fd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fab9a96f80f7e41ad0fbdc4b9bf9f8dc72910c369d003eb8cb818df8c61a6aec6e4f2a52c88c47e525622bca9d7fa727f1f473c3e6250870040fbdd9208d6fd0
|
7
|
+
data.tar.gz: fc31a533ca2591911ca13f3181a1fcff7e030ec98ea0fa140f53d88d2b6215fc36aab0b97c0377be0d829275fd7599055909130767e81a60c104c9013f7a4b0d
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,15 @@
|
|
1
|
+
# CHANGELOG
|
2
|
+
|
3
|
+
<a name="1.1.0"></a>
|
4
|
+
# [1.1.0](https://github.com/guzart/opie/compare/v1.0.0...v1.1.0) (2017-12-16)
|
5
|
+
|
6
|
+
|
7
|
+
### Features
|
8
|
+
|
9
|
+
* Add support for optional context argument ([b4938ed](https://github.com/guzart/opie/commit/b4938ed))
|
10
|
+
|
11
|
+
|
12
|
+
|
1
13
|
<a name="1.0.0"></a>
|
2
14
|
# [1.0.0](https://github.com/guzart/opie/compare/v0.1.0...v1.0.0) (2017-03-20)
|
3
15
|
|
data/README.md
CHANGED
@@ -8,6 +8,35 @@
|
|
8
8
|
**Opie gives you a simple API for creating Operations using the
|
9
9
|
[Railsway oriented programming](https://vimeo.com/113707214) paradigm.**
|
10
10
|
|
11
|
+
## API
|
12
|
+
|
13
|
+
The `Opie::Operation` API:
|
14
|
+
* `::step(Symbol) -> void` indicates a method that is executed in the operation sequence
|
15
|
+
* `#success? -> Boolean` indicates whether the operation was successful
|
16
|
+
* `#failure? -> Boolean` indicates whether the operation was a failure
|
17
|
+
* `#failure -> Hash | nil` the erorr if the operation is a `failure?`, nil when it's a success
|
18
|
+
* `#failures -> Array<Hash> | nil` an array with all errors
|
19
|
+
* `#output -> *` if succcessful, it returns the operation final output validation error
|
20
|
+
* `#step_name(Any, Any?) -> Any` the step signature. First argument is the input and the second argument is an optional context
|
21
|
+
|
22
|
+
Executing an operation:
|
23
|
+
|
24
|
+
```ruby
|
25
|
+
input = { first_name: 'John', last_name: 'McClane', email: 'john@example.com' }
|
26
|
+
context = { current_user: 'admin' }
|
27
|
+
|
28
|
+
CreateUserOperation.(input, context)
|
29
|
+
```
|
30
|
+
|
31
|
+
Internal API:
|
32
|
+
* `#fail(error_type: Symbol, error_data: *) -> Hash`
|
33
|
+
|
34
|
+
_Tentative API_
|
35
|
+
|
36
|
+
* `::step(Array<Symbol>) -> void` a series of methods to be called in parallel
|
37
|
+
* `::step(Opie::Step) -> void` an enforcer of a step signature which helps to compose other steps
|
38
|
+
* `::failure(Symbol) -> void` indicates the method that handles failures
|
39
|
+
|
11
40
|
## Usage
|
12
41
|
|
13
42
|
**Simple Usage:**
|
@@ -66,7 +95,7 @@ class HabitsController < ApplicationController
|
|
66
95
|
# POST /habits
|
67
96
|
def create
|
68
97
|
# run the `operation` – since it's a modification we can call it a `command`
|
69
|
-
result = People::AddHabit.(habit_params)
|
98
|
+
result = People::AddHabit.(habit_params, operation_context)
|
70
99
|
|
71
100
|
# render response based on operation result
|
72
101
|
if result.success?
|
@@ -81,6 +110,7 @@ class HabitsController < ApplicationController
|
|
81
110
|
# the HTTP status depends on the error type, which separating the domain from the infrastructure
|
82
111
|
def error_http_status(error_type)
|
83
112
|
case(error_type)
|
113
|
+
when :unauthorized then :unauthorized
|
84
114
|
when :validation then :unprocessable_entity
|
85
115
|
when :not_found then :not_found
|
86
116
|
else :server_error
|
@@ -97,6 +127,10 @@ class HabitsController < ApplicationController
|
|
97
127
|
color: 'DeepPink'
|
98
128
|
}
|
99
129
|
end
|
130
|
+
|
131
|
+
def operation_context
|
132
|
+
{ current_user: current_user }
|
133
|
+
end
|
100
134
|
end
|
101
135
|
```
|
102
136
|
|
@@ -142,11 +176,18 @@ module People
|
|
142
176
|
]
|
143
177
|
|
144
178
|
# first step receives ::call first argument, then the output of the step is the argument of the next step
|
179
|
+
step :authorize
|
145
180
|
step :validate
|
146
181
|
step :find_person
|
147
182
|
step :persist_habit
|
148
183
|
step :send_event
|
149
184
|
|
185
|
+
def authorize(params, context)
|
186
|
+
# Authorize using Pundit's policy api
|
187
|
+
return fail(:unauthorized) if HabitPolicy.new(context, Habit).add?
|
188
|
+
params
|
189
|
+
end
|
190
|
+
|
150
191
|
# receives the first input
|
151
192
|
def validate(params)
|
152
193
|
schema = AddHabitSchema.(params)
|
@@ -180,26 +221,6 @@ module People
|
|
180
221
|
end
|
181
222
|
```
|
182
223
|
|
183
|
-
## API
|
184
|
-
|
185
|
-
The `Opie::Operation` API:
|
186
|
-
* `::step(Symbol) -> void` indicates a method that is executed in the operation sequence
|
187
|
-
* `#success? -> Boolean` indicates whether the operation was successful
|
188
|
-
* `#failure? -> Boolean` indicates whether the operation was a failure
|
189
|
-
* `#failure -> Hash | nil` the erorr if the operation is a `failure?`, nil when it's a success
|
190
|
-
* `#failures -> Array<Hash> | nil` an array with all errors
|
191
|
-
* `#output -> *` if succcessful, it returns the operation final output
|
192
|
-
validation error
|
193
|
-
|
194
|
-
Internal API:
|
195
|
-
* `#fail(error_type: Symbol, error_data: *) -> Hash`
|
196
|
-
|
197
|
-
_Tentative API_
|
198
|
-
|
199
|
-
* `::step(Array<Symbol>) -> void` a series of methods to be called in parallel
|
200
|
-
* `::step(Opie::Step) -> void` an enforcer of a step signature which helps to compose other steps
|
201
|
-
* `::failure(Symbol) -> void` indicates the method that handles failures
|
202
|
-
|
203
224
|
## Installation
|
204
225
|
|
205
226
|
Add this line to your application's Gemfile:
|
data/lib/opie/operation.rb
CHANGED
@@ -1,22 +1,21 @@
|
|
1
|
-
require 'dry-container'
|
2
|
-
|
3
1
|
module Opie
|
4
2
|
class Operation
|
5
3
|
FAIL = '__STEP_FAILED__'.freeze
|
6
4
|
|
7
|
-
attr_reader :failure, :output
|
5
|
+
attr_reader :failure, :output, :context
|
8
6
|
|
9
|
-
def call(input = nil)
|
7
|
+
def call(input = nil, context = nil)
|
8
|
+
@context = context
|
10
9
|
execute_steps(input)
|
11
10
|
self
|
12
11
|
end
|
13
12
|
|
14
13
|
def failure?
|
15
|
-
|
14
|
+
failure
|
16
15
|
end
|
17
16
|
|
18
17
|
def success?
|
19
|
-
failure
|
18
|
+
!failure?
|
20
19
|
end
|
21
20
|
|
22
21
|
def failures
|
@@ -24,8 +23,8 @@ module Opie
|
|
24
23
|
end
|
25
24
|
|
26
25
|
class << self
|
27
|
-
def call(input = nil)
|
28
|
-
new.call(input)
|
26
|
+
def call(input = nil, context = nil)
|
27
|
+
new.call(input, context)
|
29
28
|
end
|
30
29
|
|
31
30
|
def step(name)
|
@@ -51,13 +50,19 @@ module Opie
|
|
51
50
|
|
52
51
|
next_input = input
|
53
52
|
step_list.find do |name|
|
54
|
-
next_input =
|
53
|
+
next_input = execute_step(name, next_input)
|
55
54
|
failure?
|
56
55
|
end
|
57
56
|
|
58
57
|
@output = next_input if success?
|
59
58
|
end
|
60
59
|
|
60
|
+
def execute_step(name, input)
|
61
|
+
args = [name, input]
|
62
|
+
args = args.push(context) if method(name).arity == 2
|
63
|
+
public_send(*args)
|
64
|
+
end
|
65
|
+
|
61
66
|
def fail(type, data = nil)
|
62
67
|
@failure = Failure.new(type, data)
|
63
68
|
end
|
data/lib/opie/version.rb
CHANGED
data/opie.gemspec
CHANGED
@@ -24,15 +24,13 @@ Gem::Specification.new do |spec|
|
|
24
24
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
25
25
|
spec.require_paths = ['lib']
|
26
26
|
|
27
|
-
spec.add_dependency 'dry-container', '~> 0.6'
|
28
|
-
|
29
27
|
spec.add_development_dependency 'awesome_print', '~> 1.7'
|
28
|
+
spec.add_development_dependency 'bundler', '~> 1.14'
|
30
29
|
spec.add_development_dependency 'byebug', '~> 9.0'
|
31
30
|
spec.add_development_dependency 'codecov', '~> 0'
|
32
|
-
spec.add_development_dependency 'bundler', '~> 1.14'
|
33
31
|
spec.add_development_dependency 'guard', '~> 2.14'
|
34
32
|
spec.add_development_dependency 'guard-rspec', '~> 4.7'
|
33
|
+
spec.add_development_dependency 'minitest', '~> 5.0'
|
35
34
|
spec.add_development_dependency 'rake', '~> 10.0'
|
36
35
|
spec.add_development_dependency 'rspec', '~> 3.5'
|
37
|
-
spec.add_development_dependency 'minitest', '~> 5.0'
|
38
36
|
end
|
metadata
CHANGED
@@ -1,43 +1,43 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: opie
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Arturo Guzman
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-12-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: awesome_print
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
20
|
-
type: :
|
19
|
+
version: '1.7'
|
20
|
+
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '1.7'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: bundler
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '1.
|
33
|
+
version: '1.14'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '1.
|
40
|
+
version: '1.14'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: byebug
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -66,20 +66,6 @@ dependencies:
|
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
|
-
- !ruby/object:Gem::Dependency
|
70
|
-
name: bundler
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
72
|
-
requirements:
|
73
|
-
- - "~>"
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
version: '1.14'
|
76
|
-
type: :development
|
77
|
-
prerelease: false
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
79
|
-
requirements:
|
80
|
-
- - "~>"
|
81
|
-
- !ruby/object:Gem::Version
|
82
|
-
version: '1.14'
|
83
69
|
- !ruby/object:Gem::Dependency
|
84
70
|
name: guard
|
85
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -109,47 +95,47 @@ dependencies:
|
|
109
95
|
- !ruby/object:Gem::Version
|
110
96
|
version: '4.7'
|
111
97
|
- !ruby/object:Gem::Dependency
|
112
|
-
name:
|
98
|
+
name: minitest
|
113
99
|
requirement: !ruby/object:Gem::Requirement
|
114
100
|
requirements:
|
115
101
|
- - "~>"
|
116
102
|
- !ruby/object:Gem::Version
|
117
|
-
version: '
|
103
|
+
version: '5.0'
|
118
104
|
type: :development
|
119
105
|
prerelease: false
|
120
106
|
version_requirements: !ruby/object:Gem::Requirement
|
121
107
|
requirements:
|
122
108
|
- - "~>"
|
123
109
|
- !ruby/object:Gem::Version
|
124
|
-
version: '
|
110
|
+
version: '5.0'
|
125
111
|
- !ruby/object:Gem::Dependency
|
126
|
-
name:
|
112
|
+
name: rake
|
127
113
|
requirement: !ruby/object:Gem::Requirement
|
128
114
|
requirements:
|
129
115
|
- - "~>"
|
130
116
|
- !ruby/object:Gem::Version
|
131
|
-
version: '
|
117
|
+
version: '10.0'
|
132
118
|
type: :development
|
133
119
|
prerelease: false
|
134
120
|
version_requirements: !ruby/object:Gem::Requirement
|
135
121
|
requirements:
|
136
122
|
- - "~>"
|
137
123
|
- !ruby/object:Gem::Version
|
138
|
-
version: '
|
124
|
+
version: '10.0'
|
139
125
|
- !ruby/object:Gem::Dependency
|
140
|
-
name:
|
126
|
+
name: rspec
|
141
127
|
requirement: !ruby/object:Gem::Requirement
|
142
128
|
requirements:
|
143
129
|
- - "~>"
|
144
130
|
- !ruby/object:Gem::Version
|
145
|
-
version: '5
|
131
|
+
version: '3.5'
|
146
132
|
type: :development
|
147
133
|
prerelease: false
|
148
134
|
version_requirements: !ruby/object:Gem::Requirement
|
149
135
|
requirements:
|
150
136
|
- - "~>"
|
151
137
|
- !ruby/object:Gem::Version
|
152
|
-
version: '5
|
138
|
+
version: '3.5'
|
153
139
|
description: |
|
154
140
|
Opie provides an API for building your application operations/transactions using
|
155
141
|
the Railway oriented programming paradigm
|
@@ -166,6 +152,7 @@ files:
|
|
166
152
|
- ".rspec"
|
167
153
|
- ".rubocop.yml"
|
168
154
|
- ".travis.yml"
|
155
|
+
- ".vscode/settings.json"
|
169
156
|
- CHANGELOG.md
|
170
157
|
- Gemfile
|
171
158
|
- Guardfile
|
@@ -202,7 +189,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
202
189
|
version: '0'
|
203
190
|
requirements: []
|
204
191
|
rubyforge_project:
|
205
|
-
rubygems_version: 2.
|
192
|
+
rubygems_version: 2.6.12
|
206
193
|
signing_key:
|
207
194
|
specification_version: 4
|
208
195
|
summary: Operations API for Railway oriented programming in Ruby
|