kaze 0.3.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +21 -2
  3. data/lib/kaze/commands/install_command.rb +17 -13
  4. data/lib/kaze/commands/installs_hotwire_stack.rb +6 -6
  5. data/lib/kaze/commands/installs_inertia_stacks.rb +22 -22
  6. data/lib/kaze/commands/version_command.rb +6 -0
  7. data/lib/kaze/version.rb +1 -1
  8. data/lib/kaze.rb +1 -3
  9. data/stubs/default/app/forms/auth/login_form.rb +1 -1
  10. data/stubs/default/app/forms/auth/new_password_form.rb +1 -1
  11. data/stubs/default/app/mailers/application_mailer.rb +4 -4
  12. data/stubs/default/app/mailers/user_mailer.rb +1 -1
  13. data/stubs/default/app/validators/current_password_validator.rb +1 -1
  14. data/stubs/default/app/validators/email_validator.rb +1 -1
  15. data/stubs/default/app/validators/lowercase_validator.rb +2 -2
  16. data/stubs/default/config/routes.rb +16 -16
  17. data/stubs/default/db/migrate/20240101000001_create_delayed_jobs.rb +1 -1
  18. data/stubs/hotwire/app/components/danger_button_component.rb +1 -1
  19. data/stubs/hotwire/app/components/dropdown_component.rb +7 -7
  20. data/stubs/hotwire/app/components/modal_component.rb +1 -1
  21. data/stubs/hotwire/app/components/primary_button_component.rb +1 -1
  22. data/stubs/hotwire/app/components/secondary_button_component.rb +1 -1
  23. data/stubs/hotwire/app/controllers/auth/authenticated_session_controller.rb +3 -3
  24. data/stubs/hotwire/app/controllers/auth/new_password_controller.rb +4 -4
  25. data/stubs/hotwire/app/controllers/auth/password_reset_link_controller.rb +4 -4
  26. data/stubs/hotwire/app/controllers/auth/registered_user_controller.rb +3 -3
  27. data/stubs/hotwire/app/controllers/password_controller.rb +2 -2
  28. data/stubs/hotwire/app/controllers/profile_controller.rb +5 -5
  29. data/stubs/hotwire/bin/vite +6 -6
  30. data/stubs/hotwire/config/importmap.rb +3 -3
  31. data/stubs/inertia-common/app/controllers/auth/authenticated_session_controller.rb +1 -1
  32. data/stubs/inertia-common/app/controllers/auth/new_password_controller.rb +2 -2
  33. data/stubs/inertia-common/app/controllers/auth/password_reset_link_controller.rb +2 -2
  34. data/stubs/inertia-common/app/controllers/auth/registered_user_controller.rb +1 -1
  35. data/stubs/inertia-common/app/controllers/concerns/verify_csrf_token.rb +4 -4
  36. data/stubs/inertia-common/app/controllers/dashboard_controller.rb +1 -1
  37. data/stubs/inertia-common/app/controllers/profile_controller.rb +2 -2
  38. data/stubs/inertia-common/app/controllers/welcome_controller.rb +1 -1
  39. data/stubs/inertia-common/bin/vite +6 -6
  40. metadata +2 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 367b549562d6d96be85bac57b8d0f4528598122dfe773d733fcd992de4e1616d
4
- data.tar.gz: 9d79187ce1918ff96854c36cb5e2f51e05aaf6a329afeede53a35151eaeb433d
3
+ metadata.gz: d47e0df09c4dc843e721f9df107ffcf181cab7f3922233b9b82ca6ecd1eafa20
4
+ data.tar.gz: a932b205c852cf2825867f11b9a4d0c7f580a798be9b14c96b2745a705109105
5
5
  SHA512:
