web_pipe 0.3.0 → 0.4.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/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
|