bullet_train 1.2.20 → 1.2.22

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 (34) hide show
  1. checksums.yaml +4 -4
  2. data/app/models/concerns/invitations/base.rb +2 -5
  3. data/app/models/concerns/memberships/base.rb +1 -1
  4. data/app/models/concerns/records/base.rb +1 -5
  5. data/app/views/account/invitations/new.html.erb +5 -10
  6. data/app/views/account/invitations/show.html.erb +3 -3
  7. data/app/views/account/memberships/_index.html.erb +5 -5
  8. data/app/views/account/memberships/_menu_item.html.erb +2 -2
  9. data/app/views/account/memberships/_tombstones.html.erb +4 -4
  10. data/app/views/account/memberships/edit.html.erb +9 -15
  11. data/app/views/account/memberships/index.html.erb +3 -3
  12. data/app/views/account/memberships/show.html.erb +11 -14
  13. data/app/views/account/onboarding/user_details/edit.html.erb +3 -3
  14. data/app/views/account/onboarding/user_email/edit.html.erb +3 -3
  15. data/app/views/account/teams/_menu_item.html.erb +2 -2
  16. data/app/views/account/teams/_team.html.erb +2 -2
  17. data/app/views/account/teams/edit.html.erb +5 -10
  18. data/app/views/account/teams/index.html.erb +4 -6
  19. data/app/views/account/teams/new.html.erb +3 -3
  20. data/app/views/account/users/edit.html.erb +9 -12
  21. data/app/views/devise/passwords/edit.html.erb +3 -3
  22. data/app/views/devise/passwords/new.html.erb +3 -3
  23. data/app/views/devise/registrations/_two_factor.html.erb +5 -6
  24. data/app/views/devise/registrations/new.html.erb +3 -3
  25. data/app/views/devise/sessions/new.html.erb +4 -8
  26. data/app/views/layouts/docs.html.erb +33 -33
  27. data/docs/application-options.md +2 -0
  28. data/docs/field-partials.md +1 -1
  29. data/docs/super-scaffolding/sortable.md +2 -2
  30. data/lib/bullet_train/resolver.rb +10 -7
  31. data/lib/bullet_train/version.rb +1 -1
  32. data/lib/bullet_train.rb +9 -0
  33. data/lib/tasks/bullet_train_tasks.rake +25 -7
  34. metadata +17 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4561ddbfaa81217ae48ea15b210025cb0390f3acecb2a7be5f0cd239eb0ec731
4
- data.tar.gz: 610569262d3a98cf8778a702202f21c0739b62e4e68691befa83b90b1800fab2
3
+ metadata.gz: d03b4bc2028c88dac20f3223cd1cd6ef395cae53b6cf84377360b0b068a0c0e8
4
+ data.tar.gz: 3524f24af8fd64c3be1ae14ddf99562fd9ba251faed18e88f35800ff11c3a7f2
5
5
  SHA512:
6
- metadata.gz: 2a2a672f5278fa428754aeee9f17a4115e4bf0b9420b9768790bd3d7e9a29c2a98dfeec7ce82b6d33338cd61674fc7ebf4074a7b4b7f3f239733a3e20ef8e194
7
- data.tar.gz: 4dc593a08ee2e2137a807038ca554be019b1a3fb8362e691be55f4e9834be6636a9475947b51e272205968b5665306261bc8bc63aec9e4cc6f4dbab23c9361f3
6
+ metadata.gz: 7da1cc8e9a9acaef9fa0eeeab6c135f7d3c7d6261c2518c4b29c572711fe2e347ce3da8e7476a6fd2f8515af6d6c442df77f1d7566b7d9ba95c9dc0f59026078
7
+ data.tar.gz: 622671f75556fe2358107f3acdba1f917da32347df64b325514ad670c09044b85baad4e56ed3d7edc45ae761e4bf07cac91170cbeb5ea73254e3d0f124bb3985
@@ -11,9 +11,10 @@ module Invitations::Base
11
11
 
12
12
  validates :email, presence: true
13
13
 
14
- before_create :generate_uuid
15
14
  after_create :set_added_by_membership
16
15
  after_create :send_invitation_email
16
+
17
+ attribute :uuid, default: -> { SecureRandom.hex }
17
18
  end
18
19
 
19
20
  def set_added_by_membership
@@ -24,10 +25,6 @@ module Invitations::Base
24
25
  UserMailer.invited(uuid).deliver_later
25
26
  end
26
27
 
27
- def generate_uuid
28
- self.uuid = SecureRandom.hex
29
- end
30
-
31
28
  def accept_for(user)
32
29
  User.transaction do
33
30
  user.memberships << membership
@@ -128,7 +128,7 @@ module Memberships::Base
128
128
 
129
129
  def last_initial
130
130
  return nil unless last_name.present?
131
- "#{last_name}."
131
+ "#{last_name[0]}."
132
132
  end
133
133
 
134
134
  def first_name_last_initial
@@ -73,11 +73,7 @@ module Records::Base
73
73
  end
74
74
 
75
75
  def seeding?
76
- rake_tasks = ObjectSpace.each_object(Rake::Task)
77
- return false if rake_tasks.count.zero?
78
-
79
- db_seed_task = rake_tasks.find { |task| task.name.match?(/^db:seed$/) }
80
- db_seed_task.already_invoked
76
+ Rake::Task.task_defined?("db:seed") && Rake::Task["db:seed"].already_invoked
81
77
  end
82
78
 
83
79
  # TODO This should really be in the API package and included from there.
@@ -1,12 +1,7 @@
1
- <%= render 'account/shared/page' do |p| %>
2
- <% p.content_for :title, t('.section') %>
3
- <% p.content_for :body do %>
4
- <%= render 'account/shared/box', divider: true do |p| %>
5
- <% p.content_for :title, t('.header') %>
6
- <% p.content_for :description, t('.description') %>
7
- <% p.content_for :body do %>
8
- <%= render 'form', invitation: @invitation %>
9
- <% end %>
10
- <% end %>
1
+ <%= render 'account/shared/page' do |page| %>
2
+ <% page.title t('.section') %>
3
+ <% page.body.render 'account/shared/box', divider: true do |box| %>
4
+ <% box.t :description, title: '.header' %>
5
+ <% box.body.render 'form', invitation: @invitation %>
11
6
  <% end %>
12
7
  <% end %>