6
- metadata.gz: f87b1598f94dbdead93d4dea21d766d57819ec6bf354093e45af74c5659ebf7c31927a09f22138e5bd4fd122a1210a3aef92dbd5e0f2f492978bd44000e2d2db
7
- data.tar.gz: ff833ef663bc961c1ab98c8ab671a26b04ae4da50c57a491a9a96c713b97068570f843905f6ef03591bdf53f3c306f18d881e6b75b56b0039423b5547fd84ea6
6
+ metadata.gz: 5ab37093d08694cbdacd55fab7328c8c1c8042996605dffd16b48d709007377c5479c8a95085e611ff195961caee9b64815b13e9323134a981d81f11e776e3c2
7
+ data.tar.gz: beb37ead1dd42947264d72f58a93b113795a0361cf9979d7f5166273702b2c515c262a67be9be218f5dc185a0f9897367c34bc0fc3167d1076aa5483558a00b8
data/README.md CHANGED
@@ -4,7 +4,7 @@ Heavily inspired by [Laravel Breeze](https://github.com/laravel/breeze), this ge
4
4
 
5
5
  [Kaze](https://github.com/gtkvn/kaze) is a minimal, simple implementation of all of Rails's authentication features, including login, registration, password reset. In addition, Kaze includes a simple "profile" page where the user may update their name, email address, and password.
6
6
 
7
- Kaze provides scaffolding options based on Inertia, with the choice of using Vue or React for the Inertia-based scaffolding.
7
+ Kaze provides scaffolding options based on [Hotwire](https://hotwired.dev) or [Inertia](https://inertiajs.com), with the choice of using Vue or React for the Inertia-based scaffolding.
8
8
 
9
9
  ## Installation
10
10
 
@@ -18,11 +18,30 @@ gem install kaze
18
18
 
19
19
  Once Kaze is installed, you may scaffold your application using one of the Kaze "stacks" discussed in the documentation below.
20
20
 
21
+ ## Kaze & Hotwire
22
+
23
+ The default Kaze "stack" is the Hotwire stack. Hotwire is a powerful way to building dynamic, reactive, front-end UIs primarily using Ruby and ERB templates without using much JavaScript by sending HTML instead of JSON over the wire.
24
+
25
+ The Hotwire stack may be installed by invoking the `install` command with no other additional arguments inside your app directory.
26
+
27
+ ```
28
+ kaze install
29
+ ```
30
+
31
+ After Kaze's scaffolding is installed, you may start your application:
32
+
33
+ ```
34
+ bin/setup
35
+ bin/dev
36
+ ```
37
+
38
+ Next, you may navigate to your application's `/login` or `/register` URLs in your web browser.
39
+
21
40
  ## Kaze & React / Vue
22
41
 
23
42
  Kaze offers React and Vue scaffolding via an Inertia frontend implementation. Inertia allows you to build modern, single-page React and Vue applications using classic server-side routing and controllers.
24
43
 
25
- Inertia lets you enjoy the frontend power of React and Vue combined with the incredible backend productivity of Rails and lightning-fast Vite compilation. To use an Inertia stack, specify vue or react as your desired stack when executing the install command inside your app directory:
44
+ Inertia lets you enjoy the frontend power of React and Vue combined with the incredible backend productivity of Rails and lightning-fast Vite compilation. To use an Inertia stack, specify `react` or `vue` as your desired stack when executing the `install` command inside your app directory:
26
45
 
27
46
  ```
28
47
  kaze install react
@@ -1,27 +1,27 @@
1
- require "bundler"
2
- require "fileutils"
3
- require "open3"
4
- require "thor"
1
+ require 'bundler'
2
+ require 'fileutils'
3
+ require 'open3'
4
+ require 'thor'
5
5
 
6
6
  class Kaze::Commands::InstallCommand < Thor
7
7
  include Kaze::Commands::InstallsHotwireStack
8
8
  include Kaze::Commands::InstallsInertiaStacks
9
9
 
10
- desc "install [STACK]", "Install the Kaze controllers and resources. Supported stacks: react, vue."
11
- def install(stack = "hotwire")
12
- if stack == "hotwire"
10
+ desc 'install [STACK]', 'Install the Kaze controllers and resources. Supported stacks: hotwire, react, vue.'
11
+ def install(stack = 'hotwire')
12
+ if stack == 'hotwire'
13
13
  return install_hotwire_stack
14
14
  end
15
15
 
16
- if stack == "react"
16
+ if stack == 'react'
17
17
  return install_inertia_react_stack
18
18
  end
19
19
 
20
- if stack == "vue"
20
+ if stack == 'vue'
21
21
  return install_inertia_vue_stack
22
22
  end
23
23
 
24
- say "Invalid stack. Supported stacks are [react], [vue].", :red
24
+ say 'Invalid stack. Supported stacks are [hotwire], [react], [vue].', :red
25
25
  end
26
26
 
27
27
  private
@@ -53,9 +53,13 @@ class Kaze::Commands::InstallCommand < Thor
53
53
  def install_migrations
54
54
  ensure_directory_exists("#{Dir.pwd}/db/migrate")
55
55
  FileUtils.copy_entry("#{File.dirname(__FILE__)}/../../../stubs/default/db/migrate", "#{Dir.pwd}/db/migrate")
56
- stdin, _ = Open3.capture3("rails version")
57
- versions = stdin.gsub!("Rails ", "").split(".")
58
- Open3.capture3('grep -rl ActiveRecord::Migration$ db | xargs sed -i "" "s/ActiveRecord::Migration/ActiveRecord::Migration[' + [ versions[0], versions[1] ].join(".") + ']/g"')
56
+ stdin, _ = Open3.capture3('rails version')
57
+ versions = stdin.gsub!('Rails ', '').split('.')
58
+ railsVersion = [ versions[0], versions[1] ].join('.')
59
+ Dir.children("#{Dir.pwd}/db/migrate").each do |file|
60
+ path = "#{Dir.pwd}/db/migrate/#{file}"
61
+ File.write(path, File.read(path).gsub!(/ActiveRecord::Migration$/, "ActiveRecord::Migration[#{railsVersion}]"))
62
+ end
59
63
  end
60
64
 
61
65
  def ensure_directory_exists(path)
@@ -3,9 +3,9 @@ module Kaze::Commands::InstallsHotwireStack
3
3
 
4
4
  def install_hotwire_stack
5
5
  # Gems...
6
- return unless remove_gems([ "sprockets-rails" ])
7
- return unless install_gems([ "propshaft", "view_component", "tailwindcss-rails", "turbo-rails", "dotenv", "bcrypt" ])
8
- return unless install_gems([ "hotwire-livereload" ], "development")
6
+ return unless remove_gems([ 'sprockets-rails', 'stimulus-rails' ])
7
+ return unless install_gems([ 'propshaft', 'view_component', 'tailwindcss-rails', 'turbo-rails', 'dotenv', 'bcrypt' ])
8
+ return unless install_gems([ 'hotwire-livereload' ], 'development')
9
9
 
10
10
  # Controllers...
11
11
  FileUtils.copy_entry("#{File.dirname(__FILE__)}/../../../stubs/hotwire/app/controllers", "#{Dir.pwd}/app/controllers")
@@ -54,9 +54,9 @@ module Kaze::Commands::InstallsHotwireStack
54
54
  FileUtils.copy_file("#{File.dirname(__FILE__)}/../../../stubs/hotwire/config/tailwind.config.js", "#{Dir.pwd}/config/tailwind.config.js")
55
55
  FileUtils.copy_file("#{File.dirname(__FILE__)}/../../../stubs/default/bin/dev", "#{Dir.pwd}/bin/dev")
56
56
  FileUtils.copy_file("#{File.dirname(__FILE__)}/../../../stubs/hotwire/Procfile.dev", "#{Dir.pwd}/Procfile.dev")
57
- run_command("rails tailwindcss:build")
57
+ run_command('rails tailwindcss:build')
58
58
 
59
- say ""
60
- say "Kaze scaffolding installed successfully.", :green
59
+ say ''
60
+ say 'Kaze scaffolding installed successfully.', :green
61
61
  end
62
62
  end
@@ -3,8 +3,8 @@ module Kaze::Commands::InstallsInertiaStacks
3
3
 
4
4
  def install_inertia_react_stack
5
5
  # Gems...
6
- return unless remove_gems([ "sprockets-rails" ])
7
- return unless install_gems([ "propshaft", "tailwindcss-rails", "inertia_rails", "vite_rails", "dotenv", "bcrypt", "js-routes" ])
6
+ return unless remove_gems([ 'sprockets-rails', 'turbo-rails', 'stimulus-rails' ])
7
+ return unless install_gems([ 'propshaft', 'tailwindcss-rails', 'inertia_rails', 'vite_rails', 'dotenv', 'bcrypt', 'js-routes' ])
8
8
 
9
9
  # NPM Packages...
10
10
  FileUtils.copy_file("#{File.dirname(__FILE__)}/../../../stubs/inertia-react-ts/package.json", "#{Dir.pwd}/package.json")
@@ -57,29 +57,29 @@ module Kaze::Commands::InstallsInertiaStacks
57
57
  FileUtils.copy_file("#{File.dirname(__FILE__)}/../../../stubs/default/bin/dev", "#{Dir.pwd}/bin/dev")
58
58
  FileUtils.copy_file("#{File.dirname(__FILE__)}/../../../stubs/inertia-common/bin/vite", "#{Dir.pwd}/bin/vite")
59
59
  FileUtils.copy_file("#{File.dirname(__FILE__)}/../../../stubs/inertia-common/Procfile.dev", "#{Dir.pwd}/Procfile.dev")
60
- run_command("rails generate js_routes:middleware")
60
+ run_command('rails generate js_routes:middleware')
61
61
 
62
- say ""
63
- say "Installing and building Node dependencies.", :magenta
62
+ say ''
63
+ say 'Installing and building Node dependencies.', :magenta
64
64
 
65
65
  if File.exist?("#{Dir.pwd}/pnpm-lock.yaml")
66
- run_commands([ "pnpm install", "pnpm run build" ])
66
+ run_commands([ 'pnpm install', 'pnpm run build' ])
67
67
  elsif File.exist?("#{Dir.pwd}/yarn.lock")
68
- run_commands([ "yarn install", "yarn build" ])
68
+ run_commands([ 'yarn install', 'yarn build' ])
69
69
  elsif File.exist?("#{Dir.pwd}/bun.lockb")
70
- run_commands([ "bun install", "bun run build" ])
70
+ run_commands([ 'bun install', 'bun run build' ])
71
71
  else
72
- run_commands([ "npm install", "npm run build" ])
72
+ run_commands([ 'npm install', 'npm run build' ])
73
73
  end
74
74
 
75
- say ""
76
- say "Kaze scaffolding installed successfully.", :green
75
+ say ''
76
+ say 'Kaze scaffolding installed successfully.', :green
77
77
  end
78
78
 
79
79
  def install_inertia_vue_stack
80
80
  # Gems...
81
- return unless remove_gems([ "sprockets-rails" ])
82
- return unless install_gems([ "propshaft", "tailwindcss-rails", "inertia_rails", "vite_rails", "dotenv", "bcrypt", "js-routes" ])
81
+ return unless remove_gems([ 'sprockets-rails' ])
82
+ return unless install_gems([ 'propshaft', 'tailwindcss-rails', 'inertia_rails', 'vite_rails', 'dotenv', 'bcrypt', 'js-routes' ])
83
83
 
84
84
  # NPM Packages...
85
85
  FileUtils.copy_file("#{File.dirname(__FILE__)}/../../../stubs/inertia-vue-ts/package.json", "#{Dir.pwd}/package.json")
@@ -132,22 +132,22 @@ module Kaze::Commands::InstallsInertiaStacks
132
132
  FileUtils.copy_file("#{File.dirname(__FILE__)}/../../../stubs/default/bin/dev", "#{Dir.pwd}/bin/dev")
133
133
  FileUtils.copy_file("#{File.dirname(__FILE__)}/../../../stubs/inertia-common/bin/vite", "#{Dir.pwd}/bin/vite")
134
134
  FileUtils.copy_file("#{File.dirname(__FILE__)}/../../../stubs/inertia-common/Procfile.dev", "#{Dir.pwd}/Procfile.dev")
135
- run_command("rails generate js_routes:middleware")
135
+ run_command('rails generate js_routes:middleware')
136
136
 
137
- say ""
138
- say "Installing and building Node dependencies.", :magenta
137
+ say ''
138
+ say 'Installing and building Node dependencies.', :magenta
139
139
 
140
140
  if File.exist?("#{Dir.pwd}/pnpm-lock.yaml")
141
- run_commands([ "pnpm install", "pnpm run build" ])
141
+ run_commands([ 'pnpm install', 'pnpm run build' ])
142
142
  elsif File.exist?("#{Dir.pwd}/yarn.lock")
143
- run_commands([ "yarn install", "yarn build" ])
143
+ run_commands([ 'yarn install', 'yarn build' ])
144
144
  elsif File.exist?("#{Dir.pwd}/bun.lockb")
145
- run_commands([ "bun install", "bun run build" ])
145
+ run_commands([ 'bun install', 'bun run build' ])
146
146
  else
147
- run_commands([ "npm install", "npm run build" ])
147
+ run_commands([ 'npm install', 'npm run build' ])
148
148
  end
149
149
 
150
- say ""
151
- say "Kaze scaffolding installed successfully.", :green
150
+ say ''
151
+ say 'Kaze scaffolding installed successfully.', :green
152
152
  end
153
153
  end
@@ -0,0 +1,6 @@
1
+ class Kaze::Commands::VersionCommand < Thor
2
+ desc 'version', 'Show Kaze version'
3
+ def version
4
+ puts Kaze::VERSION
5
+ end
6
+ end
data/lib/kaze/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Kaze
2
- VERSION = "0.3.0"
2
+ VERSION = "0.5.0"
3
3
  end
data/lib/kaze.rb CHANGED
@@ -1,9 +1,7 @@
1
1
  module Kaze
2
2
  end
3
3
 
4
- require "active_support"
5
- require "zeitwerk"
4
+ require 'zeitwerk'
6
5
 
7
6
  loader = Zeitwerk::Loader.for_gem
8
7
  loader.setup
9
- loader.eager_load # We need all commands loaded.
@@ -11,7 +11,7 @@ class Auth::LoginForm < ApplicationForm
11
11
 
12
12
  return user if user.present?
13
13
 
14
- errors.add(:email, message: "These credentials do not match our records.")
14
+ errors.add(:email, message: 'These credentials do not match our records.')
15
15
 
16
16
  nil
17
17
  end
@@ -10,7 +10,7 @@ class Auth::NewPasswordForm < ApplicationForm
10
10
  user = User.find_by_token_for(:password_reset, token)
11
11
 
12
12
  if user.nil?
13
- errors.add(:password, message: "This password reset token is invalid.")
13
+ errors.add(:password, message: 'This password reset token is invalid.')
14
14
  return false
15
15
  end
16
16
 
@@ -1,11 +1,11 @@
1
1
  class ApplicationMailer < ActionMailer::Base
2
2
  default from: email_address_with_name(
3
- ENV.fetch("MAIL_FROM_ADDRESS", "hello@example.com"),
4
- ENV.fetch("MAIL_FROM_NAME", "Example")
3
+ ENV.fetch('MAIL_FROM_ADDRESS', 'hello@example.com'),
4
+ ENV.fetch('MAIL_FROM_NAME', 'Example')
5
5
  )
6
- layout "mailer"
6
+ layout 'mailer'
7
7
 
8
8
  def default_url_options
9
- { host: ENV.fetch("APP_URL", "http://localhost") }
9
+ { host: ENV.fetch('APP_URL', 'http://localhost') }
10
10
  end
11
11
  end
@@ -2,7 +2,7 @@ class UserMailer < ApplicationMailer
2
2
  def reset_password
3
3
  mail(
4
4
  to: params[:user].email,
5
- subject: "Reset Password Notification"
5
+ subject: 'Reset Password Notification'
6
6
  )
7
7
  end
8
8
  end
@@ -1,5 +1,5 @@
1
1
  class CurrentPasswordValidator < ActiveModel::EachValidator
2
2
  def validate_each(record, attribute, value)
3
- record.errors.add attribute, "The password is incorrect." unless Current.user&.authenticate(value)
3
+ record.errors.add attribute, 'The password is incorrect.' unless Current.user&.authenticate(value)
4
4
  end
5
5
  end
@@ -1,7 +1,7 @@
1
1
  class EmailValidator < ActiveModel::EachValidator
2
2
  def validate_each(record, attribute, value)
3
3
  unless URI::MailTo::EMAIL_REGEXP.match?(value)
4
- record.errors.add attribute, (options[:message] || "is not an email")
4
+ record.errors.add attribute, (options[:message] || 'is not an email')
5
5
  end
6
6
  end
7
7
  end
@@ -1,6 +1,6 @@
1
1
  class LowercaseValidator < ActiveModel::EachValidator
2
2
  def validate_each(record, attribute, value)
3
- value = "" if value.nil?
4
- record.errors.add attribute, (options[:message] || "must be lowercase") unless value == value.downcase
3
+ value = '' if value.nil?
4
+ record.errors.add attribute, (options[:message] || 'must be lowercase') unless value == value.downcase
5
5
  end
6
6
  end
@@ -1,27 +1,27 @@
1
1
  Rails.application.routes.draw do
2
- get "up" => "rails/health#show", as: :rails_health_check
2
+ get 'up' => 'rails/health#show', as: :rails_health_check
3
3
 
4
- root "welcome#index"
4
+ root 'welcome#index'
5
5
 
6
- get "register", to: "auth/registered_user#new", as: :register
7
- post "register", to: "auth/registered_user#create"
6
+ get 'register', to: 'auth/registered_user#new', as: :register
7
+ post 'register', to: 'auth/registered_user#create'
8
8
 
9
- get "login", to: "auth/authenticated_session#new", as: :login
10
- post "login", to: "auth/authenticated_session#create"
9
+ get 'login', to: 'auth/authenticated_session#new', as: :login
10
+ post 'login', to: 'auth/authenticated_session#create'
11
11
 
12
- get "forgot-password", to: "auth/password_reset_link#new", as: :password_request
13
- post "forgot-password", to: "auth/password_reset_link#create", as: :password_email
12
+ get 'forgot-password', to: 'auth/password_reset_link#new', as: :password_request
13
+ post 'forgot-password', to: 'auth/password_reset_link#create', as: :password_email
14
14
 
15
- get "reset-password/:token", to: "auth/new_password#new", as: :password_reset
16
- post "reset-password", to: "auth/new_password#create", as: :password_store
15
+ get 'reset-password/:token', to: 'auth/new_password#new', as: :password_reset
16
+ post 'reset-password', to: 'auth/new_password#create', as: :password_store
17
17
 
18
- post "logout", to: "auth/authenticated_session#destroy", as: :logout
18
+ post 'logout', to: 'auth/authenticated_session#destroy', as: :logout
19
19
 
20
- get "dashboard", to: "dashboard#index", as: :dashboard
20
+ get 'dashboard', to: 'dashboard#index', as: :dashboard
21
21
 
22
- get "profile", to: "profile#edit", as: :profile_edit
23
- patch "profile", to: "profile#update", as: :profile_update
24
- delete "profile", to: "profile#destroy", as: :profile_destroy
22
+ get 'profile', to: 'profile#edit', as: :profile_edit
23
+ patch 'profile', to: 'profile#update', as: :profile_update
24
+ delete 'profile', to: 'profile#destroy', as: :profile_destroy
25
25
 
26
- put "password", to: "password#update", as: :password_update
26
+ put 'password', to: 'password#update', as: :password_update
27
27
  end
@@ -13,7 +13,7 @@ class CreateDelayedJobs < ActiveRecord::Migration
13
13
  table.timestamps null: true
14
14
  end
15
15
 
16
- add_index :delayed_jobs, [ :priority, :run_at ], name: "delayed_jobs_priority"
16
+ add_index :delayed_jobs, [ :priority, :run_at ], name: 'delayed_jobs_priority'
17
17
  end
18
18
 
19
19
  def self.down
@@ -6,7 +6,7 @@ class DangerButtonComponent < ViewComponent::Base
6
6
  ERB
7
7
 
8
8
  def initialize(attributes = {})
9
- attributes[:type] = attributes[:type] || "submit"
9
+ attributes[:type] = attributes[:type] || 'submit'
10
10
  attributes[:class] = "inline-flex items-center px-4 py-2 bg-red-600 border border-transparent rounded-md font-semibold text-xs text-white uppercase tracking-widest hover:bg-red-500 active:bg-red-700 focus:outline-none focus:ring-2 focus:ring-red-500 focus:ring-offset-2 dark:focus:ring-offset-gray-800 transition ease-in-out duration-150#{" #{attributes[:class]}" if attributes[:class]}"
11
11
  @attributes = attributes.map { |key, attribute| "#{key}=\"#{attribute}\"" }
12
12
  end
@@ -1,15 +1,15 @@
1
1
  class DropdownComponent < ViewComponent::Base
2
2
  renders_one :trigger
3
3
 
4
- def initialize(align: "right", width: "48", content_classes: "py-1 bg-white dark:bg-gray-700")
5
- if align == "left"
6
- @alignment_classes = "ltr:origin-top-left rtl:origin-top-right start-0"
7
- elsif align == "top"
8
- @alignment_classes = "origin-top"
4
+ def initialize(align: 'right', width: '48', content_classes: 'py-1 bg-white dark:bg-gray-700')
5
+ if align == 'left'
6
+ @alignment_classes = 'ltr:origin-top-left rtl:origin-top-right start-0'
7
+ elsif align == 'top'
8
+ @alignment_classes = 'origin-top'
9
9
  else
10
- @alignment_classes = "ltr:origin-top-right rtl:origin-top-left end-0"
10
+ @alignment_classes = 'ltr:origin-top-right rtl:origin-top-left end-0'
11
11
  end
12
- @width = width == "48" ? "w-48" : width
12
+ @width = width == '48' ? 'w-48' : width
13
13
  @content_classes = content_classes
14
14
  end
15
15
  end
@@ -7,7 +7,7 @@ class ModalComponent < ViewComponent::Base
7
7
  :md => 'sm:max-w-md',
8
8
  :lg => 'sm:max-w-lg',
9
9
  :xl => 'sm:max-w-xl',
10
- '2xl' => 'sm:max-w-2xl',
10
+ '2xl' => 'sm:max-w-2xl'
11
11
  }[attributes[:max_width] || '2xl']
12
12
  @attributes = attributes.without(:name, :show, :max_width)
13
13
  end
@@ -6,7 +6,7 @@ class PrimaryButtonComponent < ViewComponent::Base
6
6
  ERB
7
7
 
8
8
  def initialize(attributes = {})
9
- attributes[:type] = attributes[:type] || "submit"
9
+ attributes[:type] = attributes[:type] || 'submit'
10
10
  attributes[:class] = "inline-flex items-center px-4 py-2 bg-gray-800 dark:bg-gray-200 border border-transparent rounded-md font-semibold text-xs text-white dark:text-gray-800 uppercase tracking-widest hover:bg-gray-700 dark:hover:bg-white focus:bg-gray-700 dark:focus:bg-white active:bg-gray-900 dark:active:bg-gray-300 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 dark:focus:ring-offset-gray-800 transition ease-in-out duration-150#{" #{attributes[:class]}" if attributes[:class]}"
11
11
  @attributes = attributes.map { |key, attribute| "#{key}=\"#{attribute}\"" }
12
12
  end
@@ -6,7 +6,7 @@ class SecondaryButtonComponent < ViewComponent::Base
6
6
  ERB
7
7
 
8
8
  def initialize(attributes = {})
9
- attributes[:type] = attributes[:type] || "button"
9
+ attributes[:type] = attributes[:type] || 'button'
10
10
  attributes[:class] = "inline-flex items-center px-4 py-2 bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-500 rounded-md font-semibold text-xs text-gray-700 dark:text-gray-300 uppercase tracking-widest shadow-sm hover:bg-gray-50 dark:hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 dark:focus:ring-offset-gray-800 disabled:opacity-25 transition ease-in-out duration-150#{" #{attributes[:class]}" if attributes[:class]}"
11
11
  @attributes = attributes.map { |key, attribute| "#{key}=\"#{attribute}\"" }
12
12
  end
@@ -1,12 +1,12 @@
1
1
  class Auth::AuthenticatedSessionController < ApplicationController
2
2
  skip_authentication only: %i[new create]
3
3
 
4
- layout "guest"
4
+ layout 'guest'
5
5
 
6
6
  def new
7
7
  @form = Auth::LoginForm.new
8
8
 
9
- render "auth/login"
9
+ render 'auth/login'
10
10
  end
11
11
 
12
12
  def create
@@ -14,7 +14,7 @@ class Auth::AuthenticatedSessionController < ApplicationController
14
14
 
15
15
  user = @form.authenticate
16
16
 
17
- return render "auth/login", status: :unprocessable_entity if user.nil?
17
+ return render 'auth/login', status: :unprocessable_entity if user.nil?
18
18
 
19
19
  login user
20
20
 
@@ -1,19 +1,19 @@
1
1
  class Auth::NewPasswordController < ApplicationController
2
2
  skip_authentication
3
3
 
4
- layout "guest"
4
+ layout 'guest'
5
5
 
6
6
  def new
7
7
  @form = Auth::NewPasswordForm.new params.permit(:token)
8
8
 
9
- render "auth/reset_password"
9
+ render 'auth/reset_password'
10
10
  end
11
11
 
12
12
  def create
13
13
  @form = Auth::NewPasswordForm.new params.permit(:token, :password, :password_confirmation)
14
14
 
15
- return redirect_to login_path, flash: { status: "Your password has been reset." } if @form.reset?
15
+ return redirect_to login_path, flash: { status: 'Your password has been reset.' } if @form.reset?
16
16
 
17
- render "auth/reset_password", status: :unprocessable_entity
17
+ render 'auth/reset_password', status: :unprocessable_entity
18
18
  end
19
19
  end
@@ -1,19 +1,19 @@
1
1
  class Auth::PasswordResetLinkController < ApplicationController
2
2
  skip_authentication
3
3
 
4
- layout "guest"
4
+ layout 'guest'
5
5
 
6
6
  def new
7
7
  @form = Auth::SendPasswordResetLinkForm.new
8
8
 
9
- render "auth/forgot_password"
9
+ render 'auth/forgot_password'
10
10
  end
11
11
 
12
12
  def create
13
13
  @form = Auth::SendPasswordResetLinkForm.new params.permit(:email)
14
14
 
15
- return redirect_back_or_to password_request_path, flash: { status: "We have emailed your password reset link." } if @form.send_reset_link?
15
+ return redirect_back_or_to password_request_path, flash: { status: 'We have emailed your password reset link.' } if @form.send_reset_link?
16
16
 
17
- render "auth/forgot_password", status: :unprocessable_entity
17
+ render 'auth/forgot_password', status: :unprocessable_entity
18
18
  end
19
19
  end
@@ -1,18 +1,18 @@
1
1
  class Auth::RegisteredUserController < ApplicationController
2
2
  skip_authentication
3
3
 
4
- layout "guest"
4
+ layout 'guest'
5
5
 
6
6
  def new
7
7
  @form = Auth::RegisterForm.new
8
8
 
9
- render "auth/register"
9
+ render 'auth/register'
10
10
  end
11
11
 
12
12
  def create
13
13
  @form = Auth::RegisterForm.new params.permit(:name, :email, :password, :password_confirmation)
14
14
 
15
- return render "auth/register", status: :unprocessable_entity if @form.invalid?
15
+ return render 'auth/register', status: :unprocessable_entity if @form.invalid?
16
16
 
17
17
  user = User.create(name: @form.name, email: @form.email, password: @form.password)
18
18
 
@@ -2,10 +2,10 @@ class PasswordController < ApplicationController
2
2
  def update
3
3
  @update_password_form = UpdatePasswordForm.new params.permit(:current_password, :password, :password_confirmation)
4
4
 
5
- return render partial: "profile/partials/update_password_form", status: :unprocessable_entity if @update_password_form.invalid?
5
+ return render partial: 'profile/partials/update_password_form', status: :unprocessable_entity if @update_password_form.invalid?
6
6
 
7
7
  Current.user.update(password: @update_password_form.password)
8
8
 
9
- redirect_back_or_to profile_edit_path, flash: { status: "password-updated" }
9
+ redirect_back_or_to profile_edit_path, flash: { status: 'password-updated' }
10
10
  end
11
11
  end
@@ -4,23 +4,23 @@ class ProfileController < ApplicationController
4
4
  @update_password_form = UpdatePasswordForm.new
5
5
  @delete_user_form = DeleteUserForm.new
6
6
 
7
- render "profile/edit"
7
+ render 'profile/edit'
8
8
  end
9
9
 
10
10
  def update
11
11
  @update_profile_information_form = UpdateProfileInformationForm.new params.permit(:name, :email)
12
12
 
13
- return render partial: "profile/partials/update_profile_information_form", status: :unprocessable_entity if @update_profile_information_form.invalid?
13
+ return render partial: 'profile/partials/update_profile_information_form', status: :unprocessable_entity if @update_profile_information_form.invalid?
14
14
 
15
15
  Current.user.update(name: @update_profile_information_form.name, email: @update_profile_information_form.email)
16
16
 
17
- redirect_to profile_edit_path, flash: { status: "profile-updated" }
17
+ redirect_to profile_edit_path, flash: { status: 'profile-updated' }
18
18
  end
19
19
 
20
20
  def destroy
21
21
  @delete_user_form = DeleteUserForm.new params.permit(:password)
22
22
 
23
- return render partial: "profile/partials/delete_user_form", status: :unprocessable_entity if @delete_user_form.invalid?
23
+ return render partial: 'profile/partials/delete_user_form', status: :unprocessable_entity if @delete_user_form.invalid?
24
24
 
25
25
  user = Current.user
26
26
 
@@ -28,6 +28,6 @@ class ProfileController < ApplicationController
28
28
 
29
29
  user.delete
30
30
 
31
- redirect_to "/"
31
+ redirect_to '/'
32
32
  end
33
33
  end
@@ -8,12 +8,12 @@
8
8
  # this file is here to facilitate running it.
9
9
  #
10
10
 
11
- ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
11
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
12
12
 
13
- bundle_binstub = File.expand_path("bundle", __dir__)
13
+ bundle_binstub = File.expand_path('bundle', __dir__)
14
14
 
15
15
  if File.file?(bundle_binstub)
16
- if File.read(bundle_binstub, 300).include?("This file was generated by Bundler")
16
+ if File.read(bundle_binstub, 300).include?('This file was generated by Bundler')
17
17
  load(bundle_binstub)
18
18
  else
19
19
  abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
@@ -21,7 +21,7 @@ Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this
21
21
  end
22
22
  end
23
23
 
24
- require "rubygems"
25
- require "bundler/setup"
24
+ require 'rubygems'
25
+ require 'bundler/setup'
26
26
 
27
- load Gem.bin_path("vite_ruby", "vite")
27
+ load Gem.bin_path('vite_ruby', 'vite')
@@ -1,3 +1,3 @@
1
- pin "application"
2
- pin "@hotwired/turbo-rails", to: "turbo.min.js"
3
- pin "alpinejs"
1
+ pin 'application'
2
+ pin '@hotwired/turbo-rails', to: 'turbo.min.js'
3
+ pin 'alpinejs'
@@ -2,7 +2,7 @@ class Auth::AuthenticatedSessionController < ApplicationController
2
2
  skip_authentication only: %i[new create]
3
3
 
4
4
  def new
5
- render inertia: "Auth/Login", props: {
5
+ render inertia: 'Auth/Login', props: {
6
6
  canResetPassword: true,
7
7
  status: flash[:status]
8
8
  }
@@ -2,7 +2,7 @@ class Auth::NewPasswordController < ApplicationController
2
2
  skip_authentication
3
3
 
4
4
  def new
5
- render inertia: "Auth/ResetPassword", props: {
5
+ render inertia: 'Auth/ResetPassword', props: {
6
6
  token: params[:token]
7
7
  }
8
8
  end
@@ -10,7 +10,7 @@ class Auth::NewPasswordController < ApplicationController
10
10
  def create
11
11
  form = Auth::NewPasswordForm.new params.permit(:token, :password, :password_confirmation)
12
12
 
13
- return redirect_to login_path, flash: { status: "Your password has been reset." } if form.reset?
13
+ return redirect_to login_path, flash: { status: 'Your password has been reset.' } if form.reset?
14
14
 
15
15
  redirect_back_or_to password_reset_path(token: form.token),
16
16
  inertia: { errors: form.error_messages }
@@ -2,7 +2,7 @@ class Auth::PasswordResetLinkController < ApplicationController
2
2
  skip_authentication
3
3
 
4
4
  def new
5
- render inertia: "Auth/ForgotPassword", props: {
5
+ render inertia: 'Auth/ForgotPassword', props: {
6
6
  status: flash[:status]
7
7
  }
8
8
  end
@@ -12,6 +12,6 @@ class Auth::PasswordResetLinkController < ApplicationController
12
12
 
13
13
  return redirect_back_or_to password_request_path, inertia: { errors: form.error_messages } unless form.send_reset_link?
14
14
 
15
- redirect_back_or_to password_request_path, flash: { status: "We have emailed your password reset link." }
15
+ redirect_back_or_to password_request_path, flash: { status: 'We have emailed your password reset link.' }
16
16
  end
17
17
  end
@@ -2,7 +2,7 @@ class Auth::RegisteredUserController < ApplicationController
2
2
  skip_authentication
3
3
 
4
4
  def new
5
- render inertia: "Auth/Register"
5
+ render inertia: 'Auth/Register'
6
6
  end
7
7
 
8
8
  def create
@@ -5,20 +5,20 @@ module VerifyCsrfToken
5
5
  before_action :set_csrf_cookie
6
6
 
7
7
  rescue_from ActionController::InvalidAuthenticityToken do
8
- redirect_back fallback_location: "/", notice: "The page expired, please try again."
8
+ redirect_back fallback_location: '/', notice: 'The page expired, please try again.'
9
9
  end
10
10
  end
11
11
 
12
12
  def request_authenticity_tokens
13
- super << request.headers["HTTP_X_XSRF_TOKEN"]
13
+ super << request.headers['HTTP_X_XSRF_TOKEN']
14
14
  end
15
15
 
16
16
  private
17
17
 
18
18
  def set_csrf_cookie
19
- cookies["XSRF-TOKEN"] = {
19
+ cookies['XSRF-TOKEN'] = {
20
20
  value: form_authenticity_token,
21
- same_site: "Strict"
21
+ same_site: 'Strict'
22
22
  }
23
23
  end
24
24
  end
@@ -1,5 +1,5 @@
1
1
  class DashboardController < ApplicationController
2
2
  def index
3
- render inertia: "Dashboard"
3
+ render inertia: 'Dashboard'
4
4
  end
5
5
  end
@@ -1,6 +1,6 @@
1
1
  class ProfileController < ApplicationController
2
2
  def edit
3
- render inertia: "Profile/Edit", props: {
3
+ render inertia: 'Profile/Edit', props: {
4
4
  status: session[:status]
5
5
  }
6
6
  end
@@ -26,6 +26,6 @@ class ProfileController < ApplicationController
26
26
 
27
27
  user.delete
28
28
 
29
- redirect_to "/"
29
+ redirect_to '/'
30
30
  end
31
31
  end
@@ -2,7 +2,7 @@ class WelcomeController < ApplicationController
2
2
  skip_authentication
3
3
 
4
4
  def index
5
- render inertia: "Welcome", props: {
5
+ render inertia: 'Welcome', props: {
6
6
  railsVersion: Rails.version,
7
7
  rubyVersion: RUBY_DESCRIPTION
8
8
  }
@@ -8,12 +8,12 @@
8
8
  # this file is here to facilitate running it.
9
9
  #
10
10
 
11
- ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
11
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
12
12
 
13
- bundle_binstub = File.expand_path("bundle", __dir__)
13
+ bundle_binstub = File.expand_path('bundle', __dir__)
14
14
 
15
15
  if File.file?(bundle_binstub)
16
- if File.read(bundle_binstub, 300).include?("This file was generated by Bundler")
16
+ if File.read(bundle_binstub, 300).include?('This file was generated by Bundler')
17
17
  load(bundle_binstub)
18
18
  else
19
19
  abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
@@ -21,7 +21,7 @@ Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this
21
21
  end
22
22
  end
23
23
 
24
- require "rubygems"
25
- require "bundler/setup"
24
+ require 'rubygems'
25
+ require 'bundler/setup'
26
26
 
27
- load Gem.bin_path("vite_ruby", "vite")
27
+ load Gem.bin_path('vite_ruby', 'vite')
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kaze
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cuong Giang
@@ -68,6 +68,7 @@ files:
68
68
  - lib/kaze/commands/install_command.rb
69
69
  - lib/kaze/commands/installs_hotwire_stack.rb
70
70
  - lib/kaze/commands/installs_inertia_stacks.rb
71
+ - lib/kaze/commands/version_command.rb
71
72
  - lib/kaze/version.rb
72
73
  - stubs/default/app/assets/stylesheets/application.css
73
74
  - stubs/default/app/assets/stylesheets/application.tailwind.css