hanami-controller 2.0.0.alpha1 → 2.0.0.alpha2

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.
@@ -50,7 +50,7 @@ module Hanami
50
50
  # @since 0.3.0
51
51
  #
52
52
  # @see Hanami::Action::Params
53
- # @see http://hanamirb.org/guides/validations/overview/
53
+ # @see https://guides.hanamirb.org//validations/overview
54
54
  #
55
55
  # @example Anonymous Block
56
56
  # require 'hanami/controller'
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hanami
4
+ class Action
5
+ class ViewNameInferrer
6
+ ALTERNATIVE_NAMES = {
7
+ "create" => "new",
8
+ "update" => "edit"
9
+ }.freeze
10
+
11
+ class << self
12
+ def call(action_name:, provider:)
13
+ application = provider.respond_to?(:application) ? provider.application : Hanami.application
14
+
15
+ action_identifier_base = application.config.actions.name_inference_base
16
+ view_identifier_base = application.config.actions.view_name_inference_base
17
+
18
+ identifier = action_identifier_name(action_name, provider, action_identifier_base)
19
+
20
+ view_name = [view_identifier_base, identifier].compact.join(".")
21
+
22
+ [view_name, alternative_view_name(view_name)].compact
23
+ end
24
+
25
+ private
26
+
27
+ def action_identifier_name(action_name, provider, name_base)
28
+ provider
29
+ .inflector
30
+ .underscore(action_name)
31
+ .sub(/^#{provider.namespace_path}\//, "")
32
+ .sub(/^#{name_base}\//, "")
33
+ .gsub("/", ".")
34
+ end
35
+
36
+ def alternative_view_name(view_name)
37
+ parts = view_name.split(".")
38
+
39
+ alternative_name = ALTERNATIVE_NAMES[parts.last]
40
+
41
+ [parts[0..-2], alternative_name].join(".") if alternative_name
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -1,5 +1,4 @@
1
1
  require 'hanami/action'
2
- require 'hanami/controller/configuration'
3
2
  require 'hanami/controller/version'
4
3
  require 'hanami/controller/error'
5
4
 
@@ -45,21 +44,5 @@ module Hanami
45
44
  super("Cannot find a corresponding Mime type for '#{ format }'. Please configure it with Hanami::Controller::Configuration#format.")
46
45
  end
47
46
  end
48
-
49
- # Missing session error
50
- #
51
- # This error is raised when an action sends either `session` or `flash` to
52
- # itself and it does not include `Hanami::Action::Session`.
53
- #
54
- # @since 1.2.0
55
- #
56
- # @see Hanami::Action::Session
57
- # @see Hanami::Action#session
58
- # @see Hanami::Action#flash
59
- class MissingSessionError < Hanami::Controller::Error
60
- def initialize(session_method)
61
- super("To use `#{session_method}', add `include Hanami::Action::Session`.")
62
- end
63
- end
64
47
  end
65
48
  end
@@ -3,6 +3,6 @@ module Hanami
3
3
  # Defines the version
4
4
  #
5
5
  # @since 0.1.0
6
- VERSION = '2.0.0.alpha1'.freeze
6
+ VERSION = '2.0.0.alpha2'.freeze
7
7
  end
8
8
  end
@@ -31,7 +31,7 @@ module Hanami
31
31
 
32
32
  # Return a status for the given code
33
33
  #
34
- # @param code [Fixnum] a valid HTTP code
34
+ # @param code [Integer] a valid HTTP code
35
35
  #
36
36
  # @return [Array] a pair of code and message for an HTTP status
37
37
  #
@@ -48,7 +48,7 @@ module Hanami
48
48
 
49
49
  # Return a message for the given status code
50
50
  #
51
- # @param code [Fixnum] a valid HTTP code
51
+ # @param code [Integer] a valid HTTP code
52
52
  #
53
53
  # @return [String] a message for the given status code
54
54
  #
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hanami-controller
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0.alpha1
4
+ version: 2.0.0.alpha2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Luca Guidi
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-01-30 00:00:00.000000000 Z
11
+ date: 2021-05-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: 2.0.alpha
41
+ - !ruby/object:Gem::Dependency
42
+ name: dry-configurable
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0.12'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0.12'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: bundler
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -78,28 +92,28 @@ dependencies:
78
92
  requirements:
79
93
  - - "~>"
80
94
  - !ruby/object:Gem::Version
81
- version: '12'
95
+ version: '13'
82
96
  type: :development
83
97
  prerelease: false
84
98
  version_requirements: !ruby/object:Gem::Requirement
85
99
  requirements:
86
100
  - - "~>"
87
101
  - !ruby/object:Gem::Version
88
- version: '12'
102
+ version: '13'
89
103
  - !ruby/object:Gem::Dependency
90
104
  name: rspec
91
105
  requirement: !ruby/object:Gem::Requirement
92
106
  requirements:
93
107
  - - "~>"
94
108
  - !ruby/object:Gem::Version
95
- version: '3.7'
109
+ version: '3.9'
96
110
  type: :development
97
111
  prerelease: false
98
112
  version_requirements: !ruby/object:Gem::Requirement
99
113
  requirements:
100
114
  - - "~>"
101
115
  - !ruby/object:Gem::Version
102
- version: '3.7'
116
+ version: '3.9'
103
117
  description: Complete, fast and testable actions for Rack
104
118
  email:
105
119
  - me@lucaguidi.com
@@ -111,16 +125,21 @@ files:
111
125
  - LICENSE.md
112
126
  - README.md
113
127
  - hanami-controller.gemspec
114
- - lib/hanami-controller.rb
115
128
  - lib/hanami/action.rb
129
+ - lib/hanami/action/application_action.rb
130
+ - lib/hanami/action/application_configuration.rb
131
+ - lib/hanami/action/application_configuration/cookies.rb
132
+ - lib/hanami/action/application_configuration/sessions.rb
116
133
  - lib/hanami/action/base_params.rb
117
134
  - lib/hanami/action/cache.rb
118
135
  - lib/hanami/action/cache/cache_control.rb
119
136
  - lib/hanami/action/cache/conditional_get.rb
120
137
  - lib/hanami/action/cache/directives.rb
121
138
  - lib/hanami/action/cache/expires.rb
139
+ - lib/hanami/action/configuration.rb
122
140
  - lib/hanami/action/cookie_jar.rb
123
141
  - lib/hanami/action/cookies.rb
142
+ - lib/hanami/action/csrf_protection.rb
124
143
  - lib/hanami/action/flash.rb
125
144
  - lib/hanami/action/glue.rb
126
145
  - lib/hanami/action/halt.rb
@@ -130,9 +149,10 @@ files:
130
149
  - lib/hanami/action/request.rb
131
150
  - lib/hanami/action/response.rb
132
151
  - lib/hanami/action/session.rb
152
+ - lib/hanami/action/standalone_action.rb
133
153
  - lib/hanami/action/validatable.rb
154
+ - lib/hanami/action/view_name_inferrer.rb
134
155
  - lib/hanami/controller.rb
135
- - lib/hanami/controller/configuration.rb
136
156
  - lib/hanami/controller/error.rb
137
157
  - lib/hanami/controller/version.rb
138
158
  - lib/hanami/http/status.rb
@@ -140,7 +160,7 @@ homepage: http://hanamirb.org
140
160
  licenses:
141
161
  - MIT
142
162
  metadata: {}
143
- post_install_message:
163
+ post_install_message:
144
164
  rdoc_options: []
145
165
  require_paths:
146
166
  - lib
@@ -148,15 +168,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
148
168
  requirements:
149
169
  - - ">="
150
170
  - !ruby/object:Gem::Version
151
- version: 2.5.0
171
+ version: 2.6.0
152
172
  required_rubygems_version: !ruby/object:Gem::Requirement
153
173
  requirements:
154
174
  - - ">"
155
175
  - !ruby/object:Gem::Version
156
176
  version: 1.3.1
157
177
  requirements: []
158
- rubygems_version: 3.0.2
159
- signing_key:
178
+ rubygems_version: 3.2.4
179
+ signing_key:
160
180
  specification_version: 4
161
181
  summary: Complete, fast and testable actions for Rack and Hanami
162
182
  test_files: []
@@ -1 +0,0 @@
1
- require 'hanami/controller'
@@ -1,308 +0,0 @@
1
- require 'hanami/utils/class'
2
- require 'hanami/utils/kernel'
3
- require 'hanami/utils/string'
4
-
5
- module Hanami
6
- module Controller
7
- # Configuration for the framework, controllers and actions.
8
- #
9
- # Hanami::Controller has its own global configuration that can be manipulated
10
- # via `Hanami::Controller.configure`.
11
- #
12
- # Every time that `Hanami::Controller` and `Hanami::Action` are included, that
13
- # global configuration is being copied to the recipient. The copy will
14
- # inherit all the settings from the original, but all the subsequent changes
15
- # aren't reflected from the parent to the children, and viceversa.
16
- #
17
- # This architecture allows to have a global configuration that capture the
18
- # most common cases for an application, and let controllers and single
19
- # actions to specify exceptions.
20
- #
21
- # @since 0.2.0
22
- class Configuration
23
- # Default HTTP code for server side errors
24
- #
25
- # @since 0.2.0
26
- # @api private
27
- DEFAULT_ERROR_CODE = 500
28
-
29
- # Default public directory
30
- #
31
- # It serves as base root for file downloads
32
- #
33
- # @since 1.0.0
34
- # @api private
35
- DEFAULT_PUBLIC_DIRECTORY = 'public'.freeze
36
-
37
- # Default Mime type to format mapping
38
- #
39
- # @since 0.2.0
40
- # @api private
41
- DEFAULT_FORMATS = {
42
- 'application/octet-stream' => :all,
43
- '*/*' => :all,
44
- 'text/html' => :html
45
- }.freeze
46
-
47
- # Initialize a configuration instance
48
- #
49
- # @return [Hanami::Controller::Configuration] a new configuration's
50
- # instance
51
- #
52
- # @since 0.2.0
53
- def initialize(&blk)
54
- @handled_exceptions = {}
55
- @formats = DEFAULT_FORMATS.dup
56
- @mime_types = nil
57
- @default_request_format = nil
58
- @default_response_format = nil
59
- @default_charset = nil
60
- @default_headers = {}
61
- @cookies = {}
62
- @root_directory = ::Pathname.new(Dir.pwd).realpath
63
- @public_directory = root_directory.join(DEFAULT_PUBLIC_DIRECTORY).to_s
64
- instance_eval(&blk) unless blk.nil?
65
- freeze
66
- end
67
-
68
- # Specify how to handle an exception with an HTTP status
69
- #
70
- # Raised exceptions will return the configured HTTP status, only if
71
- # `handled_exceptions` is set on `true`.
72
- #
73
- # @param exception [Hash] the exception class must be the key and the HTTP
74
- # status the value
75
- #
76
- # @since 0.2.0
77
- #
78
- # @see Hanami::Controller#configure
79
- # @see Hanami::Action::Throwable
80
- #
81
- # @example
82
- # require 'hanami/controller'
83
- #
84
- # Hanami::Controller.configure do
85
- # handle_exception ArgumentError => 400
86
- # end
87
- def handle_exception(exception)
88
- @handled_exceptions.merge!(exception)
89
- end
90
-
91
- # Register a format
92
- #
93
- # @param hash [Hash] the symbol format must be the key and the mime type
94
- # string must be the value of the hash
95
- #
96
- # @since 0.2.0
97
- #
98
- # @see Hanami::Action::Mime
99
- #
100
- # @example
101
- # require 'hanami/controller'
102
- #
103
- # Hanami::Controller.configure do
104
- # format custom: 'application/custom'
105
- # end
106
- #
107
- # module Articles
108
- # class Index
109
- # include Hanami::Action
110
- #
111
- # def call(params)
112
- # # ...
113
- # end
114
- # end
115
- #
116
- # class Show
117
- # include Hanami::Action
118
- #
119
- # def call(params)
120
- # # ...
121
- # self.format = :custom
122
- # end
123
- # end
124
- # end
125
- #
126
- # action = Articles::Index.new
127
- #
128
- # action.call({ 'HTTP_ACCEPT' => 'text/html' })
129
- # # => Content-Type "text/html"
130
- # action.format # => :html
131
- #
132
- # action.call({ 'HTTP_ACCEPT' => 'application/custom' })
133
- # # => Content-Type "application/custom"
134
- # action.format # => :custom
135
- #
136
- #
137
- #
138
- # action = Articles::Show.new
139
- #
140
- # action.call({ 'HTTP_ACCEPT' => 'text/html' })
141
- # # => Content-Type "application/custom"
142
- # action.format # => :custom
143
- def format(hash)
144
- symbol, mime_type = *Utils::Kernel.Array(hash)
145
-
146
- @formats[Utils::Kernel.String(mime_type)] = Utils::Kernel.Symbol(symbol)
147
- end
148
-
149
- # Return the configured format's MIME types
150
- #
151
- # @since 0.8.0
152
- # @api private
153
- #
154
- # @see Hanami::Controller::Configuration#format
155
- def mime_types
156
- # FIXME: this isn't efficient. speed it up!
157
- ((@formats.keys - DEFAULT_FORMATS.keys) +
158
- Hanami::Action::Mime::TYPES.values).freeze
159
- end
160
-
161
- # Set a format as default fallback for all the requests without a strict
162
- # requirement for the mime type.
163
- #
164
- # The given format must be coercible to a symbol, and be a valid mime type
165
- # alias. If it isn't, at the runtime the framework will raise a
166
- # `Hanami::Controller::UnknownFormatError`.
167
- #
168
- # By default this value is nil.
169
- #
170
- # @since 0.5.0
171
- #
172
- # @see Hanami::Action::Mime
173
- #
174
- # FIXME: new API docs
175
- def default_request_format=(value)
176
- @default_request_format = Utils::Kernel.Symbol(value) unless value.nil?
177
- end
178
-
179
- attr_reader :default_request_format
180
-
181
- # Set a format to be used for all responses regardless of the request type.
182
- #
183
- # The given format must be coercible to a symbol, and be a valid mime type
184
- # alias. If it isn't, at the runtime the framework will raise a
185
- # `Hanami::Controller::UnknownFormatError`.
186
- #
187
- # By default this value is nil.
188
- #
189
- # @since 0.5.0
190
- #
191
- # @see Hanami::Action::Mime
192
- #
193
- # FIXME: new API docs
194
- def default_response_format=(value)
195
- @default_response_format = Utils::Kernel.Symbol(value) unless value.nil?
196
- end
197
-
198
- attr_reader :default_response_format
199
-
200
- # Set a charset as default fallback for all the requests without a strict
201
- # requirement for the charset.
202
- #
203
- # By default this value is nil.
204
- #
205
- # @since 0.3.0
206
- #
207
- # @see Hanami::Action::Mime
208
- #
209
- # FIXME: new API docs
210
- attr_accessor :default_charset
211
-
212
- attr_reader :default_headers
213
-
214
- # Set default headers for all responses
215
- #
216
- # By default this value is an empty hash.
217
- #
218
- # @since 0.4.0
219
- #
220
- # @example Getting the value
221
- # require 'hanami/controller'
222
- #
223
- # Hanami::Controller.configuration.default_headers # => {}
224
- #
225
- # @example Setting the value
226
- # require 'hanami/controller'
227
- #
228
- # Hanami::Controller::Configuration.new do |config|
229
- # config.default_headers = {
230
- # 'X-Frame-Options' => 'DENY'
231
- # }
232
- # end
233
- def default_headers=(headers)
234
- @default_headers.merge!(
235
- headers.reject { |_, v| v.nil? }
236
- )
237
- end
238
-
239
- attr_reader :cookies
240
-
241
- # Set default cookies options for all responses
242
- #
243
- # By default this value is an empty hash.
244
- #
245
- # @since 0.4.0
246
- #
247
- # @example Getting the value
248
- # require 'hanami/controller'
249
- #
250
- # Hanami::Controller.configuration.cookies # => {}
251
- #
252
- # @example Setting the value
253
- # require 'hanami/controller'
254
- #
255
- # Hanami::Controller::Configuration.new do |config|
256
- # config.cookies = {
257
- # domain: 'hanamirb.org',
258
- # path: '/controller',
259
- # secure: true,
260
- # httponly: true
261
- # }
262
- # end
263
- def cookies=(options)
264
- @cookies.merge!(
265
- options.reject { |_, v| v.nil? }
266
- )
267
- end
268
-
269
- # Returns a format for the given mime type
270
- #
271
- # @param mime_type [#to_s,#to_str] A mime type
272
- #
273
- # @return [Symbol,nil] the corresponding format, if present
274
- #
275
- # @see Hanami::Controller::Configuration#format
276
- #
277
- # @since 0.2.0
278
- # @api private
279
- def format_for(mime_type)
280
- @formats[mime_type]
281
- end
282
-
283
- # Returns a mime type for the given format
284
- #
285
- # @param format [#to_sym] a format
286
- #
287
- # @return [String,nil] the corresponding mime type, if present
288
- #
289
- # @since 0.2.0
290
- # @api private
291
- def mime_type_for(format)
292
- @formats.key(format)
293
- end
294
-
295
- # @api private
296
- # @since 1.0.0
297
- attr_reader :root_directory
298
-
299
- # FIXME: API docs
300
- def public_directory=(value)
301
- @public_directory = root_directory.join(value).to_s
302
- end
303
-
304
- attr_reader :public_directory
305
- attr_reader :handled_exceptions
306
- end
307
- end
308
- end