From 8097c2ee14ae67553a7804ec8086ba2060b8cbe9 Mon Sep 17 00:00:00 2001 From: Svyatoslav Kryukov Date: Mon, 11 Nov 2024 11:43:31 +0300 Subject: [PATCH 01/11] Upstream generators --- .github/workflows/push.yml | 21 +- .rubocop.yml | 15 + .rubocop_todo.yml | 631 ++++++++++++++++++ Gemfile | 26 +- Rakefile | 12 +- docs/guide/responses.md | 12 +- docs/guide/server-side-setup.md | 5 +- inertia_rails.gemspec | 37 +- .../controller/controller_generator.rb | 18 + .../controller/templates/controller.rb.tt | 10 + lib/generators/inertia/install/frameworks.yml | 98 +++ lib/generators/inertia/install/helpers.rb | 51 ++ .../inertia/install/install_generator.rb | 286 ++++++++ .../inertia/install/js_package_manager.rb | 50 ++ .../install/templates/assets/inertia.svg | 1 + .../install/templates/assets/react.svg | 1 + .../install/templates/assets/svelte.svg | 1 + .../install/templates/assets/vite_ruby.svg | 1 + .../inertia/install/templates/assets/vue.svg | 1 + .../install/templates}/controller.rb | 4 +- lib/generators/inertia/install/templates/dev | 23 + .../inertia/install/templates/initializer.rb | 6 + .../templates/react/InertiaExample.jsx | 60 ++ .../templates/react/InertiaExample.module.css | 80 +++ .../templates/react/InertiaExample.tsx | 60 ++ .../install/templates/react/inertia.js | 34 + .../install/templates/react/inertia.ts | 36 + .../install/templates/react/tsconfig.app.json | 27 + .../install/templates/react/tsconfig.json | 11 + .../templates/react/tsconfig.node.json | 13 + .../install/templates/react/vite-env.d.ts | 1 + .../templates/svelte/InertiaExample.svelte | 112 ++++ .../templates/svelte/InertiaExample.ts.svelte | 112 ++++ .../install/templates/svelte/inertia.js | 30 + .../install/templates/svelte/inertia.ts | 30 + .../install/templates/svelte/svelte.config.js | 7 + .../install/templates/svelte/tsconfig.json | 21 + .../templates/svelte/tsconfig.node.json | 12 + .../install/templates/svelte/vite-env.d.ts | 2 + .../templates/svelte4/InertiaExample.svelte | 116 ++++ .../svelte4/InertiaExample.ts.svelte | 116 ++++ .../install/templates/svelte4/inertia.js | 29 + .../install/templates/svelte4/inertia.ts | 29 + .../templates/svelte4/svelte.config.js | 7 + .../install/templates/svelte4/tsconfig.json | 21 + .../templates/svelte4/tsconfig.node.json | 12 + .../install/templates/svelte4/vite-env.d.ts | 2 + .../templates/tailwind/application.css | 13 + .../templates/tailwind/postcss.config.js | 6 + .../templates/tailwind/tailwind.config.js.tt | 18 + .../templates/vue/InertiaExample.ts.vue | 117 ++++ .../install/templates/vue/InertiaExample.vue | 117 ++++ .../inertia/install/templates/vue/inertia.js | 33 + .../inertia/install/templates/vue/inertia.ts | 33 + .../install/templates/vue/tsconfig.app.json | 24 + .../install/templates/vue/tsconfig.json | 11 + .../install/templates/vue/tsconfig.node.json | 22 + .../install/templates/vue/vite-env.d.ts | 1 + .../inertia/scaffold/scaffold_generator.rb | 16 + .../scaffold_controller_generator.rb | 60 ++ .../templates/controller.rb.tt | 100 +++ .../install/react/InertiaExample.jsx | 9 - .../inertia_rails/install/react/inertia.jsx | 17 - .../install/svelte/InertiaExample.svelte | 11 - .../inertia_rails/install/svelte/inertia.js | 14 - .../install/vue/InertiaExample.vue | 11 - .../inertia_rails/install/vue/inertia.js | 20 - .../inertia_rails/install_generator.rb | 84 --- .../controller/controller_generator.rb | 12 + .../controller/templates/react/view.jsx.tt | 8 + .../templates/svelte/view.svelte.tt | 2 + .../templates/svelte4/view.svelte.tt | 2 + .../controller/templates/vue/view.vue.tt | 4 + .../scaffold/scaffold_generator.rb | 12 + .../scaffold/templates/react/Edit.jsx.tt | 35 + .../scaffold/templates/react/Form.jsx.tt | 111 +++ .../scaffold/templates/react/Index.jsx.tt | 26 + .../scaffold/templates/react/New.jsx.tt | 27 + .../scaffold/templates/react/One.jsx.tt | 26 + .../scaffold/templates/react/Show.jsx.tt | 39 ++ .../scaffold/templates/svelte/Edit.svelte.tt | 36 + .../scaffold/templates/svelte/Form.svelte.tt | 98 +++ .../scaffold/templates/svelte/Index.svelte.tt | 35 + .../scaffold/templates/svelte/New.svelte.tt | 29 + .../scaffold/templates/svelte/One.svelte.tt | 28 + .../scaffold/templates/svelte/Show.svelte.tt | 41 ++ .../scaffold/templates/svelte4/Edit.svelte.tt | 37 + .../scaffold/templates/svelte4/Form.svelte.tt | 96 +++ .../templates/svelte4/Index.svelte.tt | 36 + .../scaffold/templates/svelte4/New.svelte.tt | 30 + .../scaffold/templates/svelte4/One.svelte.tt | 28 + .../scaffold/templates/svelte4/Show.svelte.tt | 46 ++ .../scaffold/templates/vue/Edit.vue.tt | 36 + .../scaffold/templates/vue/Form.vue.tt | 94 +++ .../scaffold/templates/vue/Index.vue.tt | 31 + .../scaffold/templates/vue/New.vue.tt | 29 + .../scaffold/templates/vue/One.vue.tt | 26 + .../scaffold/templates/vue/Show.vue.tt | 44 ++ .../controller/controller_generator.rb | 12 + .../controller/templates/react/view.jsx.tt | 8 + .../templates/svelte/view.svelte.tt | 2 + .../templates/svelte4/view.svelte.tt | 2 + .../controller/templates/vue/view.vue.tt | 4 + .../scaffold/scaffold_generator.rb | 12 + .../scaffold/templates/react/Edit.jsx.tt | 42 ++ .../scaffold/templates/react/Form.jsx.tt | 122 ++++ .../scaffold/templates/react/Index.jsx.tt | 43 ++ .../scaffold/templates/react/New.jsx.tt | 30 + .../scaffold/templates/react/One.jsx.tt | 26 + .../scaffold/templates/react/Show.jsx.tt | 54 ++ .../scaffold/templates/svelte/Edit.svelte.tt | 44 ++ .../scaffold/templates/svelte/Form.svelte.tt | 119 ++++ .../scaffold/templates/svelte/Index.svelte.tt | 42 ++ .../scaffold/templates/svelte/New.svelte.tt | 32 + .../scaffold/templates/svelte/One.svelte.tt | 28 + .../scaffold/templates/svelte/Show.svelte.tt | 57 ++ .../scaffold/templates/svelte4/Edit.svelte.tt | 45 ++ .../scaffold/templates/svelte4/Form.svelte.tt | 120 ++++ .../templates/svelte4/Index.svelte.tt | 43 ++ .../scaffold/templates/svelte4/New.svelte.tt | 33 + .../scaffold/templates/svelte4/One.svelte.tt | 28 + .../scaffold/templates/svelte4/Show.svelte.tt | 58 ++ .../scaffold/templates/vue/Edit.vue.tt | 44 ++ .../scaffold/templates/vue/Form.vue.tt | 127 ++++ .../scaffold/templates/vue/Index.vue.tt | 43 ++ .../scaffold/templates/vue/New.vue.tt | 32 + .../scaffold/templates/vue/One.vue.tt | 26 + .../scaffold/templates/vue/Show.vue.tt | 56 ++ lib/inertia_rails/configuration.rb | 2 +- .../generators/controller_template_base.rb | 56 ++ lib/inertia_rails/generators/helper.rb | 89 +++ .../generators/scaffold_template_base.rb | 36 + spec/fixtures/install_generator/dummy/Gemfile | 3 + .../app/views/layouts/application.html.erb | 13 + .../install_generator/dummy/config/routes.rb | 5 + .../app/views/layouts/application.html.erb | 16 + .../with_vite/config/vite.json | 1 + .../install_generator/with_vite/package.json | 1 + .../with_vite/vite.config.ts | 8 + .../install/install_generator_spec.rb | 314 +++++++++ 140 files changed, 5800 insertions(+), 209 deletions(-) create mode 100644 .rubocop.yml create mode 100644 .rubocop_todo.yml create mode 100644 lib/generators/inertia/controller/controller_generator.rb create mode 100644 lib/generators/inertia/controller/templates/controller.rb.tt create mode 100644 lib/generators/inertia/install/frameworks.yml create mode 100644 lib/generators/inertia/install/helpers.rb create mode 100644 lib/generators/inertia/install/install_generator.rb create mode 100644 lib/generators/inertia/install/js_package_manager.rb create mode 100644 lib/generators/inertia/install/templates/assets/inertia.svg create mode 100644 lib/generators/inertia/install/templates/assets/react.svg create mode 100644 lib/generators/inertia/install/templates/assets/svelte.svg create mode 100644 lib/generators/inertia/install/templates/assets/vite_ruby.svg create mode 100644 lib/generators/inertia/install/templates/assets/vue.svg rename lib/generators/{inertia_rails/install => inertia/install/templates}/controller.rb (64%) create mode 100644 lib/generators/inertia/install/templates/dev create mode 100644 lib/generators/inertia/install/templates/initializer.rb create mode 100644 lib/generators/inertia/install/templates/react/InertiaExample.jsx create mode 100644 lib/generators/inertia/install/templates/react/InertiaExample.module.css create mode 100644 lib/generators/inertia/install/templates/react/InertiaExample.tsx create mode 100644 lib/generators/inertia/install/templates/react/inertia.js create mode 100644 lib/generators/inertia/install/templates/react/inertia.ts create mode 100644 lib/generators/inertia/install/templates/react/tsconfig.app.json create mode 100644 lib/generators/inertia/install/templates/react/tsconfig.json create mode 100644 lib/generators/inertia/install/templates/react/tsconfig.node.json create mode 100644 lib/generators/inertia/install/templates/react/vite-env.d.ts create mode 100644 lib/generators/inertia/install/templates/svelte/InertiaExample.svelte create mode 100644 lib/generators/inertia/install/templates/svelte/InertiaExample.ts.svelte create mode 100644 lib/generators/inertia/install/templates/svelte/inertia.js create mode 100644 lib/generators/inertia/install/templates/svelte/inertia.ts create mode 100644 lib/generators/inertia/install/templates/svelte/svelte.config.js create mode 100644 lib/generators/inertia/install/templates/svelte/tsconfig.json create mode 100644 lib/generators/inertia/install/templates/svelte/tsconfig.node.json create mode 100644 lib/generators/inertia/install/templates/svelte/vite-env.d.ts create mode 100644 lib/generators/inertia/install/templates/svelte4/InertiaExample.svelte create mode 100644 lib/generators/inertia/install/templates/svelte4/InertiaExample.ts.svelte create mode 100644 lib/generators/inertia/install/templates/svelte4/inertia.js create mode 100644 lib/generators/inertia/install/templates/svelte4/inertia.ts create mode 100644 lib/generators/inertia/install/templates/svelte4/svelte.config.js create mode 100644 lib/generators/inertia/install/templates/svelte4/tsconfig.json create mode 100644 lib/generators/inertia/install/templates/svelte4/tsconfig.node.json create mode 100644 lib/generators/inertia/install/templates/svelte4/vite-env.d.ts create mode 100644 lib/generators/inertia/install/templates/tailwind/application.css create mode 100644 lib/generators/inertia/install/templates/tailwind/postcss.config.js create mode 100644 lib/generators/inertia/install/templates/tailwind/tailwind.config.js.tt create mode 100644 lib/generators/inertia/install/templates/vue/InertiaExample.ts.vue create mode 100644 lib/generators/inertia/install/templates/vue/InertiaExample.vue create mode 100644 lib/generators/inertia/install/templates/vue/inertia.js create mode 100644 lib/generators/inertia/install/templates/vue/inertia.ts create mode 100644 lib/generators/inertia/install/templates/vue/tsconfig.app.json create mode 100644 lib/generators/inertia/install/templates/vue/tsconfig.json create mode 100644 lib/generators/inertia/install/templates/vue/tsconfig.node.json create mode 100644 lib/generators/inertia/install/templates/vue/vite-env.d.ts create mode 100644 lib/generators/inertia/scaffold/scaffold_generator.rb create mode 100644 lib/generators/inertia/scaffold_controller/scaffold_controller_generator.rb create mode 100644 lib/generators/inertia/scaffold_controller/templates/controller.rb.tt delete mode 100644 lib/generators/inertia_rails/install/react/InertiaExample.jsx delete mode 100644 lib/generators/inertia_rails/install/react/inertia.jsx delete mode 100644 lib/generators/inertia_rails/install/svelte/InertiaExample.svelte delete mode 100644 lib/generators/inertia_rails/install/svelte/inertia.js delete mode 100644 lib/generators/inertia_rails/install/vue/InertiaExample.vue delete mode 100644 lib/generators/inertia_rails/install/vue/inertia.js delete mode 100644 lib/generators/inertia_rails/install_generator.rb create mode 100644 lib/generators/inertia_templates/controller/controller_generator.rb create mode 100644 lib/generators/inertia_templates/controller/templates/react/view.jsx.tt create mode 100644 lib/generators/inertia_templates/controller/templates/svelte/view.svelte.tt create mode 100644 lib/generators/inertia_templates/controller/templates/svelte4/view.svelte.tt create mode 100644 lib/generators/inertia_templates/controller/templates/vue/view.vue.tt create mode 100644 lib/generators/inertia_templates/scaffold/scaffold_generator.rb create mode 100644 lib/generators/inertia_templates/scaffold/templates/react/Edit.jsx.tt create mode 100644 lib/generators/inertia_templates/scaffold/templates/react/Form.jsx.tt create mode 100644 lib/generators/inertia_templates/scaffold/templates/react/Index.jsx.tt create mode 100644 lib/generators/inertia_templates/scaffold/templates/react/New.jsx.tt create mode 100644 lib/generators/inertia_templates/scaffold/templates/react/One.jsx.tt create mode 100644 lib/generators/inertia_templates/scaffold/templates/react/Show.jsx.tt create mode 100644 lib/generators/inertia_templates/scaffold/templates/svelte/Edit.svelte.tt create mode 100644 lib/generators/inertia_templates/scaffold/templates/svelte/Form.svelte.tt create mode 100644 lib/generators/inertia_templates/scaffold/templates/svelte/Index.svelte.tt create mode 100644 lib/generators/inertia_templates/scaffold/templates/svelte/New.svelte.tt create mode 100644 lib/generators/inertia_templates/scaffold/templates/svelte/One.svelte.tt create mode 100644 lib/generators/inertia_templates/scaffold/templates/svelte/Show.svelte.tt create mode 100644 lib/generators/inertia_templates/scaffold/templates/svelte4/Edit.svelte.tt create mode 100644 lib/generators/inertia_templates/scaffold/templates/svelte4/Form.svelte.tt create mode 100644 lib/generators/inertia_templates/scaffold/templates/svelte4/Index.svelte.tt create mode 100644 lib/generators/inertia_templates/scaffold/templates/svelte4/New.svelte.tt create mode 100644 lib/generators/inertia_templates/scaffold/templates/svelte4/One.svelte.tt create mode 100644 lib/generators/inertia_templates/scaffold/templates/svelte4/Show.svelte.tt create mode 100644 lib/generators/inertia_templates/scaffold/templates/vue/Edit.vue.tt create mode 100644 lib/generators/inertia_templates/scaffold/templates/vue/Form.vue.tt create mode 100644 lib/generators/inertia_templates/scaffold/templates/vue/Index.vue.tt create mode 100644 lib/generators/inertia_templates/scaffold/templates/vue/New.vue.tt create mode 100644 lib/generators/inertia_templates/scaffold/templates/vue/One.vue.tt create mode 100644 lib/generators/inertia_templates/scaffold/templates/vue/Show.vue.tt create mode 100644 lib/generators/inertia_tw_templates/controller/controller_generator.rb create mode 100644 lib/generators/inertia_tw_templates/controller/templates/react/view.jsx.tt create mode 100644 lib/generators/inertia_tw_templates/controller/templates/svelte/view.svelte.tt create mode 100644 lib/generators/inertia_tw_templates/controller/templates/svelte4/view.svelte.tt create mode 100644 lib/generators/inertia_tw_templates/controller/templates/vue/view.vue.tt create mode 100644 lib/generators/inertia_tw_templates/scaffold/scaffold_generator.rb create mode 100644 lib/generators/inertia_tw_templates/scaffold/templates/react/Edit.jsx.tt create mode 100644 lib/generators/inertia_tw_templates/scaffold/templates/react/Form.jsx.tt create mode 100644 lib/generators/inertia_tw_templates/scaffold/templates/react/Index.jsx.tt create mode 100644 lib/generators/inertia_tw_templates/scaffold/templates/react/New.jsx.tt create mode 100644 lib/generators/inertia_tw_templates/scaffold/templates/react/One.jsx.tt create mode 100644 lib/generators/inertia_tw_templates/scaffold/templates/react/Show.jsx.tt create mode 100644 lib/generators/inertia_tw_templates/scaffold/templates/svelte/Edit.svelte.tt create mode 100644 lib/generators/inertia_tw_templates/scaffold/templates/svelte/Form.svelte.tt create mode 100644 lib/generators/inertia_tw_templates/scaffold/templates/svelte/Index.svelte.tt create mode 100644 lib/generators/inertia_tw_templates/scaffold/templates/svelte/New.svelte.tt create mode 100644 lib/generators/inertia_tw_templates/scaffold/templates/svelte/One.svelte.tt create mode 100644 lib/generators/inertia_tw_templates/scaffold/templates/svelte/Show.svelte.tt create mode 100644 lib/generators/inertia_tw_templates/scaffold/templates/svelte4/Edit.svelte.tt create mode 100644 lib/generators/inertia_tw_templates/scaffold/templates/svelte4/Form.svelte.tt create mode 100644 lib/generators/inertia_tw_templates/scaffold/templates/svelte4/Index.svelte.tt create mode 100644 lib/generators/inertia_tw_templates/scaffold/templates/svelte4/New.svelte.tt create mode 100644 lib/generators/inertia_tw_templates/scaffold/templates/svelte4/One.svelte.tt create mode 100644 lib/generators/inertia_tw_templates/scaffold/templates/svelte4/Show.svelte.tt create mode 100644 lib/generators/inertia_tw_templates/scaffold/templates/vue/Edit.vue.tt create mode 100644 lib/generators/inertia_tw_templates/scaffold/templates/vue/Form.vue.tt create mode 100644 lib/generators/inertia_tw_templates/scaffold/templates/vue/Index.vue.tt create mode 100644 lib/generators/inertia_tw_templates/scaffold/templates/vue/New.vue.tt create mode 100644 lib/generators/inertia_tw_templates/scaffold/templates/vue/One.vue.tt create mode 100644 lib/generators/inertia_tw_templates/scaffold/templates/vue/Show.vue.tt create mode 100644 lib/inertia_rails/generators/controller_template_base.rb create mode 100644 lib/inertia_rails/generators/helper.rb create mode 100644 lib/inertia_rails/generators/scaffold_template_base.rb create mode 100644 spec/fixtures/install_generator/dummy/Gemfile create mode 100644 spec/fixtures/install_generator/dummy/app/views/layouts/application.html.erb create mode 100644 spec/fixtures/install_generator/dummy/config/routes.rb create mode 100644 spec/fixtures/install_generator/with_vite/app/views/layouts/application.html.erb create mode 100644 spec/fixtures/install_generator/with_vite/config/vite.json create mode 100644 spec/fixtures/install_generator/with_vite/package.json create mode 100644 spec/fixtures/install_generator/with_vite/vite.config.ts create mode 100644 spec/generators/install/install_generator_spec.rb diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index 1384c27a..2e8d8a25 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -15,6 +15,20 @@ on: - '**.md' jobs: + lint: + runs-on: ubuntu-latest + name: Linter + steps: + - uses: actions/checkout@v4 + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: "3.3" + bundler: latest + bundler-cache: true + - name: Run RuboCop + run: bundle exec rubocop + test: strategy: fail-fast: false @@ -31,6 +45,11 @@ jobs: - name: Setup System run: sudo apt-get install libsqlite3-dev + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: 22.x + - name: Set up Ruby uses: ruby/setup-ruby@v1 with: @@ -40,6 +59,6 @@ jobs: RAILS_VERSION: ${{ matrix.rails }} - name: Run tests - run: bundle exec rake + run: bundle exec rspec env: RAILS_VERSION: ${{ matrix.rails }} diff --git a/.rubocop.yml b/.rubocop.yml new file mode 100644 index 00000000..bb580f41 --- /dev/null +++ b/.rubocop.yml @@ -0,0 +1,15 @@ +inherit_from: .rubocop_todo.yml + +AllCops: + TargetRubyVersion: 3.0 + NewCops: enable + SuggestExtensions: false + +Metrics: + Enabled: false + +Style/Documentation: + Enabled: false + +Style/TrailingCommaInHashLiteral: + EnforcedStyleForMultiline: consistent_comma diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml new file mode 100644 index 00000000..99d08152 --- /dev/null +++ b/.rubocop_todo.yml @@ -0,0 +1,631 @@ +# This configuration was generated by +# `rubocop --auto-gen-config --exclude-limit 10000` +# on 2024-11-11 08:39:28 UTC using RuboCop version 1.68.0. +# The point is for the user to remove these configuration records +# one by one as the offenses are removed from the code base. +# Note that changes in the inspected code, or installation of new +# versions of RuboCop, may require this file to be generated again. + +# Offense count: 1 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: EnforcedStyle, IndentationWidth. +# SupportedStyles: outdent, indent +Layout/AccessModifierIndentation: + Exclude: + - 'lib/inertia_rails/configuration.rb' + +# Offense count: 2 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: EnforcedStyle, IndentationWidth. +# SupportedStyles: with_first_argument, with_fixed_indentation +Layout/ArgumentAlignment: + Exclude: + - 'bin/console' + - 'spec/inertia/response_spec.rb' + +# Offense count: 5 +# This cop supports safe autocorrection (--autocorrect). +Layout/BlockEndNewline: + Exclude: + - 'spec/inertia/rendering_spec.rb' + +# Offense count: 2 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: AllowForAlignment. +Layout/CommentIndentation: + Exclude: + - 'lib/inertia_rails/rspec.rb' + +# Offense count: 2 +# This cop supports safe autocorrection (--autocorrect). +Layout/EmptyLineAfterGuardClause: + Exclude: + - 'lib/inertia_rails/configuration.rb' + - 'lib/inertia_rails/controller.rb' + +# Offense count: 1 +# This cop supports safe autocorrection (--autocorrect). +Layout/EmptyLineAfterMagicComment: + Exclude: + - 'lib/inertia_rails/action_filter.rb' + +# Offense count: 1 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: EnforcedStyle. +# SupportedStyles: empty_lines, no_empty_lines +Layout/EmptyLinesAroundBlockBody: + Exclude: + - 'spec/inertia/rails_mimic_spec.rb' + +# Offense count: 3 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: AllowForAlignment, AllowBeforeTrailingComments, ForceEqualSignAlignment. +Layout/ExtraSpacing: + Exclude: + - 'lib/inertia_rails/controller.rb' + - 'spec/inertia/request_spec.rb' + - 'spec/inertia/response_spec.rb' + +# Offense count: 1 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: EnforcedStyle, IndentationWidth. +# SupportedStyles: consistent, consistent_relative_to_receiver, special_for_inner_method_call, special_for_inner_method_call_in_parentheses +Layout/FirstArgumentIndentation: + Exclude: + - 'spec/inertia/ssr_spec.rb' + +# Offense count: 2 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: IndentationWidth. +# SupportedStyles: special_inside_parentheses, consistent, align_braces +Layout/FirstHashElementIndentation: + EnforcedStyle: consistent + +# Offense count: 1 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: Width, AllowedPatterns. +Layout/IndentationWidth: + Exclude: + - 'spec/inertia/configuration_spec.rb' + +# Offense count: 5 +# This cop supports safe autocorrection (--autocorrect). +Layout/MultilineBlockLayout: + Exclude: + - 'spec/inertia/rendering_spec.rb' + +# Offense count: 4 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: EnforcedStyle, IndentationWidth. +# SupportedStyles: aligned, indented, indented_relative_to_receiver +Layout/MultilineMethodCallIndentation: + Exclude: + - 'spec/inertia/ssr_spec.rb' + +# Offense count: 7 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: EnforcedStyle, EnforcedStyleForEmptyBraces. +# SupportedStyles: space, no_space +# SupportedStylesForEmptyBraces: space, no_space +Layout/SpaceBeforeBlockBraces: + Exclude: + - 'spec/dummy/app/controllers/inertia_render_test_controller.rb' + - 'spec/inertia/error_sharing_spec.rb' + - 'spec/inertia/request_spec.rb' + +# Offense count: 4 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: EnforcedStyle, EnforcedStyleForEmptyBrackets. +# SupportedStyles: space, no_space, compact +# SupportedStylesForEmptyBrackets: space, no_space +Layout/SpaceInsideArrayLiteralBrackets: + Exclude: + - 'spec/dummy/app/controllers/inertia_test_controller.rb' + - 'spec/dummy/config/environments/production.rb' + +# Offense count: 22 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: EnforcedStyle, EnforcedStyleForEmptyBraces, SpaceBeforeBlockParameters. +# SupportedStyles: space, no_space +# SupportedStylesForEmptyBraces: space, no_space +Layout/SpaceInsideBlockBraces: + Exclude: + - 'lib/inertia_rails/renderer.rb' + - 'spec/inertia/configuration_spec.rb' + - 'spec/inertia/error_sharing_spec.rb' + - 'spec/inertia/rendering_spec.rb' + - 'spec/inertia/request_spec.rb' + +# Offense count: 130 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: EnforcedStyle, EnforcedStyleForEmptyBraces. +# SupportedStyles: space, no_space, compact +# SupportedStylesForEmptyBraces: space, no_space +Layout/SpaceInsideHashLiteralBraces: + Exclude: + - 'lib/inertia_rails/controller.rb' + - 'lib/inertia_rails/middleware.rb' + - 'lib/patches/mapper.rb' + - 'spec/dummy/app/controllers/inertia_conditional_sharing_controller.rb' + - 'spec/dummy/app/controllers/inertia_share_test_controller.rb' + - 'spec/inertia/conditional_sharing_spec.rb' + - 'spec/inertia/configuration_spec.rb' + - 'spec/inertia/middleware_spec.rb' + - 'spec/inertia/rails_mimic_spec.rb' + - 'spec/inertia/rendering_spec.rb' + - 'spec/inertia/request_spec.rb' + - 'spec/inertia/rspec_helper_spec.rb' + - 'spec/inertia/sharing_spec.rb' + - 'spec/inertia/ssr_spec.rb' + +# Offense count: 2 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: EnforcedStyle. +# SupportedStyles: final_newline, final_blank_line +Layout/TrailingEmptyLines: + Exclude: + - 'lib/tasks/inertia_rails.rake' + - 'spec/inertia/rails_mimic_spec.rb' + +# Offense count: 12 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: AllowInHeredoc. +Layout/TrailingWhitespace: + Exclude: + - 'lib/inertia_rails/rspec.rb' + - 'spec/dummy/app/controllers/inertia_render_test_controller.rb' + - 'spec/dummy/config/environments/test.rb' + +# Offense count: 1 +# Configuration parameters: AllowComments. +Lint/EmptyClass: + Exclude: + - 'spec/dummy/app/controllers/inertia_responders_test_controller.rb' + +# Offense count: 1 +# Configuration parameters: AllowedParentClasses. +Lint/MissingSuper: + Exclude: + - 'lib/inertia_rails/lazy_prop.rb' + +# Offense count: 1 +# This cop supports unsafe autocorrection (--autocorrect-all). +# Configuration parameters: AllowedImplicitNamespaces. +# AllowedImplicitNamespaces: Gem +Lint/RaiseException: + Exclude: + - 'spec/dummy/app/controllers/inertia_multithreaded_share_controller.rb' + +# Offense count: 1 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: EnforcedStyle. +# SupportedStyles: strict, consistent +Lint/SymbolConversion: + Exclude: + - 'spec/inertia/rails_mimic_spec.rb' + +# Offense count: 1 +# Configuration parameters: AllowKeywordBlockArguments. +Lint/UnderscorePrefixedVariableName: + Exclude: + - 'lib/inertia_rails/renderer.rb' + +# Offense count: 1 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: AutoCorrect, AllowUnusedKeywordArguments, IgnoreEmptyMethods, IgnoreNotImplementedMethods. +Lint/UnusedMethodArgument: + Exclude: + - 'lib/patches/mapper.rb' + +# Offense count: 1 +Naming/AccessorMethodName: + Exclude: + - 'lib/inertia_rails/rspec.rb' + +# Offense count: 2 +# Configuration parameters: ExpectMatchingDefinition, CheckDefinitionPathHierarchy, CheckDefinitionPathHierarchyRoots, Regex, IgnoreExecutableScripts, AllowedAcronyms. +# CheckDefinitionPathHierarchyRoots: lib, spec, test, src +# AllowedAcronyms: CLI, DSL, ACL, API, ASCII, CPU, CSS, DNS, EOF, GUID, HTML, HTTP, HTTPS, ID, IP, JSON, LHS, QPS, RAM, RHS, RPC, SLA, SMTP, SQL, SSH, TCP, TLS, TTL, UDP, UI, UID, UUID, URI, URL, UTF8, VM, XML, XMPP, XSRF, XSS +Naming/FileName: + Exclude: + - 'Rakefile.rb' + - 'lib/patches/debug_exceptions/patch-5-0.rb' + - 'lib/patches/debug_exceptions/patch-5-1.rb' + +# Offense count: 2 +# Configuration parameters: EnforcedStyle, CheckMethodNames, CheckSymbols, AllowedIdentifiers, AllowedPatterns. +# SupportedStyles: snake_case, normalcase, non_integer +# AllowedIdentifiers: capture3, iso8601, rfc1123_date, rfc822, rfc2822, rfc3339, x86_64 +Naming/VariableNumber: + Exclude: + - 'spec/dummy/app/controllers/inertia_test_controller.rb' + +# Offense count: 21 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: EnforcedStyle, ProceduralMethods, FunctionalMethods, AllowedMethods, AllowedPatterns, AllowBracesOnProceduralOneLiners, BracesRequiredMethods. +# SupportedStyles: line_count_based, semantic, braces_for_chaining, always_braces +# ProceduralMethods: benchmark, bm, bmbm, create, each_with_object, measure, new, realtime, tap, with_object +# FunctionalMethods: let, let!, subject, watch +# AllowedMethods: lambda, proc, it +Style/BlockDelimiters: + Exclude: + - 'lib/inertia_rails/configuration.rb' + - 'lib/inertia_rails/controller.rb' + - 'spec/inertia/action_filter_spec.rb' + - 'spec/inertia/conditional_sharing_spec.rb' + - 'spec/inertia/configuration_spec.rb' + - 'spec/inertia/rendering_spec.rb' + - 'spec/inertia/request_spec.rb' + - 'spec/inertia/rspec_helper_spec.rb' + - 'spec/inertia/sharing_spec.rb' + +# Offense count: 1 +# This cop supports unsafe autocorrection (--autocorrect-all). +# Configuration parameters: EnforcedStyle. +# SupportedStyles: nested, compact +Style/ClassAndModuleChildren: + Exclude: + - 'lib/inertia_rails/helper.rb' + +# Offense count: 2 +# This cop supports safe autocorrection (--autocorrect). +Style/ColonMethodCall: + Exclude: + - 'spec/inertia/error_sharing_spec.rb' + - 'spec/inertia/rendering_spec.rb' + +# Offense count: 1 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: EnforcedStyle, SingleLineConditionsOnly, IncludeTernaryExpressions. +# SupportedStyles: assign_to_condition, assign_inside_condition +Style/ConditionalAssignment: + Exclude: + - 'lib/inertia_rails/renderer.rb' + +# Offense count: 1 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: AutoCorrect, EnforcedStyle, AllowComments. +# SupportedStyles: empty, nil, both +Style/EmptyElse: + Exclude: + - 'lib/patches/debug_exceptions.rb' + +# Offense count: 3 +# This cop supports safe autocorrection (--autocorrect). +Style/EmptyLiteral: + Exclude: + - 'spec/inertia/request_spec.rb' + +# Offense count: 2 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: AutoCorrect, EnforcedStyle. +# SupportedStyles: compact, expanded +Style/EmptyMethod: + Exclude: + - 'spec/dummy/app/controllers/transformed_inertia_rails_mimic_controller.rb' + - 'spec/inertia/rspec_helper_spec.rb' + +# Offense count: 1 +# This cop supports safe autocorrection (--autocorrect). +Style/ExpandPathArguments: + Exclude: + - 'spec/rails_helper.rb' + +# Offense count: 74 +# This cop supports unsafe autocorrection (--autocorrect-all). +# Configuration parameters: EnforcedStyle. +# SupportedStyles: always, always_true, never +Style/FrozenStringLiteralComment: + Exclude: + - 'app/controllers/inertia_rails/static_controller.rb' + - 'bin/console' + - 'lib/inertia_rails.rb' + - 'lib/inertia_rails/controller.rb' + - 'lib/inertia_rails/engine.rb' + - 'lib/inertia_rails/helper.rb' + - 'lib/inertia_rails/inertia_rails.rb' + - 'lib/inertia_rails/middleware.rb' + - 'lib/inertia_rails/rspec.rb' + - 'lib/inertia_rails/version.rb' + - 'lib/patches/better_errors.rb' + - 'lib/patches/debug_exceptions.rb' + - 'lib/patches/debug_exceptions/patch-5-0.rb' + - 'lib/patches/debug_exceptions/patch-5-1.rb' + - 'lib/patches/mapper.rb' + - 'lib/patches/request.rb' + - 'lib/tasks/inertia_rails.rake' + - 'spec/dummy/Rakefile' + - 'spec/dummy/app/controllers/application_controller.rb' + - 'spec/dummy/app/controllers/inertia_child_share_test_controller.rb' + - 'spec/dummy/app/controllers/inertia_conditional_sharing_controller.rb' + - 'spec/dummy/app/controllers/inertia_config_test_controller.rb' + - 'spec/dummy/app/controllers/inertia_lambda_shared_props_controller.rb' + - 'spec/dummy/app/controllers/inertia_merge_instance_props_controller.rb' + - 'spec/dummy/app/controllers/inertia_merge_shared_controller.rb' + - 'spec/dummy/app/controllers/inertia_multithreaded_share_controller.rb' + - 'spec/dummy/app/controllers/inertia_rails_mimic_controller.rb' + - 'spec/dummy/app/controllers/inertia_render_test_controller.rb' + - 'spec/dummy/app/controllers/inertia_responders_test_controller.rb' + - 'spec/dummy/app/controllers/inertia_session_continuity_test_controller.rb' + - 'spec/dummy/app/controllers/inertia_share_test_controller.rb' + - 'spec/dummy/app/controllers/inertia_test_controller.rb' + - 'spec/dummy/app/controllers/transformed_inertia_rails_mimic_controller.rb' + - 'spec/dummy/app/helpers/application_helper.rb' + - 'spec/dummy/bin/rails' + - 'spec/dummy/bin/rake' + - 'spec/dummy/bin/setup' + - 'spec/dummy/config.ru' + - 'spec/dummy/config/application.rb' + - 'spec/dummy/config/boot.rb' + - 'spec/dummy/config/environment.rb' + - 'spec/dummy/config/environments/development.rb' + - 'spec/dummy/config/environments/production.rb' + - 'spec/dummy/config/environments/test.rb' + - 'spec/dummy/config/initializers/application_controller_renderer.rb' + - 'spec/dummy/config/initializers/backtrace_silencers.rb' + - 'spec/dummy/config/initializers/content_security_policy.rb' + - 'spec/dummy/config/initializers/cookies_serializer.rb' + - 'spec/dummy/config/initializers/filter_parameter_logging.rb' + - 'spec/dummy/config/initializers/inflections.rb' + - 'spec/dummy/config/initializers/mime_types.rb' + - 'spec/dummy/config/initializers/wrap_parameters.rb' + - 'spec/dummy/config/puma.rb' + - 'spec/dummy/config/routes.rb' + - 'spec/dummy/config/spring.rb' + - 'spec/inertia/action_filter_spec.rb' + - 'spec/inertia/always_prop_spec.rb' + - 'spec/inertia/base_prop_spec.rb' + - 'spec/inertia/conditional_sharing_spec.rb' + - 'spec/inertia/configuration_spec.rb' + - 'spec/inertia/error_sharing_spec.rb' + - 'spec/inertia/lazy_prop_spec.rb' + - 'spec/inertia/middleware_spec.rb' + - 'spec/inertia/rails_mimic_spec.rb' + - 'spec/inertia/rendering_spec.rb' + - 'spec/inertia/request_spec.rb' + - 'spec/inertia/response_spec.rb' + - 'spec/inertia/rspec_helper_spec.rb' + - 'spec/inertia/sharing_spec.rb' + - 'spec/inertia/ssr_spec.rb' + - 'spec/rails_helper.rb' + - 'spec/spec_helper.rb' + - 'spec/support/helper_module.rb' + - 'spec/support/shared_examples.rb' + +# Offense count: 1 +# This cop supports unsafe autocorrection (--autocorrect-all). +Style/GlobalStdStream: + Exclude: + - 'spec/dummy/config/environments/production.rb' + +# Offense count: 2 +# Configuration parameters: AllowedVariables. +Style/GlobalVars: + Exclude: + - 'spec/inertia/rspec_helper_spec.rb' + +# Offense count: 1 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: MinBodyLength, AllowConsecutiveConditionals. +Style/GuardClause: + Exclude: + - 'lib/inertia_rails/configuration.rb' + +# Offense count: 1 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: EnforcedStyle, EnforcedShorthandSyntax, UseHashRocketsWithSymbolValues, PreferHashRocketsForNonAlnumEndingSymbols. +# SupportedStyles: ruby19, hash_rockets, no_mixed_keys, ruby19_no_mixed_keys +# SupportedShorthandSyntax: always, never, either, consistent, either_consistent +Style/HashSyntax: + Exclude: + - 'lib/tasks/inertia_rails.rake' + +# Offense count: 3 +# This cop supports safe autocorrection (--autocorrect). +Style/IfUnlessModifier: + Exclude: + - 'lib/inertia_rails/configuration.rb' + - 'lib/inertia_rails/controller.rb' + - 'spec/dummy/config/environments/test.rb' + +# Offense count: 2 +# This cop supports safe autocorrection (--autocorrect). +Style/IfUnlessModifierOfIfUnless: + Exclude: + - 'lib/inertia_rails/controller.rb' + +# Offense count: 1 +# This cop supports safe autocorrection (--autocorrect). +Style/KeywordArgumentsMerging: + Exclude: + - 'lib/inertia_rails/configuration.rb' + +# Offense count: 2 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: EnforcedStyle. +# SupportedStyles: line_count_dependent, lambda, literal +Style/Lambda: + Exclude: + - 'spec/dummy/app/controllers/inertia_lambda_shared_props_controller.rb' + - 'spec/dummy/app/controllers/transformed_inertia_rails_mimic_controller.rb' + +# Offense count: 1 +# This cop supports unsafe autocorrection (--autocorrect-all). +Style/MapToSet: + Exclude: + - 'lib/inertia_rails/action_filter.rb' + +# Offense count: 1 +# This cop supports safe autocorrection (--autocorrect). +Style/MultilineIfModifier: + Exclude: + - 'lib/inertia_rails/configuration.rb' + +# Offense count: 1 +# This cop supports unsafe autocorrection (--autocorrect-all). +# Configuration parameters: EnforcedStyle. +# SupportedStyles: literals, strict +Style/MutableConstant: + Exclude: + - 'lib/inertia_rails/version.rb' + +# Offense count: 1 +# This cop supports safe autocorrection (--autocorrect). +Style/NegatedIfElseCondition: + Exclude: + - 'lib/inertia_rails/renderer.rb' + +# Offense count: 2 +# This cop supports safe autocorrection (--autocorrect). +Style/NestedModifier: + Exclude: + - 'lib/inertia_rails/controller.rb' + +# Offense count: 1 +Style/OpenStructUse: + Exclude: + - 'spec/inertia/ssr_spec.rb' + +# Offense count: 2 +# This cop supports safe autocorrection (--autocorrect). +Style/RedundantBegin: + Exclude: + - 'spec/inertia/rspec_helper_spec.rb' + +# Offense count: 5 +# This cop supports safe autocorrection (--autocorrect). +Style/RedundantConstantBase: + Exclude: + - 'lib/inertia_rails/rspec.rb' + - 'spec/dummy/config/environments/production.rb' + - 'spec/inertia/rspec_helper_spec.rb' + +# Offense count: 2 +# This cop supports unsafe autocorrection (--autocorrect-all). +# Configuration parameters: SafeForConstants. +Style/RedundantFetchBlock: + Exclude: + - 'spec/dummy/config/puma.rb' + +# Offense count: 1 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: AllowMultipleReturnValues. +Style/RedundantReturn: + Exclude: + - 'spec/dummy/app/controllers/inertia_session_continuity_test_controller.rb' + +# Offense count: 1 +# This cop supports safe autocorrection (--autocorrect). +Style/RescueModifier: + Exclude: + - 'lib/inertia_rails/renderer.rb' + +# Offense count: 1 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: AllowIfMethodIsEmpty. +Style/SingleLineMethods: + Exclude: + - 'spec/dummy/app/controllers/inertia_test_controller.rb' + +# Offense count: 2 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: AllowModifier. +Style/SoleNestedConditional: + Exclude: + - 'lib/inertia_rails/controller.rb' + +# Offense count: 90 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: EnforcedStyle, ConsistentQuotesInMultiline. +# SupportedStyles: single_quotes, double_quotes +Style/StringLiterals: + Exclude: + - 'bin/console' + - 'lib/inertia_rails/controller.rb' + - 'lib/inertia_rails/engine.rb' + - 'lib/inertia_rails/helper.rb' + - 'lib/inertia_rails/middleware.rb' + - 'lib/inertia_rails/renderer.rb' + - 'lib/inertia_rails/rspec.rb' + - 'lib/inertia_rails/version.rb' + - 'lib/patches/better_errors.rb' + - 'lib/patches/debug_exceptions/patch-5-0.rb' + - 'lib/patches/debug_exceptions/patch-5-1.rb' + - 'lib/tasks/inertia_rails.rake' + - 'spec/dummy/app/controllers/inertia_conditional_sharing_controller.rb' + - 'spec/dummy/app/controllers/inertia_config_test_controller.rb' + - 'spec/dummy/app/controllers/inertia_lambda_shared_props_controller.rb' + - 'spec/dummy/app/controllers/inertia_rails_mimic_controller.rb' + - 'spec/dummy/app/controllers/inertia_render_test_controller.rb' + - 'spec/dummy/config/application.rb' + - 'spec/dummy/config/environments/production.rb' + - 'spec/dummy/config/puma.rb' + - 'spec/dummy/config/routes.rb' + - 'spec/dummy/config/spring.rb' + - 'spec/inertia/conditional_sharing_spec.rb' + - 'spec/inertia/configuration_spec.rb' + - 'spec/inertia/rendering_spec.rb' + - 'spec/inertia/response_spec.rb' + - 'spec/inertia/rspec_helper_spec.rb' + - 'spec/rails_helper.rb' + - 'spec/spec_helper.rb' + +# Offense count: 1 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: EnforcedStyle. +# SupportedStyles: single_quotes, double_quotes +Style/StringLiteralsInInterpolation: + Exclude: + - 'lib/inertia_rails/renderer.rb' + +# Offense count: 2 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: . +# SupportedStyles: percent, brackets +Style/SymbolArray: + EnforcedStyle: percent + MinSize: 3 + +# Offense count: 11 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: EnforcedStyleForMultiline. +# SupportedStylesForMultiline: comma, consistent_comma, no_comma +Style/TrailingCommaInArguments: + Exclude: + - 'lib/inertia_rails.rb' + - 'lib/inertia_rails/renderer.rb' + - 'spec/dummy/app/controllers/inertia_config_test_controller.rb' + - 'spec/dummy/app/controllers/inertia_rails_mimic_controller.rb' + - 'spec/inertia/configuration_spec.rb' + - 'spec/inertia/rendering_spec.rb' + +# Offense count: 17 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: EnforcedStyleForMultiline. +# SupportedStylesForMultiline: comma, consistent_comma, no_comma +Style/TrailingCommaInHashLiteral: + Exclude: + - 'lib/inertia_rails/rspec.rb' + - 'spec/dummy/app/controllers/inertia_lambda_shared_props_controller.rb' + - 'spec/dummy/app/controllers/inertia_merge_instance_props_controller.rb' + - 'spec/dummy/app/controllers/inertia_merge_shared_controller.rb' + - 'spec/dummy/app/controllers/inertia_render_test_controller.rb' + - 'spec/dummy/config/environments/development.rb' + - 'spec/dummy/config/environments/test.rb' + - 'spec/inertia/response_spec.rb' + - 'spec/inertia/rspec_helper_spec.rb' + +# Offense count: 1 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: WordRegex. +# SupportedStyles: percent, brackets +Style/WordArray: + EnforcedStyle: percent + MinSize: 4 + +# Offense count: 16 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, AllowedPatterns. +# URISchemes: http, https +Layout/LineLength: + Max: 290 diff --git a/Gemfile b/Gemfile index d5cb00b8..e1b35728 100644 --- a/Gemfile +++ b/Gemfile @@ -1,15 +1,19 @@ -source "https://rubygems.org" +# frozen_string_literal: true -# Specify your gem's dependencies in inertia-rails.gemspec +source 'https://rubygems.org' + +# Specify your gem's dependencies in inertia_rails.gemspec gemspec -version = ENV["RAILS_VERSION"] || "7.2" -gem "rails", "~> #{version}.0" +version = ENV['RAILS_VERSION'] || '7.2' +gem 'rails', "~> #{version}.0" -gem "bundler", "~> 2.0" -gem "rake", "~> 13.0" -gem "rspec-rails", "~> 6.0" -gem "rails-controller-testing" -gem "sqlite3" -gem "responders" -gem "debug" +gem 'bundler', '~> 2.0' +gem 'debug' +gem 'generator_spec', '~> 0.10' +gem 'rails-controller-testing' +gem 'rake', '~> 13.0' +gem 'responders' +gem 'rspec-rails', '~> 6.0' +gem 'rubocop', '~> 1.21' +gem 'sqlite3' diff --git a/Rakefile b/Rakefile index b7e9ed54..49647511 100644 --- a/Rakefile +++ b/Rakefile @@ -1,6 +1,12 @@ -require "bundler/gem_tasks" -require "rspec/core/rake_task" +# frozen_string_literal: true + +require 'bundler/gem_tasks' +require 'rspec/core/rake_task' RSpec::Core::RakeTask.new(:spec) -task :default => :spec +require 'rubocop/rake_task' + +RuboCop::RakeTask.new + +task default: %i[spec rubocop] diff --git a/docs/guide/responses.md b/docs/guide/responses.md index c67d2d75..99e93154 100644 --- a/docs/guide/responses.md +++ b/docs/guide/responses.md @@ -125,7 +125,7 @@ You can then access this variable like a regular local variable. ## Rails generators -Gem `inertia_rails-contrib` provides a number of generators to help you get started with Inertia in your Rails application. You can generate controllers or use scaffolds to create a new resource with Inertia responses. +Inertia Rails provides a number of generators to help you get started with Inertia in your Rails application. You can generate controllers or use scaffolds to create a new resource with Inertia responses. ### Scaffold generator @@ -168,7 +168,7 @@ $ bin/rails generate inertia:scaffold Post title:string body:text #### Tailwind CSS integration -Gem `inertia_rails-contrib` tries to detect the presence of Tailwind CSS in the application and generate the templates accordingly. If you want to specify templates type, use the `--inertia-templates` option: +Inertia Rails tries to detect the presence of Tailwind CSS in the application and generate the templates accordingly. If you want to specify templates type, use the `--inertia-templates` option: - `inertia_templates` - default - `inertia_tw_templates` - Tailwind CSS @@ -213,10 +213,10 @@ export default function <%= @action.camelize %>() { You can find the default templates in the gem's source code: -- [Default controller generator templates](https://github.com/skryukov/inertia_rails-contrib/tree/main/lib/generators/inertia_templates/controller/templates) -- [Default scaffold generator templates](https://github.com/skryukov/inertia_rails-contrib/tree/main/lib/generators/inertia_templates/scaffold/templates) -- [Tailwind controller generator templates](https://github.com/skryukov/inertia_rails-contrib/tree/main/lib/generators/inertia_tw_templates/controller/templates) -- [Tailwind scaffold generator templates](https://github.com/skryukov/inertia_rails-contrib/tree/main/lib/generators/inertia_tw_templates/scaffold/templates) +- [Default controller generator templates](https://github.com/inertiajs/inertia-rails/tree/master/lib/generators/inertia_templates/controller/templates) +- [Default scaffold generator templates](https://github.com/inertiajs/inertia-rails/tree/master/lib/generators/inertia_templates/scaffold/templates) +- [Tailwind controller generator templates](https://github.com/inertiajs/inertia-rails/tree/master/lib/generators/inertia_tw_templates/controller/templates) +- [Tailwind scaffold generator templates](https://github.com/inertiajs/inertia-rails/tree/master/lib/generators/inertia_tw_templates/scaffold/templates) > [!TIP] > You can also replace the whole generator with your own implementation. See the [Rails documentation](https://guides.rubyonrails.org/generators.html#overriding-rails-generators) for more information. diff --git a/docs/guide/server-side-setup.md b/docs/guide/server-side-setup.md index b29c35b7..7351c6ef 100644 --- a/docs/guide/server-side-setup.md +++ b/docs/guide/server-side-setup.md @@ -15,12 +15,11 @@ bundle add inertia_rails ## Rails generator -If you plan to use Vite as your frontend build tool, you can use the `inertia_rails-contrib` gem to install and set 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. +If you plan to use Vite as your frontend build tool, you can use the built-in generator to install and set 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. To install and setup Inertia in a Rails application, execute the following command in the terminal: ```bash -bundle add inertia_rails-contrib bin/rails generate inertia:install ``` @@ -38,7 +37,7 @@ This command will: > To use TypeScript with Svelte, you need to install `@inertiajs/svelte` version `1.3.0-beta.2` or higher. You can use the `--inertia-version` option to specify the version. > [!NOTE] -> The `inertia_rails-contrib` gem doesn't include [Rails scaffold generators](/guide/responses#rails-generators) for TypeScript yet. +> The built-in generator doesn't include [Rails scaffold generators](/guide/responses#rails-generators) for TypeScript yet. Example output: diff --git a/inertia_rails.gemspec b/inertia_rails.gemspec index cb63ade9..5277b65a 100644 --- a/inertia_rails.gemspec +++ b/inertia_rails.gemspec @@ -1,29 +1,32 @@ # frozen_string_literal: true -require_relative "lib/inertia_rails/version" +require_relative 'lib/inertia_rails/version' Gem::Specification.new do |spec| - spec.name = "inertia_rails" + spec.name = 'inertia_rails' spec.version = InertiaRails::VERSION - spec.authors = ["Brian Knoles", "Brandon Shar", "Eugene Granovsky"] - spec.email = ["brian@bellawatt.com", "brandon@bellawatt.com", "eugene@bellawatt.com"] + spec.authors = ['Brian Knoles', 'Brandon Shar', 'Eugene Granovsky'] + spec.email = ['brian@bellawatt.com', 'brandon@bellawatt.com', 'eugene@bellawatt.com'] - spec.summary = "Inertia.js adapter for Rails" - spec.description = "Quickly build modern single-page React, Vue and Svelte apps using classic server-side routing and controllers." - spec.homepage = "https://github.com/inertiajs/inertia-rails" - spec.license = "MIT" + spec.summary = 'Inertia.js adapter for Rails' + spec.description = 'Quickly build modern single-page React, Vue and Svelte apps ' \ + 'using classic server-side routing and controllers.' + spec.homepage = 'https://github.com/inertiajs/inertia-rails' + spec.license = 'MIT' + + spec.required_ruby_version = '>= 3.0' spec.metadata = { - "bug_tracker_uri" => "#{spec.homepage}/issues", - "changelog_uri" => "#{spec.homepage}/blob/master/CHANGELOG.md", - "documentation_uri" => "#{spec.homepage}/blob/master/README.md", - "homepage_uri" => spec.homepage, - "source_code_uri" => spec.homepage, - "rubygems_mfa_required" => "true" + 'bug_tracker_uri' => "#{spec.homepage}/issues", + 'changelog_uri' => "#{spec.homepage}/blob/master/CHANGELOG.md", + 'documentation_uri' => "#{spec.homepage}/blob/master/README.md", + 'homepage_uri' => spec.homepage, + 'source_code_uri' => spec.homepage, + 'rubygems_mfa_required' => 'true', } - spec.files = Dir["{app,lib}/**/*", "CHANGELOG.md", "LICENSE.txt", "README.md"] - spec.require_paths = ["lib"] + spec.files = Dir['{app,lib}/**/*', 'CHANGELOG.md', 'LICENSE.txt', 'README.md'] + spec.require_paths = ['lib'] - spec.add_runtime_dependency "railties", '>= 6' + spec.add_dependency 'railties', '>= 6' end diff --git a/lib/generators/inertia/controller/controller_generator.rb b/lib/generators/inertia/controller/controller_generator.rb new file mode 100644 index 00000000..9356b2a5 --- /dev/null +++ b/lib/generators/inertia/controller/controller_generator.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +require 'rails/generators/rails/controller/controller_generator' +require 'inertia_rails/generators/helper' + +module Inertia + module Generators + class ControllerGenerator < Rails::Generators::ControllerGenerator + include InertiaRails::Generators::Helper + + source_root File.expand_path('./templates', __dir__) + + remove_hook_for :template_engine + + hook_for :inertia_templates, required: true, default: InertiaRails::Generators::Helper.guess_inertia_template + end + end +end diff --git a/lib/generators/inertia/controller/templates/controller.rb.tt b/lib/generators/inertia/controller/templates/controller.rb.tt new file mode 100644 index 00000000..53eb0eb4 --- /dev/null +++ b/lib/generators/inertia/controller/templates/controller.rb.tt @@ -0,0 +1,10 @@ +<% module_namespacing do -%> +class <%= class_name %>Controller < <%= parent_class_name.classify %> +<% actions.each do |action| -%> + def <%= action %> + render inertia: '<%= "#{inertia_base_path}/#{action.camelize}" %>' + end +<%= "\n" unless action == actions.last -%> +<% end -%> +end +<% end -%> diff --git a/lib/generators/inertia/install/frameworks.yml b/lib/generators/inertia/install/frameworks.yml new file mode 100644 index 00000000..6a11dc64 --- /dev/null +++ b/lib/generators/inertia/install/frameworks.yml @@ -0,0 +1,98 @@ +react: + inertia_package: "@inertiajs/react" + packages: + - "@vitejs/plugin-react" + - "react" + - "react-dom" + packages_ts: + - "@types/react" + - "@types/react-dom" + - "typescript" + vite_plugin_import: "import react from '@vitejs/plugin-react'" + vite_plugin_call: "react()" + copy_files_ts: + "InertiaExample.tsx": "%{js_destination_path}/pages/InertiaExample.tsx" + "tsconfig.json": "tsconfig.json" + "tsconfig.app.json": "tsconfig.app.json" + "tsconfig.node.json": "tsconfig.node.json" + "vite-env.d.ts": "%{js_destination_path}/vite-env.d.ts" + copy_files_js: + "InertiaExample.jsx": "%{js_destination_path}/pages/InertiaExample.jsx" + copy_files: + "InertiaExample.module.css": "%{js_destination_path}/pages/InertiaExample.module.css" + "../assets/react.svg": "%{js_destination_path}/assets/react.svg" + "../assets/inertia.svg": "%{js_destination_path}/assets/inertia.svg" + "../assets/vite_ruby.svg": "%{js_destination_path}/assets/vite_ruby.svg" + +vue: + inertia_package: "@inertiajs/vue3" + packages: + - "vue" + - "@vitejs/plugin-vue" + packages_ts: + - "typescript" + - "vue-tsc" + vite_plugin_import: "import vue from '@vitejs/plugin-vue'" + vite_plugin_call: "vue()" + copy_files: + "../assets/vue.svg": "%{js_destination_path}/assets/vue.svg" + "../assets/inertia.svg": "%{js_destination_path}/assets/inertia.svg" + "../assets/vite_ruby.svg": "%{js_destination_path}/assets/vite_ruby.svg" + copy_files_ts: + "InertiaExample.ts.vue": "%{js_destination_path}/pages/InertiaExample.vue" + "tsconfig.json": "tsconfig.json" + "tsconfig.app.json": "tsconfig.app.json" + "tsconfig.node.json": "tsconfig.node.json" + "vite-env.d.ts": "%{js_destination_path}/vite-env.d.ts" + copy_files_js: + "InertiaExample.vue": "%{js_destination_path}/pages/InertiaExample.vue" + +svelte4: + inertia_package: "@inertiajs/svelte" + packages: + - "svelte@4" + - "@sveltejs/vite-plugin-svelte@3" + packages_ts: + - "@tsconfig/svelte@4" + - "svelte-check" + - "typescript" + - "tslib" + vite_plugin_import: "import { svelte } from '@sveltejs/vite-plugin-svelte'" + vite_plugin_call: "svelte()" + copy_files_ts: + "InertiaExample.ts.svelte": "%{js_destination_path}/pages/InertiaExample.svelte" + "tsconfig.json": "tsconfig.json" + "tsconfig.node.json": "tsconfig.node.json" + "vite-env.d.ts": "%{js_destination_path}/vite-env.d.ts" + copy_files_js: + "InertiaExample.svelte": "%{js_destination_path}/pages/InertiaExample.svelte" + copy_files: + "svelte.config.js": "svelte.config.js" + "../assets/svelte.svg": "%{js_destination_path}/assets/svelte.svg" + "../assets/inertia.svg": "%{js_destination_path}/assets/inertia.svg" + "../assets/vite_ruby.svg": "%{js_destination_path}/assets/vite_ruby.svg" + +svelte: + inertia_package: "@inertiajs/svelte" + packages: + - "svelte@5" + - "@sveltejs/vite-plugin-svelte@4" + packages_ts: + - "@tsconfig/svelte@5" + - "svelte-check" + - "typescript" + - "tslib" + vite_plugin_import: "import { svelte } from '@sveltejs/vite-plugin-svelte'" + vite_plugin_call: "svelte()" + copy_files_ts: + "InertiaExample.ts.svelte": "%{js_destination_path}/pages/InertiaExample.svelte" + "tsconfig.json": "tsconfig.json" + "tsconfig.node.json": "tsconfig.node.json" + "vite-env.d.ts": "%{js_destination_path}/vite-env.d.ts" + copy_files_js: + "InertiaExample.svelte": "%{js_destination_path}/pages/InertiaExample.svelte" + copy_files: + "svelte.config.js": "svelte.config.js" + "../assets/svelte.svg": "%{js_destination_path}/assets/svelte.svg" + "../assets/inertia.svg": "%{js_destination_path}/assets/inertia.svg" + "../assets/vite_ruby.svg": "%{js_destination_path}/assets/vite_ruby.svg" diff --git a/lib/generators/inertia/install/helpers.rb b/lib/generators/inertia/install/helpers.rb new file mode 100644 index 00000000..f21f2e57 --- /dev/null +++ b/lib/generators/inertia/install/helpers.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true + +module Inertia + module Generators + module Helpers + ### FS Helpers + def js_destination_path + return ViteRuby.config.source_code_dir if defined?(ViteRuby) + + if file?('config/vite.json') + source_code_dir = JSON.parse(File.read(file_path('config/vite.json'))).dig('all', 'sourceCodeDir') + return source_code_dir if source_code_dir + end + + 'app/frontend' + end + + def js_destination_root + file_path(js_destination_path) + end + + def js_file_path(*relative_path) + File.join(js_destination_root, *relative_path) + end + + def file?(*relative_path) + File.file?(file_path(*relative_path)) + end + + def file_path(*relative_path) + File.join(destination_root, *relative_path) + end + + # Interactivity Helpers + def ask(*) + unless options[:interactive] + say_error 'Specify all options when running the generator non-interactively.', :red + exit(1) + end + + super + end + + def yes?(*) + return false unless options[:interactive] + + super + end + end + end +end diff --git a/lib/generators/inertia/install/install_generator.rb b/lib/generators/inertia/install/install_generator.rb new file mode 100644 index 00000000..5a1a0c90 --- /dev/null +++ b/lib/generators/inertia/install/install_generator.rb @@ -0,0 +1,286 @@ +# frozen_string_literal: true + +require 'yaml' +require 'rails/generators' +require 'rails/generators/base' + +require_relative 'helpers' +require_relative 'js_package_manager' + +module Inertia + module Generators + class InstallGenerator < Rails::Generators::Base + include Helpers + + FRAMEWORKS = YAML.load_file(File.expand_path('./frameworks.yml', __dir__)) + + source_root File.expand_path('./templates', __dir__) + + class_option :framework, type: :string, + desc: 'The framework you want to use with Inertia', + enum: FRAMEWORKS.keys, + default: nil + + class_option :inertia_version, type: :string, default: 'latest', + desc: 'The version of Inertia.js to install' + + class_option :typescript, type: :boolean, default: false, + desc: 'Whether to use TypeScript' + + class_option :package_manager, type: :string, default: nil, + enum: JSPackageManager.package_managers, + desc: "The package manager you want to use to install Inertia's npm packages" + + class_option :interactive, type: :boolean, default: true, + desc: 'Whether to prompt for optional installations' + + class_option :install_tailwind, type: :boolean, default: false, + desc: 'Whether to install Tailwind CSS' + class_option :install_vite, type: :boolean, default: false, + desc: 'Whether to install Vite Ruby' + class_option :example_page, type: :boolean, default: true, + desc: 'Whether to add an example Inertia page' + + class_option :verbose, type: :boolean, default: false, + desc: 'Run the generator in verbose mode' + + remove_class_option :skip_namespace, :skip_collision_check + + def install + say "Installing Inertia's Rails adapter" + + if inertia_resolved_version.version == '0' + say_error "Could not find the Inertia.js package version #{options[:inertia_version]}.", :red + exit(false) + end + + install_vite unless ruby_vite_installed? + + install_typescript if typescript? + + install_tailwind if install_tailwind? + + install_inertia + + install_example_page if options[:example_page] + + say 'Copying bin/dev' + copy_file "#{__dir__}/templates/dev", 'bin/dev' + chmod 'bin/dev', 0o755, verbose: verbose? + + say "Inertia's Rails adapter successfully installed", :green + end + + private + + def install_inertia + say "Adding Inertia's Rails adapter initializer" + template 'initializer.rb', file_path('config/initializers/inertia_rails.rb') + + say 'Installing Inertia npm packages' + add_dependencies(*FRAMEWORKS[framework]['packages']) + add_dependencies(inertia_package) + + unless File.read(vite_config_path).include?(FRAMEWORKS[framework]['vite_plugin_import']) + say "Adding Vite plugin for #{framework}" + insert_into_file vite_config_path, "\n #{FRAMEWORKS[framework]['vite_plugin_call']},", after: 'plugins: [' + prepend_file vite_config_path, "#{FRAMEWORKS[framework]['vite_plugin_import']}\n" + end + + say "Copying #{inertia_entrypoint} entrypoint" + template "#{framework}/#{inertia_entrypoint}", js_file_path("entrypoints/#{inertia_entrypoint}") + + if application_layout.exist? + say "Adding #{inertia_entrypoint} script tag to the application layout" + headers = <<-ERB + <%= #{vite_tag} "inertia" %> + <%= inertia_headers %> + ERB + insert_into_file application_layout.to_s, headers, after: "<%= vite_client_tag %>\n" + + if framework == 'react' && !application_layout.read.include?('vite_react_refresh_tag') + say 'Adding Vite React Refresh tag to the application layout' + insert_into_file application_layout.to_s, "<%= vite_react_refresh_tag %>\n ", + before: '<%= vite_client_tag %>' + end + + gsub_file application_layout.to_s, //, '<title inertia>' unless svelte? + else + say_error 'Could not find the application layout file. Please add the following tags manually:', :red + say_error '- <title>...' + say_error '+ ...' + say_error '+ <%= inertia_headers %>' + say_error '+ <%= vite_react_refresh_tag %>' if framework == 'react' + say_error "+ <%= #{vite_tag} \"inertia\" %>" + end + end + + def install_typescript + say 'Adding TypeScript support' + if svelte? && inertia_resolved_version.release < Gem::Version.new('1.3.0') + say 'WARNING: @inertiajs/svelte < 1.3.0 does not support TypeScript ' \ + "(resolved version: #{inertia_resolved_version}).", + :yellow + say 'Skipping TypeScript support for @inertiajs/svelte', :yellow + @typescript = false + return + end + + add_dependencies(*FRAMEWORKS[framework]['packages_ts']) + end + + def install_example_page + say 'Copying example Inertia controller' + template 'controller.rb', file_path('app/controllers/inertia_example_controller.rb') + + say 'Adding a route for the example Inertia controller' + route "get 'inertia-example', to: 'inertia_example#index'" + + say 'Copying page assets' + copy_files = FRAMEWORKS[framework]['copy_files'].merge( + FRAMEWORKS[framework]["copy_files_#{typescript? ? 'ts' : 'js'}"] + ) + copy_files.each do |source, destination| + template "#{framework}/#{source}", file_path(format(destination, js_destination_path: js_destination_path)) + end + end + + def install_tailwind + say 'Installing Tailwind CSS' + add_dependencies(%w[tailwindcss postcss autoprefixer @tailwindcss/forms @tailwindcss/typography + @tailwindcss/container-queries]) + + template 'tailwind/tailwind.config.js', file_path('tailwind.config.js') + copy_file 'tailwind/postcss.config.js', file_path('postcss.config.js') + copy_file 'tailwind/application.css', js_file_path('entrypoints/application.css') + + if application_layout.exist? + say 'Adding Tailwind CSS to the application layout' + insert_into_file application_layout.to_s, "<%= vite_stylesheet_tag \"application\" %>\n ", + before: '<%= vite_client_tag %>' + else + say_error 'Could not find the application layout file. Please add the following tags manually:', :red + say_error '+ <%= vite_stylesheet_tag "application" %>' if install_tailwind? + end + end + + def install_vite + unless install_vite? + say_error 'This generator only supports Ruby on Rails with Vite.', :red + exit(false) + end + + in_root do + Bundler.with_original_env do + if (capture = run('bundle add vite_rails', capture: !verbose?)) + say 'Vite Rails gem successfully installed', :green + else + say capture + say_error 'Failed to install Vite Rails gem', :red + exit(false) + end + if (capture = run('bundle exec vite install', capture: !verbose?)) + say 'Vite Rails successfully installed', :green + else + say capture + say_error 'Failed to install Vite Rails', :red + exit(false) + end + end + end + end + + def ruby_vite_installed? + return true if package_manager.present? && ruby_vite? + + if !package_manager.present? + say_status 'Could not find a package.json file to install Inertia to.', nil + elsif gem_installed?('webpacker') || gem_installed?('shakapacker') + say 'Webpacker or Shakapacker is installed.', :yellow + say 'Vite Ruby can work alongside Webpacker or Shakapacker, but it might cause issues.', :yellow + say 'Please see the Vite Ruby documentation for the migration guide:', :yellow + say 'https://vite-ruby.netlify.app/guide/migration.html#webpacker-%F0%9F%93%A6', :yellow + else + say_status 'Could not find a Vite configuration files ' \ + '(`config/vite.json` & `vite.config.{ts,js,mjs,cjs,mts,cts}`).', + nil + end + false + end + + def gem_installed?(name) + regex = /^[^#]*gem\s+['"]#{name}['"]/ + File.read(file_path('Gemfile')).match?(regex) + end + + def application_layout + @application_layout ||= Pathname.new(file_path('app/views/layouts/application.html.erb')) + end + + def ruby_vite? + file?('config/vite.json') && vite_config_path + end + + def package_manager + @package_manager ||= JSPackageManager.new(self) + end + + def add_dependencies(*packages) + package_manager.add_dependencies(*packages) + end + + def vite_config_path + @vite_config_path ||= Dir.glob(file_path('vite.config.{ts,js,mjs,cjs,mts,cts}')).first + end + + def install_vite? + return @install_vite if defined?(@install_vite) + + @install_vite = options[:install_vite] || yes?('Would you like to install Vite Ruby? (y/n)', :green) + end + + def install_tailwind? + return @install_tailwind if defined?(@install_tailwind) + + @install_tailwind = options[:install_tailwind] || yes?('Would you like to install Tailwind CSS? (y/n)', :green) + end + + def typescript? + return @typescript if defined?(@typescript) + + @typescript = options[:typescript] || yes?('Would you like to use TypeScript? (y/n)', :green) + end + + def inertia_entrypoint + "inertia.#{typescript? ? 'ts' : 'js'}" + end + + def vite_tag + typescript? ? 'vite_typescript_tag' : 'vite_javascript_tag' + end + + def inertia_resolved_version + @inertia_resolved_version ||= Gem::Version.new( + `npm show @inertiajs/core@#{options[:inertia_version]} version`.strip + ) + end + + def verbose? + options[:verbose] + end + + def svelte? + framework.start_with? 'svelte' + end + + def inertia_package + "#{FRAMEWORKS[framework]['inertia_package']}@#{options[:inertia_version]}" + end + + def framework + @framework ||= options[:framework] || ask('What framework do you want to use with Inertia?', :green, + limited_to: FRAMEWORKS.keys, default: 'react') + end + end + end +end diff --git a/lib/generators/inertia/install/js_package_manager.rb b/lib/generators/inertia/install/js_package_manager.rb new file mode 100644 index 00000000..24b0f1a6 --- /dev/null +++ b/lib/generators/inertia/install/js_package_manager.rb @@ -0,0 +1,50 @@ +# frozen_string_literal: true + +module Inertia + module Generators + class JSPackageManager + def self.package_managers + %w[npm yarn bun pnpm] + end + + def initialize(generator) + @generator = generator + end + + def present? + package_manager.present? + end + + def add_dependencies(*dependencies) + options = @generator.options[:verbose] ? '' : ' --silent' + @generator.in_root do + @generator.run "#{package_manager} add #{dependencies.join(' ')}#{options}" + end + end + + private + + def package_manager + @package_manager ||= @generator.options[:package_manager] || detect_package_manager + end + + def detect_package_manager + return nil unless file?('package.json') + + if file?('package-lock.json') + 'npm' + elsif file?('bun.lockb') + 'bun' + elsif file?('pnpm-lock.yaml') + 'pnpm' + else + 'yarn' + end + end + + def file?(*relative_path) + @generator.file?(*relative_path) + end + end + end +end diff --git a/lib/generators/inertia/install/templates/assets/inertia.svg b/lib/generators/inertia/install/templates/assets/inertia.svg new file mode 100644 index 00000000..61ec585c --- /dev/null +++ b/lib/generators/inertia/install/templates/assets/inertia.svg @@ -0,0 +1 @@ + diff --git a/lib/generators/inertia/install/templates/assets/react.svg b/lib/generators/inertia/install/templates/assets/react.svg new file mode 100644 index 00000000..ae3e3f22 --- /dev/null +++ b/lib/generators/inertia/install/templates/assets/react.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/lib/generators/inertia/install/templates/assets/svelte.svg b/lib/generators/inertia/install/templates/assets/svelte.svg new file mode 100644 index 00000000..dc9a29c1 --- /dev/null +++ b/lib/generators/inertia/install/templates/assets/svelte.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/lib/generators/inertia/install/templates/assets/vite_ruby.svg b/lib/generators/inertia/install/templates/assets/vite_ruby.svg new file mode 100644 index 00000000..c4d42701 --- /dev/null +++ b/lib/generators/inertia/install/templates/assets/vite_ruby.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/lib/generators/inertia/install/templates/assets/vue.svg b/lib/generators/inertia/install/templates/assets/vue.svg new file mode 100644 index 00000000..36a27ab2 --- /dev/null +++ b/lib/generators/inertia/install/templates/assets/vue.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/lib/generators/inertia_rails/install/controller.rb b/lib/generators/inertia/install/templates/controller.rb similarity index 64% rename from lib/generators/inertia_rails/install/controller.rb rename to lib/generators/inertia/install/templates/controller.rb index 57d8d638..0c95ffe9 100644 --- a/lib/generators/inertia_rails/install/controller.rb +++ b/lib/generators/inertia/install/templates/controller.rb @@ -1,7 +1,9 @@ +# frozen_string_literal: true + class InertiaExampleController < ApplicationController def index render inertia: 'InertiaExample', props: { - name: 'World', + name: params.fetch(:name, 'World'), } end end diff --git a/lib/generators/inertia/install/templates/dev b/lib/generators/inertia/install/templates/dev new file mode 100644 index 00000000..ef33f02c --- /dev/null +++ b/lib/generators/inertia/install/templates/dev @@ -0,0 +1,23 @@ +#!/usr/bin/env sh + +export PORT="${PORT:-3000}" + +if command -v overmind 1> /dev/null 2>&1 +then + overmind start -f Procfile.dev "$@" + exit $? +fi + +if command -v hivemind 1> /dev/null 2>&1 +then + echo "Hivemind is installed. Running the application with Hivemind..." + exec hivemind Procfile.dev "$@" + exit $? +fi + +if gem list --no-installed --exact --silent foreman; then + echo "Installing foreman..." + gem install foreman +fi + +foreman start -f Procfile.dev "$@" diff --git a/lib/generators/inertia/install/templates/initializer.rb b/lib/generators/inertia/install/templates/initializer.rb new file mode 100644 index 00000000..4e3b52e5 --- /dev/null +++ b/lib/generators/inertia/install/templates/initializer.rb @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +InertiaRails.configure do |config| + config.ssr_enabled = ViteRuby.config.ssr_build_enabled + config.version = ViteRuby.digest +end diff --git a/lib/generators/inertia/install/templates/react/InertiaExample.jsx b/lib/generators/inertia/install/templates/react/InertiaExample.jsx new file mode 100644 index 00000000..f159ccf2 --- /dev/null +++ b/lib/generators/inertia/install/templates/react/InertiaExample.jsx @@ -0,0 +1,60 @@ +import { Head } from '@inertiajs/react' +import { useState } from 'react' + +import reactSvg from '/assets/react.svg' +import inertiaSvg from '/assets/inertia.svg' +import viteRubySvg from '/assets/vite_ruby.svg' + +import cs from './InertiaExample.module.css' + +export default function InertiaExample({ name }) { + const [count, setCount] = useState(0) + + return ( + <> + + +
+

