hanami-controller 1.3.0 → 2.0.0.alpha2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +83 -0
- data/LICENSE.md +1 -1
- data/README.md +297 -538
- data/hanami-controller.gemspec +6 -5
- data/lib/hanami/action.rb +129 -73
- data/lib/hanami/action/application_action.rb +111 -0
- data/lib/hanami/action/application_configuration.rb +92 -0
- data/lib/hanami/action/application_configuration/cookies.rb +29 -0
- data/lib/hanami/action/application_configuration/sessions.rb +46 -0
- data/lib/hanami/action/base_params.rb +2 -2
- data/lib/hanami/action/cache.rb +1 -139
- data/lib/hanami/action/cache/cache_control.rb +4 -4
- data/lib/hanami/action/cache/conditional_get.rb +7 -2
- data/lib/hanami/action/cache/directives.rb +1 -1
- data/lib/hanami/action/cache/expires.rb +3 -3
- data/lib/hanami/action/configuration.rb +430 -0
- data/lib/hanami/action/cookie_jar.rb +3 -3
- data/lib/hanami/action/cookies.rb +3 -62
- data/lib/hanami/action/csrf_protection.rb +214 -0
- data/lib/hanami/action/flash.rb +102 -207
- data/lib/hanami/action/glue.rb +5 -31
- data/lib/hanami/action/halt.rb +12 -0
- data/lib/hanami/action/mime.rb +78 -485
- data/lib/hanami/action/params.rb +3 -3
- data/lib/hanami/action/rack/file.rb +1 -1
- data/lib/hanami/action/request.rb +30 -20
- data/lib/hanami/action/response.rb +193 -0
- data/lib/hanami/action/session.rb +11 -128
- data/lib/hanami/action/standalone_action.rb +581 -0
- data/lib/hanami/action/validatable.rb +2 -2
- data/lib/hanami/action/view_name_inferrer.rb +46 -0
- data/lib/hanami/controller.rb +0 -227
- data/lib/hanami/controller/version.rb +1 -1
- data/lib/hanami/http/status.rb +2 -2
- metadata +47 -30
- data/lib/hanami-controller.rb +0 -1
- data/lib/hanami/action/callable.rb +0 -92
- data/lib/hanami/action/callbacks.rb +0 -214
- data/lib/hanami/action/configurable.rb +0 -50
- data/lib/hanami/action/exposable.rb +0 -126
- data/lib/hanami/action/exposable/guard.rb +0 -104
- data/lib/hanami/action/head.rb +0 -121
- data/lib/hanami/action/rack.rb +0 -399
- data/lib/hanami/action/rack/callable.rb +0 -47
- data/lib/hanami/action/redirect.rb +0 -59
- data/lib/hanami/action/throwable.rb +0 -196
- data/lib/hanami/controller/configuration.rb +0 -763
data/lib/hanami-controller.rb
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
require 'hanami/controller'
|
@@ -1,92 +0,0 @@
|
|
1
|
-
module Hanami
|
2
|
-
module Action
|
3
|
-
module Callable
|
4
|
-
# Execute application logic.
|
5
|
-
# It implements the Rack protocol.
|
6
|
-
#
|
7
|
-
# The request params are passed as an argument to the `#call` method.
|
8
|
-
#
|
9
|
-
# If routed with Hanami::Router, it extracts the relevant bits from the
|
10
|
-
# Rack `env` (eg the requested `:id`).
|
11
|
-
#
|
12
|
-
# Otherwise everything it's passed as it is: the full Rack `env`
|
13
|
-
# in production, and the given `Hash` for unit tests. See the examples
|
14
|
-
# below.
|
15
|
-
#
|
16
|
-
# Application developers are forced to implement this method in their
|
17
|
-
# actions.
|
18
|
-
#
|
19
|
-
# @param env [Hash] the full Rack env or the params. This value may vary,
|
20
|
-
# see the examples below.
|
21
|
-
#
|
22
|
-
# @return [Array] a serialized Rack response (eg. `[200, {}, ["Hi!"]]`)
|
23
|
-
#
|
24
|
-
# @since 0.1.0
|
25
|
-
#
|
26
|
-
# @example with Hanami::Router
|
27
|
-
# require 'hanami/controller'
|
28
|
-
#
|
29
|
-
# class Show
|
30
|
-
# include Hanami::Action
|
31
|
-
#
|
32
|
-
# def call(params)
|
33
|
-
# # ...
|
34
|
-
# puts params # => { id: 23 } extracted from Rack env
|
35
|
-
# end
|
36
|
-
# end
|
37
|
-
#
|
38
|
-
# @example Standalone
|
39
|
-
# require 'hanami/controller'
|
40
|
-
#
|
41
|
-
# class Show
|
42
|
-
# include Hanami::Action
|
43
|
-
#
|
44
|
-
# def call(params)
|
45
|
-
# # ...
|
46
|
-
# puts params
|
47
|
-
# # => { :"rack.version"=>[1, 2],
|
48
|
-
# # :"rack.input"=>#<StringIO:0x007fa563463948>, ... }
|
49
|
-
# end
|
50
|
-
# end
|
51
|
-
#
|
52
|
-
# @example Unit Testing
|
53
|
-
# require 'hanami/controller'
|
54
|
-
#
|
55
|
-
# class Show
|
56
|
-
# include Hanami::Action
|
57
|
-
#
|
58
|
-
# def call(params)
|
59
|
-
# # ...
|
60
|
-
# puts params # => { id: 23, key: 'value' } passed as it is from testing
|
61
|
-
# end
|
62
|
-
# end
|
63
|
-
#
|
64
|
-
# action = Show.new
|
65
|
-
# response = action.call({ id: 23, key: 'value' })
|
66
|
-
def call(env)
|
67
|
-
_rescue do
|
68
|
-
@_env = env
|
69
|
-
@headers = ::Rack::Utils::HeaderHash.new(configuration.default_headers)
|
70
|
-
@params = self.class.params_class.new(@_env)
|
71
|
-
super @params
|
72
|
-
end
|
73
|
-
|
74
|
-
finish
|
75
|
-
end
|
76
|
-
|
77
|
-
private
|
78
|
-
|
79
|
-
# Prepare the Rack response before the control is returned to the
|
80
|
-
# webserver.
|
81
|
-
#
|
82
|
-
# @since 0.1.0
|
83
|
-
# @api private
|
84
|
-
#
|
85
|
-
# @see Hanami::Action#finish
|
86
|
-
def finish
|
87
|
-
super
|
88
|
-
response
|
89
|
-
end
|
90
|
-
end
|
91
|
-
end
|
92
|
-
end
|
@@ -1,214 +0,0 @@
|
|
1
|
-
require 'hanami/utils/class_attribute'
|
2
|
-
require 'hanami/utils/callbacks'
|
3
|
-
|
4
|
-
module Hanami
|
5
|
-
module Action
|
6
|
-
# Before and after callbacks
|
7
|
-
#
|
8
|
-
# @since 0.1.0
|
9
|
-
# @see Hanami::Action::ClassMethods#before
|
10
|
-
# @see Hanami::Action::ClassMethods#after
|
11
|
-
module Callbacks
|
12
|
-
# Override Ruby's hook for modules.
|
13
|
-
# It includes callbacks logic
|
14
|
-
#
|
15
|
-
# @param base [Class] the target action
|
16
|
-
#
|
17
|
-
# @since 0.1.0
|
18
|
-
# @api private
|
19
|
-
#
|
20
|
-
# @see http://www.ruby-doc.org/core/Module.html#method-i-included
|
21
|
-
def self.included(base)
|
22
|
-
base.class_eval do
|
23
|
-
extend ClassMethods
|
24
|
-
prepend InstanceMethods
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
# Callbacks API class methods
|
29
|
-
#
|
30
|
-
# @since 0.1.0
|
31
|
-
# @api private
|
32
|
-
module ClassMethods
|
33
|
-
# Override Ruby's hook for modules.
|
34
|
-
# It includes callbacks logic
|
35
|
-
#
|
36
|
-
# @param base [Class] the target action
|
37
|
-
#
|
38
|
-
# @since 0.1.0
|
39
|
-
# @api private
|
40
|
-
#
|
41
|
-
# @see http://www.ruby-doc.org/core/Module.html#method-i-extended
|
42
|
-
def self.extended(base)
|
43
|
-
base.class_eval do
|
44
|
-
include Utils::ClassAttribute
|
45
|
-
|
46
|
-
class_attribute :before_callbacks
|
47
|
-
self.before_callbacks = Utils::Callbacks::Chain.new
|
48
|
-
|
49
|
-
class_attribute :after_callbacks
|
50
|
-
self.after_callbacks = Utils::Callbacks::Chain.new
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
# Define a callback for an Action.
|
55
|
-
# The callback will be executed **before** the action is called, in the
|
56
|
-
# order they are added.
|
57
|
-
#
|
58
|
-
# @param callbacks [Symbol, Array<Symbol>] a single or multiple symbol(s)
|
59
|
-
# each of them is representing a name of a method available in the
|
60
|
-
# context of the Action.
|
61
|
-
#
|
62
|
-
# @param blk [Proc] an anonymous function to be executed
|
63
|
-
#
|
64
|
-
# @return [void]
|
65
|
-
#
|
66
|
-
# @since 0.3.2
|
67
|
-
#
|
68
|
-
# @see Hanami::Action::Callbacks::ClassMethods#append_after
|
69
|
-
#
|
70
|
-
# @example Method names (symbols)
|
71
|
-
# require 'hanami/controller'
|
72
|
-
#
|
73
|
-
# class Show
|
74
|
-
# include Hanami::Action
|
75
|
-
#
|
76
|
-
# before :authenticate, :set_article
|
77
|
-
#
|
78
|
-
# def call(params)
|
79
|
-
# end
|
80
|
-
#
|
81
|
-
# private
|
82
|
-
# def authenticate
|
83
|
-
# # ...
|
84
|
-
# end
|
85
|
-
#
|
86
|
-
# # `params` in the method signature is optional
|
87
|
-
# def set_article(params)
|
88
|
-
# @article = Article.find params[:id]
|
89
|
-
# end
|
90
|
-
# end
|
91
|
-
#
|
92
|
-
# # The order of execution will be:
|
93
|
-
# #
|
94
|
-
# # 1. #authenticate
|
95
|
-
# # 2. #set_article
|
96
|
-
# # 3. #call
|
97
|
-
#
|
98
|
-
# @example Anonymous functions (Procs)
|
99
|
-
# require 'hanami/controller'
|
100
|
-
#
|
101
|
-
# class Show
|
102
|
-
# include Hanami::Action
|
103
|
-
#
|
104
|
-
# before { ... } # 1 do some authentication stuff
|
105
|
-
# before {|params| @article = Article.find params[:id] } # 2
|
106
|
-
#
|
107
|
-
# def call(params)
|
108
|
-
# end
|
109
|
-
# end
|
110
|
-
#
|
111
|
-
# # The order of execution will be:
|
112
|
-
# #
|
113
|
-
# # 1. authentication
|
114
|
-
# # 2. set the article
|
115
|
-
# # 3. #call
|
116
|
-
def append_before(*callbacks, &blk)
|
117
|
-
before_callbacks.append(*callbacks, &blk)
|
118
|
-
end
|
119
|
-
|
120
|
-
# @since 0.1.0
|
121
|
-
alias_method :before, :append_before
|
122
|
-
|
123
|
-
# Define a callback for an Action.
|
124
|
-
# The callback will be executed **after** the action is called, in the
|
125
|
-
# order they are added.
|
126
|
-
#
|
127
|
-
# @param callbacks [Symbol, Array<Symbol>] a single or multiple symbol(s)
|
128
|
-
# each of them is representing a name of a method available in the
|
129
|
-
# context of the Action.
|
130
|
-
#
|
131
|
-
# @param blk [Proc] an anonymous function to be executed
|
132
|
-
#
|
133
|
-
# @return [void]
|
134
|
-
#
|
135
|
-
# @since 0.3.2
|
136
|
-
#
|
137
|
-
# @see Hanami::Action::Callbacks::ClassMethods#append_before
|
138
|
-
def append_after(*callbacks, &blk)
|
139
|
-
after_callbacks.append(*callbacks, &blk)
|
140
|
-
end
|
141
|
-
|
142
|
-
# @since 0.1.0
|
143
|
-
alias_method :after, :append_after
|
144
|
-
|
145
|
-
# Define a callback for an Action.
|
146
|
-
# The callback will be executed **before** the action is called.
|
147
|
-
# It will add the callback at the beginning of the callbacks' chain.
|
148
|
-
#
|
149
|
-
# @param callbacks [Symbol, Array<Symbol>] a single or multiple symbol(s)
|
150
|
-
# each of them is representing a name of a method available in the
|
151
|
-
# context of the Action.
|
152
|
-
#
|
153
|
-
# @param blk [Proc] an anonymous function to be executed
|
154
|
-
#
|
155
|
-
# @return [void]
|
156
|
-
#
|
157
|
-
# @since 0.3.2
|
158
|
-
#
|
159
|
-
# @see Hanami::Action::Callbacks::ClassMethods#prepend_after
|
160
|
-
def prepend_before(*callbacks, &blk)
|
161
|
-
before_callbacks.prepend(*callbacks, &blk)
|
162
|
-
end
|
163
|
-
|
164
|
-
# Define a callback for an Action.
|
165
|
-
# The callback will be executed **after** the action is called.
|
166
|
-
# It will add the callback at the beginning of the callbacks' chain.
|
167
|
-
#
|
168
|
-
# @param callbacks [Symbol, Array<Symbol>] a single or multiple symbol(s)
|
169
|
-
# each of them is representing a name of a method available in the
|
170
|
-
# context of the Action.
|
171
|
-
#
|
172
|
-
# @param blk [Proc] an anonymous function to be executed
|
173
|
-
#
|
174
|
-
# @return [void]
|
175
|
-
#
|
176
|
-
# @since 0.3.2
|
177
|
-
#
|
178
|
-
# @see Hanami::Action::Callbacks::ClassMethods#prepend_before
|
179
|
-
def prepend_after(*callbacks, &blk)
|
180
|
-
after_callbacks.prepend(*callbacks, &blk)
|
181
|
-
end
|
182
|
-
end
|
183
|
-
|
184
|
-
# Callbacks API instance methods
|
185
|
-
#
|
186
|
-
# @since 0.1.0
|
187
|
-
# @api private
|
188
|
-
module InstanceMethods
|
189
|
-
# Implements the Rack/Hanami::Action protocol
|
190
|
-
#
|
191
|
-
# @since 0.1.0
|
192
|
-
# @api private
|
193
|
-
def call(params)
|
194
|
-
_run_before_callbacks(params)
|
195
|
-
super
|
196
|
-
_run_after_callbacks(params)
|
197
|
-
end
|
198
|
-
|
199
|
-
private
|
200
|
-
# @since 0.1.0
|
201
|
-
# @api private
|
202
|
-
def _run_before_callbacks(params)
|
203
|
-
self.class.before_callbacks.run(self, params)
|
204
|
-
end
|
205
|
-
|
206
|
-
# @since 0.1.0
|
207
|
-
# @api private
|
208
|
-
def _run_after_callbacks(params)
|
209
|
-
self.class.after_callbacks.run(self, params)
|
210
|
-
end
|
211
|
-
end
|
212
|
-
end
|
213
|
-
end
|
214
|
-
end
|
@@ -1,50 +0,0 @@
|
|
1
|
-
require 'hanami/utils/class_attribute'
|
2
|
-
|
3
|
-
module Hanami
|
4
|
-
module Action
|
5
|
-
# Configuration API
|
6
|
-
#
|
7
|
-
# @since 0.2.0
|
8
|
-
#
|
9
|
-
# @see Hanami::Controller::Configuration
|
10
|
-
module Configurable
|
11
|
-
# Override Ruby's hook for modules.
|
12
|
-
# It includes configuration logic
|
13
|
-
#
|
14
|
-
# @param base [Class] the target action
|
15
|
-
#
|
16
|
-
# @since 0.2.0
|
17
|
-
# @api private
|
18
|
-
#
|
19
|
-
# @see http://www.ruby-doc.org/core-2.1.2/Module.html#method-i-included
|
20
|
-
#
|
21
|
-
# @example
|
22
|
-
# require 'hanami/controller'
|
23
|
-
#
|
24
|
-
# class Show
|
25
|
-
# include Hanami::Action
|
26
|
-
# end
|
27
|
-
#
|
28
|
-
# Show.configuration
|
29
|
-
def self.included(base)
|
30
|
-
config = Hanami::Controller::Configuration.for(base)
|
31
|
-
|
32
|
-
base.class_eval do
|
33
|
-
include Utils::ClassAttribute
|
34
|
-
|
35
|
-
class_attribute :configuration
|
36
|
-
self.configuration = config
|
37
|
-
end
|
38
|
-
|
39
|
-
config.copy!(base)
|
40
|
-
end
|
41
|
-
|
42
|
-
private
|
43
|
-
|
44
|
-
# @since 0.2.0
|
45
|
-
def configuration
|
46
|
-
self.class.configuration
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
@@ -1,126 +0,0 @@
|
|
1
|
-
require 'hanami/action/exposable/guard'
|
2
|
-
|
3
|
-
module Hanami
|
4
|
-
module Action
|
5
|
-
# Exposures API
|
6
|
-
#
|
7
|
-
# @since 0.1.0
|
8
|
-
#
|
9
|
-
# @see Hanami::Action::Exposable::ClassMethods#expose
|
10
|
-
module Exposable
|
11
|
-
# Override Ruby's hook for modules.
|
12
|
-
# It includes exposures logic
|
13
|
-
#
|
14
|
-
# @param base [Class] the target action
|
15
|
-
#
|
16
|
-
# @since 0.1.0
|
17
|
-
# @api private
|
18
|
-
#
|
19
|
-
# @see http://www.ruby-doc.org/core-2.1.2/Module.html#method-i-included
|
20
|
-
def self.included(base)
|
21
|
-
base.class_eval do
|
22
|
-
extend ClassMethods
|
23
|
-
include Guard
|
24
|
-
|
25
|
-
_expose :params
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
# Exposures API class methods
|
30
|
-
#
|
31
|
-
# @since 0.1.0
|
32
|
-
# @api private
|
33
|
-
module ClassMethods
|
34
|
-
# Expose the given attributes on the outside of the object with
|
35
|
-
# a getter and a special method called #exposures.
|
36
|
-
#
|
37
|
-
# @param names [Array<Symbol>] the name(s) of the attribute(s) to be
|
38
|
-
# exposed
|
39
|
-
#
|
40
|
-
# @return [void]
|
41
|
-
#
|
42
|
-
# @since 0.1.0
|
43
|
-
#
|
44
|
-
# @example
|
45
|
-
# require 'hanami/controller'
|
46
|
-
#
|
47
|
-
# class Show
|
48
|
-
# include Hanami::Action
|
49
|
-
#
|
50
|
-
# expose :article, :tags
|
51
|
-
#
|
52
|
-
# def call(params)
|
53
|
-
# @article = Article.find params[:id]
|
54
|
-
# @tags = Tag.for(article)
|
55
|
-
# end
|
56
|
-
# end
|
57
|
-
#
|
58
|
-
# action = Show.new
|
59
|
-
# action.call({id: 23})
|
60
|
-
#
|
61
|
-
# action.article # => #<Article ...>
|
62
|
-
# action.tags # => [#<Tag ...>, #<Tag ...>]
|
63
|
-
#
|
64
|
-
# action.exposures # => { :article => #<Article ...>, :tags => [ ... ] }
|
65
|
-
def expose(*names)
|
66
|
-
class_eval do
|
67
|
-
names.each do |name|
|
68
|
-
attr_reader(name) unless attr_reader?(name)
|
69
|
-
end
|
70
|
-
|
71
|
-
exposures.push(*names)
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
# Alias of #expose to be used in internal modules.
|
76
|
-
# #_expose is not watched by the Guard
|
77
|
-
alias _expose expose
|
78
|
-
|
79
|
-
# Set of exposures attribute names
|
80
|
-
#
|
81
|
-
# @return [Array] the exposures attribute names
|
82
|
-
#
|
83
|
-
# @since 0.1.0
|
84
|
-
# @api private
|
85
|
-
def exposures
|
86
|
-
@exposures ||= []
|
87
|
-
end
|
88
|
-
|
89
|
-
private
|
90
|
-
# Check if the attr_reader is already defined
|
91
|
-
#
|
92
|
-
# @since 0.3.0
|
93
|
-
# @api private
|
94
|
-
def attr_reader?(name)
|
95
|
-
(instance_methods | private_instance_methods).include?(name)
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
|
-
# Set of exposures
|
100
|
-
#
|
101
|
-
# @return [Hash] the exposures
|
102
|
-
#
|
103
|
-
# @since 0.1.0
|
104
|
-
#
|
105
|
-
# @see Hanami::Action::Exposable::ClassMethods.expose
|
106
|
-
def exposures
|
107
|
-
@exposures ||= {}.tap do |result|
|
108
|
-
self.class.exposures.each do |name|
|
109
|
-
result[name] = send(name)
|
110
|
-
end
|
111
|
-
end
|
112
|
-
end
|
113
|
-
|
114
|
-
# Finalize the response
|
115
|
-
#
|
116
|
-
# @since 0.3.0
|
117
|
-
# @api private
|
118
|
-
#
|
119
|
-
# @see Hanami::Action#finish
|
120
|
-
def finish
|
121
|
-
super
|
122
|
-
exposures
|
123
|
-
end
|
124
|
-
end
|
125
|
-
end
|
126
|
-
end
|