@@ -1,6 +1,6 @@
1
- <%= render 'account/shared/workflow/box' do |p| %>
2
- <% p.content_for :title, t(".join_team") %>
3
- <% p.content_for :body do %>
1
+ <%= render 'account/shared/workflow/box' do |box| %>
2
+ <% box.title t(".join_team") %>
3
+ <% box.body do %>
4
4
  <div class="space-y">
5
5
  <% if !@invitation.is_for?(current_user) %>
6
6
  <p><%= raw t('.has_invited', user_name: @invitation.from_membership.name) %></p>
@@ -3,14 +3,14 @@
3
3
  <% hide_back ||= false %>
4
4
 
5
5
  <%= updates_for context, :memberships do %>
6
- <%= render 'account/shared/box' do |p| %>
7
- <% p.content_for :title, t(".contexts.#{context.class.name.underscore}.header") %>
8
- <% p.content_for :description do %>
6
+ <%= render 'account/shared/box' do |box| %>
7
+ <% box.title t(".contexts.#{context.class.name.underscore}.header") %>
8
+ <% box.description do %>
9
9
  <%= raw t(".contexts.#{context.class.name.underscore}.#{@memberships.any? ? 'description' : 'description_empty'}") %>
10
10
  <%= render "shared/limits/index", model: @memberships.model %>
11
11
  <% end %>
12
12
 
13
- <% p.content_for :table do %>
13
+ <% box.table do %>
14
14
  <% if @memberships.any? %>
15
15
  <table class="table">
16
16
  <thead>
@@ -29,7 +29,7 @@
29
29
  <% end %>
30
30
 
31
31
  <% unless hide_actions %>
32
- <% p.content_for :actions do %>
32
+ <% box.actions do %>
33
33
  <%= link_to t('invitations.buttons.new'), new_account_team_invitation_path(@team, cancel_path: account_team_memberships_path(@team)), class: "#{first_button_primary}" %>
34
34
  <%= link_to t('global.buttons.back'), [:account, context], class: "#{first_button_primary} back" unless hide_back %>
35
35
  <% end %>
@@ -1,8 +1,8 @@
1
1
  <%= render 'account/shared/menu/item', {
2
2
  url: main_app.polymorphic_path([:account, current_team, :memberships]),
3
3
  label: t('memberships.navigation.label'),
4
- } do |p| %>
5
- <% p.content_for :icon do %>
4
+ } do |item| %>
5
+ <% item.icon do %>
6
6
  <i class="<%= t('memberships.navigation.icon') %>"></i>
7
7
  <% end %>
8
8
  <% end %>
@@ -1,13 +1,13 @@
1
1
  <% context ||= @team %>
2
2
  <% hide_actions ||= false %>
3
3
 
4
- <%= render 'account/shared/box' do |p| %>
5
- <% p.content_for :title, t("memberships.tombstones.contexts.#{context.class.name.underscore}.header") %>
6
- <% p.content_for :description do %>
4
+ <%= render 'account/shared/box' do |box| %>
5
+ <% box.title t("memberships.tombstones.contexts.#{context.class.name.underscore}.header") %>
6
+ <% box.description do %>
7
7
  <%= raw t("memberships.tombstones.contexts.#{context.class.name.underscore}.#{memberships.any? ? 'description' : 'description_empty'}") %>
8
8
  <% end %>
9
9
 
10
- <% p.content_for :body do %>
10
+ <% box.body do %>
11
11
  <% if memberships.any? %>
12
12
  <table class="table">
13
13
  <thead>
@@ -1,21 +1,15 @@
1
- <%= render 'account/shared/page' do |p| %>
2
- <% p.content_for :title, t('.section') %>
3
- <% p.content_for :body do %>
4
- <%= render 'account/shared/box', divider: true do |p| %>
5
- <% p.content_for :title, t('.header') %>
6
- <% p.content_for :description, t('.description') %>
7
- <% p.content_for :body do %>
8
- <%= render 'form', membership: @membership %>
9
- <% end %>
1
+ <%= render 'account/shared/page' do |page| %>
2
+ <% page.title t('.section') %>
3
+ <% page.body do %>
4
+ <%= render 'account/shared/box', divider: true do |box| %>
5
+ <% box.t :description, title: '.header' %>
6
+ <% box.body.render 'form', membership: @membership %>
10
7
  <% end %>
11
8
 
12
9
  <% if can? :destroy, @membership %>
13
- <%= render 'account/shared/box', divider: true do |p| %>
14
- <% p.content_for :title, t('.remove_header') %>
15
- <% p.content_for :description, t('.remove_description') %>
16
- <% p.content_for :body do %>
17
- <%= button_to t('.buttons.destroy'), [:account, @membership], method: :delete, data: { confirm: t('.buttons.confirmations.destroy') }, class: 'button' %>
18
- <% end %>
10
+ <%= render 'account/shared/box', divider: true do |box| %>
11
+ <% box.t title: '.remove_header', description: '.remove_description' %>
12
+ <% box.body.button_to t('.buttons.destroy'), [:account, @membership], method: :delete, data: { confirm: t('.buttons.confirmations.destroy') }, class: 'button' %>
19
13
  <% end %>
20
14
  <% end %>
21
15
  <% end %>
@@ -1,6 +1,6 @@
1
- <%= render 'account/shared/page' do |p| %>
2
- <% p.content_for :title, t('.section') %>
3
- <% p.content_for :body do %>
1
+ <%= render 'account/shared/page' do |page| %>
2
+ <% page.title t('.section') %>
3
+ <% page.body do %>
4
4
  <% if @memberships.current_and_invited.any? %>
5
5
  <%= render 'index' do %>
6
6
  <%= render @memberships.current_and_invited.includes(:user) %>
@@ -1,8 +1,8 @@
1
- <%= render 'account/shared/page' do |p| %>
2
- <% p.content_for :title, t('.section') %>
3
- <% p.content_for :body do %>
4
- <%= render 'account/shared/box', divider: true do |p| %>
5
- <% p.content_for :title do %>
1
+ <%= render 'account/shared/page' do |page| %>
2
+ <% page.title t('.section') %>
3
+ <% page.body do %>
4
+ <%= render 'account/shared/box', divider: true do |box| %>
5
+ <% box.title do %>
6
6
  <% if @membership.unclaimed? %>
7
7
  <%= t('.invitation_header') %>
