hanami 2.0.0.beta4 → 2.0.0.rc1
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/hanami.gemspec +8 -7
- data/lib/hanami/app.rb +47 -36
- data/lib/hanami/assets/app_config.rb +7 -15
- data/lib/hanami/assets/config.rb +5 -6
- data/lib/hanami/config/actions/content_security_policy.rb +1 -1
- data/lib/hanami/config/actions/cookies.rb +27 -0
- data/lib/hanami/config/actions/sessions.rb +42 -5
- data/lib/hanami/config/actions.rb +81 -17
- data/lib/hanami/config/logger.rb +112 -23
- data/lib/hanami/config/router.rb +0 -1
- data/lib/hanami/config/views.rb +6 -10
- data/lib/hanami/config.rb +235 -73
- data/lib/hanami/constants.rb +4 -0
- data/lib/hanami/errors.rb +17 -0
- data/lib/hanami/extensions/action/slice_configured_action.rb +9 -5
- data/lib/hanami/extensions/action.rb +59 -7
- data/lib/hanami/extensions/view/context.rb +3 -4
- data/lib/hanami/extensions/view/slice_configured_view.rb +4 -4
- data/lib/hanami/extensions/view.rb +7 -5
- data/lib/hanami/providers/inflector.rb +6 -0
- data/lib/hanami/providers/logger.rb +8 -0
- data/lib/hanami/providers/rack.rb +12 -0
- data/lib/hanami/providers/routes.rb +14 -4
- data/lib/hanami/routes.rb +36 -1
- data/lib/hanami/settings/env_store.rb +1 -1
- data/lib/hanami/settings.rb +102 -36
- data/lib/hanami/slice/router.rb +38 -16
- data/lib/hanami/slice/routing/middleware/stack.rb +66 -42
- data/lib/hanami/slice/routing/resolver.rb +10 -17
- data/lib/hanami/slice/view_name_inferrer.rb +1 -1
- data/lib/hanami/slice.rb +553 -14
- data/lib/hanami/slice_registrar.rb +20 -15
- data/lib/hanami/version.rb +2 -3
- data/lib/hanami/web/rack_logger.rb +14 -4
- data/lib/hanami.rb +122 -23
- data/spec/integration/action/csrf_protection_spec.rb +1 -1
- data/spec/integration/container/application_routes_helper_spec.rb +3 -1
- data/spec/integration/container/provider_lifecycle_spec.rb +61 -0
- data/spec/integration/container/standard_providers/rack_provider_spec.rb +44 -0
- data/spec/integration/container/{standard_bootable_components_spec.rb → standard_providers_spec.rb} +3 -3
- data/spec/integration/rack_app/body_parser_spec.rb +3 -0
- data/spec/integration/rack_app/middleware_spec.rb +427 -3
- data/spec/integration/rack_app/non_booted_rack_app_spec.rb +2 -1
- data/spec/integration/rack_app/rack_app_spec.rb +39 -11
- data/spec/integration/setup_spec.rb +4 -4
- data/spec/integration/slices/external_slice_spec.rb +2 -1
- data/spec/integration/slices/slice_configuration_spec.rb +3 -1
- data/spec/integration/slices/slice_loading_spec.rb +4 -4
- data/spec/integration/slices/slice_routing_spec.rb +4 -3
- data/spec/integration/slices_spec.rb +100 -0
- data/spec/isolation/hanami/boot/success_spec.rb +1 -1
- data/spec/support/app_integration.rb +2 -10
- data/spec/unit/hanami/config/actions/content_security_policy_spec.rb +7 -7
- data/spec/unit/hanami/config/actions/default_values_spec.rb +1 -1
- data/spec/unit/hanami/config/actions/sessions_spec.rb +1 -3
- data/spec/unit/hanami/config/actions_spec.rb +1 -12
- data/spec/unit/hanami/config/logger_spec.rb +38 -55
- data/spec/unit/hanami/config/router_spec.rb +1 -1
- data/spec/unit/hanami/config/views_spec.rb +3 -13
- data/spec/unit/hanami/settings_spec.rb +1 -1
- data/spec/unit/hanami/slice_configurable_spec.rb +5 -5
- data/spec/unit/hanami/slice_spec.rb +32 -0
- data/spec/unit/hanami/version_spec.rb +1 -1
- data/spec/unit/hanami/web/rack_logger_spec.rb +13 -2
- metadata +54 -45
- data/lib/hanami/config/sessions.rb +0 -50
- data/spec/unit/hanami/config_spec.rb +0 -43
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6a1a430f511f0bda44248e88d4fb2c87d10dc3d8fbabf092b895ff2a3bbb78db
|
4
|
+
data.tar.gz: 75c6e767584d34103505eb3637fc0fb72dde6118b35fa5f4a76a186681031e7a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 306e3261fb72d114ddcb9128de3a3c9a499bff57f1b2c51fd3cee54e644248c3bd981f54b626d7e5549e1fa9c467d86156a7c2c3e4c14c869501e698d07f6423
|
7
|
+
data.tar.gz: a59bf43bf07700e282abe6e83919fd53a5e277b7efa5706b743a25537006eef76b49409bedf0af49cae8122bd39d5c396f705f1e148a01367565e1accb46d9a6
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,25 @@
|
|
2
2
|
|
3
3
|
The web, with simplicity.
|
4
4
|
|
5
|
+
## v2.0.0.rc1 - 2022-11-08
|
6
|
+
|
7
|
+
### Added
|
8
|
+
|
9
|
+
- [Piotr Solnica] Use Zeitwerk to auto-load Hanami
|
10
|
+
- [Tim Riley] Introduce `Hanami::Slice.stop` to properly shutdown all the application slices
|
11
|
+
|
12
|
+
### Fixed
|
13
|
+
|
14
|
+
- [Luca Guidi] Ensure to properly mount Rack middleware in routing scope and slice
|
15
|
+
- [Tim Riley] Simplify and clarify usage of `Hanami::Config#enviroment`
|
16
|
+
- [Tim Riley] Improve error message for missing action class
|
17
|
+
- [Tim Riley] Expect nested slices to use parent’s namespace
|
18
|
+
|
19
|
+
### Changed
|
20
|
+
|
21
|
+
- [Piotr Solnica] Replace `Hanami::Logger` with `Dry::Logger`
|
22
|
+
- [Tim Riley] Remove duplicated configuration `config.session` and keep `config.actions.sessions`
|
23
|
+
|
5
24
|
## v2.0.0.beta4 - 2022-10-24
|
6
25
|
|
7
26
|
### Added
|
data/hanami.gemspec
CHANGED
@@ -32,13 +32,14 @@ Gem::Specification.new do |spec|
|
|
32
32
|
spec.metadata["allowed_push_host"] = "https://rubygems.org"
|
33
33
|
|
34
34
|
spec.add_dependency "bundler", ">= 1.16", "< 3"
|
35
|
-
spec.add_dependency "dry-configurable", "~> 0
|
36
|
-
spec.add_dependency "dry-core", "~> 0
|
37
|
-
spec.add_dependency "dry-inflector", "~> 0
|
38
|
-
spec.add_dependency "dry-
|
39
|
-
spec.add_dependency "dry-
|
40
|
-
spec.add_dependency "
|
41
|
-
spec.add_dependency "hanami-
|
35
|
+
spec.add_dependency "dry-configurable", "~> 1.0", "< 2"
|
36
|
+
spec.add_dependency "dry-core", "~> 1.0", "< 2"
|
37
|
+
spec.add_dependency "dry-inflector", "~> 1.0", "< 2"
|
38
|
+
spec.add_dependency "dry-monitor", "~> 1.0", "< 2"
|
39
|
+
spec.add_dependency "dry-system", "~> 1.0.rc"
|
40
|
+
spec.add_dependency "dry-logger", "~> 1.0.rc"
|
41
|
+
spec.add_dependency "hanami-cli", "~> 2.0.rc"
|
42
|
+
spec.add_dependency "hanami-utils", "~> 2.0.rc"
|
42
43
|
spec.add_dependency "zeitwerk", "~> 2.6"
|
43
44
|
|
44
45
|
spec.add_development_dependency "rspec", "~> 3.8"
|
data/lib/hanami/app.rb
CHANGED
@@ -1,17 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative "config"
|
4
3
|
require_relative "constants"
|
5
|
-
require_relative "slice"
|
6
|
-
require_relative "slice_name"
|
7
4
|
|
8
5
|
module Hanami
|
9
|
-
# The Hanami app is a singular slice tasked with managing the core components of
|
10
|
-
#
|
6
|
+
# The Hanami app is a singular slice tasked with managing the core components of the app and
|
7
|
+
# coordinating overall app boot.
|
11
8
|
#
|
12
|
-
# For smaller apps, the app may be the only slice present, whereas larger apps
|
13
|
-
#
|
14
|
-
# of shared components only.
|
9
|
+
# For smaller apps, the app may be the only slice present, whereas larger apps may consist of many
|
10
|
+
# slices, with the app reserved for holding a small number of shared components only.
|
15
11
|
#
|
16
12
|
# @see Slice
|
17
13
|
#
|
@@ -20,6 +16,8 @@ module Hanami
|
|
20
16
|
class App < Slice
|
21
17
|
@_mutex = Mutex.new
|
22
18
|
|
19
|
+
# @api private
|
20
|
+
# @since 2.0.0
|
23
21
|
def self.inherited(subclass)
|
24
22
|
super
|
25
23
|
|
@@ -31,9 +29,9 @@ module Hanami
|
|
31
29
|
subclass.class_eval do
|
32
30
|
@config = Hanami::Config.new(app_name: slice_name, env: Hanami.env)
|
33
31
|
|
34
|
-
# Prepare the load path (based on the default root of `Dir.pwd`) as early as
|
35
|
-
#
|
36
|
-
#
|
32
|
+
# Prepare the load path (based on the default root of `Dir.pwd`) as early as possible, so
|
33
|
+
# you can make a `require` inside the body of an `App` subclass, which may be useful for
|
34
|
+
# certain kinds of app configuration.
|
37
35
|
prepare_load_path
|
38
36
|
|
39
37
|
load_dotenv
|
@@ -43,29 +41,41 @@ module Hanami
|
|
43
41
|
|
44
42
|
# App class interface
|
45
43
|
module ClassMethods
|
44
|
+
# Returns the app's config.
|
45
|
+
#
|
46
|
+
# @return [Hanami::Config]
|
47
|
+
#
|
48
|
+
# @api public
|
49
|
+
# @since 2.0.0
|
46
50
|
attr_reader :config
|
47
51
|
|
52
|
+
# Returns the app's {SliceName}.
|
53
|
+
#
|
54
|
+
# @return [Hanami::SliceName]
|
55
|
+
#
|
56
|
+
# @see Slice::ClassMethods#slice_name
|
57
|
+
#
|
58
|
+
# @api public
|
59
|
+
# @since 2.0.0
|
48
60
|
def app_name
|
49
61
|
slice_name
|
50
62
|
end
|
51
63
|
|
52
|
-
# Prepares the $LOAD_PATH based on the app's configured root, prepending the `lib/`
|
53
|
-
#
|
54
|
-
# nothing.
|
64
|
+
# Prepares the $LOAD_PATH based on the app's configured root, prepending the `lib/` directory
|
65
|
+
# if it exists. If the lib directory is already added, this will do nothing.
|
55
66
|
#
|
56
|
-
# In ordinary circumstances, you should never have to call this method: this method
|
57
|
-
#
|
58
|
-
#
|
59
|
-
#
|
60
|
-
# certain app configuration steps.
|
67
|
+
# In ordinary circumstances, you should never have to call this method: this method is called
|
68
|
+
# immediately upon subclassing {Hanami::App}, as a convenicence to put lib/ (under the default
|
69
|
+
# root of `Dir.pwd`) on the load path automatically. This is helpful if you need to require
|
70
|
+
# files inside the subclass body for performing certain app configuration steps.
|
61
71
|
#
|
62
|
-
# If you change your app's `config.root` and you need to require files from its
|
63
|
-
#
|
64
|
-
#
|
72
|
+
# If you change your app's `config.root` and you need to require files from its `lib/`
|
73
|
+
# directory within your {App} subclass body, you should call {.prepare_load_path} explicitly
|
74
|
+
# after setting the new root.
|
65
75
|
#
|
66
|
-
# Otherwise, this method is called again as part of the app {.prepare} step, so if
|
67
|
-
#
|
68
|
-
#
|
76
|
+
# Otherwise, this method is called again as part of the app {.prepare} step, so if you've
|
77
|
+
# changed your app's root and do _not_ need to require files within your {App} subclass body,
|
78
|
+
# then you don't need to call this method.
|
69
79
|
#
|
70
80
|
# @example
|
71
81
|
# module MyApp
|
@@ -124,12 +134,12 @@ module Hanami
|
|
124
134
|
# Make app-wide notifications available as early as possible
|
125
135
|
container.use(:notifications)
|
126
136
|
|
127
|
-
# Ensure all basic slice preparation is complete before we make adjustments below
|
128
|
-
#
|
137
|
+
# Ensure all basic slice preparation is complete before we make adjustments below (which
|
138
|
+
# rely on the basic prepare steps having already run)
|
129
139
|
super
|
130
140
|
|
131
|
-
# Run specific prepare steps for the app slice. Note also that some
|
132
|
-
#
|
141
|
+
# Run specific prepare steps for the app slice. Note also that some standard steps have been
|
142
|
+
# skipped via the empty method overrides below.
|
133
143
|
prepare_app_component_dirs
|
134
144
|
prepare_app_providers
|
135
145
|
end
|
@@ -150,8 +160,8 @@ module Hanami
|
|
150
160
|
end
|
151
161
|
end
|
152
162
|
|
153
|
-
# When auto-registering components in app/, ignore files in `app/lib/` (these will
|
154
|
-
#
|
163
|
+
# When auto-registering components in app/, ignore files in `app/lib/` (these will be
|
164
|
+
# auto-registered as above), as well as the configured no_auto_register_paths
|
155
165
|
no_auto_register_paths = ([LIB_DIR] + config.no_auto_register_paths)
|
156
166
|
.map { |path|
|
157
167
|
path.end_with?(File::SEPARATOR) ? path : "#{path}#{File::SEPARATOR}"
|
@@ -178,14 +188,15 @@ module Hanami
|
|
178
188
|
register_provider(:logger, source: Hanami::Providers::Logger)
|
179
189
|
end
|
180
190
|
|
181
|
-
|
182
|
-
|
191
|
+
if Hanami.bundled?("rack")
|
192
|
+
require_relative "providers/rack"
|
193
|
+
register_provider(:rack, source: Hanami::Providers::Rack, namespace: true)
|
194
|
+
end
|
183
195
|
end
|
184
196
|
|
185
197
|
def prepare_autoloader
|
186
|
-
# Component dirs are automatically pushed to the autoloader by dry-system's
|
187
|
-
#
|
188
|
-
# as component dirs.
|
198
|
+
# Component dirs are automatically pushed to the autoloader by dry-system's zeitwerk plugin.
|
199
|
+
# This method adds other dirs that are not otherwise configured as component dirs.
|
189
200
|
|
190
201
|
# Autoload classes from `lib/[app_namespace]/`
|
191
202
|
if root.join(LIB_DIR, app_name.name).directory?
|
@@ -1,28 +1,27 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "dry/configurable"
|
4
|
-
require_relative "config"
|
5
4
|
|
6
5
|
module Hanami
|
6
|
+
# @api private
|
7
7
|
module Assets
|
8
|
-
#
|
9
|
-
#
|
8
|
+
# App config for assets.
|
9
|
+
#
|
10
|
+
# This is NOT RELEASED as of 2.0.0.
|
11
|
+
#
|
12
|
+
# @api private
|
10
13
|
class AppConfig
|
11
14
|
include Dry::Configurable
|
12
15
|
|
13
|
-
# @since 2.0.0
|
14
|
-
# @api private
|
15
16
|
attr_reader :base_config
|
16
17
|
protected :base_config
|
17
18
|
|
18
19
|
setting :server_url, default: "http://localhost:8080"
|
19
20
|
|
20
|
-
# @since 2.0.0
|
21
|
-
# @api private
|
22
21
|
def initialize(*)
|
23
22
|
super
|
24
23
|
|
25
|
-
@base_config = Config.new
|
24
|
+
@base_config = Assets::Config.new
|
26
25
|
end
|
27
26
|
|
28
27
|
def initialize_copy(source)
|
@@ -30,8 +29,6 @@ module Hanami
|
|
30
29
|
@base_config = source.base_config.dup
|
31
30
|
end
|
32
31
|
|
33
|
-
# @since 2.0.0
|
34
|
-
# @api private
|
35
32
|
def finalize!
|
36
33
|
end
|
37
34
|
|
@@ -39,7 +36,6 @@ module Hanami
|
|
39
36
|
#
|
40
37
|
# @return [Set]
|
41
38
|
#
|
42
|
-
# @since 2.0.0
|
43
39
|
# @api private
|
44
40
|
def settings
|
45
41
|
base_config.settings + self.class.settings
|
@@ -47,8 +43,6 @@ module Hanami
|
|
47
43
|
|
48
44
|
private
|
49
45
|
|
50
|
-
# @since 2.0.0
|
51
|
-
# @api private
|
52
46
|
def method_missing(name, *args, &block)
|
53
47
|
if config.respond_to?(name)
|
54
48
|
config.public_send(name, *args, &block)
|
@@ -59,8 +53,6 @@ module Hanami
|
|
59
53
|
end
|
60
54
|
end
|
61
55
|
|
62
|
-
# @since 2.0.0
|
63
|
-
# @api private
|
64
56
|
def respond_to_missing?(name, _incude_all = false)
|
65
57
|
config.respond_to?(name) || base_config.respond_to?(name) || super
|
66
58
|
end
|
data/lib/hanami/assets/config.rb
CHANGED
@@ -4,8 +4,11 @@ require "dry/configurable"
|
|
4
4
|
|
5
5
|
module Hanami
|
6
6
|
module Assets
|
7
|
-
#
|
8
|
-
#
|
7
|
+
# App config for assets.
|
8
|
+
#
|
9
|
+
# This is NOT RELEASED as of 2.0.0.
|
10
|
+
#
|
11
|
+
# @api private
|
9
12
|
class Config
|
10
13
|
include Dry::Configurable
|
11
14
|
|
@@ -34,8 +37,6 @@ module Hanami
|
|
34
37
|
|
35
38
|
private
|
36
39
|
|
37
|
-
# @since 2.0.0
|
38
|
-
# @api private
|
39
40
|
def method_missing(name, *args, &block)
|
40
41
|
if config.respond_to?(name)
|
41
42
|
config.public_send(name, *args, &block)
|
@@ -44,8 +45,6 @@ module Hanami
|
|
44
45
|
end
|
45
46
|
end
|
46
47
|
|
47
|
-
# @since 2.0.0
|
48
|
-
# @api private
|
49
48
|
def respond_to_missing?(name, _incude_all = false)
|
50
49
|
config.respond_to?(name) || super
|
51
50
|
end
|
@@ -9,18 +9,45 @@ module Hanami
|
|
9
9
|
# actions, and adds the `enabled?` method to allow app base action to determine whether to
|
10
10
|
# include the `Action::Cookies` module.
|
11
11
|
#
|
12
|
+
# @api public
|
12
13
|
# @since 2.0.0
|
13
14
|
class Cookies
|
15
|
+
# Returns the cookie options.
|
16
|
+
#
|
17
|
+
# @return [Hash]
|
18
|
+
#
|
19
|
+
# @api public
|
20
|
+
# @since 2.0.0
|
14
21
|
attr_reader :options
|
15
22
|
|
23
|
+
# Returns a new `Cookies`.
|
24
|
+
#
|
25
|
+
# You should not need to initialize this class directly. Instead use
|
26
|
+
# {Hanami::Config::Actions#cookies}.
|
27
|
+
#
|
28
|
+
# @api private
|
29
|
+
# @since 2.0.0
|
16
30
|
def initialize(options)
|
17
31
|
@options = options
|
18
32
|
end
|
19
33
|
|
34
|
+
# Returns true if any cookie options have been provided.
|
35
|
+
#
|
36
|
+
# @return [Boolean]
|
37
|
+
#
|
38
|
+
# @api public
|
39
|
+
# @since 2.0.0
|
20
40
|
def enabled?
|
21
41
|
!options.nil?
|
22
42
|
end
|
23
43
|
|
44
|
+
# Returns the cookie options.
|
45
|
+
#
|
46
|
+
# If no options have been provided, returns an empty hash.
|
47
|
+
#
|
48
|
+
# @return [Hash]
|
49
|
+
#
|
50
|
+
# @api public
|
24
51
|
def to_h
|
25
52
|
options.to_h
|
26
53
|
end
|
@@ -1,31 +1,68 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "dry/core/constants"
|
4
3
|
require "hanami/utils/string"
|
5
4
|
require "hanami/utils/class"
|
6
5
|
|
7
6
|
module Hanami
|
8
7
|
class Config
|
9
8
|
class Actions
|
10
|
-
# Config for HTTP
|
9
|
+
# Config for HTTP session middleware in Hanami actions.
|
11
10
|
#
|
11
|
+
# @api public
|
12
12
|
# @since 2.0.0
|
13
13
|
class Sessions
|
14
|
-
|
14
|
+
# Returns the configured session storage
|
15
|
+
#
|
16
|
+
# @return [Symbol]
|
17
|
+
#
|
18
|
+
# @api public
|
19
|
+
# @since 2.0.0
|
20
|
+
attr_reader :storage
|
15
21
|
|
22
|
+
# Returns the configured session storage options
|
23
|
+
#
|
24
|
+
# @return [Array]
|
25
|
+
#
|
26
|
+
# @api public
|
27
|
+
# @since 2.0.0
|
28
|
+
attr_reader :options
|
29
|
+
|
30
|
+
# Returns a new `Sessions`.
|
31
|
+
#
|
32
|
+
# You should not need to initialize this class directly. Instead use
|
33
|
+
# {Hanami::Config::Actions#sessions=}.
|
34
|
+
#
|
35
|
+
# @example
|
36
|
+
# config.actions.sessions = :cookie, {secret: "xyz"}
|
37
|
+
#
|
38
|
+
# @api private
|
39
|
+
# @since 2.0.0
|
16
40
|
def initialize(storage = nil, *options)
|
17
41
|
@storage = storage
|
18
42
|
@options = options
|
19
43
|
end
|
20
44
|
|
45
|
+
# Returns true if sessions have been enabled.
|
46
|
+
#
|
47
|
+
# @return [Boolean]
|
48
|
+
#
|
49
|
+
# @api public
|
50
|
+
# @since 2.0.0
|
21
51
|
def enabled?
|
22
52
|
!storage.nil?
|
23
53
|
end
|
24
54
|
|
55
|
+
# Returns an array of the session storage middleware name and its options, or an empty array
|
56
|
+
# if sessions have not been enabled.
|
57
|
+
#
|
58
|
+
# @return [Array<(Symbol, Array)>]
|
59
|
+
#
|
60
|
+
# @api public
|
61
|
+
# @since 2.0.0
|
25
62
|
def middleware
|
26
|
-
return []
|
63
|
+
return [] unless enabled?
|
27
64
|
|
28
|
-
[
|
65
|
+
[storage_middleware, options].flatten(1)
|
29
66
|
end
|
30
67
|
|
31
68
|
private
|
@@ -1,33 +1,104 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "dry/configurable"
|
4
|
-
require_relative "actions/cookies"
|
5
|
-
require_relative "actions/sessions"
|
6
|
-
require_relative "actions/content_security_policy"
|
7
|
-
require_relative "../slice/view_name_inferrer"
|
8
4
|
|
9
5
|
module Hanami
|
10
6
|
class Config
|
11
7
|
# Hanami actions config
|
12
8
|
#
|
9
|
+
# This exposes all the settings from the standalone `Hanami::Action` class, pre-configured with
|
10
|
+
# sensible defaults for actions within a full Hanami app. It also provides additional settings
|
11
|
+
# for further integration of actions with other full stack app components.
|
12
|
+
#
|
13
13
|
# @since 2.0.0
|
14
|
+
# @api public
|
14
15
|
class Actions
|
15
16
|
include Dry::Configurable
|
16
17
|
|
18
|
+
# @!attribute [rw] cookies
|
19
|
+
# Sets or returns a hash of cookie options for actions.
|
20
|
+
#
|
21
|
+
# The hash is wrapped by {Hanami::Config::Actions::Cookies}, which also provides an
|
22
|
+
# `enabled?` method, returning true in the case of any options provided.
|
23
|
+
#
|
24
|
+
# @example
|
25
|
+
# config.actions.cookies = {max_age: 300}
|
26
|
+
#
|
27
|
+
# @return [Hanami::Config::Actions::Cookies]
|
28
|
+
#
|
29
|
+
# @api public
|
30
|
+
# @since 2.0.0
|
17
31
|
setting :cookies, default: {}, constructor: -> options { Cookies.new(options) }
|
32
|
+
|
33
|
+
# @!attribute [rw] sessions
|
34
|
+
# Sets or returns the session store (and its options) for actions.
|
35
|
+
#
|
36
|
+
# The given values are taken as an argument list to be passed to {Config::Sessions#initialize}.
|
37
|
+
#
|
38
|
+
# The configured session store is used when setting up the app or slice
|
39
|
+
# {Slice::ClassMethods#router router}.
|
40
|
+
#
|
41
|
+
# @example
|
42
|
+
# config.actions.sessions = :cookie, {secret: "xyz"}
|
43
|
+
#
|
44
|
+
# @return [Config::Sessions]
|
45
|
+
#
|
46
|
+
# @see Config::Sessions
|
47
|
+
# @see Slice::ClassMethods#router
|
48
|
+
#
|
49
|
+
# @api public
|
50
|
+
# @since 2.0.0
|
18
51
|
setting :sessions, constructor: proc { |storage, *options| Sessions.new(storage, *options) }
|
52
|
+
|
53
|
+
# @!attribute [rw] csrf_protection
|
54
|
+
# Sets or returns whether CSRF protection should be enabled for action classes.
|
55
|
+
#
|
56
|
+
# Defaults to true if {#sessions} is enabled. You can override this by explicitly setting a
|
57
|
+
# true or false value.
|
58
|
+
#
|
59
|
+
# When true, this will include `Hanami::Action::CSRFProtection` in all action classes.
|
60
|
+
#
|
61
|
+
# @return [Boolean]
|
62
|
+
#
|
63
|
+
# @api public
|
64
|
+
# @since 2.0.0
|
19
65
|
setting :csrf_protection
|
20
66
|
|
67
|
+
# Returns the Content Security Policy config for actions.
|
68
|
+
#
|
69
|
+
# The resulting policy is set as a default `"Content-Security-Policy"` response header.
|
70
|
+
#
|
71
|
+
# @return [Hanami::Config::Actions::ContentSecurityPolicy]
|
72
|
+
#
|
73
|
+
# @api public
|
74
|
+
# @since 2.0.0
|
75
|
+
attr_accessor :content_security_policy
|
76
|
+
|
77
|
+
# The following settings are for view and assets integration with actions, and are NOT
|
78
|
+
# publicly released as of 2.0.0. We'll make full documentation available when these become
|
79
|
+
# public in a subsequent release.
|
80
|
+
|
81
|
+
# @!attribute [rw] name_inference_base
|
82
|
+
# @api private
|
21
83
|
setting :name_inference_base, default: "actions"
|
84
|
+
|
85
|
+
# @!attribute [rw] view_context_identifier
|
86
|
+
# @api private
|
22
87
|
setting :view_context_identifier, default: "views.context"
|
88
|
+
|
89
|
+
# @!attribute [rw] view_name_inferrer
|
90
|
+
# @api private
|
23
91
|
setting :view_name_inferrer, default: Slice::ViewNameInferrer
|
24
|
-
setting :view_name_inference_base, default: "views"
|
25
92
|
|
26
|
-
|
93
|
+
# @!attribute [rw] view_name_inference_base
|
94
|
+
# @api private
|
95
|
+
setting :view_name_inference_base, default: "views"
|
27
96
|
|
97
|
+
# @api private
|
28
98
|
attr_reader :base_config
|
29
99
|
protected :base_config
|
30
100
|
|
101
|
+
# @api private
|
31
102
|
def initialize(*, **options)
|
32
103
|
super()
|
33
104
|
|
@@ -42,32 +113,25 @@ module Hanami
|
|
42
113
|
configure_defaults
|
43
114
|
end
|
44
115
|
|
116
|
+
# @api private
|
45
117
|
def initialize_copy(source)
|
46
118
|
super
|
47
119
|
@base_config = source.base_config.dup
|
48
120
|
@content_security_policy = source.content_security_policy.dup
|
49
121
|
end
|
122
|
+
private :initialize_copy
|
50
123
|
|
124
|
+
# @api private
|
51
125
|
def finalize!
|
52
126
|
# A nil value for `csrf_protection` means it has not been explicitly configured
|
53
127
|
# (neither true nor false), so we can default it to whether sessions are enabled
|
54
128
|
self.csrf_protection = sessions.enabled? if csrf_protection.nil?
|
55
129
|
|
56
130
|
if content_security_policy
|
57
|
-
default_headers["Content-Security-Policy"] = content_security_policy.
|
131
|
+
default_headers["Content-Security-Policy"] = content_security_policy.to_s
|
58
132
|
end
|
59
133
|
end
|
60
134
|
|
61
|
-
# Returns the list of available settings
|
62
|
-
#
|
63
|
-
# @return [Set]
|
64
|
-
#
|
65
|
-
# @since 2.0.0
|
66
|
-
# @api private
|
67
|
-
def settings
|
68
|
-
Hanami::Action.settings + self.class.settings
|
69
|
-
end
|
70
|
-
|
71
135
|
private
|
72
136
|
|
73
137
|
# Apply defaults for base config
|