plutonium 0.13.3 → 0.14.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 (35) hide show
  1. checksums.yaml +4 -4
  2. data/lib/generators/pu/core/assets/assets_generator.rb +2 -2
  3. data/lib/generators/pu/core/install/install_generator.rb +0 -3
  4. data/lib/generators/pu/core/install/templates/config/initializers/plutonium.rb +10 -0
  5. data/lib/generators/pu/lib/plutonium_generators/concerns/actions.rb +19 -0
  6. data/lib/generators/pu/pkg/app/templates/config/routes.rb.tt +5 -6
  7. data/lib/generators/pu/pkg/app/templates/lib/engine.rb.tt +0 -4
  8. data/lib/generators/pu/res/conn/conn_generator.rb +4 -4
  9. data/lib/plutonium/application/controller.rb +1 -1
  10. data/lib/plutonium/application/dynamic_controllers.rb +108 -0
  11. data/lib/plutonium/auth/rodauth.rb +1 -1
  12. data/lib/plutonium/concerns/resource_validatable.rb +34 -0
  13. data/lib/plutonium/config/overlayed_hash.rb +86 -0
  14. data/lib/plutonium/configuration.rb +138 -0
  15. data/lib/plutonium/core/autodiscovery/association_renderer_discoverer.rb +1 -1
  16. data/lib/plutonium/core/autodiscovery/input_discoverer.rb +1 -1
  17. data/lib/plutonium/core/autodiscovery/renderer_discoverer.rb +1 -1
  18. data/lib/plutonium/core/controllers/entity_scoping.rb +84 -26
  19. data/lib/plutonium/helpers/assets_helper.rb +73 -20
  20. data/lib/plutonium/pkg/app.rb +3 -115
  21. data/lib/plutonium/pkg/concerns/resource_validatable.rb +36 -0
  22. data/lib/plutonium/railtie.rb +53 -30
  23. data/lib/plutonium/reloader.rb +66 -24
  24. data/lib/plutonium/resource/controller.rb +1 -1
  25. data/lib/plutonium/resource_register.rb +83 -0
  26. data/lib/plutonium/routing/mapper_extensions.rb +127 -0
  27. data/lib/plutonium/routing/resource_registration.rb +16 -0
  28. data/lib/plutonium/routing/route_set_extensions.rb +132 -0
  29. data/lib/plutonium/smart_cache.rb +151 -0
  30. data/lib/plutonium/version.rb +1 -1
  31. data/lib/plutonium.rb +41 -27
  32. data/sig/.keep +0 -0
  33. metadata +13 -4
  34. data/lib/generators/pu/rodauth/templates/app/rodauth/account_rodauth_plugin.rb.tt +0 -270
  35. data/sig/plutonium.rbs +0 -12
@@ -1,6 +1,17 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Plutonium
2
4
  module Core
3
5
  module Controllers
6
+ # EntityScoping module provides functionality for scoping controllers to specific entities.
7
+ #
8
+ # This module is designed to be included in controllers that need to operate within the context
9
+ # of a specific entity, such as a user's organization or a project.
10
+ #
11
+ # @example Usage in a controller
12
+ # class MyController < ApplicationController
13
+ # include Plutonium::Core::Controllers::EntityScoping
14
+ # end
4
15
  module EntityScoping
5
16
  extend ActiveSupport::Concern
6
17
 
@@ -9,70 +20,117 @@ module Plutonium
9
20
  helper_method :current_scoped_entity
10
21
  end
11
22
 
12
- private
13
-
23
+ # Checks if the current engine is scoped to an entity.
24
+ #
25
+ # @return [Boolean] true if scoped to an entity, false otherwise
14
26
  def scoped_to_entity?
15
27
  current_engine.scoped_to_entity?
16
28
  end
17
29
 
30
+ # Returns the strategy used for entity scoping.
31
+ #
32
+ # @return [Symbol] the scoping strategy
18
33
  def scoped_entity_strategy
