plutonium 0.39.1 → 0.40.0
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/.claude/skills/plutonium-connect-resource/SKILL.md +19 -1
- data/.claude/skills/plutonium-controller/SKILL.md +5 -9
- data/.claude/skills/plutonium-definition-query/SKILL.md +10 -2
- data/.claude/skills/plutonium-installation/SKILL.md +9 -7
- data/.claude/skills/plutonium-invites/SKILL.md +363 -0
- data/.claude/skills/plutonium-package/SKILL.md +2 -1
- data/.claude/skills/plutonium-portal/SKILL.md +30 -16
- data/.claude/skills/plutonium-rodauth/SKILL.md +111 -18
- data/CHANGELOG.md +48 -0
- data/app/assets/plutonium.css +1 -1
- data/config/initializers/sqlite_alias.rb +8 -8
- data/docs/.vitepress/config.ts +1 -0
- data/docs/getting-started/tutorial/07-author-portal.md +1 -0
- data/docs/getting-started/tutorial/08-customizing-ui.md +5 -2
- data/docs/guides/adding-resources.md +10 -0
- data/docs/guides/authentication.md +15 -8
- data/docs/guides/creating-packages.md +13 -8
- data/docs/guides/index.md +2 -0
- data/docs/guides/search-filtering.md +8 -3
- data/docs/guides/user-invites.md +497 -0
- data/docs/public/templates/base.rb +5 -1
- data/docs/public/templates/lite.rb +42 -0
- data/docs/public/templates/pluton8.rb +7 -2
- data/docs/reference/controller/index.md +12 -7
- data/docs/reference/definition/query.md +12 -3
- data/docs/reference/generators/index.md +70 -10
- data/docs/reference/portal/index.md +22 -11
- data/gemfiles/rails_7.gemfile.lock +1 -1
- data/gemfiles/rails_8.0.gemfile.lock +1 -1
- data/gemfiles/rails_8.1.gemfile.lock +1 -1
- data/lib/generators/pu/gem/active_shrine/active_shrine_generator.rb +31 -0
- data/lib/generators/pu/gem/active_shrine/templates/config/initializers/shrine.rb.tt +58 -0
- data/lib/generators/pu/gem/annotated/templates/lib/tasks/auto_annotate_models.rake +6 -1
- data/lib/generators/pu/gem/dotenv/templates/config/initializers/001_ensure_required_env.rb +3 -0
- data/lib/generators/pu/invites/USAGE +27 -0
- data/lib/generators/pu/invites/install_generator.rb +364 -0
- data/lib/generators/pu/invites/invitable/USAGE +31 -0
- data/lib/generators/pu/invites/invitable_generator.rb +143 -0
- data/lib/generators/pu/invites/templates/INSTRUCTIONS +22 -0
- data/lib/generators/pu/invites/templates/app/interactions/invite_user_interaction.rb.tt +24 -0
- data/lib/generators/pu/invites/templates/app/interactions/user_invite_user_interaction.rb.tt +26 -0
- data/lib/generators/pu/invites/templates/db/migrate/create_user_invites.rb.tt +47 -0
- data/lib/generators/pu/invites/templates/invitable/invitation.html.erb.tt +45 -0
- data/lib/generators/pu/invites/templates/invitable/invitation.text.erb.tt +15 -0
- data/lib/generators/pu/invites/templates/invitable/invite_user_interaction.rb.tt +33 -0
- data/lib/generators/pu/invites/templates/packages/invites/app/controllers/invites/user_invitations_controller.rb.tt +77 -0
- data/lib/generators/pu/invites/templates/packages/invites/app/controllers/invites/welcome_controller.rb.tt +68 -0
- data/lib/generators/pu/invites/templates/packages/invites/app/definitions/invites/user_invite_definition.rb.tt +23 -0
- data/lib/generators/pu/invites/templates/packages/invites/app/interactions/invites/cancel_invite_interaction.rb.tt +7 -0
- data/lib/generators/pu/invites/templates/packages/invites/app/interactions/invites/resend_invite_interaction.rb.tt +7 -0
- data/lib/generators/pu/invites/templates/packages/invites/app/mailers/invites/user_invite_mailer.rb.tt +34 -0
- data/lib/generators/pu/invites/templates/packages/invites/app/models/invites/user_invite.rb.tt +41 -0
- data/lib/generators/pu/invites/templates/packages/invites/app/policies/invites/user_invite_policy.rb.tt +33 -0
- data/lib/generators/pu/invites/templates/packages/invites/app/views/invites/user_invitations/error.html.erb.tt +24 -0
- data/lib/generators/pu/invites/templates/packages/invites/app/views/invites/user_invitations/landing.html.erb.tt +40 -0
- data/lib/generators/pu/invites/templates/packages/invites/app/views/invites/user_invitations/show.html.erb.tt +39 -0
- data/lib/generators/pu/invites/templates/packages/invites/app/views/invites/user_invitations/signup.html.erb.tt +49 -0
- data/lib/generators/pu/invites/templates/packages/invites/app/views/invites/user_invite_mailer/invitation.html.erb.tt +45 -0
- data/lib/generators/pu/invites/templates/packages/invites/app/views/invites/user_invite_mailer/invitation.text.erb.tt +15 -0
- data/lib/generators/pu/invites/templates/packages/invites/app/views/invites/welcome/pending_invitation.html.erb.tt +23 -0
- data/lib/generators/pu/invites/templates/packages/invites/app/views/layouts/invites/invitation.html.erb.tt +33 -0
- data/lib/generators/pu/lib/plutonium_generators/concerns/actions.rb +23 -2
- data/lib/generators/pu/lib/plutonium_generators/concerns/configures_sqlite.rb +130 -0
- data/lib/generators/pu/lib/plutonium_generators/concerns/mounts_engines.rb +72 -0
- data/lib/generators/pu/lib/plutonium_generators/concerns/package_selector.rb +4 -2
- data/lib/generators/pu/lib/plutonium_generators/model_generator_base.rb +7 -1
- data/lib/generators/pu/lite/litestream/litestream_generator.rb +105 -0
- data/lib/generators/pu/lite/rails_pulse/rails_pulse_generator.rb +88 -0
- data/lib/generators/pu/lite/rails_pulse/templates/config/initializers/rails_pulse.rb.tt +14 -0
- data/lib/generators/pu/lite/setup/setup_generator.rb +54 -0
- data/lib/generators/pu/lite/solid_cable/solid_cable_generator.rb +65 -0
- data/lib/generators/pu/lite/solid_cache/solid_cache_generator.rb +66 -0
- data/lib/generators/pu/lite/solid_errors/solid_errors_generator.rb +61 -0
- data/lib/generators/pu/lite/solid_queue/solid_queue_generator.rb +107 -0
- data/lib/generators/pu/pkg/portal/USAGE +8 -2
- data/lib/generators/pu/pkg/portal/portal_generator.rb +11 -1
- data/lib/generators/pu/pkg/portal/templates/app/controllers/concerns/controller.rb.tt +2 -0
- data/lib/generators/pu/pkg/portal/templates/app/controllers/plutonium_controller.rb.tt +1 -0
- data/lib/generators/pu/pkg/portal/templates/app/controllers/resource_controller.rb.tt +7 -0
- data/lib/generators/pu/pkg/portal/templates/lib/engine.rb.tt +3 -0
- data/lib/generators/pu/res/conn/USAGE +5 -0
- data/lib/generators/pu/res/conn/conn_generator.rb +30 -4
- data/lib/generators/pu/res/scaffold/scaffold_generator.rb +6 -3
- data/lib/generators/pu/res/scaffold/templates/policy.rb.tt +6 -6
- data/lib/generators/pu/rodauth/account_generator.rb +36 -11
- data/lib/generators/pu/rodauth/admin_generator.rb +55 -0
- data/lib/generators/pu/rodauth/install_generator.rb +1 -8
- data/lib/generators/pu/rodauth/templates/app/interactions/invite_admin_interaction.rb.tt +25 -0
- data/lib/generators/pu/rodauth/templates/app/models/account.rb.tt +6 -2
- data/lib/generators/pu/saas/USAGE +22 -0
- data/lib/generators/pu/saas/entity/USAGE +19 -0
- data/lib/generators/pu/saas/entity_generator.rb +55 -0
- data/lib/generators/pu/saas/membership/USAGE +25 -0
- data/lib/generators/pu/saas/membership_generator.rb +165 -0
- data/lib/generators/pu/saas/setup/USAGE +27 -0
- data/lib/generators/pu/saas/setup_generator.rb +98 -0
- data/lib/generators/pu/saas/user/USAGE +21 -0
- data/lib/generators/pu/saas/user_generator.rb +66 -0
- data/lib/plutonium/core/controller.rb +9 -5
- data/lib/plutonium/definition/base.rb +3 -1
- data/lib/plutonium/definition/scoping.rb +20 -0
- data/lib/plutonium/invites/concerns/cancel_invite.rb +44 -0
- data/lib/plutonium/invites/concerns/invitable.rb +98 -0
- data/lib/plutonium/invites/concerns/invite_token.rb +186 -0
- data/lib/plutonium/invites/concerns/invite_user.rb +147 -0
- data/lib/plutonium/invites/concerns/resend_invite.rb +66 -0
- data/lib/plutonium/invites/controller.rb +226 -0
- data/lib/plutonium/invites/pending_invite_check.rb +76 -0
- data/lib/plutonium/invites.rb +6 -0
- data/lib/plutonium/resource/controllers/queryable.rb +4 -0
- data/lib/plutonium/resource/query_object.rb +3 -5
- data/lib/plutonium/version.rb +1 -1
- data/package.json +1 -1
- metadata +64 -7
- data/lib/generators/pu/res/entity/entity_generator.rb +0 -158
- data/lib/generators/pu/rodauth/customer_generator.rb +0 -101
- data/public/plutonium-assets/plutonium-logo-original.png +0 -0
- data/public/plutonium-assets/plutonium-logo-white.png +0 -0
- data/public/plutonium-assets/plutonium-logo.png +0 -0
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Plutonium
|
|
4
|
+
module Invites
|
|
5
|
+
# Controller provides the invitation acceptance flow for controllers.
|
|
6
|
+
#
|
|
7
|
+
# This concern handles:
|
|
8
|
+
# - Showing the invitation landing page
|
|
9
|
+
# - Accepting invitations for logged-in users
|
|
10
|
+
# - Signup flow for new users
|
|
11
|
+
# - Cookie management for pending invitations
|
|
12
|
+
#
|
|
13
|
+
# @example Basic usage
|
|
14
|
+
# class UserInvitationsController < ApplicationController
|
|
15
|
+
# include Plutonium::Invites::Controller
|
|
16
|
+
#
|
|
17
|
+
# layout "invitation"
|
|
18
|
+
#
|
|
19
|
+
# private
|
|
20
|
+
#
|
|
21
|
+
# def invite_class
|
|
22
|
+
# UserInvite
|
|
23
|
+
# end
|
|
24
|
+
#
|
|
25
|
+
# def after_accept_path
|
|
26
|
+
# root_path
|
|
27
|
+
# end
|
|
28
|
+
#
|
|
29
|
+
# def login_path
|
|
30
|
+
# rodauth.login_path
|
|
31
|
+
# end
|
|
32
|
+
# end
|
|
33
|
+
#
|
|
34
|
+
module Controller
|
|
35
|
+
extend ActiveSupport::Concern
|
|
36
|
+
|
|
37
|
+
included do
|
|
38
|
+
helper_method :current_user if respond_to?(:helper_method)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# GET /invitations/:token
|
|
42
|
+
#
|
|
43
|
+
# Shows the invitation landing page. If the user is logged in,
|
|
44
|
+
# shows the acceptance form. If not, shows signup/login options.
|
|
45
|
+
def show
|
|
46
|
+
return unless (@invite = load_and_validate_invite(params[:token]))
|
|
47
|
+
|
|
48
|
+
# Store invitation token in cookie for later use
|
|
49
|
+
cookies.encrypted[:pending_invitation] = {
|
|
50
|
+
value: params[:token],
|
|
51
|
+
expires: 1.hour.from_now
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if current_user
|
|
55
|
+
begin
|
|
56
|
+
@invite.validate_email_constraints!(current_user.email)
|
|
57
|
+
render :show
|
|
58
|
+
rescue ActiveRecord::RecordInvalid => e
|
|
59
|
+
@error_title = "Email Validation Error"
|
|
60
|
+
@error_message = e.record.errors.full_messages.join(", ")
|
|
61
|
+
render :error, status: :forbidden
|
|
62
|
+
end
|
|
63
|
+
else
|
|
64
|
+
render :landing
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# POST /invitations/:token/accept
|
|
69
|
+
#
|
|
70
|
+
# Accepts the invitation for the currently logged-in user.
|
|
71
|
+
def accept
|
|
72
|
+
return unless (@invite = load_and_validate_invite(params[:token]))
|
|
73
|
+
|
|
74
|
+
unless current_user
|
|
75
|
+
redirect_to invitation_path(token: params[:token]),
|
|
76
|
+
alert: "Please sign in to accept this invitation"
|
|
77
|
+
return
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
@invite.accept_for_user!(current_user)
|
|
81
|
+
cookies.delete(:pending_invitation)
|
|
82
|
+
|
|
83
|
+
redirect_to after_accept_path,
|
|
84
|
+
notice: "Invitation accepted! Welcome to #{@invite.entity.to_label}!"
|
|
85
|
+
rescue ActiveRecord::RecordInvalid => e
|
|
86
|
+
@error_title = "Acceptance Error"
|
|
87
|
+
@error_message = e.record.errors.full_messages.join(", ")
|
|
88
|
+
render :error, status: :forbidden
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# GET/POST /invitations/:token/signup
|
|
92
|
+
#
|
|
93
|
+
# Handles new user signup directly from the invitation.
|
|
94
|
+
def signup
|
|
95
|
+
return unless (@invite = load_and_validate_invite(params[:token]))
|
|
96
|
+
|
|
97
|
+
if request.post?
|
|
98
|
+
handle_signup_submission
|
|
99
|
+
else
|
|
100
|
+
render :signup
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
private
|
|
105
|
+
|
|
106
|
+
# Load and validate an invite by token.
|
|
107
|
+
#
|
|
108
|
+
# @param token [String] the invitation token
|
|
109
|
+
# @return [Object, nil] the invite or nil (renders error)
|
|
110
|
+
def load_and_validate_invite(token)
|
|
111
|
+
invite = invite_class.find_for_acceptance(token)
|
|
112
|
+
|
|
113
|
+
unless invite
|
|
114
|
+
@error_title = "Invalid or Expired Invitation"
|
|
115
|
+
@error_message = "This invitation link is no longer valid. It may have expired or already been used."
|
|
116
|
+
render :error, status: :not_found
|
|
117
|
+
return nil
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
invite
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
# Handle the signup form submission.
|
|
124
|
+
def handle_signup_submission
|
|
125
|
+
email = @invite.enforce_email? ? @invite.email : params[:email]
|
|
126
|
+
password = params[:password]
|
|
127
|
+
password_confirmation = params[:password_confirmation]
|
|
128
|
+
|
|
129
|
+
if password != password_confirmation
|
|
130
|
+
flash.now[:alert] = "Passwords don't match"
|
|
131
|
+
render :signup
|
|
132
|
+
return
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
begin
|
|
136
|
+
ActiveRecord::Base.transaction do
|
|
137
|
+
existing_user = user_class.find_by(email: email)
|
|
138
|
+
if existing_user
|
|
139
|
+
flash.now[:alert] = "An account with this email already exists. Please sign in instead."
|
|
140
|
+
render :signup
|
|
141
|
+
return
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
user = create_user_for_signup(email, password)
|
|
145
|
+
|
|
146
|
+
if user&.persisted?
|
|
147
|
+
@invite.accept_for_user!(user)
|
|
148
|
+
cookies.delete(:pending_invitation)
|
|
149
|
+
sign_in_user(user)
|
|
150
|
+
redirect_to after_accept_path
|
|
151
|
+
else
|
|
152
|
+
flash.now[:alert] = "Failed to create account"
|
|
153
|
+
render :signup
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
rescue ActiveRecord::RecordInvalid => e
|
|
157
|
+
if e.record.is_a?(invite_class)
|
|
158
|
+
flash.now[:alert] = e.record.errors.full_messages.join(", ")
|
|
159
|
+
else
|
|
160
|
+
flash.now[:alert] = "Failed to create account: #{e.record.errors.full_messages.join(", ")}"
|
|
161
|
+
end
|
|
162
|
+
render :signup
|
|
163
|
+
rescue => e
|
|
164
|
+
flash.now[:alert] = "Failed to create account: #{e.message}"
|
|
165
|
+
render :signup
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
# Override to specify the invite model class.
|
|
170
|
+
#
|
|
171
|
+
# @return [Class] the invite model class
|
|
172
|
+
# @raise [NotImplementedError] if not overridden
|
|
173
|
+
def invite_class
|
|
174
|
+
raise NotImplementedError, "#{self.class}#invite_class must return the invite model class"
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
# Override to specify the user model class.
|
|
178
|
+
#
|
|
179
|
+
# @return [Class] the user model class
|
|
180
|
+
def user_class
|
|
181
|
+
User
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
# Override to customize redirect after acceptance.
|
|
185
|
+
#
|
|
186
|
+
# @return [String] the path to redirect to
|
|
187
|
+
def after_accept_path
|
|
188
|
+
"/"
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
# Override to customize the login path.
|
|
192
|
+
#
|
|
193
|
+
# @return [String] the login path
|
|
194
|
+
def login_path
|
|
195
|
+
"/login"
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
# Override to create a user during signup.
|
|
199
|
+
#
|
|
200
|
+
# This method should be overridden to integrate with your
|
|
201
|
+
# authentication system (e.g., Rodauth).
|
|
202
|
+
#
|
|
203
|
+
# @param email [String] the user's email
|
|
204
|
+
# @param password [String] the user's password
|
|
205
|
+
# @return [Object] the created user
|
|
206
|
+
def create_user_for_signup(email, password)
|
|
207
|
+
raise NotImplementedError, "#{self.class}#create_user_for_signup must be implemented for signup flow"
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
# Override to sign in the user after signup.
|
|
211
|
+
#
|
|
212
|
+
# @param user [Object] the user to sign in
|
|
213
|
+
def sign_in_user(user)
|
|
214
|
+
# Override in controller to sign in the user
|
|
215
|
+
# e.g., for Rodauth: rodauth.account_from_login(user.email); rodauth.login("signup")
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
# Override to return the current logged-in user.
|
|
219
|
+
#
|
|
220
|
+
# @return [Object, nil] the current user or nil
|
|
221
|
+
def current_user
|
|
222
|
+
nil
|
|
223
|
+
end
|
|
224
|
+
end
|
|
225
|
+
end
|
|
226
|
+
end
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Plutonium
|
|
4
|
+
module Invites
|
|
5
|
+
# PendingInviteCheck provides post-login invitation handling.
|
|
6
|
+
#
|
|
7
|
+
# Include this in a controller that users land on after login
|
|
8
|
+
# (e.g., WelcomeController, DashboardController) to check for
|
|
9
|
+
# pending invitations stored in cookies.
|
|
10
|
+
#
|
|
11
|
+
# @example Basic usage
|
|
12
|
+
# class WelcomeController < ApplicationController
|
|
13
|
+
# include Plutonium::Invites::PendingInviteCheck
|
|
14
|
+
#
|
|
15
|
+
# def index
|
|
16
|
+
# return if redirect_to_pending_invite!
|
|
17
|
+
#
|
|
18
|
+
# # Normal post-login flow...
|
|
19
|
+
# redirect_to dashboard_path
|
|
20
|
+
# end
|
|
21
|
+
#
|
|
22
|
+
# private
|
|
23
|
+
#
|
|
24
|
+
# def invite_class
|
|
25
|
+
# Invites::UserInvite
|
|
26
|
+
# end
|
|
27
|
+
# end
|
|
28
|
+
#
|
|
29
|
+
module PendingInviteCheck
|
|
30
|
+
extend ActiveSupport::Concern
|
|
31
|
+
|
|
32
|
+
private
|
|
33
|
+
|
|
34
|
+
# Check for a pending invitation and redirect if found.
|
|
35
|
+
#
|
|
36
|
+
# @return [Boolean] true if redirected, false otherwise
|
|
37
|
+
def redirect_to_pending_invite!
|
|
38
|
+
token = cookies.encrypted[:pending_invitation]
|
|
39
|
+
return false unless token
|
|
40
|
+
|
|
41
|
+
invite = invite_class.find_for_acceptance(token)
|
|
42
|
+
|
|
43
|
+
if invite
|
|
44
|
+
redirect_to invitation_path(token: token)
|
|
45
|
+
true
|
|
46
|
+
else
|
|
47
|
+
cookies.delete(:pending_invitation)
|
|
48
|
+
false
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Returns the pending invite if one exists.
|
|
53
|
+
#
|
|
54
|
+
# @return [Object, nil] the pending invite or nil
|
|
55
|
+
def pending_invite
|
|
56
|
+
token = cookies.encrypted[:pending_invitation]
|
|
57
|
+
return nil unless token
|
|
58
|
+
|
|
59
|
+
invite = invite_class.find_for_acceptance(token)
|
|
60
|
+
unless invite
|
|
61
|
+
cookies.delete(:pending_invitation)
|
|
62
|
+
return nil
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
invite
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# Override to specify the invite model class.
|
|
69
|
+
#
|
|
70
|
+
# @return [Class] the invite model class
|
|
71
|
+
def invite_class
|
|
72
|
+
raise NotImplementedError, "#{self.class}#invite_class must return the invite model class"
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
@@ -29,6 +29,10 @@ module Plutonium
|
|
|
29
29
|
query_object.default_sort_config = current_definition.default_sort
|
|
30
30
|
end
|
|
31
31
|
|
|
32
|
+
if current_definition.respond_to?(:default_scope) && current_definition.default_scope
|
|
33
|
+
query_object.default_scope_name = current_definition.default_scope
|
|
34
|
+
end
|
|
35
|
+
|
|
32
36
|
current_definition.defined_filters.each do |key, value|
|
|
33
37
|
with = value[:options][:with]
|
|
34
38
|
if with
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
module Plutonium
|
|
2
2
|
module Resource
|
|
3
3
|
class QueryObject
|
|
4
|
-
attr_reader :search_filter, :search_query
|
|
5
|
-
attr_accessor :default_sort_config
|
|
4
|
+
attr_reader :search_filter, :search_query
|
|
5
|
+
attr_accessor :default_sort_config, :default_scope_name
|
|
6
6
|
|
|
7
7
|
# Initializes a QueryObject with the given resource_class and parameters.
|
|
8
8
|
#
|
|
@@ -31,11 +31,9 @@ module Plutonium
|
|
|
31
31
|
#
|
|
32
32
|
# @param name [Symbol] The name of the scope.
|
|
33
33
|
# @param body [Proc, nil] The body of the scope.
|
|
34
|
-
|
|
35
|
-
def define_scope(name, body = nil, default: false, **)
|
|
34
|
+
def define_scope(name, body = nil, **)
|
|
36
35
|
body ||= name
|
|
37
36
|
scope_definitions[name] = build_query(body)
|
|
38
|
-
@default_scope_name = name.to_s if default
|
|
39
37
|
end
|
|
40
38
|
|
|
41
39
|
# Defines a sort with the given name and body.
|
data/lib/plutonium/version.rb
CHANGED
data/package.json
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: plutonium
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.40.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Stefan Froelich
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-02-04 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: zeitwerk
|
|
@@ -411,6 +411,7 @@ files:
|
|
|
411
411
|
- ".claude/skills/plutonium-forms/SKILL.md"
|
|
412
412
|
- ".claude/skills/plutonium-installation/SKILL.md"
|
|
413
413
|
- ".claude/skills/plutonium-interaction/SKILL.md"
|
|
414
|
+
- ".claude/skills/plutonium-invites/SKILL.md"
|
|
414
415
|
- ".claude/skills/plutonium-model-features/SKILL.md"
|
|
415
416
|
- ".claude/skills/plutonium-model/SKILL.md"
|
|
416
417
|
- ".claude/skills/plutonium-nested-resources/SKILL.md"
|
|
@@ -541,6 +542,7 @@ files:
|
|
|
541
542
|
- docs/guides/search-filtering.md
|
|
542
543
|
- docs/guides/theming.md
|
|
543
544
|
- docs/guides/troubleshooting.md
|
|
545
|
+
- docs/guides/user-invites.md
|
|
544
546
|
- docs/index.md
|
|
545
547
|
- docs/og-image.html
|
|
546
548
|
- docs/public/android-chrome-192x192.png
|
|
@@ -553,6 +555,7 @@ files:
|
|
|
553
555
|
- docs/public/plutonium.png
|
|
554
556
|
- docs/public/site.webmanifest
|
|
555
557
|
- docs/public/templates/base.rb
|
|
558
|
+
- docs/public/templates/lite.rb
|
|
556
559
|
- docs/public/templates/pluton8.rb
|
|
557
560
|
- docs/public/templates/plutonium.rb
|
|
558
561
|
- docs/public/tutorial/plutonium-association-panel.png
|
|
@@ -625,6 +628,8 @@ files:
|
|
|
625
628
|
- lib/generators/pu/field/renderer/renderer_generator.rb
|
|
626
629
|
- lib/generators/pu/field/renderer/templates/.keep
|
|
627
630
|
- lib/generators/pu/field/renderer/templates/renderer.rb.tt
|
|
631
|
+
- lib/generators/pu/gem/active_shrine/active_shrine_generator.rb
|
|
632
|
+
- lib/generators/pu/gem/active_shrine/templates/config/initializers/shrine.rb.tt
|
|
628
633
|
- lib/generators/pu/gem/annotated/annotated_generator.rb
|
|
629
634
|
- lib/generators/pu/gem/annotated/templates/.keep
|
|
630
635
|
- lib/generators/pu/gem/annotated/templates/lib/tasks/auto_annotate_models.rake
|
|
@@ -642,17 +647,54 @@ files:
|
|
|
642
647
|
- lib/generators/pu/gem/state_machines/state_machines_generator.rb
|
|
643
648
|
- lib/generators/pu/gen/pug/pug_generator.rb
|
|
644
649
|
- lib/generators/pu/gen/pug/templates/pug.rb.tt
|
|
650
|
+
- lib/generators/pu/invites/USAGE
|
|
651
|
+
- lib/generators/pu/invites/install_generator.rb
|
|
652
|
+
- lib/generators/pu/invites/invitable/USAGE
|
|
653
|
+
- lib/generators/pu/invites/invitable_generator.rb
|
|
654
|
+
- lib/generators/pu/invites/templates/INSTRUCTIONS
|
|
655
|
+
- lib/generators/pu/invites/templates/app/interactions/invite_user_interaction.rb.tt
|
|
656
|
+
- lib/generators/pu/invites/templates/app/interactions/user_invite_user_interaction.rb.tt
|
|
657
|
+
- lib/generators/pu/invites/templates/db/migrate/create_user_invites.rb.tt
|
|
658
|
+
- lib/generators/pu/invites/templates/invitable/invitation.html.erb.tt
|
|
659
|
+
- lib/generators/pu/invites/templates/invitable/invitation.text.erb.tt
|
|
660
|
+
- lib/generators/pu/invites/templates/invitable/invite_user_interaction.rb.tt
|
|
661
|
+
- lib/generators/pu/invites/templates/packages/invites/app/controllers/invites/user_invitations_controller.rb.tt
|
|
662
|
+
- lib/generators/pu/invites/templates/packages/invites/app/controllers/invites/welcome_controller.rb.tt
|
|
663
|
+
- lib/generators/pu/invites/templates/packages/invites/app/definitions/invites/user_invite_definition.rb.tt
|
|
664
|
+
- lib/generators/pu/invites/templates/packages/invites/app/interactions/invites/cancel_invite_interaction.rb.tt
|
|
665
|
+
- lib/generators/pu/invites/templates/packages/invites/app/interactions/invites/resend_invite_interaction.rb.tt
|
|
666
|
+
- lib/generators/pu/invites/templates/packages/invites/app/mailers/invites/user_invite_mailer.rb.tt
|
|
667
|
+
- lib/generators/pu/invites/templates/packages/invites/app/models/invites/user_invite.rb.tt
|
|
668
|
+
- lib/generators/pu/invites/templates/packages/invites/app/policies/invites/user_invite_policy.rb.tt
|
|
669
|
+
- lib/generators/pu/invites/templates/packages/invites/app/views/invites/user_invitations/error.html.erb.tt
|
|
670
|
+
- lib/generators/pu/invites/templates/packages/invites/app/views/invites/user_invitations/landing.html.erb.tt
|
|
671
|
+
- lib/generators/pu/invites/templates/packages/invites/app/views/invites/user_invitations/show.html.erb.tt
|
|
672
|
+
- lib/generators/pu/invites/templates/packages/invites/app/views/invites/user_invitations/signup.html.erb.tt
|
|
673
|
+
- lib/generators/pu/invites/templates/packages/invites/app/views/invites/user_invite_mailer/invitation.html.erb.tt
|
|
674
|
+
- lib/generators/pu/invites/templates/packages/invites/app/views/invites/user_invite_mailer/invitation.text.erb.tt
|
|
675
|
+
- lib/generators/pu/invites/templates/packages/invites/app/views/invites/welcome/pending_invitation.html.erb.tt
|
|
676
|
+
- lib/generators/pu/invites/templates/packages/invites/app/views/layouts/invites/invitation.html.erb.tt
|
|
645
677
|
- lib/generators/pu/lib/plutonium_generators.rb
|
|
646
678
|
- lib/generators/pu/lib/plutonium_generators/cli.rb
|
|
647
679
|
- lib/generators/pu/lib/plutonium_generators/concerns/actions.rb
|
|
648
680
|
- lib/generators/pu/lib/plutonium_generators/concerns/config.rb
|
|
681
|
+
- lib/generators/pu/lib/plutonium_generators/concerns/configures_sqlite.rb
|
|
649
682
|
- lib/generators/pu/lib/plutonium_generators/concerns/logger.rb
|
|
683
|
+
- lib/generators/pu/lib/plutonium_generators/concerns/mounts_engines.rb
|
|
650
684
|
- lib/generators/pu/lib/plutonium_generators/concerns/package_selector.rb
|
|
651
685
|
- lib/generators/pu/lib/plutonium_generators/concerns/resource_selector.rb
|
|
652
686
|
- lib/generators/pu/lib/plutonium_generators/concerns/serializer.rb
|
|
653
687
|
- lib/generators/pu/lib/plutonium_generators/generator.rb
|
|
654
688
|
- lib/generators/pu/lib/plutonium_generators/installer.rb
|
|
655
689
|
- lib/generators/pu/lib/plutonium_generators/model_generator_base.rb
|
|
690
|
+
- lib/generators/pu/lite/litestream/litestream_generator.rb
|
|
691
|
+
- lib/generators/pu/lite/rails_pulse/rails_pulse_generator.rb
|
|
692
|
+
- lib/generators/pu/lite/rails_pulse/templates/config/initializers/rails_pulse.rb.tt
|
|
693
|
+
- lib/generators/pu/lite/setup/setup_generator.rb
|
|
694
|
+
- lib/generators/pu/lite/solid_cable/solid_cable_generator.rb
|
|
695
|
+
- lib/generators/pu/lite/solid_cache/solid_cache_generator.rb
|
|
696
|
+
- lib/generators/pu/lite/solid_errors/solid_errors_generator.rb
|
|
697
|
+
- lib/generators/pu/lite/solid_queue/solid_queue_generator.rb
|
|
656
698
|
- lib/generators/pu/pkg/package/package_generator.rb
|
|
657
699
|
- lib/generators/pu/pkg/package/templates/.keep
|
|
658
700
|
- lib/generators/pu/pkg/package/templates/app/controllers/resource_controller.rb.tt
|
|
@@ -668,6 +710,7 @@ files:
|
|
|
668
710
|
- lib/generators/pu/pkg/portal/templates/app/controllers/concerns/controller.rb.tt
|
|
669
711
|
- lib/generators/pu/pkg/portal/templates/app/controllers/dashboard_controller.rb.tt
|
|
670
712
|
- lib/generators/pu/pkg/portal/templates/app/controllers/plutonium_controller.rb.tt
|
|
713
|
+
- lib/generators/pu/pkg/portal/templates/app/controllers/resource_controller.rb.tt
|
|
671
714
|
- lib/generators/pu/pkg/portal/templates/app/definitions/resource_definition.rb.tt
|
|
672
715
|
- lib/generators/pu/pkg/portal/templates/app/policies/resource_policy.rb.tt
|
|
673
716
|
- lib/generators/pu/pkg/portal/templates/app/presenters/resource_presenter.rb.tt
|
|
@@ -684,7 +727,6 @@ files:
|
|
|
684
727
|
- lib/generators/pu/res/conn/templates/app/policies/resource_policy.rb.tt
|
|
685
728
|
- lib/generators/pu/res/conn/templates/app/presenters/resource_presenter.rb.tt
|
|
686
729
|
- lib/generators/pu/res/conn/templates/app/query_objects/resource_query_object.rb.tt
|
|
687
|
-
- lib/generators/pu/res/entity/entity_generator.rb
|
|
688
730
|
- lib/generators/pu/res/model/USAGE
|
|
689
731
|
- lib/generators/pu/res/model/model_generator.rb
|
|
690
732
|
- lib/generators/pu/res/model/templates/create_table_migration.rb.tt
|
|
@@ -703,7 +745,6 @@ files:
|
|
|
703
745
|
- lib/generators/pu/rodauth/concerns/account_selector.rb
|
|
704
746
|
- lib/generators/pu/rodauth/concerns/configuration.rb
|
|
705
747
|
- lib/generators/pu/rodauth/concerns/feature_selector.rb
|
|
706
|
-
- lib/generators/pu/rodauth/customer_generator.rb
|
|
707
748
|
- lib/generators/pu/rodauth/install_generator.rb
|
|
708
749
|
- lib/generators/pu/rodauth/migration/active_record/account_expiration.erb
|
|
709
750
|
- lib/generators/pu/rodauth/migration/active_record/active_sessions.erb
|
|
@@ -729,6 +770,7 @@ files:
|
|
|
729
770
|
- lib/generators/pu/rodauth/templates/INSTRUCTIONS
|
|
730
771
|
- lib/generators/pu/rodauth/templates/app/controllers/plugin_controller.rb.tt
|
|
731
772
|
- lib/generators/pu/rodauth/templates/app/controllers/rodauth_controller.rb.tt
|
|
773
|
+
- lib/generators/pu/rodauth/templates/app/interactions/invite_admin_interaction.rb.tt
|
|
732
774
|
- lib/generators/pu/rodauth/templates/app/mailers/account_mailer.rb.tt
|
|
733
775
|
- lib/generators/pu/rodauth/templates/app/mailers/rodauth_mailer.rb.tt
|
|
734
776
|
- lib/generators/pu/rodauth/templates/app/models/account.rb.tt
|
|
@@ -756,6 +798,15 @@ files:
|
|
|
756
798
|
- lib/generators/pu/rodauth/templates/db/migrate/install_rodauth.rb.tt
|
|
757
799
|
- lib/generators/pu/rodauth/templates/lib/tasks/rodauth_admin.rake.tt
|
|
758
800
|
- lib/generators/pu/rodauth/views_generator.rb
|
|
801
|
+
- lib/generators/pu/saas/USAGE
|
|
802
|
+
- lib/generators/pu/saas/entity/USAGE
|
|
803
|
+
- lib/generators/pu/saas/entity_generator.rb
|
|
804
|
+
- lib/generators/pu/saas/membership/USAGE
|
|
805
|
+
- lib/generators/pu/saas/membership_generator.rb
|
|
806
|
+
- lib/generators/pu/saas/setup/USAGE
|
|
807
|
+
- lib/generators/pu/saas/setup_generator.rb
|
|
808
|
+
- lib/generators/pu/saas/user/USAGE
|
|
809
|
+
- lib/generators/pu/saas/user_generator.rb
|
|
759
810
|
- lib/generators/pu/service/postgres/postgres_generator.rb
|
|
760
811
|
- lib/generators/pu/service/postgres/templates/.keep
|
|
761
812
|
- lib/generators/pu/service/postgres/templates/bin/initdb.d/create-multiple-postgresql-databases.sh
|
|
@@ -792,6 +843,7 @@ files:
|
|
|
792
843
|
- lib/plutonium/definition/inheritable_config_attr.rb
|
|
793
844
|
- lib/plutonium/definition/nested_inputs.rb
|
|
794
845
|
- lib/plutonium/definition/presentable.rb
|
|
846
|
+
- lib/plutonium/definition/scoping.rb
|
|
795
847
|
- lib/plutonium/definition/search.rb
|
|
796
848
|
- lib/plutonium/definition/sorting.rb
|
|
797
849
|
- lib/plutonium/engine.rb
|
|
@@ -816,6 +868,14 @@ files:
|
|
|
816
868
|
- lib/plutonium/interaction/response/null.rb
|
|
817
869
|
- lib/plutonium/interaction/response/redirect.rb
|
|
818
870
|
- lib/plutonium/interaction/response/render.rb
|
|
871
|
+
- lib/plutonium/invites.rb
|
|
872
|
+
- lib/plutonium/invites/concerns/cancel_invite.rb
|
|
873
|
+
- lib/plutonium/invites/concerns/invitable.rb
|
|
874
|
+
- lib/plutonium/invites/concerns/invite_token.rb
|
|
875
|
+
- lib/plutonium/invites/concerns/invite_user.rb
|
|
876
|
+
- lib/plutonium/invites/concerns/resend_invite.rb
|
|
877
|
+
- lib/plutonium/invites/controller.rb
|
|
878
|
+
- lib/plutonium/invites/pending_invite_check.rb
|
|
819
879
|
- lib/plutonium/lib/after_commit.rb
|
|
820
880
|
- lib/plutonium/lib/bit_flags.rb
|
|
821
881
|
- lib/plutonium/lib/deep_freezer.rb
|
|
@@ -947,9 +1007,6 @@ files:
|
|
|
947
1007
|
- postcss.config.js
|
|
948
1008
|
- public/.keep
|
|
949
1009
|
- public/plutonium-assets/application.js
|
|
950
|
-
- public/plutonium-assets/plutonium-logo-original.png
|
|
951
|
-
- public/plutonium-assets/plutonium-logo-white.png
|
|
952
|
-
- public/plutonium-assets/plutonium-logo.png
|
|
953
1010
|
- public/plutonium-assets/plutonium.ico
|
|
954
1011
|
- sig/.keep
|
|
955
1012
|
- src/.npmignore
|