inertia_rails-contrib 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fb44326fd223ef6e631746a499a84dff76d261304651eda8d819fe23decc8857
4
- data.tar.gz: f9975ec1f185d40f88b34861d4104d0161daa8e070c39d2b60be4bcf75b61aa1
3
+ metadata.gz: b9bf363cb43e7bd6c98bcd4ca6b3538e09927f61f5687553c44a3df5a347c3e1
4
+ data.tar.gz: 31345ef902abb988dc50540f5bfc110fa392b94cb0a7d82c10dfa6a36cd4ca96
5
5
  SHA512:
6
- metadata.gz: aa516f52b025be207b951b61e4f081607cd6c2b3202cb689ae7378d650f5001008667c55ef4d1e84d869fa9fb23c0403532b429f35eea3a10ffdd80c9226c7b5
7
- data.tar.gz: e303ce54040f9d6268037210c7fe7f51929514900d22c7550b53fb0fb8264abab9cf0ac4c141e30c14bd005b261133268c15967ace013a1bf3b56bd25f24fa2c
6
+ metadata.gz: bc56d3c96c345caafbdafbf8b46c9b2d6b58d3f710f032a3127a2954df38f2453824c61d585959e751d97724b0d9612c884b3fedabacb1fded37c8b45c14e0bd
7
+ data.tar.gz: 5af321921aad351f9be524c9d533c44c5db0d359b0646e8b48abba9581e8803e7ab15eb7e8a82d7c3bf39e8065e0f987ad13735ae64731976b8f70c4a8c68310
data/CHANGELOG.md CHANGED
@@ -7,6 +7,24 @@ and this project adheres to [Semantic Versioning].
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.2.0] - 2024-08-10
11
+
12
+ Added:
13
+
14
+ - Improve installation generator ([@skryukov])
15
+ - option to install Vite Rails gem (`--install-vite`)
16
+ - option to install Tailwind CSS (`--install-tailwind`)
17
+ - option to install without interactivity (`--no-interaction` & `--framework=react|vue|svelte`)
18
+ - option to skip example page generation (`--no-example-page`)
19
+ - option to choose package manager (`--package-manager=yarn|npm|bun`)
20
+ - generate `bin/dev`
21
+
22
+ ## [0.1.1] - 2024-06-17
23
+
24
+ ### Fixed:
25
+
26
+ - Add a missing bracket to the `React/Edit` template. ([@skryukov])
27
+
10
28
  ## [0.1.0] - 2024-06-11
11
29
 
12
30
  - Initial release ([@iurev], [@skryukov])
@@ -14,7 +32,9 @@ and this project adheres to [Semantic Versioning].
14
32
  [@iurev]: https://github.com/iurev
15
33
  [@skryukov]: https://github.com/skryukov
16
34
 
17
- [Unreleased]: https://github.com/skryukov/inertia_rails-contrib/compare/v0.1.0...HEAD
35
+ [Unreleased]: https://github.com/skryukov/inertia_rails-contrib/compare/v0.2.0...HEAD
36
+ [0.2.0]: https://github.com/skryukov/inertia_rails-contrib/compare/v0.1.1...v0.2.0
37
+ [0.1.1]: https://github.com/skryukov/inertia_rails-contrib/compare/v0.1.0...v0.1.1
18
38
  [0.1.0]: https://github.com/skryukov/inertia_rails-contrib/commits/v0.1.0
19
39
 
20
40
  [Keep a Changelog]: https://keepachangelog.com/en/1.0.0/
data/README.md CHANGED
@@ -2,6 +2,10 @@
2
2
 