19
34
  current_engine.scoped_entity_strategy
20
35
  end
21
36
 
22
- def scoped_entity_class
23
- ensure_legal_entity_scoping_method_access! :scoped_entity_class
37
+ # Returns the parameter key used for entity scoping.
38
+ #
39
+ # @return [Symbol] the parameter key
40
+ # @raise [NotImplementedError] if not scoped to an entity
41
+ def scoped_entity_param_key
42
+ ensure_legal_entity_scoping_method_access!(__method__)
43
+ current_engine.scoped_entity_param_key
44
+ end
24
45
 
46
+ # Returns the class of the scoped entity.
47
+ #
48
+ # @return [Class] the scoped entity class
49
+ # @raise [NotImplementedError] if not scoped to an entity
50
+ def scoped_entity_class
51
+ ensure_legal_entity_scoping_method_access!(__method__)
25
52
  current_engine.scoped_entity_class
26
53
  end
27
54
 
28
- def scoped_entity_param_key
29
- ensure_legal_entity_scoping_method_access! :scoped_entity_param_key
30
-
31
- current_engine.scoped_entity_param_key
32
- end
55
+ private
33
56
 
57
+ # Returns the session key used to store the scoped entity.
58
+ #
59
+ # @return [Symbol] the session key
60
+ # @raise [NotImplementedError] if not scoped to an entity
34
61
  def scoped_entity_session_key
35
- ensure_legal_entity_scoping_method_access! :scoped_entity_session_key
36
-
62
+ ensure_legal_entity_scoping_method_access!(__method__)
37
63
  :"#{current_package.name.underscore}__scoped_entity_id"
38
64
  end
39
65
 
66
+ # Returns the current scoped entity for the request.
67
+ #
68
+ # @return [ActiveRecord::Base, nil] the current scoped entity or nil if not found
69
+ # @raise [NotImplementedError] if not scoped to an entity or strategy is unknown
40
70
  def current_scoped_entity
41
- ensure_legal_entity_scoping_method_access! :current_scoped_entity
42
-
71
+ ensure_legal_entity_scoping_method_access!(__method__)
43
72
  return unless current_user.present?
44
73
 
45
- @current_scoped_entity ||= case scoped_entity_strategy
74
+ @current_scoped_entity ||= fetch_current_scoped_entity
75
+ end
76
+
77
+ # Fetches the current scoped entity based on the scoping strategy.
78
+ #
79
+ # @return [ActiveRecord::Base, nil] the current scoped entity or nil if not found
80
+ # @raise [NotImplementedError] if the scoping strategy is unknown
81
+ def fetch_current_scoped_entity
82
+ case scoped_entity_strategy
46
83
  when :path
47
- scoped_entity_class
48
- .associated_with(current_user)
49
- .from_path_param(request.path_parameters[scoped_entity_param_key])
50
- .first! # Raise NotFound if user does not have access to the entity or it does not exist
84
+ fetch_entity_from_path
51
85
  when Symbol
52
- send scoped_entity_strategy
86
+ send(scoped_entity_strategy)
53
87
  else
54
- raise NotImplementedError, "unknown scoped entity strategy: #{scoped_entity_strategy.inspect}"
88
+ raise NotImplementedError, "Unknown scoped entity strategy: #{scoped_entity_strategy.inspect}"
55
89
  end
56
90
  end
57
91
 
92
+ # Fetches the scoped entity from the path parameters.
93
+ #
94
+ # @return [ActiveRecord::Base] the scoped entity
95
+ # @raise [ActiveRecord::RecordNotFound] if the entity is not found or the user doesn't have access
96
+ def fetch_entity_from_path
97
+ scoped_entity_class
98
+ .associated_with(current_user)
99
+ .from_path_param(request.path_parameters[scoped_entity_param_key])
100
+ .first!
101
+ end
102
+
103
+ # Remembers the current scoped entity in the session.
104
+ #
105
+ # @return [void]
58
106
  def remember_scoped_entity
