opie 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|