hanami 2.0.0.alpha3 → 2.0.0.alpha4
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 +69 -0
- data/lib/hanami/application/container/boot/routes_helper.rb +9 -0
- data/lib/hanami/application/routes.rb +2 -1
- data/lib/hanami/application/routes_helper.rb +34 -0
- data/lib/hanami/application/routing/resolver.rb +11 -6
- data/lib/hanami/application.rb +39 -33
- data/lib/hanami/assets/application_configuration.rb +63 -0
- data/lib/hanami/assets/configuration.rb +54 -0
- data/lib/hanami/configuration.rb +13 -2
- data/lib/hanami/version.rb +1 -1
- metadata +7 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2188bc3aee5a164b6610c6bc97fad9f0bba0384bf11a80be27228e7f19dad4e0
|
4
|
+
data.tar.gz: 7fa39987132cf6bfda0b0986a36894d08297c1df06b31354cfbeae934d73a813
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f7b1aad0186fcdaa94593ba4ff5d01cf4f8d4431aaffba173c3c795c2c0c76993a27da3aa503b0ce59fd67467615c86c50a4ab227986e38dd0986e91c30766a5
|
7
|
+
data.tar.gz: cd2d8b82bc7f98e906686fdab7299282b1c1be4b29278c9ee5b0f9b3cefbb7d31fa83013a840b2b9fa2b8e2b2f3f8c0582ca3587b35ced91f65db6f853d67cf7
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,75 @@
|
|
1
1
|
# Hanami
|
2
2
|
The web, with simplicity.
|
3
3
|
|
4
|
+
## v2.0.0.alpha4 - 2021-12-07
|
5
|
+
### Added
|
6
|
+
- [Luca Guidi] Manage Content Security Policy (CSP) with "zero-defaults" policy. New API to change CSP values and to disable the feature.
|
7
|
+
```ruby
|
8
|
+
# Read a CSP value
|
9
|
+
|
10
|
+
module MyApp
|
11
|
+
class Application < Hanami::Application
|
12
|
+
config.actions.content_security_policy[:base_uri] # => "'self'"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
```
|
16
|
+
|
17
|
+
```ruby
|
18
|
+
# Override a default CSP value
|
19
|
+
|
20
|
+
module MyApp
|
21
|
+
class Application < Hanami::Application
|
22
|
+
# This line will generate the following CSP fragment
|
23
|
+
# plugin-types ;
|
24
|
+
config.actions.content_security_policy[:plugin_types] = nil
|
25
|
+
end
|
26
|
+
end
|
27
|
+
```
|
28
|
+
|
29
|
+
```ruby
|
30
|
+
# Append to a default CSP value
|
31
|
+
|
32
|
+
module MyApp
|
33
|
+
class Application < Hanami::Application
|
34
|
+
# This line will generate the following CSP fragment
|
35
|
+
# script-src 'self' https://my.cdn.test;
|
36
|
+
config.actions.content_security_policy[:script_src] += " https://my.cdn.test"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
```
|
40
|
+
|
41
|
+
```ruby
|
42
|
+
# Add a custom CSP key. Useful when CSP standard evolves.
|
43
|
+
|
44
|
+
module MyApp
|
45
|
+
class Application < Hanami::Application
|
46
|
+
# This line will generate the following CSP fragment
|
47
|
+
# my-custom-setting 'self';
|
48
|
+
config.actions.content_security_policy[:my-custom-setting] = "'self'"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
```
|
52
|
+
|
53
|
+
```ruby
|
54
|
+
# Delete a CSP key.
|
55
|
+
|
56
|
+
module MyApp
|
57
|
+
class Application < Hanami::Application
|
58
|
+
config.actions.content_security_policy.delete(:object_src)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
```
|
62
|
+
|
63
|
+
```ruby
|
64
|
+
# Disable CSP feature.
|
65
|
+
|
66
|
+
module MyApp
|
67
|
+
class Application < Hanami::Application
|
68
|
+
config.actions.content_security_policy = false
|
69
|
+
end
|
70
|
+
end
|
71
|
+
```
|
72
|
+
|
4
73
|
## v2.0.0.alpha3 - 2021-11-09
|
5
74
|
### Added
|
6
75
|
- [Luca Guidi] Added `Hanami.shutdown` to stop all bootable components in the application container
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Hanami
|
4
|
+
class Application
|
5
|
+
# Hanami application routes helpers
|
6
|
+
#
|
7
|
+
# An instance of this class gets registered in the container
|
8
|
+
# (`routes_helper` key) once the Hanami application is booted. You can use
|
9
|
+
# it to get the route helpers for your application.
|
10
|
+
#
|
11
|
+
# @example
|
12
|
+
# MyApp::Application["routes_helper"].path(:root) # => "/"
|
13
|
+
#
|
14
|
+
# @see Hanami::Router::UrlHelpers
|
15
|
+
# @since 2.0.0
|
16
|
+
class RoutesHelper
|
17
|
+
# @since 2.0.0
|
18
|
+
# @api private
|
19
|
+
def initialize(router)
|
20
|
+
@router = router
|
21
|
+
end
|
22
|
+
|
23
|
+
# @see Hanami::Router::UrlHelpers#path
|
24
|
+
def path(*args, **kwargs, &block)
|
25
|
+
@router.path(*args, **kwargs, &block)
|
26
|
+
end
|
27
|
+
|
28
|
+
# @see Hanami::Router::UrlHelpers#url
|
29
|
+
def url(*args, **kwargs, &block)
|
30
|
+
@router.url(*args, **kwargs, &block)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -7,6 +7,8 @@ module Hanami
|
|
7
7
|
#
|
8
8
|
# @since 2.0.0
|
9
9
|
class Resolver
|
10
|
+
ENDPOINT_KEY_NAMESPACE = "actions"
|
11
|
+
|
10
12
|
require_relative "resolver/trie"
|
11
13
|
|
12
14
|
# @since 2.0.0
|
@@ -21,7 +23,7 @@ module Hanami
|
|
21
23
|
def initialize(slices:, inflector:)
|
22
24
|
@slices = slices
|
23
25
|
@inflector = inflector
|
24
|
-
@
|
26
|
+
@slice_registry = Trie.new
|
25
27
|
end
|
26
28
|
|
27
29
|
# @api private
|
@@ -50,7 +52,7 @@ module Hanami
|
|
50
52
|
# @api private
|
51
53
|
# @since 2.0.0
|
52
54
|
def register_slice_at_path(name, path)
|
53
|
-
|
55
|
+
slice_registry.add(path, name)
|
54
56
|
end
|
55
57
|
|
56
58
|
private
|
@@ -65,16 +67,19 @@ module Hanami
|
|
65
67
|
|
66
68
|
# @api private
|
67
69
|
# @since 2.0.0
|
68
|
-
attr_reader :
|
70
|
+
attr_reader :slice_registry
|
69
71
|
|
70
72
|
# @api private
|
71
73
|
# @since 2.0.0
|
72
74
|
def resolve_string_identifier(path, identifier)
|
73
|
-
slice_name =
|
75
|
+
slice_name = slice_registry.find(path) or raise "missing slice for #{path.inspect} (#{identifier.inspect})"
|
74
76
|
slice = slices[slice_name]
|
75
|
-
|
77
|
+
endpoint_key = "#{ENDPOINT_KEY_NAMESPACE}.#{identifier}"
|
76
78
|
|
77
|
-
slice
|
79
|
+
# Lazily resolve endpoint from the slice to reduce router initialization time,
|
80
|
+
# and break potential endless loops from the resolved endpoint itself requiring
|
81
|
+
# access to router-related concerns
|
82
|
+
-> (*args) { slice[endpoint_key].call(*args) }
|
78
83
|
end
|
79
84
|
end
|
80
85
|
end
|
data/lib/hanami/application.rb
CHANGED
@@ -8,6 +8,7 @@ require "rack"
|
|
8
8
|
require "zeitwerk"
|
9
9
|
require_relative "slice"
|
10
10
|
require_relative "application/autoloader/inflector_adapter"
|
11
|
+
require_relative "application/router"
|
11
12
|
require_relative "application/routes"
|
12
13
|
require_relative "application/settings"
|
13
14
|
|
@@ -71,8 +72,6 @@ module Hanami
|
|
71
72
|
|
72
73
|
autoloader.setup
|
73
74
|
|
74
|
-
load_routes
|
75
|
-
|
76
75
|
@inited = true
|
77
76
|
self
|
78
77
|
end
|
@@ -148,6 +147,8 @@ module Hanami
|
|
148
147
|
|
149
148
|
init
|
150
149
|
|
150
|
+
load_router
|
151
|
+
|
151
152
|
container.finalize!(&block)
|
152
153
|
|
153
154
|
slices.values.each(&:boot)
|
@@ -168,12 +169,6 @@ module Hanami
|
|
168
169
|
@_settings ||= load_settings
|
169
170
|
end
|
170
171
|
|
171
|
-
def routes
|
172
|
-
@_mutex.synchronize do
|
173
|
-
@_routes ||= load_routes
|
174
|
-
end
|
175
|
-
end
|
176
|
-
|
177
172
|
MODULE_DELIMITER = "::"
|
178
173
|
private_constant :MODULE_DELIMITER
|
179
174
|
|
@@ -216,6 +211,41 @@ module Hanami
|
|
216
211
|
providers.detect { |provider| component_name.include?(provider.namespace.to_s) }
|
217
212
|
end
|
218
213
|
|
214
|
+
def router
|
215
|
+
@_mutex.synchronize do
|
216
|
+
@_router ||= load_router
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
def load_router
|
221
|
+
Router.new(
|
222
|
+
routes: routes,
|
223
|
+
resolver: resolver,
|
224
|
+
**configuration.router.options,
|
225
|
+
) do
|
226
|
+
use Hanami.application[:rack_monitor]
|
227
|
+
|
228
|
+
Hanami.application.config.for_each_middleware do |m, *args, &block|
|
229
|
+
use(m, *args, &block)
|
230
|
+
end
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
def routes
|
235
|
+
require File.join(configuration.root, configuration.router.routes_path)
|
236
|
+
routes_class = autodiscover_application_constant(configuration.router.routes_class_name)
|
237
|
+
routes_class.routes
|
238
|
+
rescue LoadError
|
239
|
+
proc {}
|
240
|
+
end
|
241
|
+
|
242
|
+
def resolver
|
243
|
+
config.router.resolver.new(
|
244
|
+
slices: slices,
|
245
|
+
inflector: inflector
|
246
|
+
)
|
247
|
+
end
|
248
|
+
|
219
249
|
private
|
220
250
|
|
221
251
|
def prepare_base_load_path
|
@@ -312,13 +342,6 @@ module Hanami
|
|
312
342
|
end
|
313
343
|
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength
|
314
344
|
|
315
|
-
def load_routes
|
316
|
-
require File.join(configuration.root, configuration.router.routes_path)
|
317
|
-
routes_class = autodiscover_application_constant(configuration.router.routes_class_name)
|
318
|
-
routes_class.routes
|
319
|
-
rescue LoadError # rubocop:disable Lint/SuppressedException
|
320
|
-
end
|
321
|
-
|
322
345
|
def load_settings
|
323
346
|
prepare_base_load_path
|
324
347
|
require File.join(configuration.root, configuration.settings_path)
|
@@ -342,24 +365,7 @@ module Hanami
|
|
342
365
|
|
343
366
|
application.boot
|
344
367
|
|
345
|
-
|
346
|
-
slices: application.slices,
|
347
|
-
inflector: application.inflector
|
348
|
-
)
|
349
|
-
|
350
|
-
router = Application::Router.new(
|
351
|
-
routes: application.routes,
|
352
|
-
resolver: resolver,
|
353
|
-
**application.configuration.router.options,
|
354
|
-
) do
|
355
|
-
use application[:rack_monitor]
|
356
|
-
|
357
|
-
application.config.for_each_middleware do |m, *args, &block|
|
358
|
-
use(m, *args, &block)
|
359
|
-
end
|
360
|
-
end
|
361
|
-
|
362
|
-
@app = router.to_rack_app
|
368
|
+
@app = application.router.to_rack_app
|
363
369
|
end
|
364
370
|
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength
|
365
371
|
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "hanami/assets/configuration"
|
4
|
+
require "dry/configurable"
|
5
|
+
|
6
|
+
module Hanami
|
7
|
+
module Assets
|
8
|
+
# @since 2.0.0
|
9
|
+
# @api public
|
10
|
+
class ApplicationConfiguration
|
11
|
+
include Dry::Configurable
|
12
|
+
|
13
|
+
setting :server_url, default: "http://localhost:8080"
|
14
|
+
|
15
|
+
# @since 2.0.0
|
16
|
+
# @api private
|
17
|
+
def initialize(*)
|
18
|
+
super
|
19
|
+
|
20
|
+
@base_configuration = Assets::Configuration.new
|
21
|
+
end
|
22
|
+
|
23
|
+
# @since 2.0.0
|
24
|
+
# @api private
|
25
|
+
def finalize!
|
26
|
+
end
|
27
|
+
|
28
|
+
# Returns the list of available settings
|
29
|
+
#
|
30
|
+
# @return [Set]
|
31
|
+
#
|
32
|
+
# @since 2.0.0
|
33
|
+
# @api private
|
34
|
+
def settings
|
35
|
+
base_configuration.settings + self.class.settings
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
# @since 2.0.0
|
41
|
+
# @api private
|
42
|
+
attr_reader :base_configuration
|
43
|
+
|
44
|
+
# @since 2.0.0
|
45
|
+
# @api private
|
46
|
+
def method_missing(name, *args, &block)
|
47
|
+
if config.respond_to?(name)
|
48
|
+
config.public_send(name, *args, &block)
|
49
|
+
elsif base_configuration.respond_to?(name)
|
50
|
+
base_configuration.public_send(name, *args, &block)
|
51
|
+
else
|
52
|
+
super
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# @since 2.0.0
|
57
|
+
# @api private
|
58
|
+
def respond_to_missing?(name, _incude_all = false)
|
59
|
+
config.respond_to?(name) || base_configuration.respond_to?(name) || super
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dry/configurable"
|
4
|
+
|
5
|
+
module Hanami
|
6
|
+
module Assets
|
7
|
+
# @since 2.0.0
|
8
|
+
# @api public
|
9
|
+
class Configuration
|
10
|
+
include Dry::Configurable
|
11
|
+
|
12
|
+
# Initialize the Configuration
|
13
|
+
#
|
14
|
+
# @yield [config] the configuration object
|
15
|
+
#
|
16
|
+
# @return [Configuration]
|
17
|
+
#
|
18
|
+
# @since 2.0.0
|
19
|
+
# @api private
|
20
|
+
def initialize(*)
|
21
|
+
super
|
22
|
+
yield self if block_given?
|
23
|
+
end
|
24
|
+
|
25
|
+
# Returns the list of available settings
|
26
|
+
#
|
27
|
+
# @return [Set]
|
28
|
+
#
|
29
|
+
# @since 2.0.0
|
30
|
+
# @api private
|
31
|
+
def settings
|
32
|
+
self.class.settings
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
# @since 2.0.0
|
38
|
+
# @api private
|
39
|
+
def method_missing(name, *args, &block)
|
40
|
+
if config.respond_to?(name)
|
41
|
+
config.public_send(name, *args, &block)
|
42
|
+
else
|
43
|
+
super
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# @since 2.0.0
|
48
|
+
# @api private
|
49
|
+
def respond_to_missing?(name, _incude_all = false)
|
50
|
+
config.respond_to?(name) || super
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
data/lib/hanami/configuration.rb
CHANGED
@@ -28,7 +28,7 @@ module Hanami
|
|
28
28
|
attr_reader :actions
|
29
29
|
attr_reader :middleware
|
30
30
|
attr_reader :router
|
31
|
-
attr_reader :views
|
31
|
+
attr_reader :views, :assets
|
32
32
|
|
33
33
|
attr_reader :environments
|
34
34
|
private :environments
|
@@ -42,12 +42,22 @@ module Hanami
|
|
42
42
|
self.root = Dir.pwd
|
43
43
|
self.settings_store = Application::Settings::DotenvStore.new.with_dotenv_loaded
|
44
44
|
|
45
|
+
@assets = begin
|
46
|
+
require_path = "hanami/assets/application_configuration"
|
47
|
+
require require_path
|
48
|
+
Hanami::Assets::ApplicationConfiguration.new
|
49
|
+
rescue LoadError => e
|
50
|
+
raise e unless e.path == require_path
|
51
|
+
require_relative "configuration/null_configuration"
|
52
|
+
NullConfiguration.new
|
53
|
+
end
|
54
|
+
|
45
55
|
# Config for actions (same for views, below) may not be available if the gem isn't
|
46
56
|
# loaded; fall back to a null config object if it's missing
|
47
57
|
@actions = begin
|
48
58
|
require_path = "hanami/action/application_configuration"
|
49
59
|
require require_path
|
50
|
-
Hanami::Action::ApplicationConfiguration.new
|
60
|
+
Hanami::Action::ApplicationConfiguration.new(assets_server_url: assets.server_url)
|
51
61
|
rescue LoadError => e
|
52
62
|
raise e unless e.path == require_path
|
53
63
|
require_relative "configuration/null_configuration"
|
@@ -82,6 +92,7 @@ module Hanami
|
|
82
92
|
apply_env_config
|
83
93
|
|
84
94
|
# Finalize nested configurations
|
95
|
+
assets.finalize!
|
85
96
|
actions.finalize!
|
86
97
|
views.finalize!
|
87
98
|
logger.finalize!
|
data/lib/hanami/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hanami
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.0.
|
4
|
+
version: 2.0.0.alpha4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Luca Guidi
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-12-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -222,15 +222,19 @@ files:
|
|
222
222
|
- lib/hanami/application/container/boot/logger.rb
|
223
223
|
- lib/hanami/application/container/boot/rack_logger.rb
|
224
224
|
- lib/hanami/application/container/boot/rack_monitor.rb
|
225
|
+
- lib/hanami/application/container/boot/routes_helper.rb
|
225
226
|
- lib/hanami/application/container/boot/settings.rb
|
226
227
|
- lib/hanami/application/router.rb
|
227
228
|
- lib/hanami/application/routes.rb
|
229
|
+
- lib/hanami/application/routes_helper.rb
|
228
230
|
- lib/hanami/application/routing/middleware/stack.rb
|
229
231
|
- lib/hanami/application/routing/resolver.rb
|
230
232
|
- lib/hanami/application/routing/resolver/node.rb
|
231
233
|
- lib/hanami/application/routing/resolver/trie.rb
|
232
234
|
- lib/hanami/application/settings.rb
|
233
235
|
- lib/hanami/application/settings/dotenv_store.rb
|
236
|
+
- lib/hanami/assets/application_configuration.rb
|
237
|
+
- lib/hanami/assets/configuration.rb
|
234
238
|
- lib/hanami/boot.rb
|
235
239
|
- lib/hanami/cli/application/cli.rb
|
236
240
|
- lib/hanami/cli/application/command.rb
|
@@ -272,7 +276,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
272
276
|
- !ruby/object:Gem::Version
|
273
277
|
version: 1.3.1
|
274
278
|
requirements: []
|
275
|
-
rubygems_version: 3.2.
|
279
|
+
rubygems_version: 3.2.29
|
276
280
|
signing_key:
|
277
281
|
specification_version: 4
|
278
282
|
summary: The web, with simplicity
|