piko-lite-box 0.0.1
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 +7 -0
- data/hanami-3.0.1/CHANGELOG.md +1701 -0
- data/hanami-3.0.1/LICENSE +20 -0
- data/hanami-3.0.1/README.md +89 -0
- data/hanami-3.0.1/hanami.gemspec +49 -0
- data/hanami-3.0.1/lib/hanami/app.rb +197 -0
- data/hanami-3.0.1/lib/hanami/boot.rb +5 -0
- data/hanami-3.0.1/lib/hanami/config/actions/content_security_policy.rb +140 -0
- data/hanami-3.0.1/lib/hanami/config/actions/cookies.rb +57 -0
- data/hanami-3.0.1/lib/hanami/config/actions/sessions.rb +83 -0
- data/hanami-3.0.1/lib/hanami/config/actions.rb +189 -0
- data/hanami-3.0.1/lib/hanami/config/assets.rb +84 -0
- data/hanami-3.0.1/lib/hanami/config/console.rb +79 -0
- data/hanami-3.0.1/lib/hanami/config/db.rb +35 -0
- data/hanami-3.0.1/lib/hanami/config/i18n.rb +138 -0
- data/hanami-3.0.1/lib/hanami/config/logger.rb +207 -0
- data/hanami-3.0.1/lib/hanami/config/null_config.rb +17 -0
- data/hanami-3.0.1/lib/hanami/config/router.rb +48 -0
- data/hanami-3.0.1/lib/hanami/config/views.rb +103 -0
- data/hanami-3.0.1/lib/hanami/config.rb +564 -0
- data/hanami-3.0.1/lib/hanami/constants.rb +62 -0
- data/hanami-3.0.1/lib/hanami/env.rb +52 -0
- data/hanami-3.0.1/lib/hanami/errors.rb +41 -0
- data/hanami-3.0.1/lib/hanami/extensions/action/i18n_helper.rb +64 -0
- data/hanami-3.0.1/lib/hanami/extensions/action/name_inferrer.rb +34 -0
- data/hanami-3.0.1/lib/hanami/extensions/action/slice_configured_action.rb +190 -0
- data/hanami-3.0.1/lib/hanami/extensions/action.rb +147 -0
- data/hanami-3.0.1/lib/hanami/extensions/db/repo.rb +108 -0
- data/hanami-3.0.1/lib/hanami/extensions/mailer/slice_configured_mailer.rb +134 -0
- data/hanami-3.0.1/lib/hanami/extensions/mailer.rb +28 -0
- data/hanami-3.0.1/lib/hanami/extensions/operation/slice_configured_db_operation.rb +90 -0
- data/hanami-3.0.1/lib/hanami/extensions/operation.rb +33 -0
- data/hanami-3.0.1/lib/hanami/extensions/router/errors.rb +58 -0
- data/hanami-3.0.1/lib/hanami/extensions/view/context.rb +298 -0
- data/hanami-3.0.1/lib/hanami/extensions/view/part.rb +92 -0
- data/hanami-3.0.1/lib/hanami/extensions/view/scope.rb +36 -0
- data/hanami-3.0.1/lib/hanami/extensions/view/slice_configured_context.rb +73 -0
- data/hanami-3.0.1/lib/hanami/extensions/view/slice_configured_helpers.rb +55 -0
- data/hanami-3.0.1/lib/hanami/extensions/view/slice_configured_part.rb +73 -0
- data/hanami-3.0.1/lib/hanami/extensions/view/slice_configured_view.rb +243 -0
- data/hanami-3.0.1/lib/hanami/extensions/view/standard_helpers.rb +26 -0
- data/hanami-3.0.1/lib/hanami/extensions/view.rb +38 -0
- data/hanami-3.0.1/lib/hanami/extensions.rb +30 -0
- data/hanami-3.0.1/lib/hanami/helpers/assets_helper.rb +804 -0
- data/hanami-3.0.1/lib/hanami/helpers/form_helper/form_builder.rb +1389 -0
- data/hanami-3.0.1/lib/hanami/helpers/form_helper/values.rb +75 -0
- data/hanami-3.0.1/lib/hanami/helpers/form_helper.rb +213 -0
- data/hanami-3.0.1/lib/hanami/helpers/i18n_helper.rb +241 -0
- data/hanami-3.0.1/lib/hanami/logger/rack_formatter.rb +73 -0
- data/hanami-3.0.1/lib/hanami/logger/sql_formatter.rb +80 -0
- data/hanami-3.0.1/lib/hanami/logger/sql_logger.rb +48 -0
- data/hanami-3.0.1/lib/hanami/middleware/assets.rb +21 -0
- data/hanami-3.0.1/lib/hanami/middleware/content_security_policy_nonce.rb +53 -0
- data/hanami-3.0.1/lib/hanami/middleware/public_errors_app.rb +75 -0
- data/hanami-3.0.1/lib/hanami/middleware/render_errors.rb +90 -0
- data/hanami-3.0.1/lib/hanami/port.rb +45 -0
- data/hanami-3.0.1/lib/hanami/prepare.rb +5 -0
- data/hanami-3.0.1/lib/hanami/provider/source.rb +16 -0
- data/hanami-3.0.1/lib/hanami/provider_registrar.rb +28 -0
- data/hanami-3.0.1/lib/hanami/providers/assets.rb +28 -0
- data/hanami-3.0.1/lib/hanami/providers/db/adapter.rb +75 -0
- data/hanami-3.0.1/lib/hanami/providers/db/adapters.rb +66 -0
- data/hanami-3.0.1/lib/hanami/providers/db/config.rb +44 -0
- data/hanami-3.0.1/lib/hanami/providers/db/gateway.rb +87 -0
- data/hanami-3.0.1/lib/hanami/providers/db/sql_adapter.rb +100 -0
- data/hanami-3.0.1/lib/hanami/providers/db.rb +325 -0
- data/hanami-3.0.1/lib/hanami/providers/db_logging.rb +19 -0
- data/hanami-3.0.1/lib/hanami/providers/i18n/backend.rb +373 -0
- data/hanami-3.0.1/lib/hanami/providers/i18n/locale/en.yml +57 -0
- data/hanami-3.0.1/lib/hanami/providers/i18n.rb +114 -0
- data/hanami-3.0.1/lib/hanami/providers/inflector.rb +17 -0
- data/hanami-3.0.1/lib/hanami/providers/logger.rb +41 -0
- data/hanami-3.0.1/lib/hanami/providers/mailers.rb +101 -0
- data/hanami-3.0.1/lib/hanami/providers/rack.rb +47 -0
- data/hanami-3.0.1/lib/hanami/providers/relations.rb +31 -0
- data/hanami-3.0.1/lib/hanami/providers/routes.rb +29 -0
- data/hanami-3.0.1/lib/hanami/rake_tasks.rb +54 -0
- data/hanami-3.0.1/lib/hanami/routes.rb +146 -0
- data/hanami-3.0.1/lib/hanami/settings/composite_store.rb +53 -0
- data/hanami-3.0.1/lib/hanami/settings/env_store.rb +32 -0
- data/hanami-3.0.1/lib/hanami/settings.rb +234 -0
- data/hanami-3.0.1/lib/hanami/setup.rb +6 -0
- data/hanami-3.0.1/lib/hanami/slice/router.rb +280 -0
- data/hanami-3.0.1/lib/hanami/slice/routes_helper.rb +37 -0
- data/hanami-3.0.1/lib/hanami/slice/routing/middleware/stack.rb +216 -0
- data/hanami-3.0.1/lib/hanami/slice/routing/resolver.rb +88 -0
- data/hanami-3.0.1/lib/hanami/slice/view_name_inferrer.rb +63 -0
- data/hanami-3.0.1/lib/hanami/slice.rb +1239 -0
- data/hanami-3.0.1/lib/hanami/slice_configurable.rb +72 -0
- data/hanami-3.0.1/lib/hanami/slice_name.rb +111 -0
- data/hanami-3.0.1/lib/hanami/slice_registrar.rb +215 -0
- data/hanami-3.0.1/lib/hanami/universal_logger.rb +250 -0
- data/hanami-3.0.1/lib/hanami/version.rb +45 -0
- data/hanami-3.0.1/lib/hanami/web/rack_logger.rb +126 -0
- data/hanami-3.0.1/lib/hanami/web/welcome.html.erb +584 -0
- data/hanami-3.0.1/lib/hanami/web/welcome.rb +46 -0
- data/hanami-3.0.1/lib/hanami.rb +276 -0
- data/piko-lite-box.gemspec +11 -0
- metadata +137 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2015-2026 Hanakai team
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
6
|
+
this software and associated documentation files (the "Software"), to deal in
|
|
7
|
+
the Software without restriction, including without limitation the rights to
|
|
8
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
9
|
+
the Software, and to permit persons to whom the Software is furnished to do so,
|
|
10
|
+
subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
17
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
18
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
19
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
20
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
<!--- This file is synced from hanakai-rb/repo-sync -->
|
|
2
|
+
|
|
3
|
+
[actions]: https://github.com/hanami/hanami/actions
|
|
4
|
+
[chat]: https://discord.gg/naQApPAsZB
|
|
5
|
+
[forum]: https://discourse.hanamirb.org
|
|
6
|
+
[rubygem]: https://rubygems.org/gems/hanami
|
|
7
|
+
|
|
8
|
+
# Hanami [][rubygem] [][actions]
|
|
9
|
+
|
|
10
|
+
[][forum]
|
|
11
|
+
[][chat]
|
|
12
|
+
|
|
13
|
+
**A flexible framework for maintainable Ruby apps.**
|
|
14
|
+
|
|
15
|
+
Hanami is a **full-stack** Ruby web framework. It's made up of smaller, single-purpose libraries.
|
|
16
|
+
|
|
17
|
+
This repository is for the full-stack framework, which provides the glue that ties all the parts together:
|
|
18
|
+
|
|
19
|
+
* [**Hanami::Router**](https://github.com/hanami/router) - Rack compatible HTTP router for Ruby
|
|
20
|
+
* [**Hanami::Action**](https://github.com/hanami/hanami-action) - Full featured, fast and testable actions for Rack
|
|
21
|
+
* [**Hanami::View**](https://github.com/hanami/view) - Presentation with a separation between views and templates
|
|
22
|
+
* [**Hanami::DB**](https://github.com/hanami/db) - Database integration, complete with migrations, repositories, relations, and structs
|
|
23
|
+
* [**Hanami::Assets**](https://github.com/hanami/assets) - Assets management for Ruby
|
|
24
|
+
|
|
25
|
+
These components are designed to be used independently or together in a Hanami application.
|
|
26
|
+
|
|
27
|
+
## Installation
|
|
28
|
+
|
|
29
|
+
```shell
|
|
30
|
+
gem install hanami
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Usage
|
|
34
|
+
|
|
35
|
+
```shell
|
|
36
|
+
hanami new bookshelf
|
|
37
|
+
cd bookshelf && bundle
|
|
38
|
+
bundle exec hanami dev
|
|
39
|
+
# Now visit http://localhost:2300
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Please follow along with the [Getting Started guide](https://guides.hanamirb.org/getting-started/).
|
|
43
|
+
|
|
44
|
+
## Contributing
|
|
45
|
+
|
|
46
|
+
1. Fork it (https://github.com/hanami/hanami/fork)
|
|
47
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
|
48
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
|
49
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
|
50
|
+
5. Create a new Pull Request
|
|
51
|
+
|
|
52
|
+
In addition to contributing code, you can help to triage issues. This can include reproducing bug reports, or asking for vital information such as version numbers or reproduction instructions. If you would like to start triaging issues, one easy way to get started is to [subscribe to hanami on CodeTriage](https://www.codetriage.com/hanami/hanami).
|
|
53
|
+
|
|
54
|
+
### Tests
|
|
55
|
+
|
|
56
|
+
To run all test suite:
|
|
57
|
+
|
|
58
|
+
```shell
|
|
59
|
+
$ bundle exec rake
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
To run all the unit tests:
|
|
63
|
+
|
|
64
|
+
```shell
|
|
65
|
+
$ bundle exec rspec spec/unit
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
To run all the integration tests:
|
|
69
|
+
|
|
70
|
+
```shell
|
|
71
|
+
$ bundle exec rspec spec/integration
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
To run a single test:
|
|
75
|
+
|
|
76
|
+
```shell
|
|
77
|
+
$ bundle exec rspec path/to/spec.rb
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Links
|
|
81
|
+
|
|
82
|
+
- [User documentation](https://hanamirb.org)
|
|
83
|
+
- [API documentation](http://rubydoc.info/gems/hanami)
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
## License
|
|
87
|
+
|
|
88
|
+
See `LICENSE` file.
|
|
89
|
+
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# This file is synced from hanakai-rb/repo-sync. To update it, edit repo-sync.yml.
|
|
4
|
+
|
|
5
|
+
lib = File.expand_path("lib", __dir__)
|
|
6
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
7
|
+
require "hanami/version"
|
|
8
|
+
|
|
9
|
+
Gem::Specification.new do |spec|
|
|
10
|
+
spec.name = "hanami"
|
|
11
|
+
spec.authors = ["Hanakai team"]
|
|
12
|
+
spec.email = ["info@hanakai.org"]
|
|
13
|
+
spec.license = "MIT"
|
|
14
|
+
spec.version = Hanami::VERSION.dup
|
|
15
|
+
|
|
16
|
+
spec.summary = "A flexible framework for maintainable Ruby apps"
|
|
17
|
+
spec.description = spec.summary
|
|
18
|
+
spec.homepage = "https://hanamirb.org"
|
|
19
|
+
spec.files = Dir["CHANGELOG.md", "LICENSE", "README.md", "hanami.gemspec", "lib/**/*"]
|
|
20
|
+
spec.bindir = "exe"
|
|
21
|
+
spec.executables = Dir["exe/*"].map { |f| File.basename(f) }
|
|
22
|
+
spec.require_paths = ["lib"]
|
|
23
|
+
|
|
24
|
+
spec.extra_rdoc_files = ["README.md", "CHANGELOG.md", "LICENSE"]
|
|
25
|
+
|
|
26
|
+
spec.metadata["changelog_uri"] = "https://github.com/hanami/hanami/blob/main/CHANGELOG.md"
|
|
27
|
+
spec.metadata["source_code_uri"] = "https://github.com/hanami/hanami"
|
|
28
|
+
spec.metadata["bug_tracker_uri"] = "https://github.com/hanami/hanami/issues"
|
|
29
|
+
spec.metadata["funding_uri"] = "https://github.com/sponsors/hanami"
|
|
30
|
+
|
|
31
|
+
spec.required_ruby_version = ">= 3.3"
|
|
32
|
+
|
|
33
|
+
spec.add_runtime_dependency "bundler", ">= 2.0"
|
|
34
|
+
spec.add_runtime_dependency "dry-configurable", "~> 1.0", ">= 1.2.0", "< 2"
|
|
35
|
+
spec.add_runtime_dependency "dry-core", "~> 1.0", "< 2"
|
|
36
|
+
spec.add_runtime_dependency "dry-inflector", "~> 1.0", ">= 1.1.0", "< 2"
|
|
37
|
+
spec.add_runtime_dependency "dry-monitor", "~> 1.0", ">= 1.0.1", "< 2"
|
|
38
|
+
spec.add_runtime_dependency "dry-system", "~> 1.1"
|
|
39
|
+
spec.add_runtime_dependency "dry-logger", "~> 1.2", "< 2"
|
|
40
|
+
spec.add_runtime_dependency "hanami-cli", ">= 2.3.1"
|
|
41
|
+
spec.add_runtime_dependency "hanami-utils", "~> 3.0.0"
|
|
42
|
+
spec.add_runtime_dependency "json", ">= 2.7.2"
|
|
43
|
+
spec.add_runtime_dependency "zeitwerk", "~> 2.6"
|
|
44
|
+
spec.add_runtime_dependency "rack-session"
|
|
45
|
+
spec.add_development_dependency "rspec", "~> 3.8"
|
|
46
|
+
spec.add_development_dependency "rack-test", "~> 2.0"
|
|
47
|
+
spec.add_development_dependency "rake", "~> 13.0"
|
|
48
|
+
end
|
|
49
|
+
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "constants"
|
|
4
|
+
require_relative "env"
|
|
5
|
+
|
|
6
|
+
module Hanami
|
|
7
|
+
# The Hanami app is a singular slice tasked with managing the core components of the app and
|
|
8
|
+
# coordinating overall app boot.
|
|
9
|
+
#
|
|
10
|
+
# For smaller apps, the app may be the only slice present, whereas larger apps may consist of many
|
|
11
|
+
# slices, with the app reserved for holding a small number of shared components only.
|
|
12
|
+
#
|
|
13
|
+
# @see Slice
|
|
14
|
+
#
|
|
15
|
+
# @api public
|
|
16
|
+
# @since 2.0.0
|
|
17
|
+
class App < Slice
|
|
18
|
+
@_mutex = Mutex.new
|
|
19
|
+
|
|
20
|
+
# @api private
|
|
21
|
+
# @since 2.0.0
|
|
22
|
+
def self.inherited(subclass)
|
|
23
|
+
super
|
|
24
|
+
|
|
25
|
+
Hanami.app = subclass
|
|
26
|
+
|
|
27
|
+
subclass.extend(ClassMethods)
|
|
28
|
+
|
|
29
|
+
@_mutex.synchronize do
|
|
30
|
+
subclass.class_eval do
|
|
31
|
+
@config = Hanami::Config.new(app_name: slice_name, env: Hanami.env)
|
|
32
|
+
Hanami::Env.load
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# App class interface
|
|
38
|
+
module ClassMethods
|
|
39
|
+
# Returns the app's config.
|
|
40
|
+
#
|
|
41
|
+
# @return [Hanami::Config]
|
|
42
|
+
#
|
|
43
|
+
# @api public
|
|
44
|
+
# @since 2.0.0
|
|
45
|
+
attr_reader :config
|
|
46
|
+
|
|
47
|
+
# Returns the app's {SliceName}.
|
|
48
|
+
#
|
|
49
|
+
# @return [Hanami::SliceName]
|
|
50
|
+
#
|
|
51
|
+
# @see Slice::ClassMethods#slice_name
|
|
52
|
+
#
|
|
53
|
+
# @api public
|
|
54
|
+
# @since 2.0.0
|
|
55
|
+
def app_name
|
|
56
|
+
slice_name
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Prepares the $LOAD_PATH based on the app's configured root, prepending the `lib/` directory
|
|
60
|
+
# if it exists. If the lib directory is already added, this will do nothing.
|
|
61
|
+
#
|
|
62
|
+
# In ordinary circumstances, you should never have to call this method: this method is called
|
|
63
|
+
# immediately upon subclassing {Hanami::App}, as a convenicence to put lib/ (under the default
|
|
64
|
+
# root of `Dir.pwd`) on the load path automatically. This is helpful if you need to require
|
|
65
|
+
# files inside the subclass body for performing certain app configuration steps.
|
|
66
|
+
#
|
|
67
|
+
# If you change your app's `config.root` and you need to require files from its `lib/`
|
|
68
|
+
# directory within your {App} subclass body, you should call {.prepare_load_path} explicitly
|
|
69
|
+
# after setting the new root.
|
|
70
|
+
#
|
|
71
|
+
# Otherwise, this method is called again as part of the app {.prepare} step, so if you've
|
|
72
|
+
# changed your app's root and do _not_ need to require files within your {App} subclass body,
|
|
73
|
+
# then you don't need to call this method.
|
|
74
|
+
#
|
|
75
|
+
# @example
|
|
76
|
+
# module MyApp
|
|
77
|
+
# class App < Hanami::App
|
|
78
|
+
# config.root = Pathname(__dir__).join("../src")
|
|
79
|
+
# prepare_load_path
|
|
80
|
+
#
|
|
81
|
+
# # You can make requires for your files here
|
|
82
|
+
# end
|
|
83
|
+
# end
|
|
84
|
+
#
|
|
85
|
+
# @return [self]
|
|
86
|
+
#
|
|
87
|
+
# @api public
|
|
88
|
+
# @since 2.0.0
|
|
89
|
+
def prepare_load_path
|
|
90
|
+
if (lib_path = root.join(LIB_DIR)).directory?
|
|
91
|
+
path = lib_path.realpath.to_s
|
|
92
|
+
$LOAD_PATH.prepend(path) unless $LOAD_PATH.include?(path)
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
self
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
private
|
|
99
|
+
|
|
100
|
+
def prepare_all
|
|
101
|
+
prepare_load_path
|
|
102
|
+
|
|
103
|
+
# Make app-wide notifications available as early as possible
|
|
104
|
+
container.use(:notifications)
|
|
105
|
+
|
|
106
|
+
# Ensure all basic slice preparation is complete before we make adjustments below (which
|
|
107
|
+
# rely on the basic prepare steps having already run)
|
|
108
|
+
super
|
|
109
|
+
|
|
110
|
+
# Run specific prepare steps for the app slice. Note also that some standard steps have been
|
|
111
|
+
# skipped via the empty method overrides below.
|
|
112
|
+
prepare_app_component_dirs
|
|
113
|
+
prepare_app_providers
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
# Skip standard slice prepare steps that do not apply to the app
|
|
117
|
+
def prepare_container_component_dirs; end
|
|
118
|
+
def prepare_container_imports; end
|
|
119
|
+
|
|
120
|
+
# rubocop:disable Metrics/AbcSize
|
|
121
|
+
|
|
122
|
+
def prepare_app_component_dirs
|
|
123
|
+
# Component files in both `app/` and `app/lib/` define classes in the
|
|
124
|
+
# app's namespace
|
|
125
|
+
|
|
126
|
+
if root.join(APP_DIR, LIB_DIR).directory?
|
|
127
|
+
container.config.component_dirs.add(File.join(APP_DIR, LIB_DIR)) do |dir|
|
|
128
|
+
dir.namespaces.add_root(key: nil, const: app_name.name)
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
# When auto-registering components in `app/`, ignore files in `app/lib/` (these will be
|
|
133
|
+
# auto-registered as above), as well as the configured no_auto_register_paths
|
|
134
|
+
no_auto_register_paths = ([LIB_DIR] + config.no_auto_register_paths)
|
|
135
|
+
.map { |path|
|
|
136
|
+
path.end_with?(File::SEPARATOR) ? path : "#{path}#{File::SEPARATOR}"
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
if root.join(APP_DIR).directory?
|
|
140
|
+
container.config.component_dirs.add(APP_DIR) do |dir|
|
|
141
|
+
dir.namespaces.add_root(key: nil, const: app_name.name)
|
|
142
|
+
dir.auto_register = -> component {
|
|
143
|
+
relative_path = component.file_path.relative_path_from(root.join(APP_DIR)).to_s
|
|
144
|
+
!relative_path.start_with?(*no_auto_register_paths)
|
|
145
|
+
}
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
def prepare_app_providers
|
|
151
|
+
require_relative "providers/inflector"
|
|
152
|
+
register_provider(:inflector, source: Hanami::Providers::Inflector)
|
|
153
|
+
|
|
154
|
+
# Allow the logger to be replaced by users with a manual provider, for advanced cases.
|
|
155
|
+
#
|
|
156
|
+
# Require the logger provider source up front, to make `configure_provider(:logger)`
|
|
157
|
+
# possible.
|
|
158
|
+
require_relative "providers/logger"
|
|
159
|
+
unless container.providers[:logger]
|
|
160
|
+
register_provider(:logger, source: Hanami::Providers::Logger)
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
# Ensure the logger is wrapped by `Hanami::UniversalLogger`, even if manually registered in a
|
|
164
|
+
# user-defined provider, guaranteeing Hanami's structured and tagged logging interface across
|
|
165
|
+
# the framework.
|
|
166
|
+
container.providers[:logger].source.after(:start) do
|
|
167
|
+
container.decorate(:logger) { |logger| Hanami::UniversalLogger[logger] }
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
if Hanami.bundled?("rack")
|
|
171
|
+
require_relative "providers/rack"
|
|
172
|
+
register_provider(:rack, source: Hanami::Providers::Rack, namespace: true)
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
if Hanami.bundled?("hanami-db")
|
|
176
|
+
register_provider(:db_logging, source: Hanami::Providers::DBLogging)
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
def prepare_autoloader
|
|
181
|
+
autoloader.tag = "hanami.app.#{slice_name.name}"
|
|
182
|
+
|
|
183
|
+
# Component dirs are automatically pushed to the autoloader by dry-system's zeitwerk plugin.
|
|
184
|
+
# This method adds other dirs that are not otherwise configured as component dirs.
|
|
185
|
+
|
|
186
|
+
# Autoload classes from `lib/[app_namespace]/`
|
|
187
|
+
if root.join(LIB_DIR, app_name.name).directory?
|
|
188
|
+
autoloader.push_dir(root.join(LIB_DIR, app_name.name), namespace: namespace)
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
autoloader.setup
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
# rubocop:enable Metrics/AbcSize
|
|
195
|
+
end
|
|
196
|
+
end
|
|
197
|
+
end
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Hanami
|
|
4
|
+
class Config
|
|
5
|
+
class Actions
|
|
6
|
+
# Config for Content Security Policy in Hanami apps
|
|
7
|
+
#
|
|
8
|
+
# @since 2.0.0
|
|
9
|
+
class ContentSecurityPolicy
|
|
10
|
+
# @since 2.0.0
|
|
11
|
+
# @api private
|
|
12
|
+
def initialize(&blk)
|
|
13
|
+
@policy = {
|
|
14
|
+
base_uri: "'self'",
|
|
15
|
+
child_src: "'self'",
|
|
16
|
+
connect_src: "'self'",
|
|
17
|
+
default_src: "'none'",
|
|
18
|
+
font_src: "'self'",
|
|
19
|
+
form_action: "'self'",
|
|
20
|
+
frame_ancestors: "'self'",
|
|
21
|
+
frame_src: "'self'",
|
|
22
|
+
img_src: "'self' https: data:",
|
|
23
|
+
media_src: "'self'",
|
|
24
|
+
object_src: "'none'",
|
|
25
|
+
script_src: "'self'",
|
|
26
|
+
style_src: "'self' 'unsafe-inline' https:"
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
blk&.(self)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# @since 2.0.0
|
|
33
|
+
# @api private
|
|
34
|
+
def initialize_copy(original_object)
|
|
35
|
+
@policy = original_object.instance_variable_get(:@policy).dup
|
|
36
|
+
super
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Get a CSP setting
|
|
40
|
+
#
|
|
41
|
+
# @param key [Symbol] the underscored name of the CPS setting
|
|
42
|
+
# @return [String,NilClass] the CSP setting, if any
|
|
43
|
+
#
|
|
44
|
+
# @since 2.0.0
|
|
45
|
+
# @api public
|
|
46
|
+
#
|
|
47
|
+
# @example
|
|
48
|
+
# module MyApp
|
|
49
|
+
# class App < Hanami::App
|
|
50
|
+
# config.actions.content_security_policy[:base_uri] # => "'self'"
|
|
51
|
+
# end
|
|
52
|
+
# end
|
|
53
|
+
def [](key)
|
|
54
|
+
@policy[key]
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Set a CSP setting
|
|
58
|
+
#
|
|
59
|
+
# @param key [Symbol] the underscored name of the CPS setting
|
|
60
|
+
# @param value [String] the CSP setting value
|
|
61
|
+
#
|
|
62
|
+
# @since 2.0.0
|
|
63
|
+
# @api public
|
|
64
|
+
#
|
|
65
|
+
# @example Replace a default value
|
|
66
|
+
# module MyApp
|
|
67
|
+
# class App < Hanami::App
|
|
68
|
+
# config.actions.content_security_policy[:plugin_types] = nil
|
|
69
|
+
# end
|
|
70
|
+
# end
|
|
71
|
+
#
|
|
72
|
+
# @example Append to a default value
|
|
73
|
+
# module MyApp
|
|
74
|
+
# class App < Hanami::App
|
|
75
|
+
# config.actions.content_security_policy[:script_src] += " https://my.cdn.test"
|
|
76
|
+
# end
|
|
77
|
+
# end
|
|
78
|
+
def []=(key, value)
|
|
79
|
+
@policy[key] = value
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# Deletes a CSP key
|
|
83
|
+
#
|
|
84
|
+
# @param key [Symbol] the underscored name of the CPS setting
|
|
85
|
+
#
|
|
86
|
+
# @since 2.0.0
|
|
87
|
+
# @api public
|
|
88
|
+
#
|
|
89
|
+
# @example
|
|
90
|
+
# module MyApp
|
|
91
|
+
# class App < Hanami::App
|
|
92
|
+
# config.actions.content_security_policy.delete(:object_src)
|
|
93
|
+
# end
|
|
94
|
+
# end
|
|
95
|
+
def delete(key)
|
|
96
|
+
@policy.delete(key)
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# Returns true if 'nonce' is used in any of the policies.
|
|
100
|
+
#
|
|
101
|
+
# @return [Boolean]
|
|
102
|
+
#
|
|
103
|
+
# @api public
|
|
104
|
+
# @since 2.3.0
|
|
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 2.3.0
|
|
116
|
+
def middleware
|
|
117
|
+
return [] unless nonce?
|
|
118
|
+
|
|
119
|
+
[Hanami::Middleware::ContentSecurityPolicyNonce]
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
# @since 2.0.0
|
|
123
|
+
# @api private
|
|
124
|
+
def to_s
|
|
125
|
+
@policy.map do |key, value|
|
|
126
|
+
"#{dasherize(key)} #{value}"
|
|
127
|
+
end.join(";")
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
private
|
|
131
|
+
|
|
132
|
+
# @since 2.0.0
|
|
133
|
+
# @api private
|
|
134
|
+
def dasherize(key)
|
|
135
|
+
key.to_s.gsub("_", "-")
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Hanami
|
|
4
|
+
class Config
|
|
5
|
+
class Actions
|
|
6
|
+
# Wrapper for app-level config of HTTP cookies for Hanami actions.
|
|
7
|
+
#
|
|
8
|
+
# This decorates the hash of cookie options that is otherwise directly configurable on
|
|
9
|
+
# actions, and adds the `enabled?` method to allow app base action to determine whether to
|
|
10
|
+
# include the `Action::Cookies` module.
|
|
11
|
+
#
|
|
12
|
+
# @api public
|
|
13
|
+
# @since 2.0.0
|
|
14
|
+
class Cookies
|
|
15
|
+
# Returns the cookie options.
|
|
16
|
+
#
|
|
17
|
+
# @return [Hash]
|
|
18
|
+
#
|
|
19
|
+
# @api public
|
|
20
|
+
# @since 2.0.0
|
|
21
|
+
attr_reader :options
|
|
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
|
|
30
|
+
def initialize(options)
|
|
31
|
+
@options = options
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Returns true if any cookie options have been provided.
|
|
35
|
+
#
|
|
36
|
+
# @return [Boolean]
|
|
37
|
+
#
|
|
38
|
+
# @api public
|
|
39
|
+
# @since 2.0.0
|
|
40
|
+
def enabled?
|
|
41
|
+
!options.nil?
|
|
42
|
+
end
|
|
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
|
|
51
|
+
def to_h
|
|
52
|
+
options.to_h
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "hanami/utils/string"
|
|
4
|
+
require "hanami/utils/class"
|
|
5
|
+
|
|
6
|
+
module Hanami
|
|
7
|
+
class Config
|
|
8
|
+
class Actions
|
|
9
|
+
# Config for HTTP session middleware in Hanami actions.
|
|
10
|
+
#
|
|
11
|
+
# @api public
|
|
12
|
+
# @since 2.0.0
|
|
13
|
+
class Sessions
|
|
14
|
+
# Returns the configured session storage
|
|
15
|
+
#
|
|
16
|
+
# @return [Symbol]
|
|
17
|
+
#
|
|
18
|
+
# @api public
|
|
19
|
+
# @since 2.0.0
|
|
20
|
+
attr_reader :storage
|
|
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
|
|
40
|
+
def initialize(storage = nil, *options)
|
|
41
|
+
@storage = storage
|
|
42
|
+
@options = options
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Returns true if sessions have been enabled.
|
|
46
|
+
#
|
|
47
|
+
# @return [Boolean]
|
|
48
|
+
#
|
|
49
|
+
# @api public
|
|
50
|
+
# @since 2.0.0
|
|
51
|
+
def enabled?
|
|
52
|
+
!storage.nil?
|
|
53
|
+
end
|
|
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
|
|
62
|
+
def middleware
|
|
63
|
+
return [] unless enabled?
|
|
64
|
+
|
|
65
|
+
[storage_middleware, options].flatten(1)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
private
|
|
69
|
+
|
|
70
|
+
def storage_middleware
|
|
71
|
+
require_storage
|
|
72
|
+
|
|
73
|
+
name = Utils::String.classify(storage)
|
|
74
|
+
Utils::Class.load!(name, ::Rack::Session)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def require_storage
|
|
78
|
+
require "rack/session/#{storage}"
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|