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.
@@ -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