8
8
  <% elsif @membership.tombstone? %>
@@ -12,16 +12,14 @@
12
12
  <% end %>
13
13
  <% end %>
14
14
 
15
- <% p.content_for :description do %>
16
- <%= t('.description') %>
17
- <% end %>
15
+ <% box.t :description %>
18
16
 
19
- <% p.content_for :body do %>
17
+ <% box.body do %>
20
18
  <% with_attribute_settings object: @membership, strategy: :label do %>
21
19
  <%= render 'shared/attributes/text', attribute: :name %>
22
- <%= render 'shared/attributes/base' do |p| %>
23
- <% p.content_for :heading, t('.fields.role_ids.heading') %>
24
- <% p.content_for :body do %>
20
+ <%= render 'shared/attributes/base' do |base| %>
21
+ <% base.heading t('.fields.role_ids.heading') %>
22
+ <% base.body do %>
25
23
  <% if @membership.assignable_roles.any? %>
26
24
  <%= @membership.assignable_roles.map { |role| t(".fields.role_ids.options.#{role.key}.label") }.to_sentence %>
27
25
  <% else %>
@@ -33,7 +31,7 @@
33
31
  <%# 🚅 super scaffolding will insert new fields above this line. %>
34
32
  <% end %>
35
33
 
36
- <% p.content_for :actions do %>
34
+ <% box.actions do %>
37
35
  <% if @membership.tombstone? %>
38
36
  <%= link_to t('.buttons.reinvite'), [:reinvite, :account, @membership], class: first_button_primary, method: :post, data: {confirm: t('.buttons.confirmations.reinvite', membership_name: @membership.name)} if can? :edit, @membership %>
39
37
  <% end %>
@@ -53,7 +51,6 @@
53
51
 
54
52
  <%= link_to t('global.buttons.back'), [:account, @team, :memberships], class: first_button_primary %>
55
53
  <% end %>
56
-
57
54
  <% end %>
58
55
 
59
56
  <%= render 'account/scaffolding/completely_concrete/tangible_things/index', tangible_things: @membership.scaffolding_completely_concrete_tangible_things, context: @membership if @membership.scaffolding_completely_concrete_tangible_things.any? %>
@@ -1,8 +1,8 @@
1
1
  <% @title = t('.header') %>
2
2
 
3
- <%= render 'account/shared/workflow/box' do |p| %>
4
- <% p.content_for :title, @title %>
5
- <% p.content_for :body do %>
3
+ <%= render 'account/shared/workflow/box' do |box| %>
4
+ <% box.title @title %>
5
+ <% box.body do %>
6
6
  <% within_fields_namespace(:self) do %>
7
7
  <%= form_for @user, url: account_onboarding_user_detail_path(@user), method: :put, html: {class: 'form'} do |f| %>
8
8
  <%= render 'account/shared/forms/errors', form: f %>
@@ -1,8 +1,8 @@
1
1
  <% @title = t('.header') %>
2
2
 
3
- <%= render 'account/shared/workflow/box' do |p| %>
4
- <% p.content_for :title, @title %>
5
- <% p.content_for :body do %>
3
+ <%= render 'account/shared/workflow/box' do |box| %>
4
+ <% box.title @title %>
5
+ <% box.body do %>
6
6
  <% within_fields_namespace(:self) do %>
7
7
  <%= form_for @user, url: account_onboarding_user_email_path(@user), method: :put, html: {class: 'form'} do |f| %>
8
8
  <% if @email_taken %>
@@ -1,8 +1,8 @@
1
1
  <%= render 'account/shared/menu/item', {
2
2
  url: main_app.polymorphic_path([:account, current_team]),
3
3
  label: t('menus.main.labels.dashboard'),
4
- } do |p| %>
5
- <% p.content_for :icon do %>
4
+ } do |item| %>
5
+ <% item.icon do %>
6
6
  <i class="fal fa-home-lg-alt ti ti-home"></i>
7
7
  <% end %>
8
8
  <% end %>
@@ -1,3 +1,3 @@
1
- <%= render 'account/shared/team', link_url: [:account, team], memberships: team.memberships.current_and_invited.first(10) do |p| %>
2
- <% p.content_for :name, team.name %>
1
+ <%= render 'account/shared/team', link_url: [:account, team], memberships: team.memberships.current_and_invited.first(10) do |p| %>
2
+ <% p.name team.name %>
3
3
  <% end %>
@@ -1,12 +1,7 @@
1
- <%= render 'account/shared/page' do |p| %>
2
- <% p.content_for :title, t('.section') %>
3
- <% p.content_for :body do %>
4
- <%= render 'account/shared/box', divider: true do |p| %>
5
- <% p.content_for :title, t('.header') %>
6
- <% p.content_for :description, t('.description') %>
7
- <% p.content_for :body do %>
8
- <%= render 'form', team: @team %>
9
- <% end %>
10
- <% end %>
1
+ <%= render 'account/shared/page' do |page| %>
2
+ <% page.title t('.section') %>
3
+ <% page.body.render 'account/shared/box', divider: true do |box| %>
4
+ <% box.t :description, title: '.header' %>
5
+ <% box.body.render 'form', team: @team %>
11
6
  <% end %>
12
7
  <% end %>
@@ -1,8 +1,6 @@
1
- <%= render 'account/shared/page' do |p| %>
2
- <% p.content_for :title, t('.section') %>
3
- <% p.content_for :body do %>
4
- <%= render 'index', creative_concepts: @creative_concepts do %>
5
- <%= render @teams %>
6
- <% end %>
1
+ <%= render 'account/shared/page' do |page| %>
2
+ <% page.title t('.section') %>
3
+ <% page.body.render 'index', creative_concepts: @creative_concepts do %>
4
+ <%= render @teams %>
7
5
  <% end %>
8
6
  <% end %>
@@ -6,9 +6,9 @@ else
6
6
  end
7
7
  %>
8
8
 
9
- <%= render 'account/shared/workflow/box' do |p| %>
10
- <% p.content_for :title, @title %>
11
- <% p.content_for :body do %>
9
+ <%= render 'account/shared/workflow/box' do |box| %>
10
+ <% box.title @title %>
11
+ <% box.body do %>
12
12
  <%= form_with model: @team, url: [:account, @team], local: true, class: 'form' do |form| %>
13
13
  <%= render 'account/shared/notices' %>