59
107
  return unless scoped_to_entity?
60
108
 
61
109
  session[scoped_entity_session_key] = current_scoped_entity.to_global_id.to_s
62
110
  end
63
111
 
112
+ # Retrieves the remembered scoped entity from the session.
113
+ #
114
+ # @return [ActiveRecord::Base, nil] the remembered scoped entity or nil if not found
115
+ # @raise [NotImplementedError] if not scoped to an entity
64
116
  def remembered_scoped_entity
65
- ensure_legal_entity_scoping_method_access! :remembered_scoped_entity
66
-
67
- @remembered_scoped_entity ||= GlobalID::Locator.locate session[scoped_entity_session_key]
117
+ ensure_legal_entity_scoping_method_access!(__method__)
118
+ @remembered_scoped_entity ||= GlobalID::Locator.locate(session[scoped_entity_session_key])
68
119
  end
69
120
 
121
+ # Ensures that the method call is legal within the current scoping context.
122
+ #
123
+ # @param method [Symbol] the method being called
124
+ # @raise [NotImplementedError] if not scoped to an entity
70
125
  def ensure_legal_entity_scoping_method_access!(method)
71
126
  return if scoped_to_entity?
72
127
 
73
- raise NotImplementedError, "this request is not scoped to an entity\n\n" \
74
- "add the `scope_to_entity YourEntityRecord` directive in " \
75
- "#{current_engine} or implement #{self.class}##{method}"
128
+ raise NotImplementedError, <<~ERROR_MESSAGE
129
+ This request is not scoped to an entity.
130
+
131
+ Add the `scope_to_entity YourEntityRecord` directive in #{current_engine}
132
+ or implement #{self.class}##{method}
133
+ ERROR_MESSAGE
76
134
  end
77
135
  end
78
136
  end
@@ -1,41 +1,94 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Plutonium
2
4
  module Helpers
5
+ # Helper module for managing asset-related functionality
3
6
  module AssetsHelper
7
+ # Generate a stylesheet tag for the resource
8
+ #
9
+ # @return [ActiveSupport::SafeBuffer] HTML stylesheet link tag
4
10
  def resource_stylesheet_tag
5
- url = if Plutonium.development?
6
- filename = JSON.parse(File.read(Plutonium.root.join("src", "build", "css.manifest")))["plutonium.css"]
7
- "/build/#{filename}"
8
- else
9
- resource_stylesheet_asset
10
- end
11
- stylesheet_link_tag url, "data-turbo-track": "reload"
11
+ url = resource_asset_url_for(:css, resource_stylesheet_asset)
12
+ stylesheet_link_tag(url, "data-turbo-track": "reload")
12
13
  end
13
14
 
15
+ # Generate a script tag for the resource
16
+ #
17
+ # @return [ActiveSupport::SafeBuffer] HTML script tag
14
18
  def resource_script_tag
15
- url = if Plutonium.development?
16
- filename = JSON.parse(File.read(Plutonium.root.join("src", "build", "js.manifest")))["plutonium.js"]
17
- "/build/#{filename}"
18
- else
19
- resource_script_asset
20
- end
21
- javascript_include_tag url, "data-turbo-track": "reload", type: "module"
19
+ url = resource_asset_url_for(:js, resource_script_asset)
20
+ javascript_include_tag(url, "data-turbo-track": "reload", type: "module")
22
21
  end
23
22
 
23
+ # Generate a favicon link tag
24
+ #
25
+ # @return [ActiveSupport::SafeBuffer] HTML favicon link tag
24
26
  def resource_favicon_tag
25
- favicon_link_tag resource_favicon_asset
27
+ favicon_link_tag(resource_favicon_asset)
26
28
  end
27
29
 
