hanami-controller 2.0.0.beta1 → 2.0.0.beta4
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 +19 -0
- data/README.md +1 -1
- data/lib/hanami/action/config.rb +262 -0
- data/lib/hanami/action/constants.rb +6 -12
- data/lib/hanami/action/csrf_protection.rb +1 -0
- data/lib/hanami/action/error.rb +41 -0
- data/lib/hanami/action/mime.rb +65 -31
- data/lib/hanami/action/params.rb +5 -12
- data/lib/hanami/action/request.rb +21 -2
- data/lib/hanami/action/response.rb +20 -22
- data/lib/hanami/action/session.rb +4 -0
- data/lib/hanami/action.rb +106 -103
- data/lib/hanami/controller/version.rb +1 -1
- metadata +5 -4
- data/lib/hanami/action/configuration.rb +0 -436
@@ -1,436 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "dry/configurable"
|
4
|
-
require "hanami/utils/kernel"
|
5
|
-
require "pathname"
|
6
|
-
require_relative "mime"
|
7
|
-
|
8
|
-
module Hanami
|
9
|
-
class Action
|
10
|
-
class Configuration
|
11
|
-
include Dry::Configurable
|
12
|
-
|
13
|
-
# Initialize the Configuration
|
14
|
-
#
|
15
|
-
# @yield [config] the configuration object
|
16
|
-
#
|
17
|
-
# @return [Configuration]
|
18
|
-
#
|
19
|
-
# @since 2.0.0
|
20
|
-
# @api private
|
21
|
-
def initialize(*)
|
22
|
-
super
|
23
|
-
yield self if block_given?
|
24
|
-
end
|
25
|
-
|
26
|
-
# Returns the list of available settings
|
27
|
-
#
|
28
|
-
# @return [Set]
|
29
|
-
#
|
30
|
-
# @since 2.0.0
|
31
|
-
# @api private
|
32
|
-
def settings
|
33
|
-
self.class.settings
|
34
|
-
end
|
35
|
-
|
36
|
-
# @!method handled_exceptions=(exceptions)
|
37
|
-
#
|
38
|
-
# Specifies how to handle exceptions with an HTTP status
|
39
|
-
#
|
40
|
-
# Raised exceptions will return the corresponding HTTP status
|
41
|
-
#
|
42
|
-
# @param exceptions [Hash{Exception=>Integer}] exception classes as
|
43
|
-
# keys and HTTP statuses as values
|
44
|
-
#
|
45
|
-
# @return [void]
|
46
|
-
#
|
47
|
-
# @since 0.2.0
|
48
|
-
#
|
49
|
-
# @example
|
50
|
-
# configuration.handled_exceptions = {ArgumentError => 400}
|
51
|
-
#
|
52
|
-
# @!method handled_exceptions
|
53
|
-
#
|
54
|
-
# Returns the configured handled exceptions
|
55
|
-
#
|
56
|
-
# @return [Hash{Exception=>Integer}]
|
57
|
-
#
|
58
|
-
# @see handled_exceptions=
|
59
|
-
#
|
60
|
-
# @since 0.2.0
|
61
|
-
setting :handled_exceptions, default: {}
|
62
|
-
|
63
|
-
# Specifies how to handle exceptions with an HTTP status
|
64
|
-
#
|
65
|
-
# Raised exceptions will return the corresponding HTTP status
|
66
|
-
#
|
67
|
-
# The specified exceptions will be merged with any previously configured
|
68
|
-
# exceptions
|
69
|
-
#
|
70
|
-
# @param exceptions [Hash{Exception=>Integer}] exception classes as keys
|
71
|
-
# and HTTP statuses as values
|
72
|
-
#
|
73
|
-
# @return [void]
|
74
|
-
#
|
75
|
-
# @since 0.2.0
|
76
|
-
#
|
77
|
-
# @see handled_exceptions=
|
78
|
-
#
|
79
|
-
# @example
|
80
|
-
# configuration.handle_exceptions(ArgumentError => 400}
|
81
|
-
def handle_exception(exceptions)
|
82
|
-
self.handled_exceptions = handled_exceptions
|
83
|
-
.merge(exceptions)
|
84
|
-
.sort { |(ex1, _), (ex2, _)| ex1.ancestors.include?(ex2) ? -1 : 1 }
|
85
|
-
.to_h
|
86
|
-
end
|
87
|
-
|
88
|
-
# Default MIME type to format mapping
|
89
|
-
#
|
90
|
-
# @since 0.2.0
|
91
|
-
# @api private
|
92
|
-
DEFAULT_FORMATS = {
|
93
|
-
"application/octet-stream" => :all,
|
94
|
-
"*/*" => :all,
|
95
|
-
"text/html" => :html
|
96
|
-
}.freeze
|
97
|
-
|
98
|
-
# @!method formats=(formats)
|
99
|
-
#
|
100
|
-
# Specifies the MIME type to format mapping
|
101
|
-
#
|
102
|
-
# @param formats [Hash{String=>Symbol}] MIME type strings as keys and
|
103
|
-
# format symbols as values
|
104
|
-
#
|
105
|
-
# @return [void]
|
106
|
-
#
|
107
|
-
# @since 0.2.0
|
108
|
-
#
|
109
|
-
# @see format
|
110
|
-
# @see Hanami::Action::Mime
|
111
|
-
#
|
112
|
-
# @example
|
113
|
-
# configuration.formats = {"text/html" => :html}
|
114
|
-
#
|
115
|
-
# @!method formats
|
116
|
-
#
|
117
|
-
# Returns the configured MIME type to format mapping
|
118
|
-
#
|
119
|
-
# @return [Symbol,nil] the corresponding format, if present
|
120
|
-
#
|
121
|
-
# @see format
|
122
|
-
# @see formats=
|
123
|
-
#
|
124
|
-
# @since 0.2.0
|
125
|
-
setting :formats, default: DEFAULT_FORMATS.dup
|
126
|
-
|
127
|
-
# Registers a MIME type to format mapping
|
128
|
-
#
|
129
|
-
# @param hash [Hash{Symbol=>String}] format symbols as keys and the MIME
|
130
|
-
# type strings must as values
|
131
|
-
#
|
132
|
-
# @return [void]
|
133
|
-
#
|
134
|
-
# @since 0.2.0
|
135
|
-
#
|
136
|
-
# @see Hanami::Action::Mime
|
137
|
-
#
|
138
|
-
# @example configuration.format html: "text/html"
|
139
|
-
def format(hash)
|
140
|
-
symbol, mime_type = *Utils::Kernel.Array(hash)
|
141
|
-
formats[Utils::Kernel.String(mime_type)] = Utils::Kernel.Symbol(symbol)
|
142
|
-
end
|
143
|
-
|
144
|
-
# Returns the configured format for the given MIME type
|
145
|
-
#
|
146
|
-
# @param mime_type [#to_s,#to_str] A mime type
|
147
|
-
#
|
148
|
-
# @return [Symbol,nil] the corresponding format, nil if not found
|
149
|
-
#
|
150
|
-
# @see format
|
151
|
-
#
|
152
|
-
# @since 0.2.0
|
153
|
-
# @api private
|
154
|
-
def format_for(mime_type)
|
155
|
-
formats[mime_type]
|
156
|
-
end
|
157
|
-
|
158
|
-
# Returns the configured format's MIME types
|
159
|
-
#
|
160
|
-
# @return [Array<String>] the format's MIME types
|
161
|
-
#
|
162
|
-
# @see formats=
|
163
|
-
# @see format
|
164
|
-
#
|
165
|
-
# @since 0.8.0
|
166
|
-
#
|
167
|
-
# @api private
|
168
|
-
def mime_types
|
169
|
-
# FIXME: this isn't efficient. speed it up!
|
170
|
-
((formats.keys - DEFAULT_FORMATS.keys) +
|
171
|
-
Hanami::Action::Mime::TYPES.values).freeze
|
172
|
-
end
|
173
|
-
|
174
|
-
# Returns a MIME type for the given format
|
175
|
-
#
|
176
|
-
# @param format [#to_sym] a format
|
177
|
-
#
|
178
|
-
# @return [String,nil] the corresponding MIME type, if present
|
179
|
-
#
|
180
|
-
# @since 0.2.0
|
181
|
-
# @api private
|
182
|
-
def mime_type_for(format)
|
183
|
-
formats.key(format)
|
184
|
-
end
|
185
|
-
|
186
|
-
# @!method default_request_format=(format)
|
187
|
-
#
|
188
|
-
# Sets a format as default fallback for all the requests without a strict
|
189
|
-
# requirement for the MIME type.
|
190
|
-
#
|
191
|
-
# The given format must be coercible to a symbol, and be a valid MIME
|
192
|
-
# type alias. If it isn't, at runtime the framework will raise an
|
193
|
-
# `Hanami::Controller::UnknownFormatError`.
|
194
|
-
#
|
195
|
-
# By default, this value is nil.
|
196
|
-
#
|
197
|
-
# @param format [Symbol]
|
198
|
-
#
|
199
|
-
# @return [void]
|
200
|
-
#
|
201
|
-
# @since 0.5.0
|
202
|
-
#
|
203
|
-
# @see Hanami::Action::Mime
|
204
|
-
#
|
205
|
-
# @!method default_request_format
|
206
|
-
#
|
207
|
-
# Returns the configured default request format
|
208
|
-
#
|
209
|
-
# @return [Symbol] format
|
210
|
-
#
|
211
|
-
# @see default_request_format=
|
212
|
-
#
|
213
|
-
# @since 0.5.0
|
214
|
-
setting :default_request_format, constructor: -> (format) {
|
215
|
-
Utils::Kernel.Symbol(format) unless format.nil?
|
216
|
-
}
|
217
|
-
|
218
|
-
# @!method default_response_format=(format)
|
219
|
-
#
|
220
|
-
# Sets a format to be used for all responses regardless of the request
|
221
|
-
# type.
|
222
|
-
#
|
223
|
-
# The given format must be coercible to a symbol, and be a valid MIME
|
224
|
-
# type alias. If it isn't, at the runtime the framework will raise an
|
225
|
-
# `Hanami::Controller::UnknownFormatError`.
|
226
|
-
#
|
227
|
-
# By default, this value is nil.
|
228
|
-
#
|
229
|
-
# @param format [Symbol]
|
230
|
-
#
|
231
|
-
# @return [void]
|
232
|
-
#
|
233
|
-
# @since 0.5.0
|
234
|
-
#
|
235
|
-
# @see Hanami::Action::Mime
|
236
|
-
#
|
237
|
-
# @!method default_response_format
|
238
|
-
#
|
239
|
-
# Returns the configured default response format
|
240
|
-
#
|
241
|
-
# @return [Symbol] format
|
242
|
-
#
|
243
|
-
# @see default_request_format=
|
244
|
-
#
|
245
|
-
# @since 0.5.0
|
246
|
-
setting :default_response_format, constructor: -> (format) {
|
247
|
-
Utils::Kernel.Symbol(format) unless format.nil?
|
248
|
-
}
|
249
|
-
|
250
|
-
# @!method default_charset=(charset)
|
251
|
-
#
|
252
|
-
# Sets a charset (character set) as default fallback for all the requests
|
253
|
-
# without a strict requirement for the charset.
|
254
|
-
#
|
255
|
-
# By default, this value is nil.
|
256
|
-
#
|
257
|
-
# @param charset [String]
|
258
|
-
#
|
259
|
-
# @return [void]
|
260
|
-
#
|
261
|
-
# @since 0.3.0
|
262
|
-
#
|
263
|
-
# @see Hanami::Action::Mime
|
264
|
-
#
|
265
|
-
# @!method default_charset
|
266
|
-
#
|
267
|
-
# Returns the configured default charset.
|
268
|
-
#
|
269
|
-
# @return [String,nil] the charset, if present
|
270
|
-
#
|
271
|
-
# @see default_charset=
|
272
|
-
#
|
273
|
-
# @since 0.3.0
|
274
|
-
setting :default_charset
|
275
|
-
|
276
|
-
# @!method default_headers=(headers)
|
277
|
-
#
|
278
|
-
# Sets default headers for all responses.
|
279
|
-
#
|
280
|
-
# By default, this is an empty hash.
|
281
|
-
#
|
282
|
-
# @param headers [Hash{String=>String}] the headers
|
283
|
-
#
|
284
|
-
# @return [void]
|
285
|
-
#
|
286
|
-
# @since 0.4.0
|
287
|
-
#
|
288
|
-
# @see default_headers
|
289
|
-
#
|
290
|
-
# @example
|
291
|
-
# configuration.default_headers = {"X-Frame-Options" => "DENY"}
|
292
|
-
#
|
293
|
-
# @!method default_headers
|
294
|
-
#
|
295
|
-
# Returns the configured headers
|
296
|
-
#
|
297
|
-
# @return [Hash{String=>String}] the headers
|
298
|
-
#
|
299
|
-
# @since 0.4.0
|
300
|
-
#
|
301
|
-
# @see default_headers=
|
302
|
-
setting :default_headers, default: {}, constructor: -> (headers) { headers.compact }
|
303
|
-
|
304
|
-
# @!method cookies=(cookie_options)
|
305
|
-
#
|
306
|
-
# Sets default cookie options for all responses.
|
307
|
-
#
|
308
|
-
# By default this, is an empty hash.
|
309
|
-
#
|
310
|
-
# @param cookie_options [Hash{Symbol=>String}] the cookie options
|
311
|
-
#
|
312
|
-
# @return [void]
|
313
|
-
#
|
314
|
-
# @since 0.4.0
|
315
|
-
#
|
316
|
-
# @example
|
317
|
-
# configuration.cookies = {
|
318
|
-
# domain: "hanamirb.org",
|
319
|
-
# path: "/controller",
|
320
|
-
# secure: true,
|
321
|
-
# httponly: true
|
322
|
-
# }
|
323
|
-
#
|
324
|
-
# @!method cookies
|
325
|
-
#
|
326
|
-
# Returns the configured cookie options
|
327
|
-
#
|
328
|
-
# @return [Hash{Symbol=>String}]
|
329
|
-
#
|
330
|
-
# @since 0.4.0
|
331
|
-
#
|
332
|
-
# @see cookies=
|
333
|
-
setting :cookies, default: {}, constructor: -> (cookie_options) {
|
334
|
-
# Call `to_h` here to permit `ApplicationConfiguration::Cookies` object to be
|
335
|
-
# provided when application actions are configured
|
336
|
-
cookie_options.to_h.compact
|
337
|
-
}
|
338
|
-
|
339
|
-
# @!method root_directory=(dir)
|
340
|
-
#
|
341
|
-
# Sets the the for the public directory, which is used for file downloads.
|
342
|
-
# This must be an existent directory.
|
343
|
-
#
|
344
|
-
# Defaults to the current working directory.
|
345
|
-
#
|
346
|
-
# @param dir [String] the directory path
|
347
|
-
#
|
348
|
-
# @return [void]
|
349
|
-
#
|
350
|
-
# @since 1.0.0
|
351
|
-
#
|
352
|
-
# @api private
|
353
|
-
#
|
354
|
-
# @!method root_directory
|
355
|
-
#
|
356
|
-
# Returns the configured root directory
|
357
|
-
#
|
358
|
-
# @return [String] the directory path
|
359
|
-
#
|
360
|
-
# @see root_directory=
|
361
|
-
#
|
362
|
-
# @since 1.0.0
|
363
|
-
#
|
364
|
-
# @api private
|
365
|
-
setting :root_directory, constructor: -> (dir) {
|
366
|
-
dir ||= Dir.pwd
|
367
|
-
|
368
|
-
Pathname(dir).realpath
|
369
|
-
}
|
370
|
-
|
371
|
-
# Default public directory
|
372
|
-
#
|
373
|
-
# This serves as the root directory for file downloads
|
374
|
-
#
|
375
|
-
# @since 1.0.0
|
376
|
-
#
|
377
|
-
# @api private
|
378
|
-
DEFAULT_PUBLIC_DIRECTORY = "public"
|
379
|
-
|
380
|
-
# @!method public_directory=(directory)
|
381
|
-
#
|
382
|
-
# Sets the path to public directory. This directory is used for file downloads.
|
383
|
-
#
|
384
|
-
# This given directory will be appended onto the root directory.
|
385
|
-
#
|
386
|
-
# By default, the public directory is "public".
|
387
|
-
#
|
388
|
-
# @param directory [String] the public directory path
|
389
|
-
#
|
390
|
-
# @return [void]
|
391
|
-
#
|
392
|
-
# @since 2.0.0
|
393
|
-
#
|
394
|
-
# @see root_directory
|
395
|
-
# @see public_directory
|
396
|
-
setting :public_directory, default: DEFAULT_PUBLIC_DIRECTORY
|
397
|
-
|
398
|
-
# Returns the configured public directory, appended onto the root directory.
|
399
|
-
#
|
400
|
-
# @return [String] the fill directory path
|
401
|
-
#
|
402
|
-
# @example
|
403
|
-
# configuration.public_directory = "public"
|
404
|
-
#
|
405
|
-
# configuration.public_directory
|
406
|
-
# # => "/path/to/root/public"
|
407
|
-
#
|
408
|
-
# @since 2.0.0
|
409
|
-
#
|
410
|
-
# @see public_directory=
|
411
|
-
# @see root_directory=
|
412
|
-
def public_directory
|
413
|
-
# This must be a string, for Rack compatibility
|
414
|
-
root_directory.join(super).to_s
|
415
|
-
end
|
416
|
-
|
417
|
-
private
|
418
|
-
|
419
|
-
# @since 2.0.0
|
420
|
-
# @api private
|
421
|
-
def method_missing(name, *args, &block)
|
422
|
-
if config.respond_to?(name)
|
423
|
-
config.public_send(name, *args, &block)
|
424
|
-
else
|
425
|
-
super
|
426
|
-
end
|
427
|
-
end
|
428
|
-
|
429
|
-
# @since 2.0.0
|
430
|
-
# @api private
|
431
|
-
def respond_to_missing?(name, _incude_all = false)
|
432
|
-
config.respond_to?(name) || super
|
433
|
-
end
|
434
|
-
end
|
435
|
-
end
|
436
|
-
end
|