14
14
  <%= render 'account/shared/forms/errors', form: form %>
@@ -1,18 +1,15 @@
1
- <%= render 'account/shared/page' do |p| %>
2
- <% p.content_for :title, t('.section') %>
3
- <% p.content_for :body do %>
1
+ <%= render 'account/shared/page' do |page| %>
2
+ <% page.title t('.section') %>
3
+ <% page.body do %>
4
4
  <%= form_for [:account, @user] do |form| %>
5
5
  <%= render 'account/shared/forms/errors', form: form %>
6
6
  <% end if @user.errors.any? %>
7
7
 
8
8
  <div class="grid grid-cols-1 gap-y gap-x-8 lg:grid-cols-2">
9
9
  <div class="xl:col-span-1 space-y-8">
10
- <%= render 'account/shared/box', divider: true do |p| %>
11
- <% p.content_for :title, t('.profile.header') %>
12
- <% p.content_for :description, t('.profile.description') %>
13
- <% p.content_for :body do %>
14
- <%= render "account/users/form", user: @user %>
15
- <% end %>
10
+ <%= render 'account/shared/box', divider: true do |box| %>
11
+ <% box.t title: '.profile.header', description: '.profile.description' %>
12
+ <% box.body.render "account/users/form", user: @user %>
16
13
  <% end %>
17
14
 
18
15
  <% if two_factor_authentication_enabled? %>
@@ -25,9 +22,9 @@
25
22
  <div class="xl:col-span-1 space-y-8">
26
23
  <%= render 'account/users/oauth' %>
27
24
 
28
- <%= render 'account/shared/box', divider: true do |p| %>
29
- <% p.content_for :title, t('.password.header') %>
30
- <% p.content_for :body do %>
25
+ <%= render 'account/shared/box', divider: true do |box| %>
26
+ <% box.title t('.password.header') %>
27
+ <% box.body do %>
31
28
  <% within_fields_namespace(:update_self) do %>
32
29
  <%= form_for [:account, @user], html: {id: dom_id(@user, :password), class: 'form'} do |form| %>
33
30
  <% with_field_settings form: form do %>
@@ -1,7 +1,7 @@
1
1
  <% @title = t('devise.headers.change_password') %>
2
- <%= render 'account/shared/workflow/box' do |p| %>
3
- <% p.content_for :title, @title %>
4
- <% p.content_for :body do %>
2
+ <%= render 'account/shared/workflow/box' do |box| %>
3
+ <% box.title @title %>
4
+ <% box.body do %>
5
5
  <% within_fields_namespace(:update_self) do %>
6
6
  <%= form_for(resource, as: resource_name, url: password_path(resource_name), html: { class: 'form', method: :put }) do |f| %>
7
7
  <%= f.hidden_field :reset_password_token %>
@@ -1,6 +1,6 @@
1
- <%= render 'account/shared/workflow/box' do |p| %>
2
- <% p.content_for :title, t('devise.titles.reset_password') %>
3
- <% p.content_for :body do %>
1
+ <%= render 'account/shared/workflow/box' do |box| %>
2
+ <% box.title t('devise.titles.reset_password') %>
3
+ <% box.body do %>
4
4
  <% within_fields_namespace(:sign_up) do %>
5
5
  <%= form_for resource, as: resource_name, url: password_path(resource_name), html: {method: :post, class: 'form'} do |f| %>
6
6
  <%= render 'account/shared/forms/errors', form: f %>
@@ -1,10 +1,9 @@
1
- <%= render 'account/shared/box', divider: @backup_codes do |p| %>
2
- <% p.content_for :title, t("users.edit.two_factor.header") %>
3
- <% p.content_for :description, t("users.edit.two_factor.description_#{@user.otp_required_for_login? ? 'enabled' : 'disabled'}") %>
1
+ <%= render 'account/shared/box', divider: @backup_codes do |box| %>
2
+ <% box.title t("users.edit.two_factor.header") %>
3
+ <% box.description t("users.edit.two_factor.description_#{@user.otp_required_for_login? ? 'enabled' : 'disabled'}") %>
4
4
  <% if current_user.otp_secret %>
5
5
  <% if @backup_codes %>
6
- <% p.content_for :body do %>
7
-
6
+ <% box.body do %>
8
7
  <%= render 'account/shared/alert' do %>
9
8
  <%= t('users.edit.two_factor.warning').html_safe %>
10
9
  <% end %>
@@ -38,7 +37,7 @@
38
37
  <% end %>
39
38
  <% end %>
40
39
  <% end %>
41
- <% p.content_for :actions do %>
40
+ <% box.actions do %>
42
41
  <div class="<%= 'hidden' if @backup_codes %> space-y">
43
42
  <% if local_assigns.has_key? :verified %>
44
43
  <% if verified %>
@@ -1,6 +1,6 @@
1
- <%= render 'account/shared/workflow/box' do |p| %>
2
- <% p.content_for :title, t('devise.headers.create_account') %>
3
- <% p.content_for :body do %>
1
+ <%= render 'account/shared/workflow/box' do |box| %>
2
+ <% box.title t('devise.headers.create_account') %>
3
+ <% box.body do %>
4
4
  <% within_fields_namespace(:sign_up) do %>
5
5
  <%= form_for resource, as: resource_name, url: registration_path(resource_name), html: {class: 'form'} do |f| %>
6
6
  <%= render 'account/shared/notices' %>
@@ -1,6 +1,6 @@
1
- <%= render 'account/shared/workflow/box' do |p| %>
2
- <% p.content_for :title, t('devise.headers.sign_in') %>
3
- <% p.content_for :body do %>
1
+ <%= render 'account/shared/workflow/box' do |box| %>
2
+ <% box.title t('devise.headers.sign_in') %>
3
+ <% box.body do %>
4
4
  <% within_fields_namespace(:self) do %>
5
5
  <%# TODO: Turbo is set to `false` for now, but we may want to only bypass Turbo for JavaScript-based requests in the future. %>
6
6
  <%= form_for resource, as: resource_name, url: two_factor_authentication_enabled? ? users_pre_otp_path : session_path(resource_name), remote: two_factor_authentication_enabled?, html: {class: 'form'}, authenticity_token: true, data: {turbo: false} do |form| %>
@@ -44,11 +44,7 @@
44
44
  </div>
45
45
 
