web_pipe 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +52 -1
- data/Gemfile.lock +1 -1
- data/README.md +14 -5
- data/lib/web_pipe/dsl/class_context.rb +1 -1
- data/lib/web_pipe/dsl/dsl_context.rb +21 -11
- data/lib/web_pipe/dsl/instance_methods.rb +23 -8
- data/lib/web_pipe/plug.rb +8 -1
- data/lib/web_pipe/rack/middleware_specification.rb +56 -6
- data/lib/web_pipe/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 846bd7956d65605edaad299346280d7ae4b426d8cf4160e47ebac7375135b4e7
|
4
|
+
data.tar.gz: 41923761b8227c956f6b554bf8dc49fdc6323dc97e08399b5f8b4bc043552fdf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b2de9d0a5e7f172e9c42fcf2e97b6ff22046552670c9cf096d270438aab9d572fb4bd915fba282e578f48b39c412ba867d8359881426073b936c9734b3e8a693
|
7
|
+
data.tar.gz: b72848b3ad1e98f18dea9da6b8dc19eef99c61ffb3f71115fd041b1fe699b5ca22bf0395f80e4fd16621d1b72ba8970a1555577126f148ffadf4768ed4a417b4
|
data/CHANGELOG.md
CHANGED
@@ -4,6 +4,57 @@ 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.4.0] - 2019-07-17
|
8
|
+
### Added
|
9
|
+
- **BREAKING**: Middlewares have to be named when used ([11](https://github.com/waiting-for-dev/web_pipe/pull/11)):
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
use :cookies, Rack::Session:Cookie, secret: 'my_secret', key: 'foo'
|
13
|
+
```
|
14
|
+
|
15
|
+
- **BREAKING**: Middlewares have to be initialized when composed ([11](https://github.com/waiting-for-dev/web_pipe/pull/11)):
|
16
|
+
|
17
|
+
```ruby
|
18
|
+
use :pipe, PipeWithMiddlewares.new
|
19
|
+
```
|
20
|
+
|
21
|
+
- **BREAKING**: The array of injected plugs is now scoped within a `plugs:` kwarg ([11](https://github.com/waiting-for-dev/web_pipe/pull/11)):
|
22
|
+
|
23
|
+
```ruby
|
24
|
+
App.new(plugs: { nothing: ->(conn) { conn } })
|
25
|
+
```
|
26
|
+
|
27
|
+
- Middlewares can be injected ([11](https://github.com/waiting-for-dev/web_pipe/pull/11)):
|
28
|
+
|
29
|
+
```ruby
|
30
|
+
App.new(middlewares: { cache: [MyMiddleware, my_options] })
|
31
|
+
```
|
32
|
+
|
33
|
+
- DSL helper method `compose` to add middlewares and plugs in order and in a single shot ([12](https://github.com/waiting-for-dev/web_pipe/pull/11)):
|
34
|
+
|
35
|
+
```ruby
|
36
|
+
class App
|
37
|
+
include WebPipe.(container: Container)
|
38
|
+
|
39
|
+
use :first, FirstMiddleware
|
40
|
+
|
41
|
+
plug :first_plug, 'first_plug'
|
42
|
+
end
|
43
|
+
|
44
|
+
class AnotherApp
|
45
|
+
include WebPipe.(container: Container)
|
46
|
+
|
47
|
+
compose App
|
48
|
+
# Equivalent to:
|
49
|
+
# use App.new
|
50
|
+
# plug &App.new
|
51
|
+
|
52
|
+
use :second, SecondMiddleware
|
53
|
+
|
54
|
+
plug :second_plug, 'second_plug'
|
55
|
+
end
|
56
|
+
```
|
57
|
+
|
7
58
|
## [0.3.0] - 2019-07-12
|
8
59
|
### Added
|
9
60
|
- **BREAKING**: When plugging with `plug:`, the operation is no longer specified through `with:`. Now it is just the second positional argument ([9](https://github.com/waiting-for-dev/web_pipe/pull/9)):
|
@@ -51,7 +102,7 @@ class App
|
|
51
102
|
end
|
52
103
|
```
|
53
104
|
|
54
|
-
- WebPipe's middlewares can be composed into another WebPipe class, also through `:use
|
105
|
+
- WebPipe's middlewares can be composed into another WebPipe class, also through `:use` ([10](https://github.com/waiting-for-dev/web_pipe/pull/10)):
|
55
106
|
|
56
107
|
```ruby
|
57
108
|
class HtmlApp
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -255,8 +255,9 @@ class App
|
|
255
255
|
plug :hello, ->(conn) { conn.set_response_body('Hello') }
|
256
256
|
end
|
257
257
|
|
258
|
-
run App.new(
|
259
|
-
|
258
|
+
run App.new(plugs: {
|
259
|
+
hello: ->(conn) { conn.set_response_body('Injected') }
|
260
|
+
}
|
260
261
|
)
|
261
262
|
```
|
262
263
|
|
@@ -272,8 +273,8 @@ plugs:
|
|
272
273
|
class App
|
273
274
|
include WebPipe
|
274
275
|
|
275
|
-
use Middleware1
|
276
|
-
use Middleware2, option_1: value_1
|
276
|
+
use :middleware_1, Middleware1
|
277
|
+
use :middleware_1, Middleware2, option_1: value_1
|
277
278
|
|
278
279
|
plug :hello, ->(conn) { conn }
|
279
280
|
end
|
@@ -286,12 +287,20 @@ class. Extending from previous example:
|
|
286
287
|
class App2
|
287
288
|
include WebPipe
|
288
289
|
|
289
|
-
use App # it will also use Middleware1 and Middleware2
|
290
|
+
use :app, App.new # it will also use Middleware1 and Middleware2
|
290
291
|
|
291
292
|
plug :hello, ->(conn) { conn }
|
292
293
|
end
|
293
294
|
```
|
294
295
|
|
296
|
+
Middlewares can also be injected on initialization:
|
297
|
+
|
298
|
+
```ruby
|
299
|
+
App.new(middlewares: {
|
300
|
+
middleware_1: [AnotherMiddleware, options]
|
301
|
+
})
|
302
|
+
```
|
303
|
+
|
295
304
|
### Standalone usage
|
296
305
|
|
297
306
|
If you prefer, you can use the application builder without the
|
@@ -18,7 +18,7 @@ module WebPipe
|
|
18
18
|
# @api private
|
19
19
|
class ClassContext < Module
|
20
20
|
# Methods to be imported from the {DSLContext}.
|
21
|
-
DSL_METHODS = %i[
|
21
|
+
DSL_METHODS = %i[middleware_specifications use plugs plug compose].freeze
|
22
22
|
|
23
23
|
# @!attribute [r] container
|
24
24
|
# @return [Types::Container[]]
|
@@ -1,7 +1,6 @@
|
|
1
1
|
require 'dry/initializer'
|
2
2
|
require 'web_pipe/types'
|
3
3
|
require 'web_pipe/plug'
|
4
|
-
require 'web_pipe/rack/middleware'
|
5
4
|
require 'web_pipe/rack/middleware_specification'
|
6
5
|
|
7
6
|
module WebPipe
|
@@ -13,36 +12,37 @@ module WebPipe
|
|
13
12
|
#
|
14
13
|
# @api private
|
15
14
|
class DSLContext
|
16
|
-
# @!attribute
|
17
|
-
# @return [Array<Rack::
|
15
|
+
# @!attribute middleware_specifications
|
16
|
+
# @return [Array<Rack::MiddlewareSpecifications>]
|
18
17
|
|
19
18
|
# @!attribute plugs
|
20
19
|
# @return [Array<Plug>]
|
21
20
|
|
22
21
|
|
23
22
|
include Dry::Initializer.define -> do
|
24
|
-
param :
|
25
|
-
type: Types.Array(Rack::
|
23
|
+
param :middleware_specifications,
|
24
|
+
type: Types.Array(Rack::MiddlewareSpecification)
|
26
25
|
|
27
26
|
param :plugs,
|
28
27
|
type: Types.Array(Plug::Instance)
|
29
28
|
end
|
30
29
|
|
31
|
-
# Creates and add rack
|
30
|
+
# Creates and add rack middleware specifications to the stack.
|
32
31
|
#
|
33
32
|
# The spec can be given in two forms:
|
34
33
|
#
|
35
34
|
# - As one or two arguments, first one being a
|
36
|
-
#
|
35
|
+
# rack middleware class and second one optionally its
|
37
36
|
# initialization options.
|
38
|
-
# - As a {WebPipe} class, in which case all its rack
|
39
|
-
# will be
|
37
|
+
# - As a {WebPipe} class instance, in which case all its rack
|
38
|
+
# middlewares will be considered.
|
40
39
|
#
|
40
|
+
# @param name [Rack::MiddlewareSpecification::Name[]]
|
41
41
|
# @param spec [Rack::MiddlewareSpecification::Spec[]]
|
42
42
|
#
|
43
43
|
# @return [Array<Rack::Middleware>]
|
44
|
-
def use(*spec)
|
45
|
-
|
44
|
+
def use(name, *spec)
|
45
|
+
middleware_specifications << Rack::MiddlewareSpecification.new(name, spec)
|
46
46
|
end
|
47
47
|
|
48
48
|
# Creates and adds a plug to the stack.
|
@@ -59,6 +59,16 @@ module WebPipe
|
|
59
59
|
def plug(name, spec = nil, &block_spec)
|
60
60
|
plugs << Plug.new(name, spec || block_spec)
|
61
61
|
end
|
62
|
+
|
63
|
+
# Adds middlewares and plugs from a WebPipe to respective
|
64
|
+
# stacks.
|
65
|
+
#
|
66
|
+
# @param name [Plug::Name[], Middleware::Name[]]
|
67
|
+
# @param spec [WebPipe]
|
68
|
+
def compose(name, spec)
|
69
|
+
use(name, spec)
|
70
|
+
plug(name, &spec)
|
71
|
+
end
|
62
72
|
end
|
63
73
|
end
|
64
74
|
end
|
@@ -4,6 +4,7 @@ require 'web_pipe/conn'
|
|
4
4
|
require 'web_pipe/app'
|
5
5
|
require 'web_pipe/plug'
|
6
6
|
require 'web_pipe/rack/app_with_middlewares'
|
7
|
+
require 'web_pipe/rack/middleware_specification'
|
7
8
|
require 'web_pipe/conn_support/composition'
|
8
9
|
|
9
10
|
module WebPipe
|
@@ -12,8 +13,8 @@ module WebPipe
|
|
12
13
|
#
|
13
14
|
# It is from here that you get the rack application you can route
|
14
15
|
# to. The initialization phase gives you the chance to inject any
|
15
|
-
# of the plugs, while the instance you get has the
|
16
|
-
# expected by rack.
|
16
|
+
# of the plugs or middlewares, while the instance you get has the
|
17
|
+
# `#call` method expected by rack.
|
17
18
|
#
|
18
19
|
# The pipe state can be accessed through the pipe class, which
|
19
20
|
# has been configured through {ClassContext}.
|
@@ -21,13 +22,20 @@ module WebPipe
|
|
21
22
|
# @api private
|
22
23
|
module InstanceMethods
|
23
24
|
# No injections at all.
|
24
|
-
EMPTY_INJECTIONS =
|
25
|
+
EMPTY_INJECTIONS = {
|
26
|
+
plugs: Types::EMPTY_HASH,
|
27
|
+
middlewares: Types::EMPTY_HASH
|
28
|
+
}.freeze
|
25
29
|
|
26
|
-
# Type for how plugs should be injected.
|
27
|
-
Injections = Types::Strict::Hash.
|
30
|
+
# Type for how plugs and middlewares should be injected.
|
31
|
+
Injections = Types::Strict::Hash.schema(
|
32
|
+
plugs: Plug::Injections,
|
33
|
+
middlewares: Rack::MiddlewareSpecification::Injections
|
34
|
+
)
|
28
35
|
|
29
36
|
# @!attribute [r] injections [Injections[]]
|
30
|
-
# Injected plugs that allow overriding what
|
37
|
+
# Injected plugs and middlewares that allow overriding what
|
38
|
+
# has been configured.
|
31
39
|
|
32
40
|
|
33
41
|
include Dry::Initializer.define -> do
|
@@ -42,11 +50,18 @@ module WebPipe
|
|
42
50
|
# @return [ConnSupport::Composition::Operation[]]
|
43
51
|
attr_reader :operations
|
44
52
|
|
53
|
+
# @return [Array<Rack::Middlewares>]
|
54
|
+
attr_reader :middlewares
|
55
|
+
|
45
56
|
def initialize(*args)
|
46
57
|
super
|
47
|
-
middlewares = self.class.middlewares
|
48
58
|
container = self.class.container
|
49
|
-
@
|
59
|
+
@middlewares = Rack::MiddlewareSpecification.inject_and_resolve(
|
60
|
+
self.class.middleware_specifications, injections[:middlewares]
|
61
|
+
)
|
62
|
+
@operations = Plug.inject_and_resolve(
|
63
|
+
self.class.plugs, injections[:plugs], container, self
|
64
|
+
)
|
50
65
|
app = App.new(operations)
|
51
66
|
@rack_app = Rack::AppWithMiddlewares.new(middlewares, app)
|
52
67
|
end
|
data/lib/web_pipe/plug.rb
CHANGED
@@ -46,6 +46,13 @@ module WebPipe
|
|
46
46
|
# Type for an instance of self.
|
47
47
|
Instance = Types.Instance(self)
|
48
48
|
|
49
|
+
# Schema expected to inject plugs.
|
50
|
+
#
|
51
|
+
# @see #inject_and_resolve
|
52
|
+
Injections = Types::Strict::Hash.map(
|
53
|
+
Plug::Name, Plug::Spec
|
54
|
+
).default(Types::EMPTY_HASH)
|
55
|
+
|
49
56
|
# @!attribute [r] name
|
50
57
|
# @return [Name[]]
|
51
58
|
|
@@ -89,7 +96,7 @@ module WebPipe
|
|
89
96
|
# Change `plugs` spec's present in `injections` and resolves.
|
90
97
|
#
|
91
98
|
# @param plugs [Array<Plug>]
|
92
|
-
# @param injections [InstanceMethods::
|
99
|
+
# @param injections [InstanceMethods::PlugInjections[]]
|
93
100
|
# @container container [Types::Container[]]
|
94
101
|
# @object [Object]
|
95
102
|
#
|
@@ -9,25 +9,75 @@ module WebPipe
|
|
9
9
|
#
|
10
10
|
# - As an array where fist element is a rack middleware class
|
11
11
|
# while the rest of elements are its initialization options.
|
12
|
-
# - A single element array where it is a class
|
13
|
-
# {WebPipe}. This specifies all {Rack::Middlewares}
|
12
|
+
# - A single element array where it is an instance of a class
|
13
|
+
# including {WebPipe}. This specifies all {Rack::Middlewares}
|
14
14
|
# for that {WebPipe}.
|
15
15
|
#
|
16
16
|
# @api private
|
17
|
-
|
17
|
+
class MiddlewareSpecification
|
18
|
+
# Type for the name given to a middleware.
|
19
|
+
Name = Types::Strict::Symbol.constructor(&:to_sym)
|
20
|
+
|
21
|
+
# Poor type for the specification to resolve a rack middleware.
|
22
|
+
Spec = Types::Strict::Array
|
23
|
+
|
24
|
+
# Schema expected to inject middleware specifications.
|
25
|
+
#
|
26
|
+
# @see #inject_and_resolve
|
27
|
+
Injections = Types::Strict::Hash.map(
|
28
|
+
Rack::MiddlewareSpecification::Name, Rack::MiddlewareSpecification::Spec
|
29
|
+
).default(Types::EMPTY_HASH)
|
30
|
+
|
31
|
+
# @!attribute [r] name
|
32
|
+
# @return [Name[]]
|
33
|
+
|
34
|
+
# @!attribute [r] spec
|
35
|
+
# @return [Spec[]]
|
36
|
+
|
37
|
+
|
38
|
+
include Dry::Initializer.define -> do
|
39
|
+
param :name, Name
|
40
|
+
|
41
|
+
param :spec, Spec
|
42
|
+
end
|
43
|
+
|
44
|
+
# Change spec's present in `injections` and resolves.
|
45
|
+
#
|
46
|
+
# @param middleware_specifications [Array<MiddlewareSpecification>]
|
47
|
+
# @param injections [Injections[]]
|
48
|
+
#
|
49
|
+
# @return [Array<Rack::Middleware>]
|
50
|
+
def self.inject_and_resolve(middleware_specifications, injections)
|
51
|
+
middleware_specifications.map do |spec|
|
52
|
+
if injections.has_key?(spec.name)
|
53
|
+
spec.with(injections[spec.name])
|
54
|
+
else
|
55
|
+
spec
|
56
|
+
end.()
|
57
|
+
end.flatten
|
58
|
+
end
|
59
|
+
|
18
60
|
# Resolves {Rack::Middlewares} from given specification.
|
19
61
|
#
|
20
|
-
# @param spec [Array]
|
21
62
|
# @return [Array<Rack::Middleware>]
|
22
|
-
def
|
63
|
+
def call
|
23
64
|
klass = spec[0]
|
24
65
|
options = spec[1..-1] || Types::EMPTY_ARRAY
|
25
|
-
if klass.
|
66
|
+
if klass.is_a?(WebPipe)
|
26
67
|
klass.middlewares
|
27
68
|
elsif klass.is_a?(Class)
|
28
69
|
[Middleware.new(middleware: klass, options: options)]
|
29
70
|
end
|
30
71
|
end
|
72
|
+
|
73
|
+
# Returns new instance with {#spec} replaced.
|
74
|
+
#
|
75
|
+
# @param new_spec [Spec[]]
|
76
|
+
#
|
77
|
+
# @return [MiddlewareSpecification]
|
78
|
+
def with(new_spec)
|
79
|
+
self.class.new(name, new_spec)
|
80
|
+
end
|
31
81
|
end
|
32
82
|
end
|
33
83
|
end
|
data/lib/web_pipe/version.rb
CHANGED
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.4.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-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rack
|