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.
Files changed (99) hide show
  1. checksums.yaml +7 -0
  2. data/hanami-3.0.1/CHANGELOG.md +1701 -0
  3. data/hanami-3.0.1/LICENSE +20 -0
  4. data/hanami-3.0.1/README.md +89 -0
  5. data/hanami-3.0.1/hanami.gemspec +49 -0
  6. data/hanami-3.0.1/lib/hanami/app.rb +197 -0
  7. data/hanami-3.0.1/lib/hanami/boot.rb +5 -0
  8. data/hanami-3.0.1/lib/hanami/config/actions/content_security_policy.rb +140 -0
  9. data/hanami-3.0.1/lib/hanami/config/actions/cookies.rb +57 -0
  10. data/hanami-3.0.1/lib/hanami/config/actions/sessions.rb +83 -0
  11. data/hanami-3.0.1/lib/hanami/config/actions.rb +189 -0
  12. data/hanami-3.0.1/lib/hanami/config/assets.rb +84 -0
  13. data/hanami-3.0.1/lib/hanami/config/console.rb +79 -0
  14. data/hanami-3.0.1/lib/hanami/config/db.rb +35 -0
  15. data/hanami-3.0.1/lib/hanami/config/i18n.rb +138 -0
  16. data/hanami-3.0.1/lib/hanami/config/logger.rb +207 -0
  17. data/hanami-3.0.1/lib/hanami/config/null_config.rb +17 -0
  18. data/hanami-3.0.1/lib/hanami/config/router.rb +48 -0
  19. data/hanami-3.0.1/lib/hanami/config/views.rb +103 -0
  20. data/hanami-3.0.1/lib/hanami/config.rb +564 -0
  21. data/hanami-3.0.1/lib/hanami/constants.rb +62 -0
  22. data/hanami-3.0.1/lib/hanami/env.rb +52 -0
  23. data/hanami-3.0.1/lib/hanami/errors.rb +41 -0
  24. data/hanami-3.0.1/lib/hanami/extensions/action/i18n_helper.rb +64 -0
  25. data/hanami-3.0.1/lib/hanami/extensions/action/name_inferrer.rb +34 -0
  26. data/hanami-3.0.1/lib/hanami/extensions/action/slice_configured_action.rb +190 -0
  27. data/hanami-3.0.1/lib/hanami/extensions/action.rb +147 -0
  28. data/hanami-3.0.1/lib/hanami/extensions/db/repo.rb +108 -0
  29. data/hanami-3.0.1/lib/hanami/extensions/mailer/slice_configured_mailer.rb +134 -0
  30. data/hanami-3.0.1/lib/hanami/extensions/mailer.rb +28 -0
  31. data/hanami-3.0.1/lib/hanami/extensions/operation/slice_configured_db_operation.rb +90 -0
  32. data/hanami-3.0.1/lib/hanami/extensions/operation.rb +33 -0
  33. data/hanami-3.0.1/lib/hanami/extensions/router/errors.rb +58 -0
  34. data/hanami-3.0.1/lib/hanami/extensions/view/context.rb +298 -0
  35. data/hanami-3.0.1/lib/hanami/extensions/view/part.rb +92 -0
  36. data/hanami-3.0.1/lib/hanami/extensions/view/scope.rb +36 -0
  37. data/hanami-3.0.1/lib/hanami/extensions/view/slice_configured_context.rb +73 -0
  38. data/hanami-3.0.1/lib/hanami/extensions/view/slice_configured_helpers.rb +55 -0
  39. data/hanami-3.0.1/lib/hanami/extensions/view/slice_configured_part.rb +73 -0
  40. data/hanami-3.0.1/lib/hanami/extensions/view/slice_configured_view.rb +243 -0
  41. data/hanami-3.0.1/lib/hanami/extensions/view/standard_helpers.rb +26 -0
  42. data/hanami-3.0.1/lib/hanami/extensions/view.rb +38 -0
  43. data/hanami-3.0.1/lib/hanami/extensions.rb +30 -0
  44. data/hanami-3.0.1/lib/hanami/helpers/assets_helper.rb +804 -0
  45. data/hanami-3.0.1/lib/hanami/helpers/form_helper/form_builder.rb +1389 -0
  46. data/hanami-3.0.1/lib/hanami/helpers/form_helper/values.rb +75 -0
  47. data/hanami-3.0.1/lib/hanami/helpers/form_helper.rb +213 -0
  48. data/hanami-3.0.1/lib/hanami/helpers/i18n_helper.rb +241 -0
  49. data/hanami-3.0.1/lib/hanami/logger/rack_formatter.rb +73 -0
  50. data/hanami-3.0.1/lib/hanami/logger/sql_formatter.rb +80 -0
  51. data/hanami-3.0.1/lib/hanami/logger/sql_logger.rb +48 -0
  52. data/hanami-3.0.1/lib/hanami/middleware/assets.rb +21 -0
  53. data/hanami-3.0.1/lib/hanami/middleware/content_security_policy_nonce.rb +53 -0
  54. data/hanami-3.0.1/lib/hanami/middleware/public_errors_app.rb +75 -0
  55. data/hanami-3.0.1/lib/hanami/middleware/render_errors.rb +90 -0
  56. data/hanami-3.0.1/lib/hanami/port.rb +45 -0
  57. data/hanami-3.0.1/lib/hanami/prepare.rb +5 -0
  58. data/hanami-3.0.1/lib/hanami/provider/source.rb +16 -0
  59. data/hanami-3.0.1/lib/hanami/provider_registrar.rb +28 -0
  60. data/hanami-3.0.1/lib/hanami/providers/assets.rb +28 -0
  61. data/hanami-3.0.1/lib/hanami/providers/db/adapter.rb +75 -0
  62. data/hanami-3.0.1/lib/hanami/providers/db/adapters.rb +66 -0
  63. data/hanami-3.0.1/lib/hanami/providers/db/config.rb +44 -0
  64. data/hanami-3.0.1/lib/hanami/providers/db/gateway.rb +87 -0
  65. data/hanami-3.0.1/lib/hanami/providers/db/sql_adapter.rb +100 -0
  66. data/hanami-3.0.1/lib/hanami/providers/db.rb +325 -0
  67. data/hanami-3.0.1/lib/hanami/providers/db_logging.rb +19 -0
  68. data/hanami-3.0.1/lib/hanami/providers/i18n/backend.rb +373 -0
  69. data/hanami-3.0.1/lib/hanami/providers/i18n/locale/en.yml +57 -0
  70. data/hanami-3.0.1/lib/hanami/providers/i18n.rb +114 -0
  71. data/hanami-3.0.1/lib/hanami/providers/inflector.rb +17 -0
  72. data/hanami-3.0.1/lib/hanami/providers/logger.rb +41 -0
  73. data/hanami-3.0.1/lib/hanami/providers/mailers.rb +101 -0
  74. data/hanami-3.0.1/lib/hanami/providers/rack.rb +47 -0
  75. data/hanami-3.0.1/lib/hanami/providers/relations.rb +31 -0
  76. data/hanami-3.0.1/lib/hanami/providers/routes.rb +29 -0
  77. data/hanami-3.0.1/lib/hanami/rake_tasks.rb +54 -0
  78. data/hanami-3.0.1/lib/hanami/routes.rb +146 -0
  79. data/hanami-3.0.1/lib/hanami/settings/composite_store.rb +53 -0
  80. data/hanami-3.0.1/lib/hanami/settings/env_store.rb +32 -0
  81. data/hanami-3.0.1/lib/hanami/settings.rb +234 -0
  82. data/hanami-3.0.1/lib/hanami/setup.rb +6 -0
  83. data/hanami-3.0.1/lib/hanami/slice/router.rb +280 -0
  84. data/hanami-3.0.1/lib/hanami/slice/routes_helper.rb +37 -0
  85. data/hanami-3.0.1/lib/hanami/slice/routing/middleware/stack.rb +216 -0
  86. data/hanami-3.0.1/lib/hanami/slice/routing/resolver.rb +88 -0
  87. data/hanami-3.0.1/lib/hanami/slice/view_name_inferrer.rb +63 -0
  88. data/hanami-3.0.1/lib/hanami/slice.rb +1239 -0
  89. data/hanami-3.0.1/lib/hanami/slice_configurable.rb +72 -0
  90. data/hanami-3.0.1/lib/hanami/slice_name.rb +111 -0
  91. data/hanami-3.0.1/lib/hanami/slice_registrar.rb +215 -0
  92. data/hanami-3.0.1/lib/hanami/universal_logger.rb +250 -0
  93. data/hanami-3.0.1/lib/hanami/version.rb +45 -0
  94. data/hanami-3.0.1/lib/hanami/web/rack_logger.rb +126 -0
  95. data/hanami-3.0.1/lib/hanami/web/welcome.html.erb +584 -0
  96. data/hanami-3.0.1/lib/hanami/web/welcome.rb +46 -0
  97. data/hanami-3.0.1/lib/hanami.rb +276 -0
  98. data/piko-lite-box.gemspec +11 -0
  99. metadata +137 -0