46
46
  <% if devise_mapping.rememberable? %>
47
- <% # TODO This needs to be its own component. Can't have this kind of styling here. %>
48
- <div class="flex items-center">
49
- <%= form.check_box :remember_me, class: "h-4 w-4 text-blue focus:ring-blue-800 border-slate-300 rounded dark:bg-slate-800 dark:border-slate-900" %>
50
- <%= form.label :remember_me, class: "ml-2 block" %>
51
- </div>
47
+ <%= render 'shared/fields/option', method: :remember_me, form: form, single_check_box: true %>
52
48
  <% end %>
53
49
  <% end %>
54
50
  <% end %>
@@ -60,19 +60,19 @@
60
60
 
61
61
  <%= render 'account/shared/menu/section', title: 'Introduction' do %>
62
62
  <%= render 'account/shared/menu/item', url: '/docs', label: 'Table of Contents' do |p| %>
63
- <% p.content_for :icon do %>
63
+ <% p.icon do %>
64
64
  <i class="fal fa-home-lg-alt ti ti-list"></i>
65
65
  <% end %>
66
66
  <% end %>
67
67
 
68
68
  <%= render 'account/shared/menu/item', url: '/docs/getting-started', label: 'Getting Started' do |p| %>
69
- <% p.content_for :icon do %>
69
+ <% p.icon do %>
70
70
  <i class="fal fa-terminal ti ti-flag"></i>
71
71
  <% end %>
72
72
  <% end %>
73
73
 
74
74
  <%= render 'account/shared/menu/item', url: '/docs/upgrades', label: 'Upgrades' do |p| %>
75
- <% p.content_for :icon do %>
75
+ <% p.icon do %>
76
76
  <i class="fal fa-sparkles ti ti-arrow-up"></i>
77
77
  <% end %>
78
78
  <% end %>
@@ -80,37 +80,37 @@
80
80
 
81
81
  <%= render 'account/shared/menu/section', title: 'General Topics' do %>
82
82
  <%= render 'account/shared/menu/item', url: '/docs/modeling', label: 'Domain Modeling' do |p| %>
83
- <% p.content_for :icon do %>
83
+ <% p.icon do %>
84
84
  <i class="fal fa-bolt ti ti-ruler-pencil"></i>
85
85
  <% end %>
86
86
  <% end %>
87
87
 
88
88
  <%= render 'account/shared/menu/item', url: '/docs/indirection', label: 'Indirection' do |p| %>
89
- <% p.content_for :icon do %>
89
+ <% p.icon do %>
90
90
  <i class="fal fa-bolt ti ti-direction"></i>
91
91
  <% end %>
92
92
  <% end %>
93
93
 
94
94
  <%= render 'account/shared/menu/item', url: '/docs/overriding', label: 'Overriding' do |p| %>
95
- <% p.content_for :icon do %>
95
+ <% p.icon do %>
96
96
  <i class="fal fa-bolt ti ti-spray"></i>
97
97
  <% end %>
98
98
  <% end %>
99
99
 
100
100
  <%= render 'account/shared/menu/item', url: '/docs/tunneling', label: 'Tunneling' do |p| %>
101
- <% p.content_for :icon do %>
101
+ <% p.icon do %>
102
102
  <i class="fal fa-bolt ti ti-bolt"></i>
103
103
  <% end %>
104
104
  <% end %>
105
105
 
106
106
  <%= render 'account/shared/menu/item', url: '/docs/javascript', label: 'JavaScript' do |p| %>
107
- <% p.content_for :icon do %>
107
+ <% p.icon do %>
108
108
  <i class="fa-brands fa-js ti ti-pulse"></i>
109
109
  <% end %>
110
110
  <% end %>
111
111
 
112
112
  <%= render 'account/shared/menu/item', url: '/docs/i18n', label: 'Internationalzation' do |p| %>
113
- <% p.content_for :icon do %>
113
+ <% p.icon do %>
114
114
  <i class="fa-brands fa-js ti ti-world"></i>
115
115
  <% end %>
116
116
  <% end %>
@@ -118,37 +118,37 @@
118
118
 
119
119
  <%= render 'account/shared/menu/section', title: 'Developer Tools' do %>
120
120
  <%= render 'account/shared/menu/item', url: '/docs/super-scaffolding', label: 'Super Scaffolding' do |p| %>
121
- <% p.content_for :icon do %>
121
+ <% p.icon do %>
122
122
  <i class="fal fa-magic ti ti-wand"></i>
123
123
  <% end %>
124
124
  <% end %>
125
125
 
126
126
  <%= render 'account/shared/menu/item', url: '/docs/action-models', label: 'Action Models' do |p| %>
127
- <% p.content_for :icon do %>
127
+ <% p.icon do %>
128
128
  <i class="fal fa-bars-progress ti ti-target"></i>
129
129
  <% end %>
130
130
  <% end %>
131
131
 
132
132
  <%= render 'account/shared/menu/item', url: '/docs/seeds', label: 'Database Seeds' do |p| %>
133
- <% p.content_for :icon do %>
133
+ <% p.icon do %>
134
134
  <i class="fal fa-seedling ti ti-server"></i>
135
135
  <% end %>
136
136
  <% end %>
137
137
 
138
138
  <%= render 'account/shared/menu/item', url: '/docs/testing', label: 'Test Suite' do |p| %>
139
- <% p.content_for :icon do %>
139
+ <% p.icon do %>
140
140
  <i class="fal fa-check ti ti-check"></i>
141
141
  <% end %>
142
142
  <% end %>
143
143
 
144
144
  <%= render 'account/shared/menu/item', url: 'https://github.com/bullet-train-co/magic_test', label: 'Magic Test' do |p| %>
145
- <% p.content_for :icon do %>
145
+ <% p.icon do %>
146
146
  <i class="fal fa-check ti ti-video-camera"></i>
147
147
  <% end %>
148
148
  <% end %>
149
149
 
150
150
  <%= render 'account/shared/menu/item', url: '/docs/application-options', label: 'Application Options' do |p| %>
151
- <% p.content_for :icon do %>
151
+ <% p.icon do %>
152
152
  <i class="fal fa-gear ti ti-settings"></i>
153
153
  <% end %>
154
154
  <% end %>
@@ -156,31 +156,31 @@
156
156
 
157
157
  <%= render 'account/shared/menu/section', title: 'Accounts & Teams' do %>
