hanami 2.2.0 → 2.3.0.beta1
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 +47 -1
- data/README.md +20 -35
- data/hanami.gemspec +3 -2
- data/lib/hanami/app.rb +2 -0
- data/lib/hanami/config/actions/content_security_policy.rb +23 -0
- data/lib/hanami/config/actions.rb +21 -0
- data/lib/hanami/config/console.rb +79 -0
- data/lib/hanami/config/logger.rb +1 -1
- data/lib/hanami/config.rb +13 -0
- data/lib/hanami/constants.rb +3 -0
- data/lib/hanami/extensions/db/repo.rb +11 -6
- data/lib/hanami/extensions/operation.rb +1 -1
- data/lib/hanami/extensions/view/context.rb +10 -0
- data/lib/hanami/helpers/assets_helper.rb +92 -25
- data/lib/hanami/middleware/content_security_policy_nonce.rb +53 -0
- data/lib/hanami/slice.rb +22 -6
- data/lib/hanami/slice_registrar.rb +1 -1
- data/lib/hanami/version.rb +1 -1
- data/lib/hanami.rb +10 -2
- data/spec/integration/assets/cross_slice_assets_helpers_spec.rb +0 -1
- data/spec/integration/assets/serve_static_assets_spec.rb +1 -1
- data/spec/integration/container/autoloader_spec.rb +2 -0
- data/spec/integration/db/db_spec.rb +1 -1
- data/spec/integration/db/logging_spec.rb +63 -0
- data/spec/integration/db/repo_spec.rb +87 -2
- data/spec/integration/logging/exception_logging_spec.rb +6 -1
- data/spec/integration/rack_app/middleware_spec.rb +4 -11
- data/spec/integration/view/helpers/form_helper_spec.rb +1 -1
- data/spec/integration/web/content_security_policy_nonce_spec.rb +251 -0
- data/spec/support/app_integration.rb +2 -1
- data/spec/unit/hanami/config/actions/content_security_policy_spec.rb +7 -0
- data/spec/unit/hanami/config/console_spec.rb +22 -0
- data/spec/unit/hanami/env_spec.rb +10 -13
- data/spec/unit/hanami/slice_spec.rb +18 -0
- data/spec/unit/hanami/version_spec.rb +1 -1
- data/spec/unit/hanami/web/rack_logger_spec.rb +11 -4
- metadata +27 -18
- data/spec/support/shared_examples/cli/generate/app.rb +0 -494
- data/spec/support/shared_examples/cli/generate/migration.rb +0 -32
- data/spec/support/shared_examples/cli/generate/model.rb +0 -81
- data/spec/support/shared_examples/cli/new.rb +0 -97
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a8faef478dec45e673c25c67704b0fd7a363e784061412c64e96735040f2d07f
|
4
|
+
data.tar.gz: b88eac54b8ba6241645b616ba9eafd20d54edb888e7fca8abc9e310f414dabe5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8233b2e453669ae1528c3cadd8032cbff3a7337c590bb0962d307ddd71bb8b18e28f56cc19a5644225efaf0ad0bfa2f5a008dd8fbae2615a9bc819906e47e1cc
|
7
|
+
data.tar.gz: 07551dada781667f44be90593599a0f505e9580d82d98c70df4e18e4288651e68fb26130d3504bf228dd2b7d2237af7494d7cfac86cd06ece733920657adfa83
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,48 @@
|
|
1
1
|
# Hanami
|
2
2
|
|
3
|
-
|
3
|
+
## [Unreleased]
|
4
|
+
|
5
|
+
### Added
|
6
|
+
|
7
|
+
### Changed
|
8
|
+
|
9
|
+
### Deprecated
|
10
|
+
|
11
|
+
### Removed
|
12
|
+
|
13
|
+
### Fixed
|
14
|
+
|
15
|
+
### Security
|
16
|
+
|
17
|
+
## [v2.3.0.beta1] - 2025-10-03
|
18
|
+
|
19
|
+
### Added
|
20
|
+
|
21
|
+
- Add `config.console` settings to app. Set an alternative engine with e.g. `config.console.engine = :pry` (`:irb` is default). Add your own methods to the console with `config.console.include MyModule, AnotherModule`. (@alassek in #1540)
|
22
|
+
- Support optional nonce in Rack requests, CSP header rules and view helpers (@svoop in #1500)
|
23
|
+
- Check `ENV["APP_ENV"]` for the Hanami env if `ENV["HANAMI_ENV"]` is not set. The order of environment variable checks is now `HANAMI_ENV`->`APP_ENV`->`RACK_ENV` (@svoop in #1487).
|
24
|
+
|
25
|
+
### Changed
|
26
|
+
|
27
|
+
- Support both Rack v2 and v3. (@kyleplump in #1493)
|
28
|
+
- Support single-character slice names. (@aaronmallen in #1528)
|
29
|
+
|
30
|
+
### Fixed
|
31
|
+
|
32
|
+
- Allow `include Deps` to be used in `Hanami::DB::Repo` subclasses. (@wuarmin in #1523)
|
33
|
+
- Properly infer root relations for deeper `Hanami::DB::Repo` subclasses, such as in slices. (@wuarmin in #1478)
|
34
|
+
- Delay loading `config/routes.rb` until after autoloading is setup, which means you can access your constants there. (@timriley in #1539)
|
35
|
+
- Avoid warning from referencing deprecated `URI::DEFAULT_PARSER`. (@wuarmin in #1518)
|
36
|
+
|
37
|
+
## v2.2.1 - 2024-11-12
|
38
|
+
|
39
|
+
### Changed
|
40
|
+
|
41
|
+
- [Tim Riley] Depend on matching minor version of hanami-cli (a version spec of `"~> 2.2.1"` instead of `"~> 2.2"`). This ensures that future bumps to the minor version of hanami-cli will not be inadvertently installed on user machines (#1471)
|
42
|
+
|
43
|
+
### Fixed
|
44
|
+
|
45
|
+
- [Tim Riley] Allow base operation class to load when a Hanami app is generated with `--skip-db` (i.e. when the "rom-sql" gem is not in the bundle) (#1475)
|
4
46
|
|
5
47
|
## v2.2.0 - 2024-11-05
|
6
48
|
|
@@ -1468,3 +1510,7 @@ end
|
|
1468
1510
|
- [Luca Guidi] Introduced `Lotus::Configuration`
|
1469
1511
|
- [Luca Guidi] Introduced `Lotus::Application`
|
1470
1512
|
- [Luca Guidi] Official support for MRI 2.0
|
1513
|
+
|
1514
|
+
|
1515
|
+
[unreleased]: https://github.com/hanami/hanami/compare/v2.3.0.beta1...HEAD
|
1516
|
+
[v2.3.0.beta1] https://github.com/hanami/hanami/compare/v2.2.1...v2.3.0.beta1
|
data/README.md
CHANGED
@@ -1,12 +1,6 @@
|
|
1
1
|
# Hanami :cherry_blossom:
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
## Version
|
6
|
-
|
7
|
-
**This branch contains the code for `hanami`: 2.2**
|
8
|
-
|
9
|
-
## Frameworks
|
3
|
+
**A flexible framework for maintainable Ruby apps.**
|
10
4
|
|
11
5
|
Hanami is a **full-stack** Ruby web framework. It's made up of smaller, single-purpose libraries.
|
12
6
|
|
@@ -14,8 +8,8 @@ This repository is for the full-stack framework, which provides the glue that ti
|
|
14
8
|
|
15
9
|
* [**Hanami::Router**](https://github.com/hanami/router) - Rack compatible HTTP router for Ruby
|
16
10
|
* [**Hanami::Controller**](https://github.com/hanami/controller) - Full featured, fast and testable actions for Rack
|
17
|
-
* [**Hanami::Validations**](https://github.com/hanami/validations) - Parameter validations & coercion for actions
|
18
11
|
* [**Hanami::View**](https://github.com/hanami/view) - Presentation with a separation between views and templates
|
12
|
+
* [**Hanami::DB**](https://github.com/hanami/db) - Database integration, complete with migrations, repositories, relations, and structs
|
19
13
|
* [**Hanami::Assets**](https://github.com/hanami/assets) - Assets management for Ruby
|
20
14
|
|
21
15
|
These components are designed to be used independently or together in a Hanami application.
|
@@ -24,12 +18,10 @@ These components are designed to be used independently or together in a Hanami a
|
|
24
18
|
|
25
19
|
[](https://badge.fury.io/rb/hanami)
|
26
20
|
[](https://github.com/hanami/hanami/actions?query=workflow%3Aci+branch%3Amain)
|
27
|
-
[](https://codecov.io/gh/hanami/hanami)
|
28
|
-
[](https://depfu.com/github/hanami/hanami?project=Bundler)
|
29
21
|
|
30
22
|
## Installation
|
31
23
|
|
32
|
-
|
24
|
+
Hanami supports Ruby (MRI) 3.1+.
|
33
25
|
|
34
26
|
```shell
|
35
27
|
gem install hanami
|
@@ -40,7 +32,8 @@ gem install hanami
|
|
40
32
|
```shell
|
41
33
|
hanami new bookshelf
|
42
34
|
cd bookshelf && bundle
|
43
|
-
bundle exec hanami
|
35
|
+
bundle exec hanami dev
|
36
|
+
# Now visit http://localhost:2300
|
44
37
|
```
|
45
38
|
|
46
39
|
Please follow along with the [Getting Started guide](https://guides.hanamirb.org/getting-started/).
|
@@ -49,30 +42,22 @@ Please follow along with the [Getting Started guide](https://guides.hanamirb.org
|
|
49
42
|
|
50
43
|
You can give back to Open Source, by supporting Hanami development via [GitHub Sponsors](https://github.com/sponsors/hanami).
|
51
44
|
|
52
|
-
### Supporters
|
53
|
-
|
54
|
-
* [Trung Lê](https://github.com/runlevel5)
|
55
|
-
* [James Carlson](https://github.com/jxxcarlson)
|
56
|
-
* [Creditas](https://www.creditas.com.br/)
|
57
|
-
|
58
45
|
## Contact
|
59
46
|
|
60
|
-
* Home page
|
61
|
-
* Community
|
62
|
-
* Guides
|
63
|
-
*
|
64
|
-
*
|
65
|
-
*
|
66
|
-
* Bugs/Issues: https://github.com/hanami/hanami/issues
|
67
|
-
* Stack Overflow: http://stackoverflow.com/questions/tagged/hanami
|
68
|
-
* Forum: https://discourse.hanamirb.org
|
69
|
-
* **Chat**: http://chat.hanamirb.org
|
47
|
+
* [Home page](http://hanamirb.org)
|
48
|
+
* [Community](http://hanamirb.org/community)
|
49
|
+
* [Guides](https://guides.hanamirb.org)
|
50
|
+
* [Issues](https://github.com/hanami/hanami/issues)
|
51
|
+
* [Forum](https://discourse.hanamirb.org)
|
52
|
+
* [Chat](https://discord.gg/KFCxDmk3JQ)
|
70
53
|
|
71
54
|
## Community
|
72
55
|
|
73
|
-
We
|
56
|
+
We care about building a friendly, inclusive and helpful community. We welcome people of all backgrounds, genders and experience levels, and respect you all equally.
|
57
|
+
|
58
|
+
We do not tolerate nazis, transphobes, racists, or any kind of bigotry. See our [code of conduct](http://hanamirb.org/community/#code-of-conduct) for more.
|
74
59
|
|
75
|
-
## Contributing
|
60
|
+
## Contributing
|
76
61
|
|
77
62
|
1. Fork it ( https://github.com/hanami/hanami/fork )
|
78
63
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
@@ -110,14 +95,14 @@ $ bundle exec rspec path/to/spec.rb
|
|
110
95
|
|
111
96
|
### Development Requirements
|
112
97
|
|
113
|
-
|
114
|
-
|
115
|
-
|
98
|
+
* Ruby >= 3.1
|
99
|
+
* Bundler
|
100
|
+
* Node.js
|
116
101
|
|
117
102
|
## Versioning
|
118
103
|
|
119
|
-
|
104
|
+
Hanami uses [Semantic Versioning 2.0.0](http://semver.org).
|
120
105
|
|
121
106
|
## Copyright
|
122
107
|
|
123
|
-
Copyright © 2014–
|
108
|
+
Copyright © 2014–2025 Hanami Team – Released under MIT License.
|
data/hanami.gemspec
CHANGED
@@ -38,12 +38,13 @@ Gem::Specification.new do |spec|
|
|
38
38
|
spec.add_dependency "dry-monitor", "~> 1.0", ">= 1.0.1", "< 2"
|
39
39
|
spec.add_dependency "dry-system", "~> 1.1"
|
40
40
|
spec.add_dependency "dry-logger", "~> 1.0", "< 2"
|
41
|
-
spec.add_dependency "hanami-cli", "~> 2.
|
41
|
+
spec.add_dependency "hanami-cli", "~> 2.3.0.beta1"
|
42
42
|
spec.add_dependency "hanami-utils", "~> 2.2"
|
43
43
|
spec.add_dependency "json", ">= 2.7.2"
|
44
44
|
spec.add_dependency "zeitwerk", "~> 2.6"
|
45
|
+
spec.add_dependency "rack-session"
|
45
46
|
|
46
47
|
spec.add_development_dependency "rspec", "~> 3.8"
|
47
|
-
spec.add_development_dependency "rack-test", "~>
|
48
|
+
spec.add_development_dependency "rack-test", "~> 2.0"
|
48
49
|
spec.add_development_dependency "rake", "~> 13.0"
|
49
50
|
end
|
data/lib/hanami/app.rb
CHANGED
@@ -168,6 +168,8 @@ module Hanami
|
|
168
168
|
end
|
169
169
|
|
170
170
|
def prepare_autoloader
|
171
|
+
autoloader.tag = "hanami.app.#{slice_name.name}"
|
172
|
+
|
171
173
|
# Component dirs are automatically pushed to the autoloader by dry-system's zeitwerk plugin.
|
172
174
|
# This method adds other dirs that are not otherwise configured as component dirs.
|
173
175
|
|
@@ -96,6 +96,29 @@ module Hanami
|
|
96
96
|
@policy.delete(key)
|
97
97
|
end
|
98
98
|
|
99
|
+
# Returns true if 'nonce' is used in any of the policies.
|
100
|
+
#
|
101
|
+
# @return [Boolean]
|
102
|
+
#
|
103
|
+
# @api public
|
104
|
+
# @since x.x.x
|
105
|
+
def nonce?
|
106
|
+
@policy.any? { _2.match?(/'nonce'/) }
|
107
|
+
end
|
108
|
+
|
109
|
+
# Returns an array of middleware name to support 'nonce' in
|
110
|
+
# policies, or an empty array if 'nonce' is not used.
|
111
|
+
#
|
112
|
+
# @return [Array<(Symbol, Array)>]
|
113
|
+
#
|
114
|
+
# @api public
|
115
|
+
# @since x.x.x
|
116
|
+
def middleware
|
117
|
+
return [] unless nonce?
|
118
|
+
|
119
|
+
[Hanami::Middleware::ContentSecurityPolicyNonce]
|
120
|
+
end
|
121
|
+
|
99
122
|
# @since 2.0.0
|
100
123
|
# @api private
|
101
124
|
def to_s
|
@@ -74,6 +74,23 @@ module Hanami
|
|
74
74
|
# @since 2.0.0
|
75
75
|
attr_accessor :content_security_policy
|
76
76
|
|
77
|
+
# Returns the proc to generate Content Security Policy nonce values.
|
78
|
+
#
|
79
|
+
# The current Rack request object is provided as an optional argument
|
80
|
+
# to the proc, enabling the generation of nonces based on session IDs.
|
81
|
+
#
|
82
|
+
# @example Independent random nonce (default)
|
83
|
+
# -> { SecureRandom.urlsafe_base64(16) }
|
84
|
+
#
|
85
|
+
# @example Session dependent nonce
|
86
|
+
# ->(request) { Digest::SHA256.base64digest(request.session[:uuid])[0, 16] }
|
87
|
+
#
|
88
|
+
# @return [Proc]
|
89
|
+
#
|
90
|
+
# @api public
|
91
|
+
# @since x.x.x
|
92
|
+
setting :content_security_policy_nonce_generator, default: -> { SecureRandom.urlsafe_base64(16) }
|
93
|
+
|
77
94
|
# @!attribute [rw] method_override
|
78
95
|
# Sets or returns whether HTTP method override should be enabled for action classes.
|
79
96
|
#
|
@@ -138,6 +155,10 @@ module Hanami
|
|
138
155
|
end
|
139
156
|
end
|
140
157
|
|
158
|
+
# @api public
|
159
|
+
# @since x.x.x
|
160
|
+
def content_security_policy? = !!@content_security_policy
|
161
|
+
|
141
162
|
private
|
142
163
|
|
143
164
|
# Apply defaults for base config
|
@@ -0,0 +1,79 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dry/configurable"
|
4
|
+
|
5
|
+
module Hanami
|
6
|
+
class Config
|
7
|
+
# Hanami console config
|
8
|
+
#
|
9
|
+
# @since 2.3.0
|
10
|
+
# @api public
|
11
|
+
class Console
|
12
|
+
include Dry::Configurable
|
13
|
+
|
14
|
+
# @!attribute [rw] engine
|
15
|
+
# Sets or returns the interactive console engine to be used by `hanami console`.
|
16
|
+
# Supported values are `:irb` (default) and `:pry`.
|
17
|
+
#
|
18
|
+
# @example
|
19
|
+
# config.console.engine = :pry
|
20
|
+
#
|
21
|
+
# @return [Symbol]
|
22
|
+
#
|
23
|
+
# @api public
|
24
|
+
# @since 2.3.0
|
25
|
+
setting :engine, default: :irb
|
26
|
+
|
27
|
+
# Returns the complete list of extensions to be used in the console
|
28
|
+
#
|
29
|
+
# @example
|
30
|
+
# config.console.include MyExtension, OtherExtension
|
31
|
+
# config.console.include ThirdExtension
|
32
|
+
#
|
33
|
+
# config.console.extensions
|
34
|
+
# # => [MyExtension, OtherExtension, ThirdExtension]
|
35
|
+
#
|
36
|
+
# @return [Array<Module>]
|
37
|
+
#
|
38
|
+
# @api public
|
39
|
+
# @since 2.3.0
|
40
|
+
def extensions = @extensions.dup.freeze
|
41
|
+
|
42
|
+
# Define a module extension to be included in the console
|
43
|
+
#
|
44
|
+
# @param mod [Module] one or more modules to be included in the console
|
45
|
+
# @return [void]
|
46
|
+
#
|
47
|
+
# @api public
|
48
|
+
# @since 2.3.0
|
49
|
+
def include(*mod)
|
50
|
+
@extensions.concat(mod).uniq!
|
51
|
+
end
|
52
|
+
|
53
|
+
# @api private
|
54
|
+
def initialize
|
55
|
+
@extensions = []
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
# @api private
|
61
|
+
def initialize_copy(source)
|
62
|
+
super
|
63
|
+
@extensions = [*source.extensions]
|
64
|
+
end
|
65
|
+
|
66
|
+
def method_missing(name, *args, &block)
|
67
|
+
if config.respond_to?(name)
|
68
|
+
config.public_send(name, *args, &block)
|
69
|
+
else
|
70
|
+
super
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def respond_to_missing?(name, _include_all = false)
|
75
|
+
config.respond_to?(name) || super
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
data/lib/hanami/config/logger.rb
CHANGED
data/lib/hanami/config.rb
CHANGED
@@ -6,6 +6,7 @@ require "dry/configurable"
|
|
6
6
|
require "dry/inflector"
|
7
7
|
|
8
8
|
require_relative "constants"
|
9
|
+
require_relative "config/console"
|
9
10
|
|
10
11
|
module Hanami
|
11
12
|
# Hanami app config
|
@@ -184,6 +185,18 @@ module Hanami
|
|
184
185
|
"Hanami::Router::NotFoundError" => :not_found,
|
185
186
|
)
|
186
187
|
|
188
|
+
# @!attribute [rw] console
|
189
|
+
# Returns the app's console config
|
190
|
+
#
|
191
|
+
# @example
|
192
|
+
# config.console.engine # => :irb
|
193
|
+
#
|
194
|
+
# @return [Hanami::Config::Console]
|
195
|
+
#
|
196
|
+
# @api public
|
197
|
+
# @since 2.3.0
|
198
|
+
setting :console, default: Hanami::Config::Console.new
|
199
|
+
|
187
200
|
# Returns the app or slice's {Hanami::SliceName slice_name}.
|
188
201
|
#
|
189
202
|
# This is useful for default config values that depend on this name.
|
data/lib/hanami/constants.rb
CHANGED
@@ -69,7 +69,8 @@ module Hanami
|
|
69
69
|
resolve_rom = method(:resolve_rom)
|
70
70
|
|
71
71
|
define_method(:new) do |**kwargs|
|
72
|
-
|
72
|
+
container = kwargs.delete(:container) || resolve_rom.()
|
73
|
+
super(container: container, **kwargs)
|
73
74
|
end
|
74
75
|
end
|
75
76
|
|
@@ -77,14 +78,18 @@ module Hanami
|
|
77
78
|
slice["db.rom"]
|
78
79
|
end
|
79
80
|
|
80
|
-
|
81
|
-
return unless repo_class.to_s.end_with?("Repo")
|
81
|
+
REPO_CLASS_NAME_REGEX = /^(?<name>.+)_(repo|repository)$/
|
82
82
|
|
83
|
-
|
83
|
+
def root_for_repo_class(repo_class)
|
84
|
+
repo_class_name = slice.inflector.demodulize(repo_class)
|
84
85
|
.then { slice.inflector.underscore(_1) }
|
85
|
-
|
86
|
+
|
87
|
+
repo_class_match = repo_class_name.match(REPO_CLASS_NAME_REGEX)
|
88
|
+
return unless repo_class_match
|
89
|
+
|
90
|
+
repo_class_match[:name]
|
86
91
|
.then { slice.inflector.pluralize(_1) }
|
87
|
-
.then
|
92
|
+
.then(&:to_sym)
|
88
93
|
end
|
89
94
|
|
90
95
|
def struct_namespace
|
@@ -1,7 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "dry/operation"
|
4
|
-
require "dry/operation/extensions/rom"
|
5
4
|
|
6
5
|
module Hanami
|
7
6
|
module Extensions
|
@@ -38,6 +37,7 @@ module Hanami
|
|
38
37
|
return unless subclass.superclass == self
|
39
38
|
return unless Hanami.bundled?("hanami-db")
|
40
39
|
|
40
|
+
require "dry/operation/extensions/rom"
|
41
41
|
subclass.include Dry::Operation::Extensions::ROM
|
42
42
|
end
|
43
43
|
end
|
@@ -172,6 +172,16 @@ module Hanami
|
|
172
172
|
@request
|
173
173
|
end
|
174
174
|
|
175
|
+
# Returns true if the view is rendered from within an action and a request is available.
|
176
|
+
#
|
177
|
+
# @return [Boolean]
|
178
|
+
#
|
179
|
+
# @api public
|
180
|
+
# @since x.x.x
|
181
|
+
def request?
|
182
|
+
!!@request
|
183
|
+
end
|
184
|
+
|
175
185
|
# Returns the app's routes helper.
|
176
186
|
#
|
177
187
|
# @return [Hanami::Slice::RoutesHelper] the routes helper
|