30
+ # Generate an image tag for the logo
31
+ #
32
+ # @param classname [String] CSS class name for the image tag
33
+ # @return [ActiveSupport::SafeBuffer] HTML image tag
28
34
  def resource_logo_tag(classname:)
29
- image_tag resource_logo_asset, class: classname
35
+ image_tag(resource_logo_asset, class: classname)
30
36
  end
31
37
 
32
- def resource_logo_asset = Rails.application.config.plutonium.assets.logo
38
+ # Get the logo asset path
39
+ #
40
+ # @return [String] path to the logo asset
41
+ def resource_logo_asset
42
+ Plutonium.configuration.assets.logo
43
+ end
33
44
 
34
- def resource_stylesheet_asset = Rails.application.config.plutonium.assets.stylesheet
45
+ # Get the stylesheet asset path
46
+ #
47
+ # @return [String] path to the stylesheet asset
48
+ def resource_stylesheet_asset
49
+ Plutonium.configuration.assets.stylesheet
50
+ end
35
51
 
36
- def resource_script_asset = Rails.application.config.plutonium.assets.script
52
+ # Get the script asset path
53
+ #
54
+ # @return [String] path to the script asset
55
+ def resource_script_asset
56
+ Plutonium.configuration.assets.script
57
+ end
37
58
 
38
- def resource_favicon_asset = Rails.application.config.plutonium.assets.favicon
59
+ # Get the favicon asset path
60
+ #
61
+ # @return [String] path to the favicon asset
62
+ def resource_favicon_asset
63
+ Plutonium.configuration.assets.favicon
64
+ end
65
+
66
+ private
67
+
68
+ # Generate the appropriate asset URL based on the environment
69
+ #
70
+ # @param type [Symbol] asset type (:css or :js)
71
+ # @param fallback [String] fallback asset path
72
+ # @return [String] asset URL
73
+ def resource_asset_url_for(type, fallback)
74
+ if Plutonium.configuration.development?
75
+ resource_development_asset_url(type)
76
+ else
77
+ fallback
78
+ end
79
+ end
80
+
81
+ # Generate the asset URL for development environment
82
+ #
83
+ # @param type [Symbol] asset type (:css or :js)
84
+ # @return [String] asset URL for development
85
+ def resource_development_asset_url(type)
86
+ manifest_file = (type == :css) ? "css.manifest" : "js.manifest"
87
+ asset_key = (type == :css) ? "plutonium.css" : "plutonium.js"
88
+
89
+ filename = JSON.parse(File.read(Plutonium.root.join("src", "build", manifest_file)))[asset_key]
90
+ "/build/#{filename}"
91
+ end
39
92
  end
40
93
  end
41
94
  end
@@ -1,4 +1,4 @@
1
- require "active_support/notifications"
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Plutonium
4
4
  module Pkg
@@ -11,10 +11,11 @@ module Plutonium
11
11
  end
12
12
 
13
13
  class_methods do
14
+ include Plutonium::Concerns::ResourceValidatable
14
15
  attr_reader :scoped_entity_class, :scoped_entity_strategy, :scoped_entity_param_key
15
16
 
16
17
  def scope_to_entity(entity_class, strategy: :path, param_key: nil)
17
- raise "#{entity_class} is not a valid resource record" unless entity_class.include?(Plutonium::Resource::Record)
18
+ validate_resource! entity_class
18
19
 
19
20
  @scoped_entity_class = entity_class
20
21
  @scoped_entity_strategy = strategy
@@ -25,122 +26,9 @@ module Plutonium
25
26
  scoped_entity_class.present?
26
27
  end
27
28
 