158
158
  <%= render 'account/shared/menu/item', url: '/docs/authentication', label: 'Authentication' do |p| %>
159
- <% p.content_for :icon do %>
159
+ <% p.icon do %>
160
160
  <i class="fal fa-fingerprint ti ti-id-badge"></i>
161
161
  <% end %>
162
162
  <% end %>
163
163
 
164
164
  <%= render 'account/shared/menu/item', url: '/docs/teams', label: 'Teams' do |p| %>
165
- <% p.content_for :icon do %>
165
+ <% p.icon do %>
166
166
  <i class="fal fa-users ti ti-user"></i>
167
167
  <% end %>
168
168
  <% end %>
169
169
 
170
170
  <%= render 'account/shared/menu/item', url: '/docs/permissions', label: 'Roles & Permissions' do |p| %>
171
- <% p.content_for :icon do %>
171
+ <% p.icon do %>
172
172
  <i class="fal fa-lock-alt ti ti-lock"></i>
173
173
  <% end %>
174
174
  <% end %>
175
175
 
176
176
  <%= render 'account/shared/menu/item', url: '/docs/onboarding', label: 'Onboarding' do |p| %>
177
- <% p.content_for :icon do %>
177
+ <% p.icon do %>
178
178
  <i class="fal fa-snowboarding ti ti-direction"></i>
179
179
  <% end %>
180
180
  <% end %>
181
181
 
182
182
  <%= render 'account/shared/menu/item', url: '/docs/namespacing', label: 'Namespacing' do |p| %>
183
- <% p.content_for :icon do %>
183
+ <% p.icon do %>
184
184
  <i class="fal fa-object-group ti ti-widgetized"></i>
185
185
  <% end %>
186
186
  <% end %>
@@ -188,19 +188,19 @@
188
188
 
189
189
  <%= render 'account/shared/menu/section', title: 'User Interface' do %>
190
190
  <%= render 'account/shared/menu/item', url: '/docs/field-partials', label: 'Field Partials' do |p| %>
191
- <% p.content_for :icon do %>
191
+ <% p.icon do %>
192
192
  <i class="fal fa-i-cursor ti ti-text"></i>
193
193
  <% end %>
194
194
  <% end %>
195
195
 
196
196
  <%= render 'account/shared/menu/item', url: '/docs/themes', label: 'Themes' do |p| %>
197
- <% p.content_for :icon do %>
197
+ <% p.icon do %>
198
198
  <i class="fal fa-swatchbook ti ti-palette"></i>
199
199
  <% end %>
200
200
  <% end %>
201
201
 
202
202
  <%= render 'account/shared/menu/item', url: 'https://github.com/bullet-train-co/nice_partials', label: 'Nice Partials' do |p| %>
203
- <% p.content_for :icon do %>
203
+ <% p.icon do %>
204
204
  <i class="fal fa-swatchbook ti ti-widget"></i>
205
205
  <% end %>
206
206
  <% end %>
@@ -208,7 +208,7 @@
208
208
 
209
209
  <%= render 'account/shared/menu/section', title: 'Billing' do %>
210
210
  <%= render 'account/shared/menu/item', url: '/docs/billing/stripe', label: 'Stripe' do |p| %>
211
- <% p.content_for :icon do %>
211
+ <% p.icon do %>
212
212
  <i class="fab fa-stripe-s ti ti-money"></i>
213
213
  <% end %>
214
214
  <% end %>
@@ -216,31 +216,31 @@
216
216
 
217
217
  <%= render 'account/shared/menu/section', title: 'Integration' do %>
218
218
  <%= render 'account/shared/menu/item', url: '/docs/api', label: 'REST API' do |p| %>
219
- <% p.content_for :icon do %>
219
+ <% p.icon do %>
220
220
  <i class="fal fa-brackets-curly ti ti-settings"></i>
221
221
  <% end %>
222
222
  <% end %>
223
223
 
224
224
  <%= render 'account/shared/menu/item', url: '/docs/zapier', label: 'Zapier' do |p| %>
225
- <% p.content_for :icon do %>
225
+ <% p.icon do %>
226
226
  <i class="fal fa-bolt ti ti-bolt"></i>
227
227
  <% end %>
228
228
  <% end %>
229
229
 
230
230
  <%= render 'account/shared/menu/item', url: '/docs/oauth', label: 'OAuth Providers' do |p| %>
231
- <% p.content_for :icon do %>
231
+ <% p.icon do %>
232
232
  <i class="fal fa-at ti ti-reload"></i>
233
233
  <% end %>
234
234
  <% end %>
235
235
 
236
236
  <%= render 'account/shared/menu/item', url: '/docs/webhooks/outgoing', label: 'Outgoing Webhooks' do |p| %>
237
- <% p.content_for :icon do %>
237
+ <% p.icon do %>
238
238
  <i class="fal fa-outlet ti ti-pulse"></i>
239
239
  <% end %>
240
240
  <% end %>
241
241
 
242
242
  <%= render 'account/shared/menu/item', url: '/docs/webhooks/incoming', label: 'Incoming Webhooks' do |p| %>
243
- <% p.content_for :icon do %>
243
+ <% p.icon do %>
244
244
  <i class="fal fa-plug ti ti-plug"></i>
245
245
  <% end %>
246
246
  <% end %>
@@ -248,7 +248,7 @@
248
248
 
249
249
  <%= render 'account/shared/menu/section', title: 'Internationalization' do %>
250
250
  <%= render 'account/shared/menu/item', url: '/docs/i18n', label: 'Translations' do |p| %>
251
- <% p.content_for :icon do %>
251
+ <% p.icon do %>
252
252
  <i class="fal fa-language ti ti-world"></i>
253
253
  <% end %>
254
254
  <% end %>
@@ -256,7 +256,7 @@
256
256
 
257
257
  <%= render 'account/shared/menu/section', title: 'Add-Ons' do %>
258
258
  <%= render 'account/shared/menu/item', url: '/docs/font-awesome-pro', label: 'Font Awesome Pro' do |p| %>
259
- <% p.content_for :icon do %>
259
+ <% p.icon do %>
260
260
  <i class="fal fa-flag ti ti-flag"></i>
261
261
  <% end %>
262
262
  <% end %>
@@ -264,13 +264,13 @@
264
264
 
