kaze 0.3.0 → 0.5.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 (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