28
- def initialize_register!
29
- # this exists solely to support hot reloads
30
- # if the user has modified the register especially if they removed a registration, we have no way of telling
31
- # so instead we start over
32
- @resource_register = []
33
- end
34
-
35
- def register_resource(resource)
36
- @resource_register.append resource
37
- end
38
-
39
- def resource_register
40
- @resource_register || []
41
- end
42
-
43
- def registered_resource_route_key_lookup
44
- @registered_resource_route_key_lookup = resource_register.map { |resource|
45
- [resource.model_name.singular_route_key.to_sym, resource]
46
- }.to_h
47
- end
48
-
49
- def draw_custom_routes(&block)
50
- @custom_routes_block = block
51
- end
52
-
53
- def draw_resource_routes
54
- ActiveSupport::Notifications.instrument("plutonium.app.draw_resource_routes", app: self.class.module_parent.to_s) do
55
- draw_resource_routes_internal
56
- end
57
- end
58
-
59
29
  def dom_id
60
30
  module_parent_name.underscore.dasherize
61
31
  end
62
-
63
- private
64
-
65
- def draw_resource_routes_internal
66
- custom_routes_block = @custom_routes_block
67
- registered_resources = resource_register
68
- scoped_entity_param_key = self.scoped_entity_param_key if scoped_entity_strategy == :path
69
- routes.draw do
70
- shared_resource_concerns = [:interactive_resource_actions] # TODO: make this a config parameter
71
- concern :interactive_resource_actions do
72
- # these concerns power the interactive actions feature
73
- member do
74
- get "record_actions/:interactive_action", action: :begin_interactive_resource_record_action,
75
- as: :interactive_resource_record_action
76
- post "record_actions/:interactive_action", action: :commit_interactive_resource_record_action
77
- end
78
-
79
- collection do
80
- get "collection_actions/:interactive_action", action: :begin_interactive_resource_collection_action,
81
- as: :interactive_resource_collection_action
82
- post "collection_actions/:interactive_action", action: :commit_interactive_resource_collection_action
83
-
84
- get "recordless_actions/:interactive_action", action: :begin_interactive_resource_recordless_action,
85
- as: :interactive_resource_recordless_action
86
- post "recordless_actions/:interactive_action", action: :commit_interactive_resource_recordless_action
87
- end
88
- end
89
-
90
- resource_route_names = []
91
- resource_route_opts_lookup = {}
92
- # for each of our registered resources, we are registering the routes required
93
- registered_resources.each do |resource|
94
- resource_name = resource.to_s # Deeply::Namespaced::ResourceModel
95
- resource_controller = resource_name.pluralize.underscore # deeply/namespaced/resource_models
96
- resource_route = resource.model_name.plural # deeply_namespaced_resource_models
97
- resource_route_name = :"#{resource_route}_routes" # deeply_namespaced_resource_models_routes
98
-
99
- resource_route_opts = {}
100
- # rails is not smart enough to infer Deeply::Namespaced::ResourceModelsController from deeply_namespaced_resource_models
101
- # since we are heavy on namespaces, we choose to be explicit to guarantee there is no confusion
102
- resource_route_opts[:controller] = resource_controller
103
- # using collection for path is much nicer than the alternative
104
- # e.g. deeply/namespaced/resource_models vs deeply_namespaced_resource_models
105
- resource_route_opts[:path] = resource.model_name.collection
106
- resource_route_opts_lookup[resource_route] = resource_route_opts
107
-
108
- # defining our resources with concerns allows us to defer materializing till later,
109
- # ensuring that resource_route_opts_lookup is populated
110
- concern resource_route_name do
111
- resources resource_route, **resource_route_opts, concerns: shared_resource_concerns do
112
- nested_resources_route_opts = resource_route_opts_lookup.slice(*resource.has_many_association_routes)
113
- nested_resources_route_opts.each do |nested_resource_route, nested_resource_route_opts|
114
- resources nested_resource_route, **nested_resource_route_opts, concerns: shared_resource_concerns
115
- end
116
- end
117
- end
118
- resource_route_names << resource_route_name
119
- end
120
-
121
- # materialize our routes using a scope
122
- # if the app is scoped to an entity, ensure that the expected route param and url helper prefix are specified.
123
-
124
- # path => /:entity/deeply/namespaced/resource_models/:deeply_namespaced_resource_model_id/
125
- # helper => entity_deeply_namespaced_resource_models_path
126
- scope_name = scoped_entity_param_key.present? ? ":#{scoped_entity_param_key}" : ""
127
-
128
- # path => /deeply/namespaced/resource_models/:deeply_namespaced_resource_model_id/
129
- # helper => deeply_namespaced_resource_models_path
130
- scope_options = scoped_entity_param_key.present? ? {as: scoped_entity_param_key} : {}
131
-
132
- scope scope_name, scope_options do
133
- instance_exec(&custom_routes_block) if custom_routes_block.present?
134
- # we have to reverse sort our resource routes in order to prevent routing conflicts
135
- # e.g. /blogs/1 and blogs/comments cause an issue if Blog is registered before Blogs::Comment
136
- # attempting to load blogs/comments routes to blogs/:id which fails with a 404 since BlogsController
137
- # essentially performs a Blog.find('comments')
138
- # since the route names for these 2 will be 'blogs' and 'blog_comments',
139
- # reverse sorting ensures that blog_comments is registered first, preventing the issue described above
140
- concerns resource_route_names.sort
141
- end
142
- end
143
- end
144
32
  end