265
265
  <%= render 'account/shared/menu/section', title: 'Deployment' do %>
266
266
  <%= render 'account/shared/menu/item', url: '/docs/heroku', label: 'Heroku' do |p| %>
267
- <% p.content_for :icon do %>
267
+ <% p.icon do %>
268
268
  <i class="fal fa-cloud ti ti-cloud-up"></i>
269
269
  <% end %>
270
270
  <% end %>
271
271
 
272
272
  <%= render 'account/shared/menu/item', url: '/docs/desktop', label: 'Desktop Applications' do |p| %>
273
- <% p.content_for :icon do %>
273
+ <% p.icon do %>
274
274
  <i class="fal fa-window-restore ti ti-desktop"></i>
275
275
  <% end %>
276
276
  <% end %>
@@ -15,6 +15,7 @@ The helper methods below can also be directly invoked in your application if you
15
15
  | FONTAWESOME_NPM_AUTH_TOKEN | String | `"your_font_awesome_token"` | `font_awesome?` |
16
16
  | SILENCE_LOGS | Boolean | `"true"` | `silence_logs?` |
17
17
  | TESTING_PROVISION_KEY | String | `"asdf123"` | N/A |
18
+ | OPENAI_ACCESS_TOKEN | String |`your_openai_token`| `openai_enabled?` |
18
19
 
19
20
  | Option | Description |
20
21
  | --- | --- |
@@ -27,3 +28,4 @@ The helper methods below can also be directly invoked in your application if you
27
28
  | FONTAWESOME_NPM_AUTH_TOKEN | Enables use of Font Awesome. |
28
29
  | SILENCE_LOGS | Silences Super Scaffolding logs. |
29
30
  | TESTING_PROVISION_KEY | Creates a test `Platform::Application` by accessing `/testing/provision?key=your_provision_key` |