3
3
  A collection of extensions, developer tools, and the [community documentation](https://inertia-rails.netlify.app) for [Inertia's Rails adapter](https://github.com/inertiajs/inertia-rails).
4
4
 
5
+ <a href="https://evilmartians.com/?utm_source=inertia_rails-contrib&utm_campaign=project_page">
6
+ <img src="https://evilmartians.com/badges/sponsored-by-evil-martians.svg" alt="Built by Evil Martians" width="236" height="54">
7
+ </a>
8
+
5
9
  ## Installation
6
10
 
7
11
  Install the gem and add to the application's Gemfile by executing:
@@ -16,40 +20,7 @@ If bundler is not being used to manage dependencies, install the gem by executin
16
20
 
17
21
  ### Installation generator
18
22
 
19
- `InertiaRailsContrib` comes with a generator that installs and sets up Inertia in a Rails application. **It requires the [Vite Ruby](https://vite-ruby.netlify.app) gem to be installed and configured in the application.**
20
-
21
- <details>
22
- <summary>Creating a new Rails application and configuring Vite</summary>
23
-
24
- This is actually a simple process. First, create a new Rails application:
25
- ```bash
26
- rails new myapp --skip-js
27
- ```
28
-
29
- Next, install the Vite Ruby gem:
30
-
31
- ```bash
32
- bundle add vite_ruby
33
- bundle exec vite install
34
- ```
35
-
36
- If you use macOS, you may need to edit the `config/vite.rb` file to add the following line:
37
-
38
- ```json
39
- {
40
- "development": {
41
- + "host": "127.0.0.1",
42
- "autoBuild": true,
43
- "publicOutputDir": "vite-dev",
44
- "port": 3036
45
- }
46
- }
47
- ```
48
-
49
- That's it! Vite is now installed and configured in the Rails application. For more information, refer to the [Vite Ruby documentation](https://vite-ruby.netlify.app) and the [Vite-lizing Rails: get live reload and hot replacement with Vite Ruby](https://evilmartians.com/chronicles/vite-lizing-rails-get-live-reload-and-hot-replacement-with-vite-ruby) article.
50
-
51
- The next step is to install Inertia!
52
- </details>
23
+ `InertiaRailsContrib` comes with a generator that installs and sets up Inertia in a Rails application. It automatically detects if the [Vite Rails](https://vite-ruby.netlify.app/guide/rails.html) gem is installed and will attempt to install it if not present.
53
24
 
54
25
  To install and setup Inertia in a Rails application, execute the following command in the terminal:
55
26
 
@@ -58,77 +29,74 @@ bundle add inertia_rails-contrib
58
29
  bin/rails generate inertia:install
59
30
  ```
60
31
 
61
- This command will ask you for the frontend framework you are using (React, Vue, or Svelte) and will install the necessary dependencies and set up the application to work with Inertia.
32
+ This command will:
33
+ - Check for Vite Rails and install it if not present
34
+ - Ask you to choose your preferred frontend framework (React, Vue, or Svelte)
35
+ - Ask if you want to install Tailwind CSS
36
+ - Install necessary dependencies
37
+ - Set up the application to work with Inertia
38
+ - Copy example Inertia controller and views (can be skipped with the `--skip-example` option)
62
39
 
63
40
  Example output:
64
41
 
65
42
  ```bash
66
43
  $ bin/rails generate inertia:install
67
-
68
44
  Installing Inertia's Rails adapter
45
+ Could not find a package.json file to install Inertia to.
46
+ Would you like to install Vite Ruby? (y/n) y
47
+ run bundle add vite_rails from "."
48
+ Vite Rails gem successfully installed
49
+ run bundle exec vite install from "."
50
+ Vite Rails successfully installed
51
+ Would you like to install Tailwind CSS? (y/n) y
52
+ Installing Tailwind CSS
53
+ run npm add tailwindcss postcss autoprefixer @tailwindcss/forms @tailwindcss/typography @tailwindcss/container-queries --silent from "."
54
+ create tailwind.config.js
55
+ create postcss.config.js
56
+ create app/frontend/entrypoints/application.css
57
+ Adding Tailwind CSS to the application layout
58
+ insert app/views/layouts/application.html.erb
69
59
  Adding Inertia's Rails adapter initializer
70
60
  create config/initializers/inertia_rails.rb
71
61
  Installing Inertia npm packages
72
- What framework do you want to use with Turbo Mount? [react, vue, svelte] (react)
73
- run npm add @inertiajs/inertia @inertiajs/react react react-dom from "."
74
-
75
- added 6 packages, removed 42 packages, and audited 69 packages in 8s
76
-
77
- 18 packages are looking for funding
78
- run `npm fund` for details
79
-
80
- 2 moderate severity vulnerabilities
81
-
82
- Some issues need review, and may require choosing
83
- a different dependency.
84
-
85
- Run `npm audit` for details.
86
- run npm add --save-dev @vitejs/plugin-react from "."
87
-
88
- added 58 packages, and audited 127 packages in 6s
89
-
90
- 22 packages are looking for funding
91
- run `npm fund` for details
92
-
93
- 2 moderate severity vulnerabilities
94
-
95
- Some issues need review, and may require choosing
96
- a different dependency.
97
-
98
- Run `npm audit` for details.
62
+ What framework do you want to use with Inertia? [react, vue, svelte] (react)
63
+ run npm add @inertiajs/react react react-dom @vitejs/plugin-react --silent from "."
99
64
  Adding Vite plugin for react
100
65
  insert vite.config.ts
101
66
  prepend vite.config.ts
102
- Add "type": "module", to the package.json file
103
- gsub package.json
104
- Copying inertia.js into Vite entrypoints
67
+ Copying inertia.js entrypoint
105
68
  create app/frontend/entrypoints/inertia.js
106
69
  Adding inertia.js script tag to the application layout
107
70
  insert app/views/layouts/application.html.erb
108
71
  Adding Vite React Refresh tag to the application layout
109
72
  insert app/views/layouts/application.html.erb
73
+ gsub app/views/layouts/application.html.erb
110
74
  Copying example Inertia controller
111
75
  create app/controllers/inertia_example_controller.rb
112
76
  Adding a route for the example Inertia controller
113
77
  route get 'inertia-example', to: 'inertia_example#index'
114
- Copying framework related files
78
+ Copying page assets
115
79
  create app/frontend/pages/InertiaExample.jsx
80
+ create app/frontend/pages/InertiaExample.module.css
81
+ create app/frontend/assets/react.svg
82
+ create app/frontend/assets/inertia.svg
83
+ create app/frontend/assets/vite_ruby.svg
84
+ Copying bin/dev
85
+ create bin/dev
116
86
  Inertia's Rails adapter successfully installed
117
87
  ```
118
88
 
119
89
  With that done, you can now start the Rails server and the Vite development server (we recommend using [Overmind](https://github.com/DarthSim/overmind)):
120
90
 
121
91
  ```bash
122
- overmind start -f Procfile.dev
123
- # or
124
- foreman start -f Procfile.dev
92
+ bin/dev
125
93
  ```
126
94
 
127
- And navigate to `http://127.0.0.1:5100/inertia-example` to see the example Inertia page.
95
+ And navigate to `http://localhost:3100/inertia-example` to see the example Inertia page.
128
96
 
129
97
  ### Scaffold generator
130
98
 
131
- `InertiaRailsContrib` also comes with a scaffold generator that generates a scaffold for a model with Inertia. To use it, execute the following command in the terminal:
99
+ `InertiaRailsContrib` also comes with a scaffold generator that generates a new resource with Inertia responses. To use it, execute the following command in the terminal:
132
100
 
133
101
  ```bash
134
102
  bin/rails generate inertia:scaffold ModelName field1:type field2:type
@@ -0,0 +1,41 @@
1
+ react:
2
+ packages:
3
+ - "@inertiajs/react"
4
+ - "react"
5
+ - "react-dom"
6
+ - "@vitejs/plugin-react"
7
+ vite_plugin_import: "import react from '@vitejs/plugin-react'"
8
+ vite_plugin_call: "react()"
9
+ copy_files:
10
+ "InertiaExample.jsx": "%{js_destination_path}/pages/InertiaExample.jsx"
11
+ "InertiaExample.module.css": "%{js_destination_path}/pages/InertiaExample.module.css"
12
+ "../assets/react.svg": "%{js_destination_path}/assets/react.svg"
13
+ "../assets/inertia.svg": "%{js_destination_path}/assets/inertia.svg"
14
+ "../assets/vite_ruby.svg": "%{js_destination_path}/assets/vite_ruby.svg"
15
+
16
+ vue:
17
+ packages:
18
+ - "@inertiajs/vue3"
19
+ - "vue"
20
+ - "@vitejs/plugin-vue"
21
+ vite_plugin_import: "import vue from '@vitejs/plugin-vue'"
22
+ vite_plugin_call: "vue()"
23
+ copy_files:
24
+ "InertiaExample.vue": "%{js_destination_path}/pages/InertiaExample.vue"
25
+ "../assets/vue.svg": "%{js_destination_path}/assets/vue.svg"
26
+ "../assets/inertia.svg": "%{js_destination_path}/assets/inertia.svg"
27
+ "../assets/vite_ruby.svg": "%{js_destination_path}/assets/vite_ruby.svg"
28
+
29
+ svelte:
30
+ packages:
31
+ - "@inertiajs/svelte"
32
+ - "svelte"
33
+ - "@sveltejs/vite-plugin-svelte"
34
+ vite_plugin_import: "import { svelte } from '@sveltejs/vite-plugin-svelte'"
35
+ vite_plugin_call: "svelte()"
36
+ copy_files:
37
+ "svelte.config.js": "svelte.config.js"
38
+ "InertiaExample.svelte": "%{js_destination_path}/pages/InertiaExample.svelte"
39
+ "../assets/svelte.svg": "%{js_destination_path}/assets/svelte.svg"
40
+ "../assets/inertia.svg": "%{js_destination_path}/assets/inertia.svg"
41
+ "../assets/vite_ruby.svg": "%{js_destination_path}/assets/vite_ruby.svg"
@@ -0,0 +1,42 @@
1
+ module Inertia
2
+ module Generators
3
+ module Helpers
4
+ ### FS Helpers
5
+ def js_destination_path
6
+ defined?(ViteRuby) ? ViteRuby.config.source_code_dir : "app/frontend"
7
+ end
8
+
9
+ def js_destination_root
10
+ file_path(js_destination_path)
11
+ end
12
+
13
+ def js_file_path(*relative_path)
14
+ File.join(js_destination_root, *relative_path)
15
+ end
16
+
17
+ def file?(*relative_path)
18
+ File.file?(file_path(*relative_path))
19
+ end
20
+
21
+ def file_path(*relative_path)
22
+ File.join(destination_root, *relative_path)
23
+ end
24
+
25
+ # Interactivity Helpers
26
+ def ask(*)
27
+ unless options[:interactive]
28
+ say_error "Specify all options when running the generator non-interactively.", :red
29
+ exit(1)
30
+ end
31
+
32
+ super
33
+ end
34
+
35
+ def yes?(*)
36
+ return false unless options[:interactive]
37
+
38
+ super
39
+ end
40
+ end
41
+ end
42
+ end
@@ -1,66 +1,53 @@
1
+ require "yaml"
2
+ require "rails/generators"
3
+ require "rails/generators/base"
4
+
5
+ require_relative "helpers"
6
+
1
7
  module Inertia
2
8
  module Generators
3
9
  class InstallGenerator < Rails::Generators::Base
10
+ include Helpers
11
+
12
+ FRAMEWORKS = YAML.load_file(File.expand_path("./frameworks.yml", __dir__))
13
+
4
14
  source_root File.expand_path("./templates", __dir__)
5
15
 
6
- APPLICATION_LAYOUT = Rails.root.join("app/views/layouts/application.html.erb")
7
-
8
- FRAMEWORKS = {
9
- "react" => {
10
- packages: %w[@inertiajs/react react react-dom],
11
- dev_packages: %w[@vitejs/plugin-react],
12
- vite_plugin_import: "import react from '@vitejs/plugin-react'",
13
- vite_plugin_call: "react()",
14
- copy_files: {
15
- "InertiaExample.jsx" => "app/frontend/pages/InertiaExample.jsx",
16
- "InertiaExample.module.css" => "app/frontend/pages/InertiaExample.module.css",
17
- "../assets/react.svg" => "app/frontend/assets/react.svg",
18
- "../assets/inertia.svg" => "app/frontend/assets/inertia.svg",
19
- "../assets/vite_ruby.svg" => "app/frontend/assets/vite_ruby.svg"
20
- }
21
- },
22
- "vue" => {
23
- packages: %w[@inertiajs/vue3 vue],
24
- dev_packages: %w[@vitejs/plugin-vue],
25
- vite_plugin_import: "import vue from '@vitejs/plugin-vue'",
26
- vite_plugin_call: "vue()",
27
- copy_files: {
28
- "InertiaExample.vue" => "app/frontend/pages/InertiaExample.vue",
29
- "../assets/vue.svg" => "app/frontend/assets/vue.svg",
30
- "../assets/inertia.svg" => "app/frontend/assets/inertia.svg",
31
- "../assets/vite_ruby.svg" => "app/frontend/assets/vite_ruby.svg"
32
- }
33
- },
34
- "svelte" => {
35
- packages: %w[@inertiajs/svelte svelte @sveltejs/vite-plugin-svelte],
36
- dev_packages: %w[@vitejs/plugin-vue],
37
- vite_plugin_import: "import { svelte } from '@sveltejs/vite-plugin-svelte'",
38
- vite_plugin_call: "svelte()",
39
- copy_files: {
40
- "svelte.config.js" => "svelte.config.js",
41
- "InertiaExample.svelte" => "app/frontend/pages/InertiaExample.svelte",
42
- "../assets/svelte.svg" => "app/frontend/assets/svelte.svg",
43
- "../assets/inertia.svg" => "app/frontend/assets/inertia.svg",
44
- "../assets/vite_ruby.svg" => "app/frontend/assets/vite_ruby.svg"
45
- }
46
- }
47
- }
16
+ class_option :framework, type: :string,
17
+ desc: "The framework you want to use with Inertia",
18
+ enum: FRAMEWORKS.keys,
19
+ default: nil
20
+
21
+ class_option :package_manager, type: :string, default: nil, enum: %w[npm yarn bun],
22
+ desc: "The package manager you want to use to install Inertia's npm packages"
23
+
24
+ class_option :interactive, type: :boolean, default: true,
25
+ desc: "Whether to prompt for optional installations"
26
+
27
+ class_option :install_tailwind, type: :boolean, default: false,
28
+ desc: "Whether to install Tailwind CSS"
29
+ class_option :install_vite, type: :boolean, default: false,
30
+ desc: "Whether to install Vite Ruby"
31
+ class_option :example_page, type: :boolean, default: true,
32
+ desc: "Whether to add an example Inertia page"
33
+
34
+ remove_class_option :skip_namespace, :skip_collision_check
48
35
 
49
36
  def install
50
37
  say "Installing Inertia's Rails adapter"
51
38
 
52
- if package_manager.nil?
53
- say "Could not find a package.json file to install Inertia to.", :red
54
- exit!
55
- end
39
+ install_vite unless ruby_vite_installed?
56
40
 
57
- unless ruby_vite?
58
- say "Could not find a Vite configuration file `config/vite.json`. This generator only supports Ruby on Rails with Vite.", :red
59
- exit!
60
- end
41
+ install_tailwind if install_tailwind?
61
42
 
62
43
  install_inertia
63
44
 
45
+ install_example_page if options[:example_page]
46
+
47
+ say "Copying bin/dev"
48
+ copy_file "#{__dir__}/templates/dev", "bin/dev"
49
+ chmod "bin/dev", 0o755, verbose: false
50
+
64
51
  say "Inertia's Rails adapter successfully installed", :green
65
52
  end
66
53
 
@@ -68,71 +55,136 @@ module Inertia
68
55
 
69
56
  def install_inertia
70
57
  say "Adding Inertia's Rails adapter initializer"
71
- template "initializer.rb", Rails.root.join("config/initializers/inertia_rails.rb").to_s
58
+ template "initializer.rb", file_path("config/initializers/inertia_rails.rb")
72
59
 
73
60
  say "Installing Inertia npm packages"
74
- add_packages(*FRAMEWORKS[framework][:packages])
75
- add_packages("--save-dev", *FRAMEWORKS[framework][:dev_packages])
61
+ add_packages(*FRAMEWORKS[framework]["packages"])
76
62
 
77
- unless File.read(vite_config_path).include?(FRAMEWORKS[framework][:vite_plugin_import])
63
+ unless File.read(vite_config_path).include?(FRAMEWORKS[framework]["vite_plugin_import"])
78
64
  say "Adding Vite plugin for #{framework}"
79
- insert_into_file vite_config_path, "\n #{FRAMEWORKS[framework][:vite_plugin_call]},", after: "plugins: ["
80
- prepend_file vite_config_path, "#{FRAMEWORKS[framework][:vite_plugin_import]}\n"
81
- end
82
-
83
- unless Rails.root.join("package.json").read.include?('"type": "module"')
84
- say 'Add "type": "module", to the package.json file'
85
- gsub_file Rails.root.join("package.json").to_s, /\A\s*\{/, "{\n \"type\": \"module\","
65
+ insert_into_file vite_config_path, "\n #{FRAMEWORKS[framework]["vite_plugin_call"]},", after: "plugins: ["
66
+ prepend_file vite_config_path, "#{FRAMEWORKS[framework]["vite_plugin_import"]}\n"
86
67
  end
87
68
 
88
- say "Copying inertia.js into Vite entrypoints", :blue
89
- template "#{framework}/inertia.js", Rails.root.join("app/frontend/entrypoints/inertia.js").to_s
90
-
91
- say "Adding inertia.js script tag to the application layout"
92
- headers = <<-ERB
93
- <%= vite_javascript_tag 'inertia' %>
69
+ say "Copying inertia.js entrypoint"
70
+ template "#{framework}/inertia.js", js_file_path("entrypoints/inertia.js")
94
71
 
72
+ if application_layout.exist?
73
+ say "Adding inertia.js script tag to the application layout"
74
+ headers = <<-ERB
75
+ <%= vite_javascript_tag "inertia" %>
95
76
  <%= inertia_headers %>
96
- ERB
97
- insert_into_file APPLICATION_LAYOUT.to_s, headers, after: "<%= vite_client_tag %>\n"
77
+ ERB
78
+ headers += "\n <%= vite_stylesheet_tag \"application\" %>" if install_tailwind?
79
+
80
+ insert_into_file application_layout.to_s, headers, after: "<%= vite_client_tag %>\n"
98
81
 
99
- if framework == "react" && !APPLICATION_LAYOUT.read.include?("vite_react_refresh_tag")
100
- say "Adding Vite React Refresh tag to the application layout"
101
- insert_into_file APPLICATION_LAYOUT.to_s, "<%= vite_react_refresh_tag %>\n ", before: "<%= vite_client_tag %>"
82
+ if framework == "react" && !application_layout.read.include?("vite_react_refresh_tag")
83
+ say "Adding Vite React Refresh tag to the application layout"
84
+ insert_into_file application_layout.to_s, "<%= vite_react_refresh_tag %>\n ", before: "<%= vite_client_tag %>"
85
+ gsub_file application_layout.to_s, /<title>/, "<title inertia>"
86
+ end
87
+ else
88
+ say_error "Could not find the application layout file. Please add the following tags manually:", :red
89
+ say_error "- <title>...</title>"
90
+ say_error "+ <title inertia>...</title>"
91
+ say_error "+ <%= inertia_headers %>"
92
+ say_error "+ <%= vite_react_refresh_tag %>" if framework == "react"
93
+ say_error "+ <%= vite_javascript_tag \"inertia\" %>"
102
94
  end
95
+ end
103
96
 
97
+ def install_example_page
104
98
  say "Copying example Inertia controller"
105
- template "controller.rb", Rails.root.join("app/controllers/inertia_example_controller.rb").to_s
99
+ template "controller.rb", file_path("app/controllers/inertia_example_controller.rb")
106
100
 
107
101
  say "Adding a route for the example Inertia controller"
108
102
  route "get 'inertia-example', to: 'inertia_example#index'"
109
103
 
110
- say "Copying framework related files"
111
- FRAMEWORKS[framework][:copy_files].each do |source, destination|
112
- template "#{framework}/#{source}", Rails.root.join(destination).to_s
104
+ say "Copying page assets"
105
+ FRAMEWORKS[framework]["copy_files"].each do |source, destination|
106
+ template "#{framework}/#{source}", file_path(destination % {js_destination_path: js_destination_path})
107
+ end
108
+ end
109
+
110
+ def install_tailwind
111
+ say "Installing Tailwind CSS"
112
+ add_packages(%w[tailwindcss postcss autoprefixer @tailwindcss/forms @tailwindcss/typography @tailwindcss/container-queries])
113
+
114
+ template "tailwind/tailwind.config.js", file_path("tailwind.config.js")
115
+ copy_file "tailwind/postcss.config.js", file_path("postcss.config.js")
116
+ copy_file "tailwind/application.css", js_file_path("entrypoints/application.css")
117
+
118
+ if application_layout.exist?
119
+ say "Adding Tailwind CSS to the application layout"
120
+ insert_into_file application_layout.to_s, "<%= vite_stylesheet_tag \"application\" %>\n ", before: "<%= vite_client_tag %>"
121
+ else
122
+ say_error "Could not find the application layout file. Please add the following tags manually:", :red
123
+ say_error "+ <%= vite_stylesheet_tag \"application\" %>" if install_tailwind?
124
+ end
125
+ end
126
+
127
+ def install_vite
128
+ unless install_vite?
129
+ say_error "This generator only supports Ruby on Rails with Vite.", :red
130
+ exit(false)
131
+ end
132
+
133
+ in_root do
134
+ Bundler.with_original_env do
135
+ if (capture = run("bundle add vite_rails", capture: true))
136
+ say "Vite Rails gem successfully installed", :green
137
+ else
138
+ say capture
139
+ say_error "Failed to install Vite Rails gem", :red
140
+ exit(false)
141
+ end
142
+ if (capture = run("bundle exec vite install", capture: true))
143
+ say "Vite Rails successfully installed", :green
144
+ else
145
+ say capture
146
+ say_error "Failed to install Vite Rails", :red
147
+ exit(false)
148
+ end
149
+ end
113
150
  end
114
151
  end
115
152
 
153
+ def ruby_vite_installed?
154
+ return true if package_manager && ruby_vite?
155
+
156
+ if package_manager.nil?
157
+ say_status "Could not find a package.json file to install Inertia to.", nil
158
+ else
159
+ say_status "Could not find a Vite configuration files (`config/vite.json` & `vite.config.{ts,js,mjs,cjs}`).", nil
160
+ end
161
+ false
162
+ end
163
+
164
+ def application_layout
165
+ @application_layout ||= Pathname.new(file_path("app/views/layouts/application.html.erb"))
166
+ end
167
+
116
168
  def ruby_vite?
117
- Rails.root.join("config/vite.json").exist? && vite_config_path
169
+ file?("config/vite.json") && vite_config_path
118
170
  end
119
171
 
120
172
  def package_manager
121
- return @package_manager if defined?(@package_manager)
122
-
123
- @package_manager = detect_package_manager
173
+ options[:package_manager] || detect_package_manager
124
174
  end
125
175
 
126
176
  def add_packages(*packages)
127
- run "#{package_manager} add #{packages.join(" ")}"
177
+ in_root do
178
+ run "#{package_manager} add #{packages.join(" ")} --silent"
179
+ end
128
180
  end
129
181
 
130
182
  def detect_package_manager
131
- return nil unless Rails.root.join("package.json").exist?
183
+ return nil unless file?("package.json")
132
184
 
133
- if Rails.root.join("package-lock.json").exist?
185
+ if file?("package-lock.json")
134
186
  "npm"
135
- elsif Rails.root.join("bun.config.js").exist?
187
+ elsif file?("bun.config.js") || file?("bun.lockb")
136
188
  "bun"
137
189
  else
138
190
  "yarn"
@@ -140,11 +192,23 @@ module Inertia
140
192
  end
141
193
 
142
194
  def vite_config_path
143
- @vite_config_path ||= Dir.glob(Rails.root.join("vite.config.{ts,js,mjs,cjs}")).first
195
+ @vite_config_path ||= Dir.glob(file_path("vite.config.{ts,js,mjs,cjs}")).first
196
+ end
197
+
198
+ def install_vite?
199
+ return @install_vite if defined?(@install_vite)
200
+
201
+ @install_vite = options[:install_vite] || yes?("Would you like to install Vite Ruby? (y/n)", :green)
202
+ end
203
+
204
+ def install_tailwind?
205
+ return @install_tailwind if defined?(@install_tailwind)
206
+
207
+ @install_tailwind = options[:install_tailwind] || yes?("Would you like to install Tailwind CSS? (y/n)", :green)
144
208
  end
145
209
 
146
210
  def framework
147
- @framework ||= ask("What framework do you want to use with Turbo Mount?", limited_to: FRAMEWORKS.keys, default: "react")
211
+ @framework ||= options[:framework] || ask("What framework do you want to use with Inertia?", :green, limited_to: FRAMEWORKS.keys, default: "react")
148
212
  end
149
213
  end
150
214
  end
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env sh
2
+
3
+ export PORT="${PORT:-3000}"
4
+
5
+ if command -v overmind 1> /dev/null 2>&1
6
+ then
7
+ overmind start -f Procfile.dev "$@"
8
+ exit $?
9
+ fi
10
+
11
+ if command -v hivemind 1> /dev/null 2>&1
12
+ then
13
+ echo "Hivemind is installed. Running the application with Hivemind..."
14
+ exec hivemind Procfile.dev "$@"
15
+ exit $?
16
+ fi
17
+
18
+ if gem list --no-installed --exact --silent foreman; then
19
+ echo "Installing foreman..."
20
+ gem install foreman
21
+ fi
22
+
23
+ foreman start -f Procfile.dev "$@"
@@ -21,7 +21,7 @@ createInertiaApp({
21
21
  // and use the following lines.
22
22
  // see https://inertia-rails.netlify.app/guide/pages#default-layouts
23
23
  //
24
- // const page = pages[`./pages/${name}.jsx`]
24
+ // const page = pages[`../pages/${name}.jsx`]
25
25
  // page.default.layout ||= (page) => createElement(Layout, null, page)
26
26
  // return page
27
27
  },
@@ -19,7 +19,7 @@ createInertiaApp({
19
19
  // and use the following lines.
20
20
  // see https://inertia-rails.netlify.app/guide/pages#default-layouts
21
21
  //
22
- // const page = pages[`./pages/${name}.vue`]
22
+ // const page = pages[`../pages/${name}.vue`]
23
23
  // page.default.layout ||= (page) => createElement(Layout, null, page)
24
24
  // return page
25
25
  },
@@ -0,0 +1,13 @@
1
+ @tailwind base;
2
+ @tailwind components;
3
+ @tailwind utilities;
4
+
5
+ /*
6
+
7
+ @layer components {
8
+ .btn-primary {
9
+ @apply py-2 px-4 bg-blue-200;
10
+ }
11
+ }
12
+
13
+ */
@@ -0,0 +1,6 @@
1
+ export default {
2
+ plugins: {
3
+ tailwindcss: {},
4
+ autoprefixer: {},
5
+ },
6
+ }
@@ -0,0 +1,18 @@
1
+ /** @type {import('tailwindcss').Config} */
2
+
3
+ module.exports = {
4
+ content: [
5
+ './public/*.html',
6
+ './app/helpers/**/*.rb',
7
+ './<%= js_destination_path %>/**/*.{js,ts,jsx,tsx,vue,svelte}',
8
+ './app/views/**/*.{erb,haml,html,slim}'
9
+ ],
10
+ theme: {
11
+ extend: {},
12
+ },
13
+ plugins: [
14
+ require('@tailwindcss/forms'),
15
+ require('@tailwindcss/typography'),
16
+ require('@tailwindcss/container-queries'),
17
+ ]
18
+ }
@@ -20,7 +20,7 @@ createInertiaApp({
20
20
  // and use the following lines.
21
21
  // see https://inertia-rails.netlify.app/guide/pages#default-layouts
22
22
  //
23
- // const page = pages[`./pages/${name}.vue`]
23
+ // const page = pages[`../pages/${name}.vue`]
24
24
  // page.default.layout ||= (page) => createElement(Layout, null, page)
25
25
  // return page
26
26
  },
@@ -84,19 +84,17 @@ class <%= controller_class_name %>Controller < ApplicationController
84
84
  def <%= "serialize_#{singular_table_name}" %>(<%= singular_table_name %>)
85
85
  <%= singular_table_name %>.as_json(only: [
86
86
  <%= attributes_to_serialize.map { |attribute| ":#{attribute}" }.join(", ") %>
87
- ])<% if attributes.any?(&:attachment?) -%>.tap do |hash|
88
- <% attributes.filter(&:attachment?).map do |attribute| -%>
87
+ ])<%- if attributes.any?(&:attachment?) || attributes.any?(&:attachments?) -%>.tap do |hash|
88
+ <%- attributes.filter(&:attachment?).map do |attribute| -%>
89
89
  hash["<%= attribute.column_name %>"] = {filename: <%= singular_table_name %>.<%= attribute.column_name %>.filename, url: url_for(<%= singular_table_name %>.<%= attribute.column_name %>)} if <%= singular_table_name %>.<%= attribute.column_name %>.attached?
90
- <% end -%>
91
- end<% end -%><% if attributes.any?(&:attachments?) -%>.tap do |hash|
92
- <% attributes.filter(&:attachments?).map do |attribute| -%>
90
+ <%- end -%>
91
+ <%- attributes.filter(&:attachments?).map do |attribute| -%>
93
92
  hash["<%= attribute.column_name %>"] =
94
93
  <%= singular_table_name %>.<%= attribute.column_name %>.flat_map do |file|
95
94
  {filename: file.filename.to_s, url: url_for(file)}
96
95
  end
97
- <% end -%>
98
- end
99
- <% end -%>
96
+ <%- end -%>
97
+ end<% end %>
100
98
  end
101
99
  end
102
100
  <% end -%>
@@ -16,11 +16,10 @@ export default function Edit({ <%= singular_table_name %> }) {
16
16
  form.post(`<%= js_resource_path %>`, {
17
17
  headers: { 'X-HTTP-METHOD-OVERRIDE': 'put' },
18
18
  })
19
- }}
20
19
  <% else -%>
21
20
  form.patch(`<%= js_resource_path %>`)
22
- }
23
21
  <% end -%>
22
+ }}
24
23
  submitText="Update <%= human_name.downcase %>"
25
24
  />
26
25
 
@@ -17,11 +17,10 @@ export default function Edit({ <%= singular_table_name %> }) {
17
17
  form.post(`<%= js_resource_path %>`, {
18
18
  headers: { 'X-HTTP-METHOD-OVERRIDE': 'put' },
19
19
  })
20
- }}
21
20
  <% else -%>
22
21
  form.patch(`<%= js_resource_path %>`)
23
- }
24
22
  <% end -%>
23
+ }}
25
24
  submitText="Update <%= human_name.downcase %>"
26
25
  />
27
26
 
@@ -35,7 +35,11 @@ module InertiaRailsContrib
35
35
  end
36
36
 
37
37
  def pages_path
38
- "app/frontend/pages"
38
+ "#{root_path}/pages"
39
+ end
40
+
41
+ def root_path
42
+ (defined?(ViteRuby) ? ViteRuby.config.source_code_dir : "app/frontend")
39
43
  end
40
44
 
41
45
  def extension
@@ -9,7 +9,7 @@ module InertiaRailsContrib
9
9
  when /@inertiajs\/vue3/
10
10
  "vue"
11
11
  else
12
- puts "Could not determine the Inertia.js framework you are using."
12
+ say_error "Could not determine the Inertia.js framework you are using."
13
13
  end
14
14
  end
15
15
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module InertiaRailsContrib
4
- VERSION = "0.1.0"
4
+ VERSION = "0.2.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: inertia_rails-contrib
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Svyatoslav Kryukov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-06-11 00:00:00.000000000 Z
11
+ date: 2024-08-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: railties
@@ -50,6 +50,8 @@ files:
50
50
  - README.md
51
51
  - lib/generators/inertia/controller/controller_generator.rb
52
52
  - lib/generators/inertia/controller/templates/controller.rb.tt
53
+ - lib/generators/inertia/install/frameworks.yml
54
+ - lib/generators/inertia/install/helpers.rb
53
55
  - lib/generators/inertia/install/install_generator.rb
54
56
  - lib/generators/inertia/install/templates/assets/inertia.svg
55
57
  - lib/generators/inertia/install/templates/assets/react.svg
@@ -57,6 +59,7 @@ files:
57
59
  - lib/generators/inertia/install/templates/assets/vite_ruby.svg
58
60
  - lib/generators/inertia/install/templates/assets/vue.svg
59
61
  - lib/generators/inertia/install/templates/controller.rb
62
+ - lib/generators/inertia/install/templates/dev
60
63
  - lib/generators/inertia/install/templates/initializer.rb
61
64
  - lib/generators/inertia/install/templates/react/InertiaExample.jsx
62
65
  - lib/generators/inertia/install/templates/react/InertiaExample.module.css
@@ -64,6 +67,9 @@ files:
64
67
  - lib/generators/inertia/install/templates/svelte/InertiaExample.svelte
65
68
  - lib/generators/inertia/install/templates/svelte/inertia.js
66
69
  - lib/generators/inertia/install/templates/svelte/svelte.config.js
70
+ - lib/generators/inertia/install/templates/tailwind/application.css
71
+ - lib/generators/inertia/install/templates/tailwind/postcss.config.js
72
+ - lib/generators/inertia/install/templates/tailwind/tailwind.config.js.tt
67
73
  - lib/generators/inertia/install/templates/vue/InertiaExample.vue
68
74
  - lib/generators/inertia/install/templates/vue/inertia.js
69
75
  - lib/generators/inertia/scaffold/scaffold_generator.rb