hanami 2.0.0.beta4 → 2.0.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|