31
+ | OPENAI_ACCESS_TOKEN | Enables use [OpenAI](https://openai.com/) with the [ruby-openai](https://github.com/alexrudall/ruby-openai) gem. |
@@ -114,7 +114,7 @@ Certain form field partials like `buttons` and `super_select` can also have thei
114
114
  | `boolean` | `boolean` | | `assign_boolean` | | |
115
115
  | [`buttons`](/docs/field-partials/buttons.md) | `string` | Optionally | `assign_checkboxes` | | |
116
116
  | `cloudinary_image` | `string` | | | | |
117
- | `color_picker` | | | | [pickr](https://simonwep.github.io/pickr/) | |
117
+ | `color_picker` | `string` | | | [pickr](https://simonwep.github.io/pickr/) | |
118
118
  | `date_and_time_field` | `datetime` | | `assign_date_and_time` | [Date Range Picker](https://www.daterangepicker.com) | |
119
119
  | `date_field` | `date` | | `assign_date` | [Date Range Picker](https://www.daterangepicker.com) | |
120
120
  | `email_field` | `string` | | | | |
@@ -12,7 +12,7 @@ The `--sortable` option:
12
12
 
13
13
  1. Wraps the table's body in a `sortable` Stimulus controller, providing drag-and-drop re-ordering;
14
14
  2. Adds a `reorder` action to your resource via `include SortableActions`, triggered automatically on re-order;
15
- 3. Adds a migration to add the `sort_order` column to your model to store the ordering;
15
+ 3. Adds a `sort_order` attribute to your model to store the ordering;
16
16
  4. Adds a `default_scope` which orders by `sort_order` and auto increments `sort_order` on create via `include Sortable` on the model.
17
17
 
18
18
  ## Disabling Saving on Re-order
@@ -134,4 +134,4 @@ And on the `sortable` element, catch the `sortable:drop`, `sortable:drag` (for c
134
134
  data-confirm-reorder-target="sortable"
135
135
  ...
136
136
  >
137
- ```
137
+ ```
@@ -72,7 +72,10 @@ module BulletTrain
72
72
  if open
73
73
  path = source_file[:package_name] ? source_file[:absolute_path] : (source_file[:project_path]).to_s
74
74
  puts "Opening `#{path}`.\n".green
75
- exec "open #{path}"
75
+
76
+ # TODO: Use TerminalCommands to open this file
77
+ open_command = `which open`.present? ? "open" : "xdg-open"
78
+ exec "#{open_command} #{path}"
76
79
  end
77
80
  else
78
81
  puts "Couldn't resolve `#{@needle}`.".red
@@ -101,7 +104,8 @@ module BulletTrain
101
104
 
102
105
  if result[:absolute_path]
103
106
  if result[:absolute_path].include?("/bullet_train")
104
- base_path = "bullet_train" + result[:absolute_path].partition("/bullet_train").last
107
+ regex = /#{"bullet_train-core" if result[:absolute_path].include?("bullet_train-core")}\/bullet_train[.\-_a-z|0-9]*.*/
108
+ base_path = result[:absolute_path].scan(regex).pop
105
109
 
106
110
  # Try to calculate which package the file is from, and what it's path is within that project.
107
111
  ["app", "config", "lib"].each do |directory|
@@ -146,14 +150,13 @@ module BulletTrain
146
150
  # all we need to do is change it to "shared/attributes/code"
147
151
  partial_parts.last.gsub!(/(_)|(\.html\.erb)/, "")
148
152
  @needle = partial_parts.join("/")
149
- elsif @needle.match?(/bullet_train-/)
153
+ elsif @needle.match?(/bullet_train/)
150
154
  # If it's a full path, we need to make sure we're getting it from the right package.
151
- _, partial_view_package, partial_path_without_package = @needle.partition(/bullet_train-[a-z|\-_0-9.]*/)
155
+ _, partial_view_package, partial_path_without_package = @needle.partition(/bullet_train-core\/bullet_train[a-z|\-_0-9.]*/)
152
156
 
153
- # Pop off the version so we can call `bundle show` correctly.
154
- # Also change `bullet_train-base` to `bullet_train`.
157
+ # Pop off `bullet_train-core` and the gem's version so we can call `bundle show` correctly.
158
+ partial_view_package.gsub!(/bullet_train-core\//, "")
155
159
  partial_view_package.gsub!(/[-|.0-9]*$/, "") if partial_view_package.match?(/[-|.0-9]*$/)
156
- partial_view_package.gsub!("-base", "") if /base/.match?(@needle)
157
160
 
158
161
  local_package_path = `bundle show #{partial_view_package}`.chomp
159
162
  return local_package_path + partial_path_without_package
@@ -1,3 +1,3 @@
1
1
  module BulletTrain
2
- VERSION = "1.2.20"
2
+ VERSION = "1.2.22"
3
3
  end
data/lib/bullet_train.rb CHANGED
@@ -33,6 +33,7 @@ require "commonmarker"
33
33
  require "extended_email_reply_parser"
34
34
  require "pagy"
35
35
  require "devise/pwned_password"
36
+ require "openai"
36
37
 
37
38
  module BulletTrain
38
39
  mattr_accessor :routing_concerns, default: []
@@ -152,3 +153,11 @@ end
152
153
  def silence_logs?
153
154
  ENV["SILENCE_LOGS"].present?
154
155
  end
156
+
157
+ def openai_enabled?
158
+ ENV["OPENAI_ACCESS_TOKEN"].present?
159
+ end
160
+
161
+ def openai_organization_exists?
162
+ ENV["OPENAI_ORGANIZATION_ID"]
163
+ end
@@ -112,15 +112,23 @@ namespace :bullet_train do
112
112
  puts ""
113
113
  puts "bin/hack: " + "Clone bullet_train-core and link up gems (will only link up gems if already cloned).".blue
114
114
  puts "bin/hack --link: " + "Link all of your Bullet Train gems to `local/bullet_train-core`.".blue
115
+ puts "bin/hack --link github: " + "Link all of your Bullet Train gems to the public repositories on GitHub".blue
115
116
  puts "bin/hack --link (version-number): " + "Link all of your Bullet Train gems to the version number passed.".blue
116
117
  puts "bin/hack --reset: " + "Resets all of your gems to their original definition.".blue
117
118
  puts "bin/hack --watch-js: " + "Watches for any changes in JavaScript files gems that have an npm package.".blue
118
119
  puts "bin/hack --clean-js: " + "Resets all of your npm packages from `local/bullet_train-core` to their original definition.".blue
119
120
  exit
120
121
  when "--link", "--reset"
121
- version = process[:values].pop
122
- set_core_gems(process[:flag], version, framework_packages)
123
- stream "bundle install"
122
+ link_flag_value = process[:values].pop
123
+ set_core_gems(process[:flag], link_flag_value, framework_packages)
124
+
125
+ # Bundler will throw an error if we try to `bundle install` right after adding the GitHub link to the Gemfile.
126
+ if link_flag_value == "github"
127
+ puts ""
128
+ puts "Now you can run `bundle install` to check out the public repositories on GitHub."
129
+ else
130
+ stream "bundle install"
131
+ end
124
132
  when "--watch-js", "--clean-js"
125
133
  package_name = process[:values].pop
126
134
  framework_package = framework_packages.select { |k, v| k.to_s == package_name }
@@ -218,9 +226,10 @@ namespace :bullet_train do
218
226
  end
219
227
 
220
228
  # Pass "--link" or "--reset" as a flag to set the gems.
221
- def set_core_gems(flag, version, framework_packages)
229
+ def set_core_gems(flag, link_flag_value, framework_packages)
222
230
  packages = framework_packages.keys
223
231
  gemfile_lines = File.readlines("./Gemfile")
232
+ version_regexp = /[\d|.]/
224
233
 
225
234
  packages.each do |package|
226
235
  original_path = "gem \"#{package}\""
@@ -241,7 +250,14 @@ namespace :bullet_train do
241
250
  puts "We can't do anything with this. Sorry! We'll proceed, but you have to link this package yourself.".red
242
251
  elsif `cat Gemfile | grep "gem \\\"#{package}\\\""`.chomp.present?
243
252
  puts "#{package} is directly present in the `Gemfile`, so we'll update that line.".green
244
- line = version.present? ? "#{line.chomp}, \"#{version}\"\n" : line.gsub(original_path, local_path)
253
+
254
+ line = if link_flag_value == "github"
255
+ "#{line.chomp}, git: 'http://github.com/bullet-train-co/bullet_train-core.git'\n"
256
+ elsif link_flag_value&.match?(version_regexp)
257
+ "#{line.chomp}, \"#{link_flag_value}\"\n"
258
+ else
259
+ line.gsub(original_path, local_path)
260
+ end
245
261
  end
246
262
  elsif flag == "--reset"
247
263
  if line.match?(/bullet_train/)
@@ -258,8 +274,10 @@ namespace :bullet_train do
258
274
  if flag == "--link"
259
275
  unless match_found
260
276
  puts "Could not find #{package}. Adding to the end of the Gemfile.".blue
261
- new_lines << if version
262
- "#{original_path.chomp}, \"#{version}\"\n"
277
+ new_lines << if link_flag_value == "github"
278
+ "#{original_path.chomp}, git: 'http://github.com/bullet-train-co/bullet_train-core.git'\n"
279
+ elsif link_flag_value&.match?(version_regexp)
280
+ "#{original_path.chomp}, \"#{link_flag_value}\"\n"
263
281
  else
264
282
  "#{local_path}\n"
265
283
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bullet_train
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.20
4
+ version: 1.2.22
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Culver
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-03-11 00:00:00.000000000 Z
11
+ date: 2023-03-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: standard
@@ -388,6 +388,20 @@ dependencies:
388
388
  - - ">="
389
389
  - !ruby/object:Gem::Version
390
390
  version: '0'
391
+ - !ruby/object:Gem::Dependency
392
+ name: ruby-openai
393
+ requirement: !ruby/object:Gem::Requirement
394
+ requirements:
395
+ - - ">="
396
+ - !ruby/object:Gem::Version
397
+ version: '0'
398
+ type: :runtime
399
+ prerelease: false
400
+ version_requirements: !ruby/object:Gem::Requirement
401
+ requirements:
402
+ - - ">="
403
+ - !ruby/object:Gem::Version
404
+ version: '0'
391
405
  - !ruby/object:Gem::Dependency
392
406
  name: unicode-emoji
393
407
  requirement: !ruby/object:Gem::Requirement
@@ -722,7 +736,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
722
736
  - !ruby/object:Gem::Version
723
737
  version: '0'
724
738
  requirements: []
725
- rubygems_version: 3.4.1
739
+ rubygems_version: 3.3.7
726
740
  signing_key:
727
741
  specification_version: 4
728
742
  summary: Bullet Train