@@ -0,0 +1,100 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hanami
4
+ module Providers
5
+ class DB < Hanami::Provider::Source
6
+ # @api public
7
+ # @since 2.2.0
8
+ class SQLAdapter < Adapter
9
+ # @api public
10
+ # @since 2.2.0
11
+ setting :extensions, mutable: true
12
+
13
+ # @api public
14
+ # @since 2.2.0
15
+ def extension(*extensions)
16
+ self.extensions.concat(extensions).uniq!
17
+ end
18
+
19
+ # @api public
20
+ # @since 2.2.0
21
+ def extensions
22
+ config.extensions ||= []
23
+ end
24
+
25
+ # @api private
26
+ def configure_from_adapter(other_adapter)
27
+ super
28
+
29
+ return if skip_defaults?
30
+
31
+ # As part of gateway configuration, every gateway will receive the "any adapter" here,
32
+ # which is a plain `Adapter`, not an `SQLAdapter`. Its configuration will have been merged
33
+ # by `super`, so no further work is required.
34
+ return unless other_adapter.is_a?(self.class)
35
+
36
+ extensions.concat(other_adapter.extensions).uniq! unless skip_defaults?(:extensions)
37
+ end
38
+
39
+ # @api private
40
+ def configure_for_database(database_url)
41
+ return if skip_defaults?
42
+
43
+ configure_plugins
44
+ configure_extensions(database_url)
45
+ end
46
+
47
+ # @api private
48
+ private def configure_plugins
49
+ return if skip_defaults?(:plugins)
50
+
51
+ # Configure the plugin via a frozen proc, so it can be properly uniq'ed when configured
52
+ # for multiple gateways. See `Hanami::Providers::DB::Config#each_plugin`.
53
+ plugin(relations: :instrumentation, &INSTRUMENTATION_PLUGIN_CONFIG)
54
+
55
+ plugin relations: :auto_restrictions
56
+ end
57
+
58
+ # @api private
59
+ INSTRUMENTATION_PLUGIN_CONFIG = -> plugin {
60
+ plugin.notifications = target["notifications"]
61
+ }.freeze
62
+ private_constant :INSTRUMENTATION_PLUGIN_CONFIG
63
+
64
+ # @api private
65
+ private def configure_extensions(database_url)
66
+ return if skip_defaults?(:extensions)
67
+
68
+ # Extensions for all SQL databases
69
+ extension(
70
+ :caller_logging,
71
+ :error_sql,
72
+ :sql_comments
73
+ )
74
+
75
+ # Extensions for specific databases
76
+ if database_url.to_s.start_with?(%r{postgres(ql)*://})
77
+ extension(
78
+ :pg_array,
79
+ :pg_enum,
80
+ :pg_json,
81
+ :pg_range
82
+ )
83
+ end
84
+ end
85
+
86
+ # @api private
87
+ def gateway_options
88
+ {extensions: extensions}
89
+ end
90
+
91
+ # @api public
92
+ # @since 2.2.0
93
+ def clear
94
+ config.extensions = nil
95
+ super
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,325 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "dry/configurable"
4
+ require "dry/core"
5
+ require "uri"
6
+ require_relative "../constants"
7
+
8
+ module Hanami
9
+ module Providers
10
+ # rubocop:disable Metrics/AbcSize, Metrics/PerceivedComplexity
11
+
12
+ # @api private
13
+ # @since 2.2.0
14
+ class DB < Hanami::Provider::Source
15
+ extend Dry::Core::Cache
16
+
17
+ include Dry::Configurable(config_class: Providers::DB::Config)
18
+
19
+ setting :adapters, mutable: true, default: Adapters.new
20
+ setting :gateways, default: {}
21
+
22
+ def initialize(...)
23
+ super(...)
24
+
25
+ @config_finalized = false
26
+ end
27
+
28
+ def finalize_config
29
+ return if @config_finalized
30
+
31
+ apply_parent_config if apply_parent_config?
32
+
33
+ configure_gateways
34
+
35
+ @config_finalized = true
36
+
37
+ self
38
+ end
39
+
40
+ def prepare
41
+ prepare_and_import_parent_db and return if import_from_parent?
42
+
43
+ override_rom_inflector
44
+
45
+ finalize_config
46
+
47
+ require "hanami-db"
48
+
49
+ gateways = prepare_gateways
50
+
51
+ if gateways[:default]
52
+ register "gateway", gateways[:default]
53
+ elsif gateways.length == 1
54
+ register "gateway", gateways.values.first
55
+ end
56
+ gateways.each do |key, gateway|
57
+ register "gateways.#{key}", gateway
58
+ end
59
+
60
+ @rom_config = ROM::Configuration.new(gateways)
61
+
62
+ config.each_plugin do |adapter_name, plugin_spec, config_block|
63
+ if config_block
64
+ @rom_config.plugin(adapter_name, plugin_spec) do |plugin_config|
65
+ instance_exec(plugin_config, &config_block)
66
+ end
67
+ else
68
+ @rom_config.plugin(adapter_name, plugin_spec)
69
+ end
70
+ end
71
+
72
+ register "config", @rom_config
73
+ end
74
+
75
+ def start
76
+ start_and_import_parent_db and return if import_from_parent?
77
+
78
+ # Set up DB logging for the whole app. We share the app's notifications bus across all
79
+ # slices, so we only need to configure the subsciprtion for DB logging just once.
80
+ slice.app.start :db_logging
81
+
82
+ # Register ROM components
83
+ register_rom_components :relation, "relations"
84
+ register_rom_components :command, File.join("db", "commands")
85
+ register_rom_components :mapper, File.join("db", "mappers")
86
+
87
+ rom = ROM.container(@rom_config)
88
+
89
+ register "rom", rom
90
+ end
91
+
92
+ def stop
93
+ slice["db.rom"].disconnect
94
+ end
95
+
96
+ # @api private
97
+ # @since 2.2.0
98
+ def database_urls
99
+ finalize_config
100
+ config.gateways.transform_values { _1.database_url }
101
+ end
102
+
103
+ private
104
+
105
+ def parent_db_provider
106
+ return @parent_db_provider if instance_variable_defined?(:@parent_db_provider)
107
+
108
+ @parent_db_provider = slice.parent && slice.parent.container.providers[:db]
109
+ end
110
+
111
+ def apply_parent_config
112
+ parent_db_provider.source.finalize_config
113
+
114
+ self.class.settings.keys.each do |key|
115
+ # Preserve settings already configured locally
116
+ next if config.configured?(key)
117
+
118
+ # Skip gateway config, we handle this in #configure_gateways
119
+ next if key == :gateways
120
+
121
+ # Skip adapter config, we handle this below
122
+ next if key == :adapters
123
+
124
+ config[key] = parent_db_provider.source.config[key]
125
+ end
126
+
127
+ parent_db_provider.source.config.adapters.each do |adapter_name, parent_adapter|
128
+ adapter = config.adapter(adapter_name)
129
+
130
+ adapter.class.settings.keys.each do |key|
131
+ next if adapter.config.configured?(key)
132
+
133
+ adapter.config[key] = parent_adapter.config[key].dup
134
+ end
135
+ end
136
+ end
137
+
138
+ def apply_parent_config?
139
+ slice.config.db.configure_from_parent && parent_db_provider
140
+ end
141
+
142
+ def import_from_parent?
143
+ slice.config.db.import_from_parent && slice.parent
144
+ end
145
+
146
+ def prepare_and_import_parent_db
147
+ return unless parent_db_provider
148
+
149
+ slice.parent.prepare :db
150
+ @rom_config = slice.parent["db.config"]
151
+
152
+ register "config", (@rom_config = slice.parent["db.config"])
153
+ register "gateway", slice.parent["db.gateway"]
154
+ end
155
+
156
+ def start_and_import_parent_db
157
+ return unless parent_db_provider
158
+
159
+ slice.parent.start :db
160
+
161
+ register "rom", slice.parent["db.rom"]
162
+ end
163
+
164
+ # ROM 5.3 doesn't have a configurable inflector.
165
+ #
166
+ # This is a problem in Hanami because using different
167
+ # inflection rules for ROM will lead to constant loading
168
+ # errors.
169
+ def override_rom_inflector
170
+ return if ROM::Inflector == Hanami.app["inflector"]
171
+
172
+ ROM.instance_eval {
173
+ remove_const :Inflector
174
+ const_set :Inflector, Hanami.app["inflector"]
175
+ }
176
+ end
177
+
178
+ def configure_gateways
179
+ # Create gateway configs for gateways detected from database_url ENV vars
180
+ database_urls_from_env = detect_database_urls_from_env
181
+ database_urls_from_env.keys.each do |key|
182
+ config.gateways[key] ||= Gateway.new
183
+ end
184
+
185
+ # Create a single default gateway if none is configured or detected from database URLs
186
+ config.gateways[:default] = Gateway.new if config.gateways.empty?
187
+
188
+ # Leave gateways in a stable order: :default first, followed by others in sort order
189
+ if config.gateways.length > 1
190
+ gateways = config.gateways
191
+ config.gateways = {default: gateways[:default], **gateways.sort.to_h}.compact
192
+ end
193
+
194
+ config.gateways.each do |key, gw_config|
195
+ gw_config.database_url ||= database_urls_from_env.fetch(key) {
196
+ raise Hanami::ComponentLoadError, "A database_url for gateway #{key} is required to start :db."
197
+ }
198
+
199
+ ensure_database_gem(gw_config.database_url)
200
+
201
+ apply_parent_gateway_config(key, gw_config) if apply_parent_config?
202
+
203
+ gw_config.configure_adapter(config.adapters)
204
+ end
205
+ end
206
+
207
+ def apply_parent_gateway_config(key, gw_config)
208
+ parent_gw_config = parent_db_provider.source.config.gateways[key]
209
+
210
+ # Only copy config from a parent gateway with the same name _and_ database URL
211
+ return unless parent_gw_config&.database_url == gw_config.database_url
212
+
213
+ # Copy config from matching parent gateway
214
+ (gw_config.class.settings.keys - [:adapter]).each do |key|
215
+ next if gw_config.config.configured?(key)
216
+
217
+ gw_config.config[key] = parent_gw_config.config[key].dup
218
+ end
219
+
220
+ # If there is an adapter configured within this slice, prefer that, and do not copy the
221
+ # adapter from the parent gateway
222
+ unless config.adapters[gw_config.adapter_name] || gw_config.configured?(:adapter)
223
+ gw_config.adapter = parent_gw_config.adapter.dup
224
+ end
225
+ end
226
+
227
+ def prepare_gateways
228
+ config.gateways.transform_values { |gw_config|
229
+ # Avoid spurious connections by reusing identically configured gateways across slices
230
+ fetch_or_store(gw_config.cache_keys) {
231
+ ROM::Gateway.setup(
232
+ gw_config.adapter_name,
233
+ gw_config.database_url,
234
+ **gw_config.options
235
+ )
236
+ }
237
+ }
238
+ end
239
+
240
+ def detect_database_urls_from_env
241
+ database_urls = {}
242
+
243
+ env_var_prefix = slice.slice_name.name.gsub("/", "__").upcase + "__" unless slice.app?
244
+
245
+ # Build gateway URLs from ENV vars with specific gateway named suffixes
246
+ gateway_prefix = "#{env_var_prefix}DATABASE_URL__"
247
+ ENV.select { |(k, _)| k.start_with?(gateway_prefix) }
248
+ .each do |(var, _)|
249
+ gateway_name = var.split(gateway_prefix).last.downcase
250
+
251
+ database_urls[gateway_name.to_sym] = ENV[var]
252
+ end
253
+
254
+ # Set the default gateway from ENV var without suffix
255
+ unless database_urls.key?(:default)
256
+ fallback_vars = ["#{env_var_prefix}DATABASE_URL", "DATABASE_URL"].uniq
257
+
258
+ fallback_vars.each do |var|
259
+ url = ENV[var]
260
+ database_urls[:default] = url and break if url
261
+ end
262
+ end
263
+
264
+ if Hanami.env?(:test)
265
+ database_urls.transform_values! { Hanami::DB::Testing.database_url(_1) }
266
+ end
267
+
268
+ database_urls
269
+ end
270
+
271
+ # @api private
272
+ # @since 2.2.0
273
+ DATABASE_GEMS = {
274
+ "mysql2" => "mysql2",
275
+ "postgres" => "pg",
276
+ "sqlite" => "sqlite3"
277
+ }.freeze
278
+ private_constant :DATABASE_GEMS
279
+
280
+ # Raises an error if the relevant database gem for the configured database_url is not
281
+ # installed.
282
+ #
283
+ # Takes a conservative approach to raising errors. It only does so for the database_url
284
+ # schemes generated by the `hanami new` CLI command. Uknown schemes are ignored and no errors
285
+ # are raised.
286
+ def ensure_database_gem(database_url)
287
+ scheme = URI(database_url).scheme
288
+ return unless scheme
289
+
290
+ database_gem = DATABASE_GEMS[scheme]
291
+ return unless database_gem
292
+
293
+ return if Hanami.bundled?(database_gem)
294
+
295
+ raise Hanami::ComponentLoadError, <<~STR
296
+ The "#{database_gem}" gem is required to connect to #{database_url}. Please add it to your Gemfile.
297
+ STR
298
+ end
299
+
300
+ def register_rom_components(component_type, path)
301
+ components_path = target.source_path.join(path)
302
+ components_path.glob("**/*.rb").each do |component_file|
303
+ component_name = component_file
304
+ .relative_path_from(components_path)
305
+ .sub(RB_EXT_REGEXP, "")
306
+ .to_s
307
+
308
+ component_class = target.inflector.camelize(
309
+ "#{target.slice_name.name}/#{path}/#{component_name}"
310
+ ).then { target.inflector.constantize(_1) }
311
+
312
+ @rom_config.public_send(:"register_#{component_type}", component_class)
313
+ end
314
+ end
315
+ end
316
+ # rubocop:enable Metrics/AbcSize, Metrics/PerceivedComplexity
317
+
318
+ Dry::System.register_provider_source(
319
+ :db,
320
+ source: DB,
321
+ group: :hanami,
322
+ provider_options: {namespace: true}
323
+ )
324
+ end
325
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hanami
4
+ module Providers
5
+ # @api private
6
+ class DBLogging < Hanami::Provider::Source
7
+ def prepare
8
+ slice["notifications"].register_event :sql
9
+ end
10
+
11
+ def start
12
+ require "hanami/logger/sql_logger"
13
+ Hanami::Logger::SQLLogger
14
+ .new(slice["logger"], level: slice.config.db.log_level)
15
+ .subscribe(slice["notifications"])
16
+ end
17
+ end
18
+ end
19
+ end