plutonium 0.39.2 → 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.
Files changed (119) hide show
  1. checksums.yaml +4 -4
  2. data/.claude/skills/plutonium-connect-resource/SKILL.md +19 -1
  3. data/.claude/skills/plutonium-controller/SKILL.md +5 -9
  4. data/.claude/skills/plutonium-definition-query/SKILL.md +10 -2
  5. data/.claude/skills/plutonium-installation/SKILL.md +9 -7
  6. data/.claude/skills/plutonium-invites/SKILL.md +363 -0
  7. data/.claude/skills/plutonium-package/SKILL.md +2 -1
  8. data/.claude/skills/plutonium-portal/SKILL.md +30 -16
  9. data/.claude/skills/plutonium-rodauth/SKILL.md +111 -18
  10. data/CHANGELOG.md +43 -0
  11. data/app/assets/plutonium.css +1 -1
  12. data/config/initializers/sqlite_alias.rb +8 -8
  13. data/docs/.vitepress/config.ts +1 -0
  14. data/docs/getting-started/tutorial/07-author-portal.md +1 -0
  15. data/docs/getting-started/tutorial/08-customizing-ui.md +5 -2
  16. data/docs/guides/adding-resources.md +10 -0
  17. data/docs/guides/authentication.md +15 -8
  18. data/docs/guides/creating-packages.md +13 -8
  19. data/docs/guides/index.md +2 -0
  20. data/docs/guides/search-filtering.md +8 -3
  21. data/docs/guides/user-invites.md +497 -0
  22. data/docs/public/templates/base.rb +5 -1
  23. data/docs/public/templates/lite.rb +42 -0
  24. data/docs/public/templates/pluton8.rb +7 -2
  25. data/docs/reference/controller/index.md +12 -7
  26. data/docs/reference/definition/query.md +12 -3
  27. data/docs/reference/generators/index.md +70 -10
  28. data/docs/reference/portal/index.md +22 -11
  29. data/gemfiles/rails_7.gemfile.lock +1 -1
  30. data/gemfiles/rails_8.0.gemfile.lock +1 -1
  31. data/gemfiles/rails_8.1.gemfile.lock +1 -1
  32. data/lib/generators/pu/gem/active_shrine/active_shrine_generator.rb +31 -0
  33. data/lib/generators/pu/gem/active_shrine/templates/config/initializers/shrine.rb.tt +58 -0
  34. data/lib/generators/pu/gem/annotated/templates/lib/tasks/auto_annotate_models.rake +6 -1
  35. data/lib/generators/pu/gem/dotenv/templates/config/initializers/001_ensure_required_env.rb +3 -0
  36. data/lib/generators/pu/invites/USAGE +27 -0
  37. data/lib/generators/pu/invites/install_generator.rb +364 -0
  38. data/lib/generators/pu/invites/invitable/USAGE +31 -0
  39. data/lib/generators/pu/invites/invitable_generator.rb +143 -0
  40. data/lib/generators/pu/invites/templates/INSTRUCTIONS +22 -0
  41. data/lib/generators/pu/invites/templates/app/interactions/invite_user_interaction.rb.tt +24 -0
  42. data/lib/generators/pu/invites/templates/app/interactions/user_invite_user_interaction.rb.tt +26 -0
  43. data/lib/generators/pu/invites/templates/db/migrate/create_user_invites.rb.tt +47 -0
  44. data/lib/generators/pu/invites/templates/invitable/invitation.html.erb.tt +45 -0
  45. data/lib/generators/pu/invites/templates/invitable/invitation.text.erb.tt +15 -0
  46. data/lib/generators/pu/invites/templates/invitable/invite_user_interaction.rb.tt +33 -0
  47. data/lib/generators/pu/invites/templates/packages/invites/app/controllers/invites/user_invitations_controller.rb.tt +77 -0
  48. data/lib/generators/pu/invites/templates/packages/invites/app/controllers/invites/welcome_controller.rb.tt +68 -0
  49. data/lib/generators/pu/invites/templates/packages/invites/app/definitions/invites/user_invite_definition.rb.tt +23 -0
  50. data/lib/generators/pu/invites/templates/packages/invites/app/interactions/invites/cancel_invite_interaction.rb.tt +7 -0
  51. data/lib/generators/pu/invites/templates/packages/invites/app/interactions/invites/resend_invite_interaction.rb.tt +7 -0
  52. data/lib/generators/pu/invites/templates/packages/invites/app/mailers/invites/user_invite_mailer.rb.tt +34 -0
  53. data/lib/generators/pu/invites/templates/packages/invites/app/models/invites/user_invite.rb.tt +41 -0
  54. data/lib/generators/pu/invites/templates/packages/invites/app/policies/invites/user_invite_policy.rb.tt +33 -0
  55. data/lib/generators/pu/invites/templates/packages/invites/app/views/invites/user_invitations/error.html.erb.tt +24 -0
  56. data/lib/generators/pu/invites/templates/packages/invites/app/views/invites/user_invitations/landing.html.erb.tt +40 -0
  57. data/lib/generators/pu/invites/templates/packages/invites/app/views/invites/user_invitations/show.html.erb.tt +39 -0
  58. data/lib/generators/pu/invites/templates/packages/invites/app/views/invites/user_invitations/signup.html.erb.tt +49 -0
  59. data/lib/generators/pu/invites/templates/packages/invites/app/views/invites/user_invite_mailer/invitation.html.erb.tt +45 -0
  60. data/lib/generators/pu/invites/templates/packages/invites/app/views/invites/user_invite_mailer/invitation.text.erb.tt +15 -0
  61. data/lib/generators/pu/invites/templates/packages/invites/app/views/invites/welcome/pending_invitation.html.erb.tt +23 -0
  62. data/lib/generators/pu/invites/templates/packages/invites/app/views/layouts/invites/invitation.html.erb.tt +33 -0
  63. data/lib/generators/pu/lib/plutonium_generators/concerns/actions.rb +23 -2
  64. data/lib/generators/pu/lib/plutonium_generators/concerns/configures_sqlite.rb +130 -0
  65. data/lib/generators/pu/lib/plutonium_generators/concerns/mounts_engines.rb +72 -0
  66. data/lib/generators/pu/lib/plutonium_generators/concerns/package_selector.rb +4 -2
  67. data/lib/generators/pu/lib/plutonium_generators/model_generator_base.rb +7 -1
  68. data/lib/generators/pu/lite/litestream/litestream_generator.rb +105 -0
  69. data/lib/generators/pu/lite/rails_pulse/rails_pulse_generator.rb +88 -0
  70. data/lib/generators/pu/lite/rails_pulse/templates/config/initializers/rails_pulse.rb.tt +14 -0
  71. data/lib/generators/pu/lite/setup/setup_generator.rb +54 -0
  72. data/lib/generators/pu/lite/solid_cable/solid_cable_generator.rb +65 -0
  73. data/lib/generators/pu/lite/solid_cache/solid_cache_generator.rb +66 -0
  74. data/lib/generators/pu/lite/solid_errors/solid_errors_generator.rb +61 -0
  75. data/lib/generators/pu/lite/solid_queue/solid_queue_generator.rb +107 -0
  76. data/lib/generators/pu/pkg/portal/USAGE +8 -2
  77. data/lib/generators/pu/pkg/portal/portal_generator.rb +11 -1
  78. data/lib/generators/pu/pkg/portal/templates/app/controllers/concerns/controller.rb.tt +2 -0
  79. data/lib/generators/pu/pkg/portal/templates/app/controllers/plutonium_controller.rb.tt +1 -0
  80. data/lib/generators/pu/pkg/portal/templates/app/controllers/resource_controller.rb.tt +7 -0
  81. data/lib/generators/pu/pkg/portal/templates/lib/engine.rb.tt +3 -0
  82. data/lib/generators/pu/res/conn/USAGE +5 -0
  83. data/lib/generators/pu/res/conn/conn_generator.rb +30 -4
  84. data/lib/generators/pu/res/scaffold/scaffold_generator.rb +6 -3
  85. data/lib/generators/pu/res/scaffold/templates/policy.rb.tt +6 -6
  86. data/lib/generators/pu/rodauth/account_generator.rb +36 -11
  87. data/lib/generators/pu/rodauth/admin_generator.rb +55 -0
  88. data/lib/generators/pu/rodauth/install_generator.rb +1 -8
  89. data/lib/generators/pu/rodauth/templates/app/interactions/invite_admin_interaction.rb.tt +25 -0
  90. data/lib/generators/pu/rodauth/templates/app/models/account.rb.tt +6 -2
  91. data/lib/generators/pu/saas/USAGE +22 -0
  92. data/lib/generators/pu/saas/entity/USAGE +19 -0
  93. data/lib/generators/pu/saas/entity_generator.rb +55 -0
  94. data/lib/generators/pu/saas/membership/USAGE +25 -0
  95. data/lib/generators/pu/saas/membership_generator.rb +165 -0
  96. data/lib/generators/pu/saas/setup/USAGE +27 -0
  97. data/lib/generators/pu/saas/setup_generator.rb +98 -0
  98. data/lib/generators/pu/saas/user/USAGE +21 -0
  99. data/lib/generators/pu/saas/user_generator.rb +66 -0
  100. data/lib/plutonium/definition/base.rb +3 -1
  101. data/lib/plutonium/definition/scoping.rb +20 -0
  102. data/lib/plutonium/invites/concerns/cancel_invite.rb +44 -0
  103. data/lib/plutonium/invites/concerns/invitable.rb +98 -0
  104. data/lib/plutonium/invites/concerns/invite_token.rb +186 -0
  105. data/lib/plutonium/invites/concerns/invite_user.rb +147 -0
  106. data/lib/plutonium/invites/concerns/resend_invite.rb +66 -0
  107. data/lib/plutonium/invites/controller.rb +226 -0
  108. data/lib/plutonium/invites/pending_invite_check.rb +76 -0
  109. data/lib/plutonium/invites.rb +6 -0
  110. data/lib/plutonium/resource/controllers/queryable.rb +4 -0
  111. data/lib/plutonium/resource/query_object.rb +3 -5
  112. data/lib/plutonium/version.rb +1 -1
  113. data/package.json +1 -1
  114. metadata +64 -7
  115. data/lib/generators/pu/res/entity/entity_generator.rb +0 -158
  116. data/lib/generators/pu/rodauth/customer_generator.rb +0 -101
  117. data/public/plutonium-assets/plutonium-logo-original.png +0 -0
  118. data/public/plutonium-assets/plutonium-logo-white.png +0 -0
  119. data/public/plutonium-assets/plutonium-logo.png +0 -0