Hello {name}!

+ +
+ + Inertia logo + + + Vite Ruby logo + + + React logo + +
+ +

Inertia + Vite Ruby + React

+ +
+ +

+ Edit app/frontend/pages/InertiaExample.jsx and save to + test HMR +

+
+

+ Click on the Inertia, Vite Ruby, and React logos to learn more +

+
+ + ) +} diff --git a/lib/generators/inertia/install/templates/react/InertiaExample.module.css b/lib/generators/inertia/install/templates/react/InertiaExample.module.css new file mode 100644 index 00000000..dea73ca3 --- /dev/null +++ b/lib/generators/inertia/install/templates/react/InertiaExample.module.css @@ -0,0 +1,80 @@ +.root { + font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; + line-height: 1.5; + font-weight: 400; + color: #213547; + background-color: #ffffff; + max-width: 1280px; + margin: 0 auto; + padding: 2rem; + text-align: center; +} + +.h1 { + font-size: 3.2em; + line-height: 1.1; +} + +.h2 { + font-size: 2.6em; + line-height: 1.1; +} + +.button { + border-radius: 8px; + border: 1px solid transparent; + padding: 0.6em 1.2em; + font-size: 1em; + font-weight: 500; + font-family: inherit; + background-color: #f9f9f9; + cursor: pointer; + transition: border-color 0.25s; +} +.button:hover { + border-color: #646cff; +} +.button:focus, +.button:focus-visible { + outline: 4px auto -webkit-focus-ring-color; +} + +.logo { + display: inline-block; + height: 6em; + padding: 1.5em; + will-change: filter; + transition: filter 300ms; +} +.logo:hover { + filter: drop-shadow(0 0 2em #646cffaa); +} +.logo.vite:hover { + filter: drop-shadow(0 0 2em #e4023baa); +} +.logo.react:hover { + filter: drop-shadow(0 0 2em #61dafbaa); +} + +@keyframes logo-spin { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } +} + +@media (prefers-reduced-motion: no-preference) { + .logo.react { + animation: logo-spin infinite 20s linear; + } +} + +.card { + padding: 2em; +} + +.read-the-docs { + color: #888; +} diff --git a/lib/generators/inertia/install/templates/react/InertiaExample.tsx b/lib/generators/inertia/install/templates/react/InertiaExample.tsx new file mode 100644 index 00000000..8937b077 --- /dev/null +++ b/lib/generators/inertia/install/templates/react/InertiaExample.tsx @@ -0,0 +1,60 @@ +import { Head } from '@inertiajs/react' +import { useState } from 'react' + +import reactSvg from '/assets/react.svg' +import inertiaSvg from '/assets/inertia.svg' +import viteRubySvg from '/assets/vite_ruby.svg' + +import cs from './InertiaExample.module.css' + +export default function InertiaExample({ name }: { name: string }) { + const [count, setCount] = useState(0) + + return ( + <> + + +
+

Hello {name}!

+ +
+ + Inertia logo + + + Vite Ruby logo + + + React logo + +
+ +

Inertia + Vite Ruby + React

+ +
+ +

+ Edit app/frontend/pages/InertiaExample.jsx and save to + test HMR +

+
+

+ Click on the Inertia, Vite Ruby, and React logos to learn more +

+
+ + ) +} diff --git a/lib/generators/inertia/install/templates/react/inertia.js b/lib/generators/inertia/install/templates/react/inertia.js new file mode 100644 index 00000000..f00cad69 --- /dev/null +++ b/lib/generators/inertia/install/templates/react/inertia.js @@ -0,0 +1,34 @@ +import { createInertiaApp } from '@inertiajs/react' +import { createElement } from 'react' +import { createRoot } from 'react-dom/client' + +createInertiaApp({ + // Set default page title + // see https://inertia-rails.netlify.app/guide/title-and-meta + // + // title: title => title ? `${title} - App` : 'App', + + // Disable progress bar + // + // see https://inertia-rails.netlify.app/guide/progress-indicators + // progress: false, + + resolve: (name) => { + const pages = import.meta.glob('../pages/**/*.jsx', { eager: true }) + return pages[`../pages/${name}.jsx`] + + // To use a default layout, import the Layout component + // and use the following lines. + // see https://inertia-rails.netlify.app/guide/pages#default-layouts + // + // const page = pages[`../pages/${name}.jsx`] + // page.default.layout ||= (page) => createElement(Layout, null, page) + // return page + }, + + setup({ el, App, props }) { + const root = createRoot(el) + + root.render(createElement(App, props)) + }, +}) diff --git a/lib/generators/inertia/install/templates/react/inertia.ts b/lib/generators/inertia/install/templates/react/inertia.ts new file mode 100644 index 00000000..4ef3a280 --- /dev/null +++ b/lib/generators/inertia/install/templates/react/inertia.ts @@ -0,0 +1,36 @@ +import { createInertiaApp } from '@inertiajs/react' +import { createElement, ReactNode } from 'react' +import { createRoot } from 'react-dom/client' + +type ResolvedComponent = { default: ReactNode, layout?: (page: ReactNode) => ReactNode } + +createInertiaApp({ + // Set default page title + // see https://inertia-rails.netlify.app/guide/title-and-meta + // + // title: title => title ? `${title} - App` : 'App', + + // Disable progress bar + // + // see https://inertia-rails.netlify.app/guide/progress-indicators + // progress: false, + + resolve: (name) => { + const pages = import.meta.glob('../pages/**/*.tsx', { eager: true }) + return pages[`../pages/${name}.tsx`] + + // To use a default layout, import the Layout component + // and use the following lines. + // see https://inertia-rails.netlify.app/guide/pages#default-layouts + // + // const page = pages[`../pages/${name}.tsx`] + // page.default.layout ||= (page) => createElement(Layout, null, page) + // return page + }, + + setup({ el, App, props }) { + const root = createRoot(el) + + root.render(createElement(App, props)) + }, +}) diff --git a/lib/generators/inertia/install/templates/react/tsconfig.app.json b/lib/generators/inertia/install/templates/react/tsconfig.app.json new file mode 100644 index 00000000..ff1c5b10 --- /dev/null +++ b/lib/generators/inertia/install/templates/react/tsconfig.app.json @@ -0,0 +1,27 @@ +{ + "compilerOptions": { + "composite": true, + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", + "target": "ES2020", + "useDefineForClassFields": true, + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "module": "ESNext", + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "resolveJsonModule": true, + "isolatedModules": true, + "moduleDetection": "force", + "noEmit": true, + "jsx": "react-jsx", + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true, + }, + "include": ["<%= js_destination_path %>"] +} diff --git a/lib/generators/inertia/install/templates/react/tsconfig.json b/lib/generators/inertia/install/templates/react/tsconfig.json new file mode 100644 index 00000000..ea9d0cd8 --- /dev/null +++ b/lib/generators/inertia/install/templates/react/tsconfig.json @@ -0,0 +1,11 @@ +{ + "files": [], + "references": [ + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.node.json" + } + ] +} diff --git a/lib/generators/inertia/install/templates/react/tsconfig.node.json b/lib/generators/inertia/install/templates/react/tsconfig.node.json new file mode 100644 index 00000000..3afdd6e3 --- /dev/null +++ b/lib/generators/inertia/install/templates/react/tsconfig.node.json @@ -0,0 +1,13 @@ +{ + "compilerOptions": { + "composite": true, + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", + "skipLibCheck": true, + "module": "ESNext", + "moduleResolution": "bundler", + "allowSyntheticDefaultImports": true, + "strict": true, + "noEmit": true + }, + "include": ["vite.config.ts"] +} diff --git a/lib/generators/inertia/install/templates/react/vite-env.d.ts b/lib/generators/inertia/install/templates/react/vite-env.d.ts new file mode 100644 index 00000000..11f02fe2 --- /dev/null +++ b/lib/generators/inertia/install/templates/react/vite-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/lib/generators/inertia/install/templates/svelte/InertiaExample.svelte b/lib/generators/inertia/install/templates/svelte/InertiaExample.svelte new file mode 100644 index 00000000..4c6d2942 --- /dev/null +++ b/lib/generators/inertia/install/templates/svelte/InertiaExample.svelte @@ -0,0 +1,112 @@ + + + + Inertia + Vite Ruby + Svelte Example + + +
+

Hello {name}!

+ +
+ + + + + + + + + +
+ +

Inertia + Vite Ruby + Svelte

+ +
+ +

+ Edit app/frontend/pages/InertiaExample.svelte and save to test + HMR +

+
+

+ Click on the Inertia, Vite Ruby, and Svelte logos to learn more +

+
+ + diff --git a/lib/generators/inertia/install/templates/svelte/InertiaExample.ts.svelte b/lib/generators/inertia/install/templates/svelte/InertiaExample.ts.svelte new file mode 100644 index 00000000..0ed1c7df --- /dev/null +++ b/lib/generators/inertia/install/templates/svelte/InertiaExample.ts.svelte @@ -0,0 +1,112 @@ + + + + Inertia + Vite Ruby + Svelte Example + + +
+

Hello {name}!

+ +
+ + + + + + + + + +
+ +

Inertia + Vite Ruby + Svelte

+ +
+ +

+ Edit app/frontend/pages/InertiaExample.svelte and save to test + HMR +

+
+

+ Click on the Inertia, Vite Ruby, and Svelte logos to learn more +

+
+ + diff --git a/lib/generators/inertia/install/templates/svelte/inertia.js b/lib/generators/inertia/install/templates/svelte/inertia.js new file mode 100644 index 00000000..1ea6c22f --- /dev/null +++ b/lib/generators/inertia/install/templates/svelte/inertia.js @@ -0,0 +1,30 @@ +import { createInertiaApp } from '@inertiajs/svelte' +import { mount } from 'svelte'; + +createInertiaApp({ + // Set default page title + // see https://inertia-rails.netlify.app/guide/title-and-meta + // + // title: title => title ? `${title} - App` : 'App', + + // Disable progress bar + // + // see https://inertia-rails.netlify.app/guide/progress-indicators + // progress: false, + + resolve: (name) => { + const pages = import.meta.glob('../pages/**/*.svelte', { eager: true }) + return pages[`../pages/${name}.svelte`] + + // To use a default layout, import the Layout component + // and use the following lines. + // see https://inertia-rails.netlify.app/guide/pages#default-layouts + // + // const page = pages[`../pages/${name}.svelte`] + // return { default: page.default, layout: page.layout || Layout } + }, + + setup({ el, App, props }) { + mount(App, { target: el, props }) + }, +}) diff --git a/lib/generators/inertia/install/templates/svelte/inertia.ts b/lib/generators/inertia/install/templates/svelte/inertia.ts new file mode 100644 index 00000000..d6d55cd6 --- /dev/null +++ b/lib/generators/inertia/install/templates/svelte/inertia.ts @@ -0,0 +1,30 @@ +import { createInertiaApp, type ResolvedComponent } from '@inertiajs/svelte' +import { mount } from 'svelte' + +createInertiaApp({ + // Set default page title + // see https://inertia-rails.netlify.app/guide/title-and-meta + // + // title: title => title ? `${title} - App` : 'App', + + // Disable progress bar + // + // see https://inertia-rails.netlify.app/guide/progress-indicators + // progress: false, + + resolve: (name) => { + const pages = import.meta.glob('../pages/**/*.svelte', { eager: true }) + return pages[`../pages/${name}.svelte`] + + // To use a default layout, import the Layout component + // and use the following lines. + // see https://inertia-rails.netlify.app/guide/pages#default-layouts + // + // const page = pages[`../pages/${name}.svelte`] + // return { default: page.default, layout: page.layout || Layout } + }, + + setup({ el, App, props }) { + mount(App, { target: el, props }) + }, +}) diff --git a/lib/generators/inertia/install/templates/svelte/svelte.config.js b/lib/generators/inertia/install/templates/svelte/svelte.config.js new file mode 100644 index 00000000..b0683fd2 --- /dev/null +++ b/lib/generators/inertia/install/templates/svelte/svelte.config.js @@ -0,0 +1,7 @@ +import { vitePreprocess } from '@sveltejs/vite-plugin-svelte' + +export default { + // Consult https://svelte.dev/docs#compile-time-svelte-preprocess + // for more information about preprocessors + preprocess: vitePreprocess(), +} diff --git a/lib/generators/inertia/install/templates/svelte/tsconfig.json b/lib/generators/inertia/install/templates/svelte/tsconfig.json new file mode 100644 index 00000000..acbc1cdf --- /dev/null +++ b/lib/generators/inertia/install/templates/svelte/tsconfig.json @@ -0,0 +1,21 @@ +{ + "extends": "@tsconfig/svelte/tsconfig.json", + "compilerOptions": { + "target": "ESNext", + "useDefineForClassFields": true, + "module": "ESNext", + "resolveJsonModule": true, + /** + * Typecheck JS in `.svelte` and `.js` files by default. + * Disable checkJs if you'd like to use dynamic types in JS. + * Note that setting allowJs false does not prevent the use + * of JS in `.svelte` files. + */ + "allowJs": true, + "checkJs": true, + "isolatedModules": true, + "moduleDetection": "force", + }, + "include": ["<%= js_destination_path %>/**/*.ts", "<%= js_destination_path %>/**/*.js", "<%= js_destination_path %>/**/*.svelte"], + "references": [{ "path": "./tsconfig.node.json" }] +} diff --git a/lib/generators/inertia/install/templates/svelte/tsconfig.node.json b/lib/generators/inertia/install/templates/svelte/tsconfig.node.json new file mode 100644 index 00000000..3126cd74 --- /dev/null +++ b/lib/generators/inertia/install/templates/svelte/tsconfig.node.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "composite": true, + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", + "skipLibCheck": true, + "module": "ESNext", + "moduleResolution": "bundler", + "strict": true, + "noEmit": true, + }, + "include": ["vite.config.ts"] +} diff --git a/lib/generators/inertia/install/templates/svelte/vite-env.d.ts b/lib/generators/inertia/install/templates/svelte/vite-env.d.ts new file mode 100644 index 00000000..4078e747 --- /dev/null +++ b/lib/generators/inertia/install/templates/svelte/vite-env.d.ts @@ -0,0 +1,2 @@ +/// +/// diff --git a/lib/generators/inertia/install/templates/svelte4/InertiaExample.svelte b/lib/generators/inertia/install/templates/svelte4/InertiaExample.svelte new file mode 100644 index 00000000..96785fe5 --- /dev/null +++ b/lib/generators/inertia/install/templates/svelte4/InertiaExample.svelte @@ -0,0 +1,116 @@ + + + + Inertia + Vite Ruby + Svelte Example + + +
+

Hello {name}!

+ + + +

Inertia + Vite Ruby + Svelte

+ +
+ +

+ Edit app/frontend/pages/InertiaExample.svelte and save to test + HMR +

+
+

+ Click on the Inertia, Vite Ruby, and Svelte logos to learn more +

+
+ + diff --git a/lib/generators/inertia/install/templates/svelte4/InertiaExample.ts.svelte b/lib/generators/inertia/install/templates/svelte4/InertiaExample.ts.svelte new file mode 100644 index 00000000..b0d42e3a --- /dev/null +++ b/lib/generators/inertia/install/templates/svelte4/InertiaExample.ts.svelte @@ -0,0 +1,116 @@ + + + + Inertia + Vite Ruby + Svelte Example + + +
+

Hello {name}!

+ + + +

Inertia + Vite Ruby + Svelte

+ +
+ +

+ Edit app/frontend/pages/InertiaExample.svelte and save to test + HMR +

+
+

+ Click on the Inertia, Vite Ruby, and Svelte logos to learn more +

+
+ + diff --git a/lib/generators/inertia/install/templates/svelte4/inertia.js b/lib/generators/inertia/install/templates/svelte4/inertia.js new file mode 100644 index 00000000..7c288a6e --- /dev/null +++ b/lib/generators/inertia/install/templates/svelte4/inertia.js @@ -0,0 +1,29 @@ +import { createInertiaApp } from '@inertiajs/svelte' + +createInertiaApp({ + // Set default page title + // see https://inertia-rails.netlify.app/guide/title-and-meta + // + // title: title => title ? `${title} - App` : 'App', + + // Disable progress bar + // + // see https://inertia-rails.netlify.app/guide/progress-indicators + // progress: false, + + resolve: (name) => { + const pages = import.meta.glob('../pages/**/*.svelte', { eager: true }) + return pages[`../pages/${name}.svelte`] + + // To use a default layout, import the Layout component + // and use the following lines. + // see https://inertia-rails.netlify.app/guide/pages#default-layouts + // + // const page = pages[`../pages/${name}.svelte`] + // return { default: page.default, layout: page.layout || Layout } + }, + + setup({ el, App, props }) { + new App({ target: el, props }) + }, +}) diff --git a/lib/generators/inertia/install/templates/svelte4/inertia.ts b/lib/generators/inertia/install/templates/svelte4/inertia.ts new file mode 100644 index 00000000..a4a75495 --- /dev/null +++ b/lib/generators/inertia/install/templates/svelte4/inertia.ts @@ -0,0 +1,29 @@ +import { createInertiaApp, type ResolvedComponent } from '@inertiajs/svelte' + +createInertiaApp({ + // Set default page title + // see https://inertia-rails.netlify.app/guide/title-and-meta + // + // title: title => title ? `${title} - App` : 'App', + + // Disable progress bar + // + // see https://inertia-rails.netlify.app/guide/progress-indicators + // progress: false, + + resolve: (name) => { + const pages = import.meta.glob('../pages/**/*.svelte', { eager: true }) + return pages[`../pages/${name}.svelte`] + + // To use a default layout, import the Layout component + // and use the following lines. + // see https://inertia-rails.netlify.app/guide/pages#default-layouts + // + // const page = pages[`../pages/${name}.svelte`] + // return { default: page.default, layout: page.layout || Layout } + }, + + setup({ el, App, props }) { + new App({ target: el, props }) + }, +}) diff --git a/lib/generators/inertia/install/templates/svelte4/svelte.config.js b/lib/generators/inertia/install/templates/svelte4/svelte.config.js new file mode 100644 index 00000000..b0683fd2 --- /dev/null +++ b/lib/generators/inertia/install/templates/svelte4/svelte.config.js @@ -0,0 +1,7 @@ +import { vitePreprocess } from '@sveltejs/vite-plugin-svelte' + +export default { + // Consult https://svelte.dev/docs#compile-time-svelte-preprocess + // for more information about preprocessors + preprocess: vitePreprocess(), +} diff --git a/lib/generators/inertia/install/templates/svelte4/tsconfig.json b/lib/generators/inertia/install/templates/svelte4/tsconfig.json new file mode 100644 index 00000000..acbc1cdf --- /dev/null +++ b/lib/generators/inertia/install/templates/svelte4/tsconfig.json @@ -0,0 +1,21 @@ +{ + "extends": "@tsconfig/svelte/tsconfig.json", + "compilerOptions": { + "target": "ESNext", + "useDefineForClassFields": true, + "module": "ESNext", + "resolveJsonModule": true, + /** + * Typecheck JS in `.svelte` and `.js` files by default. + * Disable checkJs if you'd like to use dynamic types in JS. + * Note that setting allowJs false does not prevent the use + * of JS in `.svelte` files. + */ + "allowJs": true, + "checkJs": true, + "isolatedModules": true, + "moduleDetection": "force", + }, + "include": ["<%= js_destination_path %>/**/*.ts", "<%= js_destination_path %>/**/*.js", "<%= js_destination_path %>/**/*.svelte"], + "references": [{ "path": "./tsconfig.node.json" }] +} diff --git a/lib/generators/inertia/install/templates/svelte4/tsconfig.node.json b/lib/generators/inertia/install/templates/svelte4/tsconfig.node.json new file mode 100644 index 00000000..3126cd74 --- /dev/null +++ b/lib/generators/inertia/install/templates/svelte4/tsconfig.node.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "composite": true, + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", + "skipLibCheck": true, + "module": "ESNext", + "moduleResolution": "bundler", + "strict": true, + "noEmit": true, + }, + "include": ["vite.config.ts"] +} diff --git a/lib/generators/inertia/install/templates/svelte4/vite-env.d.ts b/lib/generators/inertia/install/templates/svelte4/vite-env.d.ts new file mode 100644 index 00000000..4078e747 --- /dev/null +++ b/lib/generators/inertia/install/templates/svelte4/vite-env.d.ts @@ -0,0 +1,2 @@ +/// +/// diff --git a/lib/generators/inertia/install/templates/tailwind/application.css b/lib/generators/inertia/install/templates/tailwind/application.css new file mode 100644 index 00000000..8666d2f3 --- /dev/null +++ b/lib/generators/inertia/install/templates/tailwind/application.css @@ -0,0 +1,13 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +/* + +@layer components { + .btn-primary { + @apply py-2 px-4 bg-blue-200; + } +} + +*/ diff --git a/lib/generators/inertia/install/templates/tailwind/postcss.config.js b/lib/generators/inertia/install/templates/tailwind/postcss.config.js new file mode 100644 index 00000000..2e7af2b7 --- /dev/null +++ b/lib/generators/inertia/install/templates/tailwind/postcss.config.js @@ -0,0 +1,6 @@ +export default { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, +} diff --git a/lib/generators/inertia/install/templates/tailwind/tailwind.config.js.tt b/lib/generators/inertia/install/templates/tailwind/tailwind.config.js.tt new file mode 100644 index 00000000..dae93715 --- /dev/null +++ b/lib/generators/inertia/install/templates/tailwind/tailwind.config.js.tt @@ -0,0 +1,18 @@ +/** @type {import('tailwindcss').Config} */ + +module.exports = { + content: [ + './public/*.html', + './app/helpers/**/*.rb', + './<%= js_destination_path %>/**/*.{js,ts,jsx,tsx,vue,svelte}', + './app/views/**/*.{erb,haml,html,slim}' + ], + theme: { + extend: {}, + }, + plugins: [ + require('@tailwindcss/forms'), + require('@tailwindcss/typography'), + require('@tailwindcss/container-queries'), + ] +} diff --git a/lib/generators/inertia/install/templates/vue/InertiaExample.ts.vue b/lib/generators/inertia/install/templates/vue/InertiaExample.ts.vue new file mode 100644 index 00000000..42392ac4 --- /dev/null +++ b/lib/generators/inertia/install/templates/vue/InertiaExample.ts.vue @@ -0,0 +1,117 @@ + + + + + diff --git a/lib/generators/inertia/install/templates/vue/InertiaExample.vue b/lib/generators/inertia/install/templates/vue/InertiaExample.vue new file mode 100644 index 00000000..06d00c5d --- /dev/null +++ b/lib/generators/inertia/install/templates/vue/InertiaExample.vue @@ -0,0 +1,117 @@ + + + + + diff --git a/lib/generators/inertia/install/templates/vue/inertia.js b/lib/generators/inertia/install/templates/vue/inertia.js new file mode 100644 index 00000000..5e72d481 --- /dev/null +++ b/lib/generators/inertia/install/templates/vue/inertia.js @@ -0,0 +1,33 @@ +import { createInertiaApp } from '@inertiajs/vue3' +import { createApp, h } from 'vue' + +createInertiaApp({ + // Set default page title + // see https://inertia-rails.netlify.app/guide/title-and-meta + // + // title: title => title ? `${title} - App` : 'App', + + // Disable progress bar + // + // see https://inertia-rails.netlify.app/guide/progress-indicators + // progress: false, + + resolve: (name) => { + const pages = import.meta.glob('../pages/**/*.vue', { eager: true }) + return pages[`../pages/${name}.vue`] + + // To use a default layout, import the Layout component + // and use the following lines. + // see https://inertia-rails.netlify.app/guide/pages#default-layouts + // + // const page = pages[`../pages/${name}.vue`] + // page.default.layout = page.default.layout || Layout + // return page + }, + + setup({ el, App, props, plugin }) { + createApp({ render: () => h(App, props) }) + .use(plugin) + .mount(el) + }, +}) diff --git a/lib/generators/inertia/install/templates/vue/inertia.ts b/lib/generators/inertia/install/templates/vue/inertia.ts new file mode 100644 index 00000000..b4c62d63 --- /dev/null +++ b/lib/generators/inertia/install/templates/vue/inertia.ts @@ -0,0 +1,33 @@ +import { createInertiaApp } from '@inertiajs/vue3' +import {createApp, DefineComponent, h} from 'vue' + +createInertiaApp({ + // Set default page title + // see https://inertia-rails.netlify.app/guide/title-and-meta + // + // title: title => title ? `${title} - App` : 'App', + + // Disable progress bar + // + // see https://inertia-rails.netlify.app/guide/progress-indicators + // progress: false, + + resolve: (name) => { + const pages = import.meta.glob('../pages/**/*.vue', { eager: true }) + return pages[`../pages/${name}.vue`] + + // To use a default layout, import the Layout component + // and use the following lines. + // see https://inertia-rails.netlify.app/guide/pages#default-layouts + // + // const page = pages[`../pages/${name}.vue`] + // page.default.layout = page.default.layout || Layout + // return page + }, + + setup({ el, App, props, plugin }) { + createApp({ render: () => h(App, props) }) + .use(plugin) + .mount(el) + }, +}) diff --git a/lib/generators/inertia/install/templates/vue/tsconfig.app.json b/lib/generators/inertia/install/templates/vue/tsconfig.app.json new file mode 100644 index 00000000..dc7d6ca1 --- /dev/null +++ b/lib/generators/inertia/install/templates/vue/tsconfig.app.json @@ -0,0 +1,24 @@ +{ + "compilerOptions": { + "target": "ES2020", + "useDefineForClassFields": true, + "module": "ESNext", + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "isolatedModules": true, + "moduleDetection": "force", + "noEmit": true, + "jsx": "preserve", + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true + }, + "include": ["<%= js_destination_path %>/**/*.ts", "<%= js_destination_path %>/**/*.tsx", "<%= js_destination_path %>/**/*.vue"] +} diff --git a/lib/generators/inertia/install/templates/vue/tsconfig.json b/lib/generators/inertia/install/templates/vue/tsconfig.json new file mode 100644 index 00000000..ea9d0cd8 --- /dev/null +++ b/lib/generators/inertia/install/templates/vue/tsconfig.json @@ -0,0 +1,11 @@ +{ + "files": [], + "references": [ + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.node.json" + } + ] +} diff --git a/lib/generators/inertia/install/templates/vue/tsconfig.node.json b/lib/generators/inertia/install/templates/vue/tsconfig.node.json new file mode 100644 index 00000000..0d3d7144 --- /dev/null +++ b/lib/generators/inertia/install/templates/vue/tsconfig.node.json @@ -0,0 +1,22 @@ +{ + "compilerOptions": { + "target": "ES2022", + "lib": ["ES2023"], + "module": "ESNext", + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "isolatedModules": true, + "moduleDetection": "force", + "noEmit": true, + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true + }, + "include": ["vite.config.ts"] +} diff --git a/lib/generators/inertia/install/templates/vue/vite-env.d.ts b/lib/generators/inertia/install/templates/vue/vite-env.d.ts new file mode 100644 index 00000000..11f02fe2 --- /dev/null +++ b/lib/generators/inertia/install/templates/vue/vite-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/lib/generators/inertia/scaffold/scaffold_generator.rb b/lib/generators/inertia/scaffold/scaffold_generator.rb new file mode 100644 index 00000000..6717e92c --- /dev/null +++ b/lib/generators/inertia/scaffold/scaffold_generator.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +require 'rails/generators/rails/resource/resource_generator' + +module Inertia + module Generators + class ScaffoldGenerator < Rails::Generators::ResourceGenerator # :nodoc: + remove_hook_for :resource_controller + remove_class_option :actions + + class_option :resource_route, type: :boolean + + hook_for :scaffold_controller, required: true + end + end +end diff --git a/lib/generators/inertia/scaffold_controller/scaffold_controller_generator.rb b/lib/generators/inertia/scaffold_controller/scaffold_controller_generator.rb new file mode 100644 index 00000000..86d22041 --- /dev/null +++ b/lib/generators/inertia/scaffold_controller/scaffold_controller_generator.rb @@ -0,0 +1,60 @@ +# frozen_string_literal: true + +require 'rails/generators/resource_helpers' +require 'inertia_rails/generators/helper' + +module Inertia + module Generators + # This class is a modified copy of Rails::Generators::ScaffoldControllerGenerator. + # We don't use inheritance because some gems (i.e. jsbuilder) monkey-patch it. + class ScaffoldControllerGenerator < Rails::Generators::NamedBase + include InertiaRails::Generators::Helper + include Rails::Generators::ResourceHelpers + + source_root File.expand_path('./templates', __dir__) + + check_class_collision suffix: 'Controller' + + class_option :helper, type: :boolean + class_option :orm, banner: 'NAME', type: :string, required: true, + desc: 'ORM to generate the controller for' + + class_option :skip_routes, type: :boolean, desc: "Don't add routes to config/routes.rb." + + argument :attributes, type: :array, default: [], banner: 'field:type field:type' + + def create_controller_files + template 'controller.rb', + File.join('app/controllers', controller_class_path, "#{controller_file_name}_controller.rb") + end + + hook_for :inertia_templates, as: :scaffold, required: true, + default: InertiaRails::Generators::Helper.guess_inertia_template + + hook_for :resource_route, in: :rails, required: true do |route| + invoke route unless options.skip_routes? + end + + hook_for :test_framework, in: :rails, as: :scaffold + + # Invoke the helper using the controller name (pluralized) + hook_for :helper, in: :rails, as: :scaffold do |invoked| + invoke invoked, [controller_name] + end + + private + + def permitted_params + attachments, others = attributes_names.partition { |name| attachments?(name) } + params = others.map { |name| ":#{name}" } + params += attachments.map { |name| "#{name}: []" } + params.join(', ') + end + + def attachments?(name) + attribute = attributes.find { |attr| attr.name == name } + attribute&.attachments? + end + end + end +end diff --git a/lib/generators/inertia/scaffold_controller/templates/controller.rb.tt b/lib/generators/inertia/scaffold_controller/templates/controller.rb.tt new file mode 100644 index 00000000..03e9a49f --- /dev/null +++ b/lib/generators/inertia/scaffold_controller/templates/controller.rb.tt @@ -0,0 +1,100 @@ +<% module_namespacing do -%> +class <%= controller_class_name %>Controller < ApplicationController + before_action :set_<%= singular_table_name %>, only: %i[ show edit update destroy ] + +<% if regular_class_path.any? -%> + wrap_parameters :<%= singular_table_name %> + +<% end -%> + inertia_share flash: -> { flash.to_hash } + + # GET <%= route_url %> + def index + @<%= plural_table_name %> = <%= orm_class.all(class_name) %> + render inertia: '<%= "#{inertia_base_path}/Index" %>', props: { + <%= plural_table_name %>: @<%= plural_table_name %>.map do |<%= singular_table_name %>| + <%= "serialize_#{singular_table_name}" %>(<%= singular_table_name %>) + end + } + end + + # GET <%= route_url %>/1 + def show + render inertia: '<%= "#{inertia_base_path}/Show" %>', props: { + <%= singular_table_name %>: <%= "serialize_#{singular_table_name}" %>(@<%= singular_table_name %>) + } + end + + # GET <%= route_url %>/new + def new + @<%= singular_table_name %> = <%= orm_class.build(class_name) %> + render inertia: '<%= "#{inertia_base_path}/New" %>', props: { + <%= singular_table_name %>: <%= "serialize_#{singular_table_name}" %>(@<%= singular_table_name %>) + } + end + + # GET <%= route_url %>/1/edit + def edit + render inertia: '<%= "#{inertia_base_path}/Edit" %>', props: { + <%= singular_table_name %>: <%= "serialize_#{singular_table_name}" %>(@<%= singular_table_name %>) + } + end + + # POST <%= route_url %> + def create + @<%= singular_table_name %> = <%= orm_class.build(class_name, "#{singular_table_name}_params") %> + + if @<%= orm_instance.save %> + redirect_to <%= redirect_resource_name %>, notice: <%= %("#{human_name} was successfully created.") %> + else + redirect_to <%= new_helper %>, inertia: { errors: @<%= singular_table_name %>.errors } + end + end + + # PATCH/PUT <%= route_url %>/1 + def update + if @<%= orm_instance.update("#{singular_table_name}_params") %> + redirect_to <%= redirect_resource_name %>, notice: <%= %("#{human_name} was successfully updated.") %> + else + redirect_to <%= edit_helper %>, inertia: { errors: @<%= singular_table_name %>.errors } + end + end + + # DELETE <%= route_url %>/1 + def destroy + @<%= orm_instance.destroy %> + redirect_to <%= index_helper %>_url, notice: <%= %("#{human_name} was successfully destroyed.") %> + end + + private + # Use callbacks to share common setup or constraints between actions. + def set_<%= singular_table_name %> + @<%= singular_table_name %> = <%= orm_class.find(class_name, "params[:id]") %> + end + + # Only allow a list of trusted parameters through. + def <%= "#{singular_table_name}_params" %> + <%- if attributes_names.empty? -%> + params.fetch(:<%= singular_table_name %>, {}) + <%- else -%> + params.require(:<%= singular_table_name %>).permit(<%= permitted_params %>) + <%- end -%> + end + + def <%= "serialize_#{singular_table_name}" %>(<%= singular_table_name %>) + <%= singular_table_name %>.as_json(only: [ + <%= attributes_to_serialize.map { |attribute| ":#{attribute}" }.join(", ") %> + ])<%- if attributes.any?(&:attachment?) || attributes.any?(&:attachments?) -%>.tap do |hash| + <%- attributes.filter(&:attachment?).map do |attribute| -%> + 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? + <%- end -%> + <%- attributes.filter(&:attachments?).map do |attribute| -%> + hash["<%= attribute.column_name %>"] = + <%= singular_table_name %>.<%= attribute.column_name %>.flat_map do |file| + {filename: file.filename.to_s, url: url_for(file)} + end + <%- end -%> + end<% end %> + end +end +<% end -%> diff --git a/lib/generators/inertia_rails/install/react/InertiaExample.jsx b/lib/generators/inertia_rails/install/react/InertiaExample.jsx deleted file mode 100644 index ab8aeeb9..00000000 --- a/lib/generators/inertia_rails/install/react/InertiaExample.jsx +++ /dev/null @@ -1,9 +0,0 @@ -import React from 'react'; - -const InertiaExample = ({name}) => ( - <> -

Hello {name}!

- -); - -export default InertiaExample; diff --git a/lib/generators/inertia_rails/install/react/inertia.jsx b/lib/generators/inertia_rails/install/react/inertia.jsx deleted file mode 100644 index b1def90d..00000000 --- a/lib/generators/inertia_rails/install/react/inertia.jsx +++ /dev/null @@ -1,17 +0,0 @@ -import { App } from '@inertiajs/inertia-react'; -import React from 'react'; -import { render } from 'react-dom'; -import { InertiaProgress } from '@inertiajs/progress'; - -document.addEventListener('DOMContentLoaded', () => { - InertiaProgress.init(); - const el = document.getElementById('app') - - render( - require(`../Pages/${name}`).default} - />, - el - ) -}); diff --git a/lib/generators/inertia_rails/install/svelte/InertiaExample.svelte b/lib/generators/inertia_rails/install/svelte/InertiaExample.svelte deleted file mode 100644 index 4a2caef8..00000000 --- a/lib/generators/inertia_rails/install/svelte/InertiaExample.svelte +++ /dev/null @@ -1,11 +0,0 @@ - - - - -

- Hello {name}! -

\ No newline at end of file diff --git a/lib/generators/inertia_rails/install/svelte/inertia.js b/lib/generators/inertia_rails/install/svelte/inertia.js deleted file mode 100644 index 7310e20a..00000000 --- a/lib/generators/inertia_rails/install/svelte/inertia.js +++ /dev/null @@ -1,14 +0,0 @@ -import { createInertiaApp } from '@inertiajs/inertia-svelte' -import { InertiaProgress } from '@inertiajs/progress' - -document.addEventListener('DOMContentLoaded', () => { - InertiaProgress.init() - - createInertiaApp({ - id: 'app', - resolve: name => import(`../Pages/${name}.svelte`), - setup({ el, App, props }) { - new App({ target: el, props }) - }, - }) -}) diff --git a/lib/generators/inertia_rails/install/vue/InertiaExample.vue b/lib/generators/inertia_rails/install/vue/InertiaExample.vue deleted file mode 100644 index a52dfd01..00000000 --- a/lib/generators/inertia_rails/install/vue/InertiaExample.vue +++ /dev/null @@ -1,11 +0,0 @@ - - - diff --git a/lib/generators/inertia_rails/install/vue/inertia.js b/lib/generators/inertia_rails/install/vue/inertia.js deleted file mode 100644 index bb692d9a..00000000 --- a/lib/generators/inertia_rails/install/vue/inertia.js +++ /dev/null @@ -1,20 +0,0 @@ -import Vue from 'vue' - -import { app, plugin } from '@inertiajs/inertia-vue' -import { InertiaProgress } from '@inertiajs/progress' - -document.addEventListener('DOMContentLoaded', () => { - InertiaProgress.init(); - const el = document.getElementById('app') - - Vue.use(plugin) - - new Vue({ - render: h => h(app, { - props: { - initialPage: JSON.parse(el.dataset.page), - resolveComponent: name => require(`../Pages/${name}`).default, - }, - }), - }).$mount(el) -}) diff --git a/lib/generators/inertia_rails/install_generator.rb b/lib/generators/inertia_rails/install_generator.rb deleted file mode 100644 index 2ddc8221..00000000 --- a/lib/generators/inertia_rails/install_generator.rb +++ /dev/null @@ -1,84 +0,0 @@ -module InertiaRails - class InstallGenerator < Rails::Generators::Base - source_root File.expand_path('./install', __dir__) - class_option :front_end, type: :string, default: 'react' - - FRONT_END_INSTALLERS = [ - 'react', - 'vue', - 'svelte', - ] - - def install - exit! unless installable? - - install_base! - - send "install_#{options[:front_end]}!" - - say "You're all set! Run rails s and checkout localhost:3000/inertia-example", :green - end - - protected - - def installable? - unless run("./bin/rails webpacker:verify_install") - say "Sorry, you need to have webpacker installed for inertia_rails default setup.", :red - return false - end - - unless options[:front_end].in? FRONT_END_INSTALLERS - say "Sorry, there is no generator for #{options[:front_end]}!\n\n", :red - say "If you are a #{options[:front_end]} developer, please help us improve inertia_rails by contributing an installer.\n\n" - say "https://github.com/inertiajs/inertia-rails/\n\n" - - return false - end - - true - end - - def install_base! - say "Adding inertia pack tag to application layout", :blue - insert_into_file Rails.root.join("app/views/layouts/application.html.erb").to_s, after: "<%= javascript_pack_tag 'application' %>\n" do - "\t\t<%= javascript_pack_tag 'inertia' %>\n" - end - - say "Installing inertia client packages", :blue - run "yarn add @inertiajs/inertia @inertiajs/progress" - - say "Copying example files", :blue - template "controller.rb", Rails.root.join("app/controllers/inertia_example_controller.rb").to_s - - say "Adding a route for the example inertia controller...", :blue - route "get 'inertia-example', to: 'inertia_example#index'" - end - - def install_react! - say "Creating a React page component...", :blue - run 'yarn add @inertiajs/inertia-react' - template "react/InertiaExample.jsx", Rails.root.join("app/javascript/Pages/InertiaExample.js").to_s - say "Copying inertia.jsx into webpacker's packs folder...", :blue - template "react/inertia.jsx", Rails.root.join("app/javascript/packs/inertia.jsx").to_s - say "done!", :green - end - - def install_vue! - say "Creating a Vue page component...", :blue - run 'yarn add @inertiajs/inertia-vue' - template "vue/InertiaExample.vue", Rails.root.join("app/javascript/Pages/InertiaExample.vue").to_s - say "Copying inertia.js into webpacker's packs folder...", :blue - template "vue/inertia.js", Rails.root.join("app/javascript/packs/inertia.js").to_s - say "done!", :green - end - - def install_svelte! - say "Creating a Svelte page component...", :blue - run 'yarn add @inertiajs/inertia-svelte' - template "svelte/InertiaExample.svelte", Rails.root.join("app/javascript/Pages/InertiaExample.svelte").to_s - say "Copying inertia.js into webpacker's packs folder...", :blue - template "svelte/inertia.js", Rails.root.join("app/javascript/packs/inertia.js").to_s - say "done!", :green - end - end -end diff --git a/lib/generators/inertia_templates/controller/controller_generator.rb b/lib/generators/inertia_templates/controller/controller_generator.rb new file mode 100644 index 00000000..0b4608c6 --- /dev/null +++ b/lib/generators/inertia_templates/controller/controller_generator.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +require 'inertia_rails/generators/controller_template_base' + +module InertiaTemplates + module Generators + class ControllerGenerator < InertiaRails::Generators::ControllerTemplateBase + hide! + source_root File.expand_path('./templates', __dir__) + end + end +end diff --git a/lib/generators/inertia_templates/controller/templates/react/view.jsx.tt b/lib/generators/inertia_templates/controller/templates/react/view.jsx.tt new file mode 100644 index 00000000..799ea4c5 --- /dev/null +++ b/lib/generators/inertia_templates/controller/templates/react/view.jsx.tt @@ -0,0 +1,8 @@ +export default function <%= @action.camelize %>() { + return ( + <> +

<%= class_name %>#<%= @action %>

+

Find me in <%= @path %>

+ + ); +} diff --git a/lib/generators/inertia_templates/controller/templates/svelte/view.svelte.tt b/lib/generators/inertia_templates/controller/templates/svelte/view.svelte.tt new file mode 100644 index 00000000..cd54d13d --- /dev/null +++ b/lib/generators/inertia_templates/controller/templates/svelte/view.svelte.tt @@ -0,0 +1,2 @@ +

<%= class_name %>#<%= @action %>

+

Find me in <%= @path %>

diff --git a/lib/generators/inertia_templates/controller/templates/svelte4/view.svelte.tt b/lib/generators/inertia_templates/controller/templates/svelte4/view.svelte.tt new file mode 100644 index 00000000..cd54d13d --- /dev/null +++ b/lib/generators/inertia_templates/controller/templates/svelte4/view.svelte.tt @@ -0,0 +1,2 @@ +

<%= class_name %>#<%= @action %>

+

Find me in <%= @path %>

diff --git a/lib/generators/inertia_templates/controller/templates/vue/view.vue.tt b/lib/generators/inertia_templates/controller/templates/vue/view.vue.tt new file mode 100644 index 00000000..14e2f96d --- /dev/null +++ b/lib/generators/inertia_templates/controller/templates/vue/view.vue.tt @@ -0,0 +1,4 @@ + diff --git a/lib/generators/inertia_templates/scaffold/scaffold_generator.rb b/lib/generators/inertia_templates/scaffold/scaffold_generator.rb new file mode 100644 index 00000000..b7674f0f --- /dev/null +++ b/lib/generators/inertia_templates/scaffold/scaffold_generator.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +require 'inertia_rails/generators/scaffold_template_base' + +module InertiaTemplates + module Generators + class ScaffoldGenerator < InertiaRails::Generators::ScaffoldTemplateBase + hide! + source_root File.expand_path('./templates', __dir__) + end + end +end diff --git a/lib/generators/inertia_templates/scaffold/templates/react/Edit.jsx.tt b/lib/generators/inertia_templates/scaffold/templates/react/Edit.jsx.tt new file mode 100644 index 00000000..faf0c3b5 --- /dev/null +++ b/lib/generators/inertia_templates/scaffold/templates/react/Edit.jsx.tt @@ -0,0 +1,35 @@ +import { Link, Head } from '@inertiajs/react' +import Form from './Form' + +export default function Edit({ <%= singular_table_name %> }) { + return ( + <> + + +

Editing <%= human_name.downcase %>

+ +
={<%= singular_table_name %>} + onSubmit={(form) => { + form.transform((data) => ({ <%= singular_table_name %>: data })) +<% if attributes.any?(&:attachments?) -%> + form.post(`<%= js_resource_path %>`, { + headers: { 'X-HTTP-METHOD-OVERRIDE': 'put' }, + }) +<% else -%> + form.patch(`<%= js_resource_path %>`) +<% end -%> + }} + submitText="Update <%= human_name.downcase %>" + /> + +
+ +
+ `}>Show this <%= human_name.downcase %> + {' | '} + Back to <%= human_name.pluralize.downcase %> +
+ + ) +} diff --git a/lib/generators/inertia_templates/scaffold/templates/react/Form.jsx.tt b/lib/generators/inertia_templates/scaffold/templates/react/Form.jsx.tt new file mode 100644 index 00000000..e062dcbf --- /dev/null +++ b/lib/generators/inertia_templates/scaffold/templates/react/Form.jsx.tt @@ -0,0 +1,111 @@ +import { useForm } from '@inertiajs/react' + +export default function Form({ <%= singular_table_name %>, onSubmit, submitText }) { + const form = useForm({ +<% attributes.each do |attribute| -%> +<% if attribute.password_digest? -%> + password: '', + password_confirmation: '', +<% else -%> + <%= attribute.column_name %>: <%= singular_table_name %>.<%= attribute.column_name %> || <%= default_value(attribute) %>, +<% end -%> +<% end -%> + }) + const { data, setData, errors, processing } = form + + const handleSubmit = (e) => { + e.preventDefault() + onSubmit(form) + } + + return ( + +<% attributes.each do |attribute| -%> +<% if attribute.password_digest? -%> +
+ + setData('password', e.target.value)} + /> + {errors.password && ( +
{errors.password.join(', ')}
+ )} +
+ +
+ + setData('password_confirmation', e.target.value)} + /> + {errors.password_confirmation && ( +
{errors.password_confirmation.join(', ')}
+ )} +
+<% else -%> +
+ +<% if input_type(attribute) == "text_area" -%> + +<% elsif attribute.attachment? -%> + ($form.<%= attribute.column_name %> = e.target.files[0])} + /> +<% elsif attribute.attachments? -%> + ($form.<%= attribute.column_name %> = Array.from(e.target.files))} + /> +<% else -%> + ={$form.<%= attribute.column_name %>} + /> +<% end -%> + {#if $form.errors.<%= attribute.column_name %>} +
{$form.errors.<%= attribute.column_name %>.join(', ')}
+ {/if} +
+<% end -%> +<% end -%> +
+ +
+
+ + diff --git a/lib/generators/inertia_templates/scaffold/templates/svelte/Index.svelte.tt b/lib/generators/inertia_templates/scaffold/templates/svelte/Index.svelte.tt new file mode 100644 index 00000000..e8a7e7dd --- /dev/null +++ b/lib/generators/inertia_templates/scaffold/templates/svelte/Index.svelte.tt @@ -0,0 +1,35 @@ + + + + <%= human_name.pluralize %> + + +{#if flash.notice} +

{flash.notice}

+{/if} + +

<%= human_name.pluralize %>

+ +
+ {#each <%= plural_table_name %> as <%= singular_table_name %> (<%= singular_table_name %>.id)} +
+ <<%= inertia_component_name %> {<%= singular_table_name %>} /> +

+ `}>Show this <%= human_name.downcase %> +

+
+ {/each} +
+ +New <%= human_name.downcase %> + + diff --git a/lib/generators/inertia_templates/scaffold/templates/svelte/New.svelte.tt b/lib/generators/inertia_templates/scaffold/templates/svelte/New.svelte.tt new file mode 100644 index 00000000..d46b4656 --- /dev/null +++ b/lib/generators/inertia_templates/scaffold/templates/svelte/New.svelte.tt @@ -0,0 +1,29 @@ + + + + New <%= human_name.downcase %> + + +

New <%= human_name.downcase %>

+ +
} + submitText="Create <%= human_name.downcase %>" + onSubmit={handleSubmit} +/> + +
+ +
+ Back to <%= human_name.pluralize.downcase %> +
diff --git a/lib/generators/inertia_templates/scaffold/templates/svelte/One.svelte.tt b/lib/generators/inertia_templates/scaffold/templates/svelte/One.svelte.tt new file mode 100644 index 00000000..717b129b --- /dev/null +++ b/lib/generators/inertia_templates/scaffold/templates/svelte/One.svelte.tt @@ -0,0 +1,28 @@ + + +
+<% attributes.reject(&:password_digest?).each do |attribute| -%> +

+ <%= attribute.human_name %>: +<% if attribute.attachment? -%> + {#if <%= singular_table_name %>.<%= attribute.column_name %>} + .<%= attribute.column_name %>.url}> + {<%= singular_table_name %>.<%= attribute.column_name %>.filename} + + {/if} +

+<% elsif attribute.attachments? -%> +

+ {#each <%= singular_table_name %>.<%= attribute.column_name %> as { url, filename }} + + {/each} +<% else -%> + {<%= singular_table_name %>.<%= attribute.column_name %>} +

+<% end -%> +<% end -%> +
diff --git a/lib/generators/inertia_templates/scaffold/templates/svelte/Show.svelte.tt b/lib/generators/inertia_templates/scaffold/templates/svelte/Show.svelte.tt new file mode 100644 index 00000000..065a0587 --- /dev/null +++ b/lib/generators/inertia_templates/scaffold/templates/svelte/Show.svelte.tt @@ -0,0 +1,41 @@ + + + + <%= human_name %> #{<%= singular_table_name %>.id} + + +{#if flash.notice} +

{flash.notice}

+{/if} + +

<%= human_name %> #{<%= singular_table_name %>.id}

+ +<<%= inertia_component_name %> {<%= singular_table_name %>} /> + +
+ `}>Edit this <%= human_name.downcase %> | + Back to <%= human_name.pluralize.downcase %> + +
+ + `} method="delete" onclick={onDestroy}> + Destroy this <%= human_name.downcase %> + +
+ + diff --git a/lib/generators/inertia_templates/scaffold/templates/svelte4/Edit.svelte.tt b/lib/generators/inertia_templates/scaffold/templates/svelte4/Edit.svelte.tt new file mode 100644 index 00000000..8f45c81f --- /dev/null +++ b/lib/generators/inertia_templates/scaffold/templates/svelte4/Edit.svelte.tt @@ -0,0 +1,37 @@ + + + + Editing <%= human_name.downcase %> + + +

Editing <%= human_name.downcase %>

+ +} + submitText="Update <%= human_name.downcase %>" + on:submit={handleSubmit} +/> + +
+ +
+ `}>Show this <%= human_name.downcase %> | + Back to <%= human_name.pluralize.downcase %> +
diff --git a/lib/generators/inertia_templates/scaffold/templates/svelte4/Form.svelte.tt b/lib/generators/inertia_templates/scaffold/templates/svelte4/Form.svelte.tt new file mode 100644 index 00000000..8519c334 --- /dev/null +++ b/lib/generators/inertia_templates/scaffold/templates/svelte4/Form.svelte.tt @@ -0,0 +1,96 @@ + + + +<% attributes.each do |attribute| -%> +<% if attribute.password_digest? -%> +
+ + + {#if $form.errors.password} +
{$form.errors.password.join(', ')}
+ {/if} +
+ +
+ + + {#if $form.errors.password_confirmation} +
{$form.errors.password_confirmation.join(', ')}
+ {/if} +
+<% else -%> +
+ +<% if input_type(attribute) == "text_area" -%> + +<% elsif attribute.attachment? -%> + ($form.<%= attribute.column_name %> = e.target.files[0])} + /> +<% elsif attribute.attachments? -%> + ($form.<%= attribute.column_name %> = Array.from(e.target.files))} + /> +<% else -%> + ={$form.<%= attribute.column_name %>} + /> +<% end -%> + {#if $form.errors.<%= attribute.column_name %>} +
{$form.errors.<%= attribute.column_name %>.join(', ')}
+ {/if} +
+<% end -%> +<% end -%> +
+ +
+
+ + diff --git a/lib/generators/inertia_templates/scaffold/templates/svelte4/Index.svelte.tt b/lib/generators/inertia_templates/scaffold/templates/svelte4/Index.svelte.tt new file mode 100644 index 00000000..7164c7b7 --- /dev/null +++ b/lib/generators/inertia_templates/scaffold/templates/svelte4/Index.svelte.tt @@ -0,0 +1,36 @@ + + + + <%= human_name.pluralize %> + + +{#if flash.notice} +

{flash.notice}

+{/if} + +

<%= human_name.pluralize %>

+ +
+ {#each <%= plural_table_name %> as <%= singular_table_name %> (<%= singular_table_name %>.id)} +
+ <<%= inertia_component_name %> {<%= singular_table_name %>} /> +

+ `}>Show this <%= human_name.downcase %> +

+
+ {/each} +
+ +New <%= human_name.downcase %> + + diff --git a/lib/generators/inertia_templates/scaffold/templates/svelte4/New.svelte.tt b/lib/generators/inertia_templates/scaffold/templates/svelte4/New.svelte.tt new file mode 100644 index 00000000..6238cd2d --- /dev/null +++ b/lib/generators/inertia_templates/scaffold/templates/svelte4/New.svelte.tt @@ -0,0 +1,30 @@ + + + + New <%= human_name.downcase %> + + +

New <%= human_name.downcase %>

+ +
} + submitText="Create <%= human_name.downcase %>" + on:submit={handleSubmit} +/> + +
+ +
+ Back to <%= human_name.pluralize.downcase %> +
diff --git a/lib/generators/inertia_templates/scaffold/templates/svelte4/One.svelte.tt b/lib/generators/inertia_templates/scaffold/templates/svelte4/One.svelte.tt new file mode 100644 index 00000000..01b918a8 --- /dev/null +++ b/lib/generators/inertia_templates/scaffold/templates/svelte4/One.svelte.tt @@ -0,0 +1,28 @@ + + +
+<% attributes.reject(&:password_digest?).each do |attribute| -%> +

+ <%= attribute.human_name %>: +<% if attribute.attachment? -%> + {#if <%= singular_table_name %>.<%= attribute.column_name %>} + .<%= attribute.column_name %>.url}> + {<%= singular_table_name %>.<%= attribute.column_name %>.filename} + + {/if} +

+<% elsif attribute.attachments? -%> +

+ {#each <%= singular_table_name %>.<%= attribute.column_name %> as { url, filename }} + + {/each} +<% else -%> + {<%= singular_table_name %>.<%= attribute.column_name %>} +

+<% end -%> +<% end -%> +
diff --git a/lib/generators/inertia_templates/scaffold/templates/svelte4/Show.svelte.tt b/lib/generators/inertia_templates/scaffold/templates/svelte4/Show.svelte.tt new file mode 100644 index 00000000..c1653236 --- /dev/null +++ b/lib/generators/inertia_templates/scaffold/templates/svelte4/Show.svelte.tt @@ -0,0 +1,46 @@ + + + + <%= human_name %> #{<%= singular_table_name %>.id} + + +{#if flash.notice} +

{flash.notice}

+{/if} + +

<%= human_name %> #{<%= singular_table_name %>.id}

+ +<<%= inertia_component_name %> {<%= singular_table_name %>} /> + +
+ `}>Edit this <%= human_name.downcase %> | + Back to <%= human_name.pluralize.downcase %> + +
+ + +
+ + diff --git a/lib/generators/inertia_templates/scaffold/templates/vue/Edit.vue.tt b/lib/generators/inertia_templates/scaffold/templates/vue/Edit.vue.tt new file mode 100644 index 00000000..8e789236 --- /dev/null +++ b/lib/generators/inertia_templates/scaffold/templates/vue/Edit.vue.tt @@ -0,0 +1,36 @@ + + + diff --git a/lib/generators/inertia_templates/scaffold/templates/vue/Form.vue.tt b/lib/generators/inertia_templates/scaffold/templates/vue/Form.vue.tt new file mode 100644 index 00000000..226d9330 --- /dev/null +++ b/lib/generators/inertia_templates/scaffold/templates/vue/Form.vue.tt @@ -0,0 +1,94 @@ +