145
33
  end
146
34
  end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Plutonium
4
+ module Pkg
5
+ module Concerns
6
+ # Provides methods for validating Plutonium resources
7
+ module ResourceValidatable
8
+ extend ActiveSupport::Concern
9
+
10
+ # Custom error class for invalid resources
11
+ class InvalidResourceError < StandardError; end
12
+
13
+ private
14
+
15
+ # Validates if a given resource is a valid Plutonium::Resource::Record
16
+ #
17
+ # @param resource [Object] The resource to validate
18
+ # @raise [InvalidResourceError] If the resource is not valid
19
+ # @return [void]
20
+ def validate_resource!(resource)
21
+ unless valid_resource?(resource)
22
+ raise InvalidResourceError, "#{resource} is not a valid Plutonium::Resource::Record"
23
+ end
24
+ end
25
+
26
+ # Checks if a given resource is a valid Plutonium::Resource::Record
27
+ #
28
+ # @param resource [Object] The resource to check
29
+ # @return [Boolean] True if the resource is valid, false otherwise
30
+ def valid_resource?(resource)
31
+ resource.is_a?(Class) && resource.include?(Plutonium::Resource::Record)
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -1,45 +1,76 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "view_component"
2
4
 
3
5
  module Plutonium
6
+ # Plutonium::Railtie integrates Plutonium with Rails applications.
7
+ #
8
+ # This Railtie sets up configurations, initializers, and tasks for Plutonium
9
+ # to work seamlessly within a Rails environment.
4
10
  class Railtie < Rails::Railtie
5
- config.plutonium = ActiveSupport::OrderedOptions.new
6
- config.plutonium.cache_discovery = defined?(Rails.env) && !Rails.env.development?
7
- config.plutonium.enable_hotreload = defined?(Rails.env) && Rails.env.development?
8
-
9
- config.plutonium.assets = ActiveSupport::OrderedOptions.new
10
- config.plutonium.assets.logo = "plutonium.png"
11
- config.plutonium.assets.favicon = "plutonium.ico"
12
- config.plutonium.assets.stylesheet = "plutonium.css"
13
- config.plutonium.assets.script = "plutonium.min.js"
14
-
11
+ # Assets to be precompiled
12
+ #
15
13
  # If you don't want to precompile Plutonium's assets (eg. because you're using webpack),
16
14
  # you can do this in an intiailzer:
17
15
  #
18
16
  # config.after_initialize do
19
17
  # config.assets.precompile -= Plutonium::Railtie::PRECOMPILE_ASSETS
20
18
  # end
