web_pipe 0.4.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/CHANGELOG.md +81 -13
- data/README.md +3 -3
- data/lib/web_pipe/app.rb +8 -7
- data/lib/web_pipe/conn_support/composition.rb +6 -5
- data/lib/web_pipe/conn_support/errors.rb +16 -0
- data/lib/web_pipe/conn_support/types.rb +3 -3
- data/lib/web_pipe/dsl/builder.rb +3 -8
- data/lib/web_pipe/dsl/class_context.rb +3 -8
- data/lib/web_pipe/dsl/dsl_context.rb +24 -15
- data/lib/web_pipe/dsl/instance_methods.rb +3 -10
- data/lib/web_pipe/extensions/container/container.rb +30 -0
- data/lib/web_pipe/{plugs → extensions/container/plugs}/container.rb +0 -0
- data/lib/web_pipe/extensions/dry_schema/dry_schema.rb +78 -0
- data/lib/web_pipe/extensions/dry_schema/plugs/param_sanitization_handler.rb +27 -0
- data/lib/web_pipe/extensions/dry_schema/plugs/sanitize_params.rb +46 -0
- data/lib/web_pipe/extensions/dry_view/dry_view.rb +8 -3
- data/lib/web_pipe/extensions/flash/flash.rb +76 -0
- data/lib/web_pipe/plug.rb +5 -10
- data/lib/web_pipe/rack/app_with_middlewares.rb +5 -11
- data/lib/web_pipe/rack/middleware.rb +0 -1
- data/lib/web_pipe/rack/middleware_specification.rb +5 -9
- data/lib/web_pipe/version.rb +1 -1
- data/lib/web_pipe.rb +16 -0
- data/web_pipe.gemspec +2 -1
- metadata +36 -18
- data/Gemfile.lock +0 -99
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 17cb26c4876d3063751dd001c823d57f3ada911be264407078b76bd8cfc684b5
|
4
|
+
data.tar.gz: 251591e61a0f30661a09ca507f28231e418fa9a626856613c8e171a67a107f37
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8ae7586e3ed9a3969d540609bad29257f0d7c5eb06c244ad954e7a10cce44507ce5b247a7f7a18ece6d3713969108e8c172aac85442f01d41824bd477270bbe1
|
7
|
+
data.tar.gz: d3a4900f7daf79377aaf7dd9ad3df397b5b55d16eb53d1ac025a029f9feb28e392819b969f9a64e5573216252db257f9e6f4ef359960c246b45321ed3708d6c7
|
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
@@ -4,33 +4,86 @@ All notable changes to this project will be documented in this file.
|
|
4
4
|
The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
5
5
|
and this project adheres to [Semantic Versioning](http://semver.org/).
|
6
6
|
|
7
|
+
## [0.5.0] - 2019-07-26
|
8
|
+
### Added
|
9
|
+
- **BREAKING**: `container` is now an extension
|
10
|
+
([16](https://github.com/waiting-for-dev/web_pipe/pull/16)):
|
11
|
+
|
12
|
+
It adds a `Conn#container` method, while the plug while being the same than before it has been moved to `web_pipe/extensions/container/plugs/container`.
|
13
|
+
|
14
|
+
- Extension providing Integration with `dry-schema` [([18](https://github.com/waiting-for-dev/web_pipe/pull/18))]. See [`extensions/dry_schema.rb`](lib/web_pipe/extensions/dry_schema/dry_schema.rb).
|
15
|
+
|
16
|
+
- No need to manually call `#to_proc` when composing plugs. This makes both of
|
17
|
+
the following valid
|
18
|
+
([13](https://github.com/waiting-for-dev/web_pipe/pull/13)):
|
19
|
+
|
20
|
+
```ruby
|
21
|
+
plug :app, &App.new
|
22
|
+
plug :app, App.new
|
23
|
+
```
|
24
|
+
|
25
|
+
- Extension adding flash functionality to conn ([15](https://github.com/waiting-for-dev/web_pipe/pull/15)).
|
26
|
+
|
27
|
+
For this extension to work,
|
28
|
+
[`Rack::Flash`](https://github.com/treeder/rack-flash) and `Rack::Session`
|
29
|
+
middlewares must be used:
|
30
|
+
|
31
|
+
```ruby
|
32
|
+
require 'rack-flash'
|
33
|
+
require 'rack/session/cookie'
|
34
|
+
|
35
|
+
class App
|
36
|
+
include WebPipe
|
37
|
+
|
38
|
+
use :session, Rack::Session::Cookie, secret: 'secret'
|
39
|
+
use :flash, Rack::Flash
|
40
|
+
|
41
|
+
plug :put_in_flash, ->(conn) { conn.put_flash(:error, 'Error') }
|
42
|
+
plug :put_in_flash_now, ->(conn) { conn.put_flash_now(:error_now, 'Error now') }
|
43
|
+
end
|
44
|
+
```
|
45
|
+
|
46
|
+
Usually you will expose `conn.flash` to your views.
|
47
|
+
|
48
|
+
- Extension automatically require their associated plugs, so there is no need
|
49
|
+
to require them manually anymore.
|
50
|
+
|
51
|
+
### Fixed
|
52
|
+
- Fixed bug not allowing middlewares to modify responses initially set with
|
53
|
+
default values ([14](https://github.com/waiting-for-dev/web_pipe/pull/14))
|
54
|
+
|
7
55
|
## [0.4.0] - 2019-07-17
|
8
56
|
### Added
|
9
|
-
- **BREAKING**: Middlewares have to be named when used
|
57
|
+
- **BREAKING**: Middlewares have to be named when used
|
58
|
+
([11](https://github.com/waiting-for-dev/web_pipe/pull/11)):
|
10
59
|
|
11
60
|
```ruby
|
12
61
|
use :cookies, Rack::Session:Cookie, secret: 'my_secret', key: 'foo'
|
13
62
|
```
|
14
63
|
|
15
|
-
- **BREAKING**: Middlewares have to be initialized when composed
|
64
|
+
- **BREAKING**: Middlewares have to be initialized when composed
|
65
|
+
([11](https://github.com/waiting-for-dev/web_pipe/pull/11)):
|
16
66
|
|
17
67
|
```ruby
|
18
68
|
use :pipe, PipeWithMiddlewares.new
|
19
69
|
```
|
20
70
|
|
21
|
-
- **BREAKING**: The array of injected plugs is now scoped within a `plugs:`
|
71
|
+
- **BREAKING**: The array of injected plugs is now scoped within a `plugs:`
|
72
|
+
kwarg ([11](https://github.com/waiting-for-dev/web_pipe/pull/11)):
|
22
73
|
|
23
74
|
```ruby
|
24
75
|
App.new(plugs: { nothing: ->(conn) { conn } })
|
25
76
|
```
|
26
77
|
|
27
|
-
- Middlewares can be injected
|
78
|
+
- Middlewares can be injected
|
79
|
+
([11](https://github.com/waiting-for-dev/web_pipe/pull/11)):
|
28
80
|
|
29
81
|
```ruby
|
30
82
|
App.new(middlewares: { cache: [MyMiddleware, my_options] })
|
31
83
|
```
|
32
84
|
|
33
|
-
- DSL helper method `compose` to add middlewares and plugs in order and in a
|
85
|
+
- DSL helper method `compose` to add middlewares and plugs in order and in a
|
86
|
+
single shot ([12](https://github.com/waiting-for-dev/web_pipe/pull/11)):
|
34
87
|
|
35
88
|
```ruby
|
36
89
|
class App
|
@@ -57,18 +110,23 @@ end
|
|
57
110
|
|
58
111
|
## [0.3.0] - 2019-07-12
|
59
112
|
### Added
|
60
|
-
- **BREAKING**: When plugging with `plug:`, the operation is no longer
|
113
|
+
- **BREAKING**: When plugging with `plug:`, the operation is no longer
|
114
|
+
specified through `with:`. Now it is just the second positional argument
|
115
|
+
([9](https://github.com/waiting-for-dev/web_pipe/pull/9)):
|
61
116
|
|
62
117
|
```ruby
|
63
118
|
plug :from_container, 'container'
|
64
119
|
plug :inline, ->(conn) { conn.set_response_body('Hello world') }
|
65
120
|
```
|
66
|
-
- It is possible to plug a block
|
121
|
+
- It is possible to plug a block
|
122
|
+
([9](https://github.com/waiting-for-dev/web_pipe/pull/9)):
|
67
123
|
```ruby
|
68
124
|
plug(:content_type) { |conn| conn.add_response_header('Content-Type', 'text/html') }
|
69
125
|
```
|
70
126
|
|
71
|
-
- WebPipe plug's can be composed. A WebPipe proc representation is the
|
127
|
+
- WebPipe plug's can be composed. A WebPipe proc representation is the
|
128
|
+
composition of all its operations, which is an operation itself
|
129
|
+
([9](https://github.com/waiting-for-dev/web_pipe/pull/9)):
|
72
130
|
|
73
131
|
```ruby
|
74
132
|
class HtmlApp
|
@@ -102,7 +160,8 @@ class App
|
|
102
160
|
end
|
103
161
|
```
|
104
162
|
|
105
|
-
- WebPipe's middlewares can be composed into another WebPipe class, also
|
163
|
+
- WebPipe's middlewares can be composed into another WebPipe class, also
|
164
|
+
through `:use` ([10](https://github.com/waiting-for-dev/web_pipe/pull/10)):
|
106
165
|
|
107
166
|
```ruby
|
108
167
|
class HtmlApp
|
@@ -121,12 +180,21 @@ end
|
|
121
180
|
|
122
181
|
## [0.2.0] - 2019-07-05
|
123
182
|
### Added
|
124
|
-
- dry-view integration
|
125
|
-
|
126
|
-
|
183
|
+
- dry-view integration
|
184
|
+
([#1](https://github.com/waiting-for-dev/web_pipe/pull/1),
|
185
|
+
[#3](https://github.com/waiting-for-dev/web_pipe/pull/3),
|
186
|
+
[#4](https://github.com/waiting-for-dev/web_pipe/pull/4),
|
187
|
+
[#5](https://github.com/waiting-for-dev/web_pipe/pull/5) and
|
188
|
+
[#6](https://github.com/waiting-for-dev/web_pipe/pull/6))
|
189
|
+
- Configuring a container in `WebPipe::Conn`
|
190
|
+
([#2](https://github.com/waiting-for-dev/web_pipe/pull/2) and
|
191
|
+
[#5](https://github.com/waiting-for-dev/web_pipe/pull/5))
|
192
|
+
- Plug to set `Content-Type` response header
|
193
|
+
([#7](https://github.com/waiting-for-dev/web_pipe/pull/7))
|
127
194
|
|
128
195
|
### Fixed
|
129
|
-
- Fix key interpolation in `KeyNotFoundInBagError`
|
196
|
+
- Fix key interpolation in `KeyNotFoundInBagError`
|
197
|
+
([#8](https://github.com/waiting-for-dev/web_pipe/pull/8))
|
130
198
|
|
131
199
|
## [0.1.0] - 2019-05-07
|
132
200
|
### Added
|
data/README.md
CHANGED
@@ -212,7 +212,7 @@ end
|
|
212
212
|
class App
|
213
213
|
include WebPipe
|
214
214
|
|
215
|
-
plug :html,
|
215
|
+
plug :html, HtmlApp.new
|
216
216
|
plug :body
|
217
217
|
|
218
218
|
private
|
@@ -321,8 +321,6 @@ WebPipe::App.new([op_1, op_2])
|
|
321
321
|
`web_pipe` ships with a series of common operations you can take
|
322
322
|
advantage in order to build your application:
|
323
323
|
|
324
|
-
- [container](lib/web_pipe/plugs/container.rb): Allows
|
325
|
-
configuring a container to resolve dependencies.
|
326
324
|
- [content_type](lib/web_pipe/plugs/content_type.rb): Sets
|
327
325
|
`Content-Type` response header.
|
328
326
|
|
@@ -332,6 +330,8 @@ By default, `web_pipe` behavior is the very minimal you need to build
|
|
332
330
|
a web application. However, you can extend it with the following
|
333
331
|
extensions (click on each name for details on the usage):
|
334
332
|
|
333
|
+
- [container](lib/web_pipe/plugs/container.rb): Allows
|
334
|
+
configuring a container to resolve dependencies.
|
335
335
|
- [dry-view](lib/web_pipe/extensions/dry_view/dry_view.rb):
|
336
336
|
Integration with [`dry-view`](https://dry-rb.org/gems/dry-view/)
|
337
337
|
rendering system.
|
data/lib/web_pipe/app.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
require 'dry/initializer'
|
2
1
|
require 'web_pipe/types'
|
3
2
|
require 'web_pipe/conn'
|
4
3
|
require 'web_pipe/conn_support/builder'
|
@@ -28,12 +27,14 @@ module WebPipe
|
|
28
27
|
|
29
28
|
include Dry::Monads::Result::Mixin
|
30
29
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
30
|
+
# @!attribute [r] operations
|
31
|
+
# @return [Array<Operation[]>]
|
32
|
+
attr_reader :operations
|
33
|
+
|
34
|
+
def initialize(operations)
|
35
|
+
@operations = Types.Array(
|
36
|
+
ConnSupport::Composition::Operation
|
37
|
+
)[operations]
|
37
38
|
end
|
38
39
|
|
39
40
|
# @param env [Hash] Rack env
|
@@ -1,4 +1,3 @@
|
|
1
|
-
require 'dry/initializer'
|
2
1
|
require 'dry/monads/result'
|
3
2
|
require 'web_pipe/types'
|
4
3
|
require 'web_pipe/conn'
|
@@ -41,10 +40,12 @@ module WebPipe
|
|
41
40
|
|
42
41
|
include Dry::Monads::Result::Mixin
|
43
42
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
43
|
+
# @!attribute [r] operations
|
44
|
+
# @return [Array<Operation[]>]
|
45
|
+
attr_reader :operations
|
46
|
+
|
47
|
+
def initialize(operations)
|
48
|
+
@operations = Types.Array(Operation)[operations]
|
48
49
|
end
|
49
50
|
|
50
51
|
# @param conn [Conn]
|
@@ -12,5 +12,21 @@ module WebPipe
|
|
12
12
|
)
|
13
13
|
end
|
14
14
|
end
|
15
|
+
|
16
|
+
# Error raised when trying to use a conn's feature which requires
|
17
|
+
# a rack middleware which is not present
|
18
|
+
class MissingMiddlewareError < RuntimeError
|
19
|
+
# @param feature [String] Name of the feature intended to be used
|
20
|
+
# @param middleware [String] Name of the missing middleware
|
21
|
+
# @param gem [String] Gem name for the middleware
|
22
|
+
def initialize(feature, middleware, gem)
|
23
|
+
super(
|
24
|
+
<<~eos
|
25
|
+
In order to use #{feature} you must use #{middleware} middleware:
|
26
|
+
https://rubygems.org/gems/#{gem}
|
27
|
+
eos
|
28
|
+
)
|
29
|
+
end
|
30
|
+
end
|
15
31
|
end
|
16
32
|
end
|
@@ -34,15 +34,15 @@ module WebPipe
|
|
34
34
|
Status = Strict::Integer.
|
35
35
|
default(200).
|
36
36
|
constrained(gteq: 100, lteq: 599)
|
37
|
-
ResponseBody = Interface(:each).default
|
37
|
+
ResponseBody = Interface(:each).default { [''] }
|
38
38
|
|
39
39
|
Headers = Strict::Hash.
|
40
40
|
map(Strict::String, Strict::String).
|
41
|
-
default
|
41
|
+
default { {} }
|
42
42
|
|
43
43
|
Bag = Strict::Hash.
|
44
44
|
map(Strict::Symbol, Strict::Any).
|
45
|
-
default
|
45
|
+
default { {} }
|
46
46
|
end
|
47
47
|
end
|
48
48
|
end
|
data/lib/web_pipe/dsl/builder.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
require 'dry/initializer'
|
2
1
|
require 'web_pipe/types'
|
3
2
|
require 'web_pipe/dsl/class_context'
|
4
3
|
require 'web_pipe/dsl/instance_methods'
|
@@ -16,17 +15,13 @@ module WebPipe
|
|
16
15
|
|
17
16
|
# @!attribute [r] container
|
18
17
|
# @return [Types::Container[]]
|
19
|
-
|
20
|
-
|
21
|
-
include Dry::Initializer.define -> do
|
22
|
-
option :container, type: Types::Container, default: proc { EMPTY_CONTAINER }
|
23
|
-
end
|
18
|
+
attr_reader :container
|
24
19
|
|
25
20
|
# @return [ClassContext]
|
26
21
|
attr_reader :class_context
|
27
22
|
|
28
|
-
def initialize(
|
29
|
-
|
23
|
+
def initialize(container: EMPTY_CONTAINER)
|
24
|
+
@container = Types::Container[container]
|
30
25
|
@class_context = ClassContext.new(container: container)
|
31
26
|
end
|
32
27
|
|
@@ -1,4 +1,3 @@
|
|
1
|
-
require 'dry-initializer'
|
2
1
|
require 'web_pipe/types'
|
3
2
|
require 'web_pipe/dsl/dsl_context'
|
4
3
|
|
@@ -22,17 +21,13 @@ module WebPipe
|
|
22
21
|
|
23
22
|
# @!attribute [r] container
|
24
23
|
# @return [Types::Container[]]
|
25
|
-
|
26
|
-
|
27
|
-
include Dry::Initializer.define -> do
|
28
|
-
option :container, type: Types::Container
|
29
|
-
end
|
24
|
+
attr_reader :container
|
30
25
|
|
31
26
|
# @return [DSLContext]
|
32
27
|
attr_reader :dsl_context
|
33
28
|
|
34
|
-
def initialize(
|
35
|
-
|
29
|
+
def initialize(container:)
|
30
|
+
@container = Types::Container[container]
|
36
31
|
@dsl_context = DSLContext.new([], [])
|
37
32
|
define_container
|
38
33
|
define_dsl
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require '
|
1
|
+
require 'web_pipe'
|
2
2
|
require 'web_pipe/types'
|
3
3
|
require 'web_pipe/plug'
|
4
4
|
require 'web_pipe/rack/middleware_specification'
|
@@ -14,17 +14,17 @@ module WebPipe
|
|
14
14
|
class DSLContext
|
15
15
|
# @!attribute middleware_specifications
|
16
16
|
# @return [Array<Rack::MiddlewareSpecifications>]
|
17
|
+
attr_reader :middleware_specifications
|
17
18
|
|
18
19
|
# @!attribute plugs
|
19
20
|
# @return [Array<Plug>]
|
21
|
+
attr_reader :plugs
|
20
22
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
param :plugs,
|
27
|
-
type: Types.Array(Plug::Instance)
|
23
|
+
def initialize(middleware_specifications, plugs)
|
24
|
+
@middleware_specifications = Types.Array(
|
25
|
+
Rack::MiddlewareSpecification
|
26
|
+
)[middleware_specifications]
|
27
|
+
@plugs = Types.Array(Plug::Instance)[plugs]
|
28
28
|
end
|
29
29
|
|
30
30
|
# Creates and add rack middleware specifications to the stack.
|
@@ -42,22 +42,31 @@ module WebPipe
|
|
42
42
|
#
|
43
43
|
# @return [Array<Rack::Middleware>]
|
44
44
|
def use(name, *spec)
|
45
|
-
middleware_specifications << Rack::MiddlewareSpecification.new(name, spec)
|
45
|
+
middleware_specifications << Rack::MiddlewareSpecification.new(name: name, spec: spec)
|
46
46
|
end
|
47
47
|
|
48
48
|
# Creates and adds a plug to the stack.
|
49
49
|
#
|
50
|
-
# The spec can be given as a {Plug::Spec}
|
51
|
-
# is captured into a {Proc}
|
52
|
-
# {Plug::Spec}
|
50
|
+
# The spec can be given as a {Plug::Spec}, as a block (which
|
51
|
+
# is captured into a {Proc}, one of the options for a
|
52
|
+
# {Plug::Spec} or as a {WebPipe} (in which case all its plugs
|
53
|
+
# will be composed).
|
53
54
|
#
|
54
55
|
# @param name [Plug::Name[]]
|
55
|
-
# @param spec [Plug::Spec[]]
|
56
|
+
# @param spec [Plug::Spec[], WebPipe]
|
56
57
|
# @param block_spec [Proc]
|
57
58
|
#
|
58
59
|
# @return [Array<Plug>]
|
59
60
|
def plug(name, spec = nil, &block_spec)
|
60
|
-
|
61
|
+
plug_spec = if spec.is_a?(WebPipe)
|
62
|
+
spec.to_proc
|
63
|
+
elsif spec
|
64
|
+
spec
|
65
|
+
else
|
66
|
+
block_spec
|
67
|
+
end
|
68
|
+
|
69
|
+
plugs << Plug.new(name: name, spec: plug_spec)
|
61
70
|
end
|
62
71
|
|
63
72
|
# Adds middlewares and plugs from a WebPipe to respective
|
@@ -67,7 +76,7 @@ module WebPipe
|
|
67
76
|
# @param spec [WebPipe]
|
68
77
|
def compose(name, spec)
|
69
78
|
use(name, spec)
|
70
|
-
plug(name,
|
79
|
+
plug(name, spec)
|
71
80
|
end
|
72
81
|
end
|
73
82
|
end
|
@@ -1,4 +1,3 @@
|
|
1
|
-
require 'dry/initializer'
|
2
1
|
require 'web_pipe/types'
|
3
2
|
require 'web_pipe/conn'
|
4
3
|
require 'web_pipe/app'
|
@@ -36,13 +35,7 @@ module WebPipe
|
|
36
35
|
# @!attribute [r] injections [Injections[]]
|
37
36
|
# Injected plugs and middlewares that allow overriding what
|
38
37
|
# has been configured.
|
39
|
-
|
40
|
-
|
41
|
-
include Dry::Initializer.define -> do
|
42
|
-
param :injections,
|
43
|
-
default: proc { EMPTY_INJECTIONS },
|
44
|
-
type: Injections
|
45
|
-
end
|
38
|
+
attr_reader :injections
|
46
39
|
|
47
40
|
# @return [Rack::AppWithMiddlewares[]]
|
48
41
|
attr_reader :rack_app
|
@@ -53,8 +46,8 @@ module WebPipe
|
|
53
46
|
# @return [Array<Rack::Middlewares>]
|
54
47
|
attr_reader :middlewares
|
55
48
|
|
56
|
-
def initialize(
|
57
|
-
|
49
|
+
def initialize(injects = EMPTY_INJECTIONS)
|
50
|
+
@injections = Injections[injects]
|
58
51
|
container = self.class.container
|
59
52
|
@middlewares = Rack::MiddlewareSpecification.inject_and_resolve(
|
60
53
|
self.class.middleware_specifications, injections[:middlewares]
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'web_pipe'
|
2
|
+
|
3
|
+
module WebPipe
|
4
|
+
# Extension adding a `#container` method to fetch bag's `:container`
|
5
|
+
# key.
|
6
|
+
#
|
7
|
+
# Usually, the container is set with {WebPipe::Plugs::Container}.
|
8
|
+
#
|
9
|
+
# @example
|
10
|
+
# require 'web_pipe'
|
11
|
+
#
|
12
|
+
# WebPipe.load_extensions(:container)
|
13
|
+
#
|
14
|
+
# class App
|
15
|
+
# include WebPipe
|
16
|
+
#
|
17
|
+
# plug :container, WebPipe::Plugs::Container[MyContainer]
|
18
|
+
# plug :render, ->(conn) { conn.set_response_body(conn.container['view']) }
|
19
|
+
# end
|
20
|
+
module Container
|
21
|
+
# Returns bag `:container` value
|
22
|
+
#
|
23
|
+
# @return [Any]
|
24
|
+
def container
|
25
|
+
fetch(:container)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
Conn.include(Container)
|
30
|
+
end
|
File without changes
|
@@ -0,0 +1,78 @@
|
|
1
|
+
require 'web_pipe'
|
2
|
+
|
3
|
+
module WebPipe
|
4
|
+
# Integration with `dry-schema` validation library.
|
5
|
+
#
|
6
|
+
# This extension provides a simple integration with `dry-schema`
|
7
|
+
# library to streamline param sanitization.
|
8
|
+
#
|
9
|
+
# On its own, the library just provides with a
|
10
|
+
# `Conn#sanitized_params` method, which will return what is set into
|
11
|
+
# bag's `:sanitized_params` key.
|
12
|
+
#
|
13
|
+
# This key in the bag is what will be populated by `SanitizeParams`
|
14
|
+
# plug, which accepts a `dry-validation` schema that will be applied
|
15
|
+
# to `Conn#params`:
|
16
|
+
#
|
17
|
+
# @example
|
18
|
+
# require 'web_pipe'
|
19
|
+
#
|
20
|
+
# WebPipe.load_extensions(:dry_schema)
|
21
|
+
#
|
22
|
+
# class App
|
23
|
+
# include WebPipe
|
24
|
+
#
|
25
|
+
# Schema = Dry::Schema.Params do
|
26
|
+
# required(:name).filled(:string)
|
27
|
+
# end
|
28
|
+
#
|
29
|
+
# plug :sanitize_params, WebPipe::Plugs::SanitizeParams[Schema]
|
30
|
+
# plug(:do_something_with_params) do |conn|
|
31
|
+
# DB.persist(:entity, conn.sanitized_params)
|
32
|
+
# end
|
33
|
+
# end
|
34
|
+
#
|
35
|
+
# By default, when the result of applying the schema is a failure,
|
36
|
+
# {Conn} is tainted with a 500 as status code. However, you can
|
37
|
+
# specify your own handler for the unhappy path. It will take the
|
38
|
+
# {Conn} and {Dry::Schema::Result} instances as arguments:
|
39
|
+
#
|
40
|
+
# @example
|
41
|
+
# plug :sanitize_params, WebPipe::Plugs::SanitizeParams[
|
42
|
+
# Schema,
|
43
|
+
# ->(conn, result) { ... }
|
44
|
+
# ]
|
45
|
+
#
|
46
|
+
# A common workflow is applying the same handler for all param
|
47
|
+
# sanitization across your application. This can be achieved setting
|
48
|
+
# a `:param_sanitization_handler` bag key in a upstream operation
|
49
|
+
# which can be composed downstream for any number of
|
50
|
+
# pipes. `SanitizeParams` will used configured handler if none is
|
51
|
+
# injected as argument. Another plug `ParamSanitizationHandler`
|
52
|
+
# exists to help with this process:
|
53
|
+
#
|
54
|
+
# @example
|
55
|
+
# class App
|
56
|
+
# plug :sanitization_handler, WebPipe::Plugs::ParamSanitizationHandler[
|
57
|
+
# ->(conn, result) { ... }
|
58
|
+
# ]
|
59
|
+
# end
|
60
|
+
#
|
61
|
+
# class Subapp
|
62
|
+
# Schema = Dry::Schema.Params { ... }
|
63
|
+
#
|
64
|
+
# plug :app, App.new
|
65
|
+
# plug :sanitize_params, WebPipe::Plugs::SanitizeParams[Schema]
|
66
|
+
# end
|
67
|
+
#
|
68
|
+
# @see https://dry-rb.org/gems/dry-schema/
|
69
|
+
module DrySchema
|
70
|
+
SANITIZED_PARAMS_KEY = :sanitized_params
|
71
|
+
|
72
|
+
def sanitized_params
|
73
|
+
fetch(SANITIZED_PARAMS_KEY)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
Conn.include(DrySchema)
|
78
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'web_pipe/types'
|
2
|
+
|
3
|
+
module WebPipe
|
4
|
+
module Plugs
|
5
|
+
# Sets `:param_sanitization_handler` bag key.
|
6
|
+
#
|
7
|
+
# @see WebPipe::DrySchema
|
8
|
+
module ParamSanitizationHandler
|
9
|
+
# Bag key to store the handler.
|
10
|
+
#
|
11
|
+
# @return [Symbol]
|
12
|
+
PARAM_SANITIZATION_HANDLER_KEY = :param_sanitization_handler
|
13
|
+
|
14
|
+
# Type constructor for the handler.
|
15
|
+
Handler = Types.Interface(:call)
|
16
|
+
|
17
|
+
# @param handler [Handler[]]
|
18
|
+
#
|
19
|
+
# @return [ConnSupport::Composition::Operation[]]
|
20
|
+
def self.[](handler)
|
21
|
+
lambda do |conn|
|
22
|
+
conn.put(PARAM_SANITIZATION_HANDLER_KEY, Handler[handler])
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'web_pipe/types'
|
2
|
+
require 'web_pipe/extensions/dry_schema/dry_schema'
|
3
|
+
require 'web_pipe/extensions/dry_schema/plugs/param_sanitization_handler'
|
4
|
+
|
5
|
+
module WebPipe
|
6
|
+
module Plugs
|
7
|
+
# Sanitize {Conn#params} with given `dry-schema` Schema.
|
8
|
+
#
|
9
|
+
# @see WebPipe::DrySchema
|
10
|
+
module SanitizeParams
|
11
|
+
# Default handler if none is configured nor injected.
|
12
|
+
#
|
13
|
+
# @return [ParamSanitizationHandler::Handler[]]
|
14
|
+
DEFAULT_HANDLER = lambda do |conn, _result|
|
15
|
+
conn.
|
16
|
+
set_status(500).
|
17
|
+
set_response_body('Given params do not conform with the expected schema').
|
18
|
+
taint
|
19
|
+
end
|
20
|
+
|
21
|
+
# @param schema [Dry::Schema::Processor]
|
22
|
+
# @param handler [ParamSanitizationHandler::Handler[]]
|
23
|
+
#
|
24
|
+
# @return [ConnSupport::Composition::Operation[], Types::Undefined]
|
25
|
+
def self.[](schema, handler = Types::Undefined)
|
26
|
+
lambda do |conn|
|
27
|
+
result = schema.(conn.params)
|
28
|
+
if result.success?
|
29
|
+
conn.put(DrySchema::SANITIZED_PARAMS_KEY, result.output)
|
30
|
+
else
|
31
|
+
get_handler(conn, handler).(conn, result)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.get_handler(conn, handler)
|
37
|
+
return handler unless handler == Types::Undefined
|
38
|
+
|
39
|
+
conn.fetch(
|
40
|
+
Plugs::ParamSanitizationHandler::PARAM_SANITIZATION_HANDLER_KEY, DEFAULT_HANDLER
|
41
|
+
)
|
42
|
+
end
|
43
|
+
private_class_method :get_handler
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -29,10 +29,12 @@ module WebPipe
|
|
29
29
|
# end
|
30
30
|
#
|
31
31
|
# If {WebPipe::Conn#bag} has a `:container` key, the view instance
|
32
|
-
# can be resolved from it. {WebPipe::
|
33
|
-
# to streamline this integration.
|
32
|
+
# can be resolved from it. {WebPipe::Container} extension can be
|
33
|
+
# used to streamline this integration.
|
34
34
|
#
|
35
35
|
# @example
|
36
|
+
# WebPipe.load_extensions(:dry_view, :container)
|
37
|
+
#
|
36
38
|
# class App
|
37
39
|
# include WebPipe
|
38
40
|
#
|
@@ -100,7 +102,8 @@ module WebPipe
|
|
100
102
|
# # ...
|
101
103
|
#
|
102
104
|
# @see https://dry-rb.org/gems/dry-view/
|
103
|
-
|
105
|
+
# @see WebPipe::Container
|
106
|
+
module DryView
|
104
107
|
# Where to find in {#bag} request's view context
|
105
108
|
VIEW_CONTEXT_KEY = :view_context
|
106
109
|
|
@@ -153,4 +156,6 @@ module WebPipe
|
|
153
156
|
kwargs.merge(context: context)
|
154
157
|
end
|
155
158
|
end
|
159
|
+
|
160
|
+
Conn.include(DryView)
|
156
161
|
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'web_pipe/conn'
|
4
|
+
require 'web_pipe/conn_support/errors'
|
5
|
+
|
6
|
+
module WebPipe
|
7
|
+
# Provides with a tipical flash messages functionality.
|
8
|
+
#
|
9
|
+
# @example
|
10
|
+
# require 'web_pipe'
|
11
|
+
# require 'rack/session/cookie'
|
12
|
+
# require 'rack-flash'
|
13
|
+
#
|
14
|
+
# WebPipe.load_extensions(:flash)
|
15
|
+
#
|
16
|
+
# class MyApp
|
17
|
+
# include WebPipe
|
18
|
+
#
|
19
|
+
# use :session, Rack::Session::Cookie, secret: 'secret'
|
20
|
+
# use :flash, Rack::Flash
|
21
|
+
#
|
22
|
+
# plug :put_in_flash, ->(conn) { conn.put_flash(:notice, 'Hello world') }
|
23
|
+
# plug :put_in_flash_now, ->(conn) { conn.put_flash_now(:notice_now, 'Hello world now') }
|
24
|
+
# end
|
25
|
+
#
|
26
|
+
# Usually, you will end up making `conn.flash` available to your view system:
|
27
|
+
#
|
28
|
+
# @example
|
29
|
+
# <div class="notice"><%= flash[:notice] %></div>
|
30
|
+
#
|
31
|
+
# For this extension to be used, `Rack::Flash` middleware must be
|
32
|
+
# added to the stack (gem name is `rack-flash3`. This middleware in
|
33
|
+
# turns depend on `Rack::Session` middleware.
|
34
|
+
#
|
35
|
+
# This extension is a very simple wrapper around `Rack::Flash` API.
|
36
|
+
#
|
37
|
+
# @see https://github.com/nakajima/rack-flash
|
38
|
+
module Flash
|
39
|
+
RACK_FLASH_KEY = 'x-rack.flash'
|
40
|
+
|
41
|
+
# Returns the flash bag.
|
42
|
+
#
|
43
|
+
# @return [Rack::Flash::FlashHash]
|
44
|
+
#
|
45
|
+
# @raises ConnSupport::MissingMiddlewareError when `Rack::Flash`
|
46
|
+
# is not being used as middleware
|
47
|
+
def flash
|
48
|
+
env.fetch(RACK_FLASH_KEY) do
|
49
|
+
raise ConnSupport::MissingMiddlewareError.new(
|
50
|
+
'flash', 'Rack::Flash', 'rack-flash3'
|
51
|
+
)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# Puts an item to the flash bag to be consumed by next request.
|
56
|
+
#
|
57
|
+
# @param key [String]
|
58
|
+
# @param value [String]
|
59
|
+
def put_flash(key, value)
|
60
|
+
flash[key] = value
|
61
|
+
self
|
62
|
+
end
|
63
|
+
|
64
|
+
# Puts an item to the flash bag to be consumed by the same request
|
65
|
+
# in process.
|
66
|
+
#
|
67
|
+
# @param key [String]
|
68
|
+
# @param value [String]
|
69
|
+
def put_flash_now(key, value)
|
70
|
+
flash.now[key] = value
|
71
|
+
self
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
Conn.include(Flash)
|
76
|
+
end
|
data/lib/web_pipe/plug.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require 'dry/
|
1
|
+
require 'dry/struct'
|
2
2
|
require 'web_pipe/types'
|
3
3
|
require 'web_pipe/conn_support/composition'
|
4
4
|
|
@@ -17,7 +17,7 @@ module WebPipe
|
|
17
17
|
# from the `container`.
|
18
18
|
#
|
19
19
|
# @api private
|
20
|
-
class Plug
|
20
|
+
class Plug < Dry::Struct
|
21
21
|
# Error raised when no operation can be resolved from a {Spec}.
|
22
22
|
class InvalidPlugError < ArgumentError
|
23
23
|
# @param name [Any] Name for the plug that can't be resolved
|
@@ -55,23 +55,18 @@ module WebPipe
|
|
55
55
|
|
56
56
|
# @!attribute [r] name
|
57
57
|
# @return [Name[]]
|
58
|
+
attribute :name, Name
|
58
59
|
|
59
60
|
# @!attribute [r] spec
|
60
61
|
# @return [Spec[]]
|
61
|
-
|
62
|
-
|
63
|
-
include Dry::Initializer.define -> do
|
64
|
-
param :name, Name
|
65
|
-
|
66
|
-
param :spec, Spec
|
67
|
-
end
|
62
|
+
attribute :spec, Spec
|
68
63
|
|
69
64
|
# Creates a new instance with given `spec` but keeping `name`.
|
70
65
|
#
|
71
66
|
# @param new_spec [Spec[]]
|
72
67
|
# @return [self]
|
73
68
|
def with(new_spec)
|
74
|
-
|
69
|
+
new(spec: new_spec)
|
75
70
|
end
|
76
71
|
|
77
72
|
# Resolves the operation.
|
@@ -1,4 +1,3 @@
|
|
1
|
-
require 'dry/initializer'
|
2
1
|
require 'web_pipe/types'
|
3
2
|
require 'web_pipe/rack/middleware'
|
4
3
|
require 'rack'
|
@@ -17,23 +16,18 @@ module WebPipe
|
|
17
16
|
|
18
17
|
# @!attribute [r] rack_middlewares
|
19
18
|
# @return [Array<RackMiddleware>]
|
19
|
+
attr_reader :rack_middlewares
|
20
20
|
|
21
21
|
# @!attribute [r] app
|
22
22
|
# @return [App[]]
|
23
|
-
|
24
|
-
|
25
|
-
include Dry::Initializer.define -> do
|
26
|
-
param :rack_middlewares,
|
27
|
-
type: Types.Array(Middleware)
|
28
|
-
|
29
|
-
param :app, type: App
|
30
|
-
end
|
23
|
+
attr_reader :app
|
31
24
|
|
32
25
|
# @return [Rack::Builder]
|
33
26
|
attr_reader :builder
|
34
27
|
|
35
|
-
def initialize(
|
36
|
-
|
28
|
+
def initialize(rack_middlewares, app)
|
29
|
+
@rack_middlewares = Types.Array(Middleware)[rack_middlewares]
|
30
|
+
@app = App[app]
|
37
31
|
@builder = build_rack_app(rack_middlewares, app)
|
38
32
|
end
|
39
33
|
|
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'dry/struct'
|
1
2
|
require 'web_pipe/rack/middleware'
|
2
3
|
require 'web_pipe/types'
|
3
4
|
|
@@ -14,7 +15,7 @@ module WebPipe
|
|
14
15
|
# for that {WebPipe}.
|
15
16
|
#
|
16
17
|
# @api private
|
17
|
-
class MiddlewareSpecification
|
18
|
+
class MiddlewareSpecification < Dry::Struct
|
18
19
|
# Type for the name given to a middleware.
|
19
20
|
Name = Types::Strict::Symbol.constructor(&:to_sym)
|
20
21
|
|
@@ -30,16 +31,11 @@ module WebPipe
|
|
30
31
|
|
31
32
|
# @!attribute [r] name
|
32
33
|
# @return [Name[]]
|
34
|
+
attribute :name, Name
|
33
35
|
|
34
36
|
# @!attribute [r] spec
|
35
37
|
# @return [Spec[]]
|
36
|
-
|
37
|
-
|
38
|
-
include Dry::Initializer.define -> do
|
39
|
-
param :name, Name
|
40
|
-
|
41
|
-
param :spec, Spec
|
42
|
-
end
|
38
|
+
attribute :spec, Spec
|
43
39
|
|
44
40
|
# Change spec's present in `injections` and resolves.
|
45
41
|
#
|
@@ -76,7 +72,7 @@ module WebPipe
|
|
76
72
|
#
|
77
73
|
# @return [MiddlewareSpecification]
|
78
74
|
def with(new_spec)
|
79
|
-
|
75
|
+
new(spec: new_spec)
|
80
76
|
end
|
81
77
|
end
|
82
78
|
end
|
data/lib/web_pipe/version.rb
CHANGED
data/lib/web_pipe.rb
CHANGED
@@ -16,7 +16,23 @@ module WebPipe
|
|
16
16
|
DSL::Builder.new(*args)
|
17
17
|
end
|
18
18
|
|
19
|
+
register_extension :dry_schema do
|
20
|
+
require 'web_pipe/extensions/dry_schema/dry_schema'
|
21
|
+
require 'web_pipe/extensions/dry_schema/plugs/sanitize_params'
|
22
|
+
require 'web_pipe/extensions/dry_schema/plugs/param_sanitization_handler'
|
23
|
+
end
|
24
|
+
|
19
25
|
register_extension :dry_view do
|
20
26
|
require 'web_pipe/extensions/dry_view/dry_view'
|
27
|
+
require 'web_pipe/extensions/dry_view/plugs/view_context'
|
28
|
+
end
|
29
|
+
|
30
|
+
register_extension :container do
|
31
|
+
require 'web_pipe/extensions/container/container'
|
32
|
+
require 'web_pipe/extensions/container/plugs/container'
|
33
|
+
end
|
34
|
+
|
35
|
+
register_extension :flash do
|
36
|
+
require 'web_pipe/extensions/flash/flash'
|
21
37
|
end
|
22
38
|
end
|
data/web_pipe.gemspec
CHANGED
@@ -39,7 +39,6 @@ Gem::Specification.new do |spec|
|
|
39
39
|
spec.add_runtime_dependency "dry-monads", "~> 1.2"
|
40
40
|
spec.add_runtime_dependency "dry-types", "~> 1.1"
|
41
41
|
spec.add_runtime_dependency "dry-struct", "~> 1.0"
|
42
|
-
spec.add_runtime_dependency "dry-initializer", "~> 3.0"
|
43
42
|
|
44
43
|
spec.add_development_dependency "bundler", "~> 1.17"
|
45
44
|
spec.add_development_dependency "rake", "~> 10.0"
|
@@ -49,4 +48,6 @@ Gem::Specification.new do |spec|
|
|
49
48
|
spec.add_development_dependency "redcarpet", "~> 3.4"
|
50
49
|
spec.add_development_dependency "pry-byebug"
|
51
50
|
spec.add_development_dependency "dry-view", "~> 0.7"
|
51
|
+
spec.add_development_dependency "rack-flash3", "~> 1.0"
|
52
|
+
spec.add_development_dependency "dry-schema", "~> 1.0"
|
52
53
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: web_pipe
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Marc Busqué
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-07-
|
11
|
+
date: 2019-07-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rack
|
@@ -66,20 +66,6 @@ dependencies:
|
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '1.0'
|
69
|
-
- !ruby/object:Gem::Dependency
|
70
|
-
name: dry-initializer
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
72
|
-
requirements:
|
73
|
-
- - "~>"
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
version: '3.0'
|
76
|
-
type: :runtime
|
77
|
-
prerelease: false
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
79
|
-
requirements:
|
80
|
-
- - "~>"
|
81
|
-
- !ruby/object:Gem::Version
|
82
|
-
version: '3.0'
|
83
69
|
- !ruby/object:Gem::Dependency
|
84
70
|
name: bundler
|
85
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -198,6 +184,34 @@ dependencies:
|
|
198
184
|
- - "~>"
|
199
185
|
- !ruby/object:Gem::Version
|
200
186
|
version: '0.7'
|
187
|
+
- !ruby/object:Gem::Dependency
|
188
|
+
name: rack-flash3
|
189
|
+
requirement: !ruby/object:Gem::Requirement
|
190
|
+
requirements:
|
191
|
+
- - "~>"
|
192
|
+
- !ruby/object:Gem::Version
|
193
|
+
version: '1.0'
|
194
|
+
type: :development
|
195
|
+
prerelease: false
|
196
|
+
version_requirements: !ruby/object:Gem::Requirement
|
197
|
+
requirements:
|
198
|
+
- - "~>"
|
199
|
+
- !ruby/object:Gem::Version
|
200
|
+
version: '1.0'
|
201
|
+
- !ruby/object:Gem::Dependency
|
202
|
+
name: dry-schema
|
203
|
+
requirement: !ruby/object:Gem::Requirement
|
204
|
+
requirements:
|
205
|
+
- - "~>"
|
206
|
+
- !ruby/object:Gem::Version
|
207
|
+
version: '1.0'
|
208
|
+
type: :development
|
209
|
+
prerelease: false
|
210
|
+
version_requirements: !ruby/object:Gem::Requirement
|
211
|
+
requirements:
|
212
|
+
- - "~>"
|
213
|
+
- !ruby/object:Gem::Version
|
214
|
+
version: '1.0'
|
201
215
|
description:
|
202
216
|
email:
|
203
217
|
- marc@lamarciana.com
|
@@ -211,7 +225,6 @@ files:
|
|
211
225
|
- ".yardopts"
|
212
226
|
- CHANGELOG.md
|
213
227
|
- Gemfile
|
214
|
-
- Gemfile.lock
|
215
228
|
- README.md
|
216
229
|
- Rakefile
|
217
230
|
- bin/console
|
@@ -229,11 +242,16 @@ files:
|
|
229
242
|
- lib/web_pipe/dsl/class_context.rb
|
230
243
|
- lib/web_pipe/dsl/dsl_context.rb
|
231
244
|
- lib/web_pipe/dsl/instance_methods.rb
|
245
|
+
- lib/web_pipe/extensions/container/container.rb
|
246
|
+
- lib/web_pipe/extensions/container/plugs/container.rb
|
247
|
+
- lib/web_pipe/extensions/dry_schema/dry_schema.rb
|
248
|
+
- lib/web_pipe/extensions/dry_schema/plugs/param_sanitization_handler.rb
|
249
|
+
- lib/web_pipe/extensions/dry_schema/plugs/sanitize_params.rb
|
232
250
|
- lib/web_pipe/extensions/dry_view/dry_view.rb
|
233
251
|
- lib/web_pipe/extensions/dry_view/plugs/view_context.rb
|
252
|
+
- lib/web_pipe/extensions/flash/flash.rb
|
234
253
|
- lib/web_pipe/plug.rb
|
235
254
|
- lib/web_pipe/plugs.rb
|
236
|
-
- lib/web_pipe/plugs/container.rb
|
237
255
|
- lib/web_pipe/plugs/content_type.rb
|
238
256
|
- lib/web_pipe/rack/app_with_middlewares.rb
|
239
257
|
- lib/web_pipe/rack/middleware.rb
|
data/Gemfile.lock
DELETED
@@ -1,99 +0,0 @@
|
|
1
|
-
PATH
|
2
|
-
remote: .
|
3
|
-
specs:
|
4
|
-
web_pipe (0.3.0)
|
5
|
-
dry-initializer (~> 3.0)
|
6
|
-
dry-monads (~> 1.2)
|
7
|
-
dry-struct (~> 1.0)
|
8
|
-
dry-types (~> 1.1)
|
9
|
-
rack (~> 2.0)
|
10
|
-
|
11
|
-
GEM
|
12
|
-
remote: https://rubygems.org/
|
13
|
-
specs:
|
14
|
-
byebug (11.0.0)
|
15
|
-
coderay (1.1.2)
|
16
|
-
concurrent-ruby (1.1.5)
|
17
|
-
diff-lcs (1.3)
|
18
|
-
dry-configurable (0.8.2)
|
19
|
-
concurrent-ruby (~> 1.0)
|
20
|
-
dry-core (~> 0.4, >= 0.4.7)
|
21
|
-
dry-container (0.7.1)
|
22
|
-
concurrent-ruby (~> 1.0)
|
23
|
-
dry-configurable (~> 0.1, >= 0.1.3)
|
24
|
-
dry-core (0.4.7)
|
25
|
-
concurrent-ruby (~> 1.0)
|
26
|
-
dry-equalizer (0.2.2)
|
27
|
-
dry-inflector (0.1.2)
|
28
|
-
dry-initializer (3.0.1)
|
29
|
-
dry-logic (1.0.2)
|
30
|
-
concurrent-ruby (~> 1.0)
|
31
|
-
dry-core (~> 0.2)
|
32
|
-
dry-equalizer (~> 0.2)
|
33
|
-
dry-monads (1.2.0)
|
34
|
-
concurrent-ruby (~> 1.0)
|
35
|
-
dry-core (~> 0.4, >= 0.4.4)
|
36
|
-
dry-equalizer
|
37
|
-
dry-struct (1.0.0)
|
38
|
-
dry-core (~> 0.4, >= 0.4.3)
|
39
|
-
dry-equalizer (~> 0.2)
|
40
|
-
dry-types (~> 1.0)
|
41
|
-
ice_nine (~> 0.11)
|
42
|
-
dry-types (1.1.0)
|
43
|
-
concurrent-ruby (~> 1.0)
|
44
|
-
dry-container (~> 0.3)
|
45
|
-
dry-core (~> 0.4, >= 0.4.4)
|
46
|
-
dry-equalizer (~> 0.2, >= 0.2.2)
|
47
|
-
dry-inflector (~> 0.1, >= 0.1.2)
|
48
|
-
dry-logic (~> 1.0, >= 1.0.2)
|
49
|
-
dry-view (0.7.0)
|
50
|
-
dry-configurable (~> 0.1)
|
51
|
-
dry-core (~> 0.2)
|
52
|
-
dry-equalizer (~> 0.2)
|
53
|
-
dry-inflector (~> 0.1)
|
54
|
-
tilt (~> 2.0, >= 2.0.6)
|
55
|
-
ice_nine (0.11.2)
|
56
|
-
method_source (0.9.2)
|
57
|
-
pry (0.12.2)
|
58
|
-
coderay (~> 1.1.0)
|
59
|
-
method_source (~> 0.9.0)
|
60
|
-
pry-byebug (3.7.0)
|
61
|
-
byebug (~> 11.0)
|
62
|
-
pry (~> 0.10)
|
63
|
-
rack (2.0.6)
|
64
|
-
rack-test (1.1.0)
|
65
|
-
rack (>= 1.0, < 3)
|
66
|
-
rake (10.5.0)
|
67
|
-
redcarpet (3.4.0)
|
68
|
-
rspec (3.8.0)
|
69
|
-
rspec-core (~> 3.8.0)
|
70
|
-
rspec-expectations (~> 3.8.0)
|
71
|
-
rspec-mocks (~> 3.8.0)
|
72
|
-
rspec-core (3.8.0)
|
73
|
-
rspec-support (~> 3.8.0)
|
74
|
-
rspec-expectations (3.8.2)
|
75
|
-
diff-lcs (>= 1.2.0, < 2.0)
|
76
|
-
rspec-support (~> 3.8.0)
|
77
|
-
rspec-mocks (3.8.0)
|
78
|
-
diff-lcs (>= 1.2.0, < 2.0)
|
79
|
-
rspec-support (~> 3.8.0)
|
80
|
-
rspec-support (3.8.0)
|
81
|
-
tilt (2.0.9)
|
82
|
-
yard (0.9.20)
|
83
|
-
|
84
|
-
PLATFORMS
|
85
|
-
ruby
|
86
|
-
|
87
|
-
DEPENDENCIES
|
88
|
-
bundler (~> 1.17)
|
89
|
-
dry-view (~> 0.7)
|
90
|
-
pry-byebug
|
91
|
-
rack-test (~> 1.1)
|
92
|
-
rake (~> 10.0)
|
93
|
-
redcarpet (~> 3.4)
|
94
|
-
rspec (~> 3.0)
|
95
|
-
web_pipe!
|
96
|
-
yard (~> 0.9, >= 0.9.20)
|
97
|
-
|
98
|
-
BUNDLED WITH
|
99
|
-
1.17.2
|