@@ -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, :default_scope_name
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
- # @param default [Boolean] Whether this scope is the default.
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.
@@ -1,5 +1,5 @@
1
1
  module Plutonium
2
- VERSION = "0.39.2"
2
+ VERSION = "0.40.0"
3
3
  NEXT_MAJOR_VERSION = VERSION.split(".").tap { |v|
4
4
  v[1] = v[1].to_i + 1
5
5
  v[2] = 0
data/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@radioactive-labs/plutonium",
3
- "version": "0.39.2",
3
+ "version": "0.40.0",
4
4
  "description": "Build production-ready Rails apps in minutes, not days. Convention-driven, fully customizable, AI-ready.",
5
5
  "type": "module",
6
6
  "main": "src/js/core.js",
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.39.2
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-01-27 00:00:00.000000000 Z
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
@@ -1,158 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "rails/generators/named_base"
4
- require_relative "../../lib/plutonium_generators"
5
-
6
- module Pu
7
- module Res
8
- class EntityGenerator < ::Rails::Generators::NamedBase
9
- include PlutoniumGenerators::Generator
10
-
11
- desc "Generate an entity model for customer accounts"
12
-
13
- class_option :model, type: :boolean, default: true
14
- class_option :allow_signup, type: :boolean, default: true,
15
- desc: "Whether to allow customer to sign up to the platform"
16
- class_option :auth_account, type: :string,
17
- desc: "Specify the authentication account name", required: true
18
-
19
- def start
20
- ensure_customer_model_exists! if behavior == :invoke
21
- generate_entity_resource
22
- generate_membership_resource
23
- end
24
-
25
- private
26
-
27
- def ensure_customer_model_exists!
28
- customer_model_path = File.join("app", "models", "#{normalized_auth_account_name}.rb")
29
- unless File.exist?(customer_model_path)
30
- raise "Customer model '#{normalized_auth_account_name}' does not exist. Please create it first."
31
- end
32
- rescue => e
33
- exception "#{self.class} failed:", e
34
- end
35
-
36
- def generate_entity_resource
37
- Rails::Generators.invoke(
38
- "pu:res:scaffold",
39
- [
40
- normalized_name,
41
- "name:string",
42
- "--model",
43
- ("--force" if options[:force]),
44
- ("--skip" if options[:skip]),
45
- "--dest=#{selected_destination_feature}"
46
- ].compact,
47
- behavior: behavior,
48
- destination_root: destination_root
49
- )
50
-
51
- add_unique_index_to_migration(normalized_name, [:name])
52
- end
53
-
54
- def generate_membership_resource
55
- Rails::Generators.invoke(
56
- "pu:res:scaffold",
57
- [
58
- normalized_entity_membership_name,
59
- *membership_attributes,
60
- "--model",
61
- ("--force" if options[:force]),
62
- ("--skip" if options[:skip]),
63
- "--dest=#{selected_destination_feature}"
64
- ].compact,
65
- behavior: behavior,
66
- destination_root: destination_root
67
- )
68
-
69
- add_unique_index_to_migration(
70
- normalized_entity_membership_name,
71
- ["#{normalized_name}_id", "#{normalized_auth_account_name}_id"]
72
- )
73
-
74
- add_default_to_role_column
75
- add_role_enum_to_model
76
- add_unique_validation_to_model
77
- end
78
-
79
- private
80
-
81
- def selected_destination_feature = "main_app"
82
-
83
- def normalized_name = name.underscore
84
-
85
- def normalized_entity_membership_name
86
- "#{normalized_name}_#{normalized_auth_account_name}"
87
- end
88
-
89
- def normalized_auth_account_name = options[:auth_account].underscore
90
-
91
- def add_unique_index_to_migration(model_name, index_columns)
92
- migration_dir = File.join("db", "migrate")
93
- migration_file = Dir[File.join(migration_dir, "*_create_#{model_name.pluralize}.rb")].first
94
-
95
- modify_file_if_exists(migration_file) do |file|
96
- index_definition = build_index_definition(model_name, index_columns)
97
- insert_into_file migration_file, indent(index_definition, 4), before: /^ end\s*$/
98
- end
99
- end
100
-
101
- def build_index_definition(model_name, index_columns)
102
- table_name = model_name.pluralize
103
-
104
- case index_columns
105
- when Array
106
- if index_columns.size == 1
107
- "add_index :#{table_name}, :#{index_columns.first}, unique: true\n"
108
- else
109
- column_list = index_columns.map { |col| ":#{col}" }.join(", ")
110
- "add_index :#{table_name}, [#{column_list}], unique: true\n"
111
- end
112
- else
113
- "add_index :#{table_name}, :#{index_columns}, unique: true\n"
114
- end
115
- end
116
-
117
- def membership_attributes
118
- [
119
- "#{normalized_name}:references",
120
- "#{normalized_auth_account_name}:references",
121
- "role:integer"
122
- ]
123
- end
124
-
125
- def add_default_to_role_column
126
- migration_dir = File.join("db", "migrate")
127
- migration_file = Dir[File.join(migration_dir, "*_create_#{normalized_entity_membership_name.pluralize}.rb")].first
128
-
129
- modify_file_if_exists(migration_file) do |file|
130
- gsub_file file, /t\.integer :role, null: false/, "t.integer :role, null: false, default: 0 # Member by default"
131
- end
132
- end
133
-
134
- def add_role_enum_to_model
135
- model_file = File.join("app", "models", "#{normalized_entity_membership_name}.rb")
136
-
137
- modify_file_if_exists(model_file) do |file|
138
- enum_definition = "\nenum :role, member: 0, owner: 1"
139
- insert_into_file file, indent(enum_definition, 2), before: /^\s*# add model configurations above\./
140
- end
141
- end
142
-
143
- def add_unique_validation_to_model
144
- model_file = File.join("app", "models", "#{normalized_entity_membership_name}.rb")
145
-
146
- modify_file_if_exists(model_file) do |file|
147
- validation_definition = "validates :#{normalized_auth_account_name}, uniqueness: {scope: :#{normalized_name}_id, message: \"is already a member of this entity\"}\n"
148
- insert_into_file file, indent(validation_definition, 2), before: /^\s*# add validations above\./
149
- end
150
- end
151
-
152
- def modify_file_if_exists(file_path)
153
- return unless file_path && File.exist?(file_path)
154
- yield(file_path)
155
- end
156
- end
157
- end
158
- end
@@ -1,101 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- return unless defined?(Rodauth::Rails)
4
-
5
- require "rails/generators/named_base"
6
- require_relative "../lib/plutonium_generators"
7
-
8
- module Pu
9
- module Rodauth
10
- class CustomerGenerator < ::Rails::Generators::NamedBase
11
- include PlutoniumGenerators::Concerns::Logger
12
-
13
- source_root File.expand_path("templates", __dir__)
14
-
15
- desc "Generate a rodauth-rails account optimized for customer-based tasks"
16
-
17
- class_option :allow_signup, type: :boolean, default: true,
18
- desc: "Whether to allow customer to sign up to the platform"
19
-
20
- class_option :entity, default: "Entity",
21
- desc: "Generate an entity model for customer accounts. Defaults to 'Entity'",
22
- aliases: ["--entity", "-e"]
23
-
24
- def start
25
- create_customer_account
26
- create_entity_model_and_membership
27
- configure_model_relationships
28
- rescue => e
29
- exception "#{self.class} failed:", e
30
- end
31
-
32
- private
33
-
34
- def create_customer_account
35
- invoke "pu:rodauth:account", [name],
36
- defaults: false,
37
- **customer_features,
38
- force: options[:force],
39
- skip: options[:skip],
40
- lint: true
41
- end
42
-
43
- def create_entity_model_and_membership
44
- invoke "pu:res:entity", [normalized_entity_name],
45
- auth_account: normalized_name,
46
- force: options[:force],
47
- skip: options[:skip]
48
- end
49
-
50
- def configure_model_relationships
51
- entity_model_path = File.join("app", "models", "#{normalized_entity_name}.rb")
52
- if File.exist?(entity_model_path)
53
- insert_into_file entity_model_path, <<~RUBY + " ", before: /# add has_many associations above\.\n/
54
- has_many :#{normalized_entity_membership_name.pluralize}
55
- has_many :#{normalized_name.pluralize}, through: :#{normalized_entity_membership_name.pluralize}
56
- RUBY
57
- end
58
-
59
- customer_model_path = File.join("app", "models", "#{normalized_name}.rb")
60
- if File.exist?(customer_model_path)
61
- insert_into_file customer_model_path, <<~RUBY + " ", before: /# add has_many associations above\.\n/
62
- has_many :#{normalized_entity_membership_name.pluralize}
63
- has_many :#{normalized_entity_name.pluralize}, through: :#{normalized_entity_membership_name.pluralize}
64
- RUBY
65
- end
66
- end
67
-
68
- private
69
-
70
- def customer_features
71
- features = %i[
72
- login
73
- remember
74
- logout
75
- create_account
76
- verify_account
77
- verify_account_grace_period
78
- reset_password
79
- reset_password_notify
80
- change_login
81
- verify_login_change
82
- change_password
83
- change_password_notify
84
- case_insensitive_login
85
- internal_request
86
- ]
87
-
88
- features.delete(:create_account) unless options[:allow_signup]
89
- features.map { |feature| [feature, true] }.to_h
90
- end
91
-
92
- def normalized_name = name.underscore
93
-
94
- def normalized_entity_name = options[:entity].underscore
95
-
96
- def normalized_entity_membership_name
97
- "#{normalized_entity_name.underscore}_#{normalized_name}"
98
- end
99
- end
100
- end
101
- end