21
- PRECOMPILE_ASSETS = %w[plutonium.js plutonium.js.map plutonium.min.js plutonium.min.js.map plutonium.css plutonium.png plutonium.ico]
19
+ PRECOMPILE_ASSETS = %w[
20
+ plutonium.js plutonium.js.map plutonium.min.js plutonium.min.js.map
21
+ plutonium.css plutonium.png plutonium.ico
22
+ ].freeze
22
23
 
23
24
  initializer "plutonium.assets" do
24
- next unless Rails.application.config.respond_to?(:assets)
25
+ setup_asset_pipeline if Rails.application.config.respond_to?(:assets)
26
+ end
27
+
28
+ initializer "plutonium.load_components" do
29
+ load_base_component
30
+ end
31
+
32
+ initializer "plutonium.initializers" do
33
+ load_plutonium_initializers
34
+ end
25
35
 
36
+ initializer "plutonium.asset_server" do
37
+ setup_development_asset_server if Plutonium.configuration.development?
38
+ end
39
+
40
+ initializer "plutonium.view_components_capture_compat" do
41
+ config.view_component.capture_compatibility_patch_enabled = true
42
+ end
43
+
44
+ initializer "plutonium.action_dispatch_extensions" do
45
+ extend_action_dispatch
46
+ end
47
+
48
+ rake_tasks do
49
+ load "tasks/create_rodauth_admin.rake"
50
+ end
51
+
52
+ config.after_initialize do
53
+ Plutonium::Reloader.start! if Plutonium.configuration.enable_hotreload
54
+ Plutonium::ZEITWERK_LOADER.eager_load if Rails.env.production?
55
+ end
56
+
57
+ private
58
+
59
+ def setup_asset_pipeline
26
60
  Rails.application.config.assets.precompile += PRECOMPILE_ASSETS
27
61
  Rails.application.config.assets.paths << Plutonium.root.join("app/assets").to_s
28
62
  end
29
63
 
30
- initializer "plutonium.load_components" do
64
+ def load_base_component
31
65
  load Plutonium.root.join("app", "views", "components", "base.rb")
32
66
  end
33
67
 
34
- initializer "plutonium.initializers" do
68
+ def load_plutonium_initializers
35
69
  Dir.glob(Plutonium.root.join("config", "initializers", "**", "*.rb")) { |file| load file }
36
70
  end
37
71
 
38
- initializer "plutonium.asset_server" do
39
- next unless Plutonium.development?
40
-
72
+ def setup_development_asset_server
41
73
  puts "=> [plutonium] starting assets server"
42
- # setup a middleware to serve our assets
43
74
  config.app_middleware.insert_before(
44
75
  ActionDispatch::Static,
45
76
  Rack::Static,
@@ -47,23 +78,15 @@ module Plutonium
47
78
  root: Plutonium.root.join("src").to_s,
48
79
  cascade: true,
49
80
  header_rules: [
50
- # Cache all static files in public caches (e.g. Rack::Cache) as well as in the browser
51
81
  [:all, {"cache-control" => "public, max-age=31536000"}]
52
82
  ]
53
83
  )
54
84
  end
55
85
 
56
- initializer "plutonium.view_components_capture_compat" do
57
- config.view_component.capture_compatibility_patch_enabled = true
58
- end
59
-
60
- rake_tasks do
61
- load "tasks/create_rodauth_admin.rake"
62
- end
63
-
64
- config.after_initialize do
65
- Plutonium::Reloader.start! if Rails.application.config.plutonium.enable_hotreload
66
- Plutonium::ZEITWERK_LOADER.eager_load if Rails.env.production?
86
+ def extend_action_dispatch
87
+ ActionDispatch::Routing::Mapper.prepend Plutonium::Routing::MapperExtensions
88
+ ActionDispatch::Routing::RouteSet.prepend Plutonium::Routing::RouteSetExtensions
89
+ Rails::Engine.include Plutonium::Routing::ResourceRegistration
67
90
  end
68
91
  end
69
92
  end