inertiax_rails 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/push.yml +33 -0
  3. data/.gitignore +22 -0
  4. data/.rspec +3 -0
  5. data/CHANGELOG.md +173 -0
  6. data/CODE_OF_CONDUCT.md +74 -0
  7. data/Gemfile +7 -0
  8. data/LICENSE.txt +21 -0
  9. data/README.md +273 -0
  10. data/Rakefile +6 -0
  11. data/app/controllers/inertia_rails/static_controller.rb +7 -0
  12. data/app/views/inertia.html.erb +1 -0
  13. data/app/views/inertia_ssr.html.erb +1 -0
  14. data/bin/console +14 -0
  15. data/bin/setup +8 -0
  16. data/inertiax_rails.gemspec +37 -0
  17. data/lib/generators/inertia_rails/install/controller.rb +7 -0
  18. data/lib/generators/inertia_rails/install/react/InertiaExample.jsx +9 -0
  19. data/lib/generators/inertia_rails/install/react/inertia.jsx +17 -0
  20. data/lib/generators/inertia_rails/install/svelte/InertiaExample.svelte +11 -0
  21. data/lib/generators/inertia_rails/install/svelte/inertia.js +14 -0
  22. data/lib/generators/inertia_rails/install/vue/InertiaExample.vue +11 -0
  23. data/lib/generators/inertia_rails/install/vue/inertia.js +20 -0
  24. data/lib/generators/inertia_rails/install_generator.rb +84 -0
  25. data/lib/inertia_rails/controller.rb +110 -0
  26. data/lib/inertia_rails/engine.rb +16 -0
  27. data/lib/inertia_rails/inertia_rails.rb +52 -0
  28. data/lib/inertia_rails/lazy.rb +28 -0
  29. data/lib/inertia_rails/middleware.rb +97 -0
  30. data/lib/inertia_rails/renderer.rb +92 -0
  31. data/lib/inertia_rails/rspec.rb +125 -0
  32. data/lib/inertia_rails/version.rb +3 -0
  33. data/lib/inertia_rails.rb +24 -0
  34. data/lib/patches/better_errors.rb +17 -0
  35. data/lib/patches/debug_exceptions/patch-5-0.rb +23 -0
  36. data/lib/patches/debug_exceptions/patch-5-1.rb +26 -0
  37. data/lib/patches/debug_exceptions.rb +17 -0
  38. data/lib/patches/mapper.rb +8 -0
  39. data/lib/patches/request.rb +9 -0
  40. data/lib/tasks/inertia_rails.rake +16 -0
  41. metadata +203 -0
@@ -0,0 +1,125 @@
1
+ require "rspec/core"
2
+ require "rspec/matchers"
3
+
4
+ module InertiaRails
5
+ module RSpec
6
+ class InertiaRenderWrapper
7
+ attr_reader :view_data, :props, :component
8
+
9
+ def initialize
10
+ @view_data = nil
11
+ @props = nil
12
+ @component = nil
13
+ end
14
+
15
+ def call(params)
16
+ set_values(params)
17
+ @render_method&.call(params)
18
+ end
19
+
20
+ def wrap_render(render_method)
21
+ @render_method = render_method
22
+ self
23
+ end
24
+
25
+ protected
26
+
27
+ def set_values(params)
28
+ @view_data = params[:locals].except(:page)
29
+ @props = params[:locals][:page][:props]
30
+ @component = params[:locals][:page][:component]
31
+ end
32
+ end
33
+
34
+ module Helpers
35
+ def inertia
36
+ raise 'Inertia test helpers aren\'t set up! Make sure you add inertia: true to describe blocks using inertia tests.' unless inertia_tests_setup?
37
+
38
+ if @_inertia_render_wrapper.nil? && !::RSpec.configuration.inertia[:skip_missing_renderer_warnings]
39
+ warn 'WARNING: the test never created an Inertia renderer. Maybe the code wasn\'t able to reach a `render inertia:` call? If this was intended, or you don\'t want to see this message, set ::RSpec.configuration.inertia[:skip_missing_renderer_warnings] = true'
40
+ end
41
+ @_inertia_render_wrapper
42
+ end
43
+
44
+ def expect_inertia
45
+ expect(inertia)
46
+ end
47
+
48
+ def inertia_wrap_render(render)
49
+ @_inertia_render_wrapper = InertiaRenderWrapper.new.wrap_render(render)
50
+ end
51
+
52
+ protected
53
+
54
+ def inertia_tests_setup?
55
+ ::RSpec.current_example.metadata.fetch(:inertia, false)
56
+ end
57
+ end
58
+ end
59
+ end
60
+
61
+ RSpec.configure do |config|
62
+ config.include ::InertiaRails::RSpec::Helpers
63
+ config.add_setting :inertia, default: {
64
+ skip_missing_renderer_warnings: false
65
+ }
66
+
67
+ config.before(:each, inertia: true) do
68
+ new_renderer = InertiaRails::Renderer.method(:new)
69
+ allow(InertiaRails::Renderer).to receive(:new) do |component, controller, request, response, render, named_args|
70
+ new_renderer.call(component, controller, request, response, inertia_wrap_render(render), **named_args)
71
+ end
72
+ end
73
+ end
74
+
75
+ RSpec::Matchers.define :have_exact_props do |expected_props|
76
+ match do |inertia|
77
+ # Computed props have symbolized keys.
78
+ expect(inertia.props).to eq expected_props.deep_symbolize_keys
79
+ end
80
+
81
+ failure_message do |inertia|
82
+ "expected inertia props to receive #{expected_props}, instead received #{inertia.props || 'nothing'}"
83
+ end
84
+ end
85
+
86
+ RSpec::Matchers.define :include_props do |expected_props|
87
+ match do |inertia|
88
+ # Computed props have symbolized keys.
89
+ expect(inertia.props).to include expected_props.deep_symbolize_keys
90
+ end
91
+
92
+ failure_message do |inertia|
93
+ "expected inertia props to include #{expected_props}, instead received #{inertia.props || 'nothing'}"
94
+ end
95
+ end
96
+
97
+ RSpec::Matchers.define :render_component do |expected_component|
98
+ match do |inertia|
99
+ expect(inertia.component).to eq expected_component
100
+ end
101
+
102
+ failure_message do |inertia|
103
+ "expected rendered inertia component to be #{expected_component}, instead received #{inertia.component || 'nothing'}"
104
+ end
105
+ end
106
+
107
+ RSpec::Matchers.define :have_exact_view_data do |expected_view_data|
108
+ match do |inertia|
109
+ expect(inertia.view_data).to eq expected_view_data
110
+ end
111
+
112
+ failure_message do |inertia|
113
+ "expected inertia view data to receive #{expected_view_data}, instead received #{inertia.view_data || 'nothing'}"
114
+ end
115
+ end
116
+
117
+ RSpec::Matchers.define :include_view_data do |expected_view_data|
118
+ match do |inertia|
119
+ expect(inertia.view_data).to include expected_view_data
120
+ end
121
+
122
+ failure_message do |inertia|
123
+ "expected inertia view data to include #{expected_view_data}, instead received #{inertia.view_data || 'nothing'}"
124
+ end
125
+ end
@@ -0,0 +1,3 @@
1
+ module InertiaRails
2
+ VERSION = "2.0.0"
3
+ end
@@ -0,0 +1,24 @@
1
+ require 'inertia_rails/renderer'
2
+ require 'inertia_rails/engine'
3
+
4
+ require 'patches/debug_exceptions'
5
+ require 'patches/better_errors'
6
+ require 'patches/request'
7
+ require 'patches/mapper'
8
+
9
+ ActionController::Renderers.add :inertia do |component, options|
10
+ InertiaRails::Renderer.new(
11
+ component,
12
+ self,
13
+ request,
14
+ response,
15
+ method(:render),
16
+ props: options[:props],
17
+ view_data: options[:view_data],
18
+ deep_merge: options[:deep_merge],
19
+ ).render
20
+ end
21
+
22
+ module InertiaRails
23
+ class Error < StandardError; end
24
+ end
@@ -0,0 +1,17 @@
1
+ # Patch BetterErrors::Middleware to render HTML for Inertia requests
2
+ #
3
+ # Original source:
4
+ # https://github.com/BetterErrors/better_errors/blob/v2.5.1/lib/better_errors/middleware.rb
5
+ #
6
+
7
+ if defined?(BetterErrors)
8
+ BetterErrors::Middleware.class_eval do
9
+ prepend(InertiaBetterErrors = Module.new do
10
+ def text?(env)
11
+ return false if env["HTTP_X_INERTIA"]
12
+
13
+ super
14
+ end
15
+ end)
16
+ end
17
+ end
@@ -0,0 +1,23 @@
1
+ # Patch ActionDispatch::DebugExceptions to render HTML for Inertia requests
2
+ #
3
+ # Original source:
4
+ # https://github.com/rails/rails/blob/5-0-stable/actionpack/lib/action_dispatch/middleware/debug_exceptions.rb
5
+ #
6
+
7
+ ActionDispatch::DebugExceptions.class_eval do
8
+ prepend(InertiaDebugExceptions = Module.new do
9
+ def render_for_default_application(request, wrapper)
10
+ template = create_template(request, wrapper)
11
+ file = "rescues/#{wrapper.rescue_template}"
12
+
13
+ if request.xhr? && !request.headers['X-Inertia'] # <<<< this line is changed only
14
+ body = template.render(template: file, layout: false, formats: [:text])
15
+ format = "text/plain"
16
+ else
17
+ body = template.render(template: file, layout: 'rescues/layout')
18
+ format = "text/html"
19
+ end
20
+ render(wrapper.status_code, body, format)
21
+ end
22
+ end)
23
+ end
@@ -0,0 +1,26 @@
1
+ # Patch ActionDispatch::DebugExceptions to render HTML for Inertia requests
2
+ #
3
+ # Original source (unchanged since Rails 5.1):
4
+ # https://github.com/rails/rails/blob/5-1-stable/actionpack/lib/action_dispatch/middleware/debug_exceptions.rb
5
+ # https://github.com/rails/rails/blob/5-2-stable/actionpack/lib/action_dispatch/middleware/debug_exceptions.rb
6
+ # https://github.com/rails/rails/blob/6-0-stable/actionpack/lib/action_dispatch/middleware/debug_exceptions.rb
7
+ #
8
+
9
+ ActionDispatch::DebugExceptions.class_eval do
10
+ prepend(InertiaDebugExceptions = Module.new do
11
+ def render_for_browser_request(request, wrapper)
12
+ template = create_template(request, wrapper)
13
+ file = "rescues/#{wrapper.rescue_template}"
14
+
15
+ if request.xhr? && !request.headers['X-Inertia'] # <<<< this line is changed only
16
+ body = template.render(template: file, layout: false, formats: [:text])
17
+ format = "text/plain"
18
+ else
19
+ body = template.render(template: file, layout: "rescues/layout")
20
+ format = "text/html"
21
+ end
22
+
23
+ render(wrapper.status_code, body, format)
24
+ end
25
+ end)
26
+ end
@@ -0,0 +1,17 @@
1
+ # Patch ActionDispatch::DebugExceptions to render HTML for Inertia requests
2
+ #
3
+ # Rails has introduced text rendering for XHR requests with Rails 4.1 and
4
+ # changed the implementation in 4.2, 5.0 and 5.1 (unchanged since then).
5
+ #
6
+ # The original source needs to be patched, so that Inertia requests are
7
+ # NOT responded with plain text, but with HTML.
8
+
9
+ if defined?(ActionDispatch::DebugExceptions)
10
+ if ActionPack.version.to_s >= '5.1'
11
+ require 'patches/debug_exceptions/patch-5-1'
12
+ elsif ActionPack.version.to_s >= '5.0'
13
+ require 'patches/debug_exceptions/patch-5-0'
14
+ else
15
+ # This gem supports Rails 5 or later
16
+ end
17
+ end
@@ -0,0 +1,8 @@
1
+ ActionDispatch::Routing::Mapper.class_eval do
2
+ def inertia(args, &block)
3
+ route = args.keys.first
4
+ component = args.values.first
5
+
6
+ get(route => 'inertia_rails/static#static', defaults: {component: component})
7
+ end
8
+ end
@@ -0,0 +1,9 @@
1
+ ActionDispatch::Request.class_eval do
2
+ def inertia?
3
+ key? 'HTTP_X_INERTIA'
4
+ end
5
+
6
+ def inertia_partial?
7
+ key? 'HTTP_X_INERTIA_PARTIAL_DATA'
8
+ end
9
+ end
@@ -0,0 +1,16 @@
1
+ namespace :inertia_rails do
2
+ namespace :install do
3
+ desc "Installs inertia_rails packages and configurations for a React based app"
4
+ task :react => :environment do
5
+ system 'rails g inertia_rails:install --front_end react'
6
+ end
7
+ desc "Installs inertia_rails packages and configurations for a Vue based app"
8
+ task vue: :environment do
9
+ system 'rails g inertia_rails:install --front_end vue'
10
+ end
11
+ desc "Installs inertia_rails packages and configurations for a Svelte based app"
12
+ task svelte: :environment do
13
+ system 'rails g inertia_rails:install --front_end svelte'
14
+ end
15
+ end
16
+ end
metadata ADDED
@@ -0,0 +1,203 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: inertiax_rails
3
+ version: !ruby/object:Gem::Version
4
+ version: 2.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Brian Knoles
8
+ - Brandon Shar
9
+ - Eugene Granovsky
10
+ - Stefan Buhrmester
11
+ autorequire:
12
+ bindir: exe
13
+ cert_chain: []
14
+ date: 2024-07-25 00:00:00.000000000 Z
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: railties
18
+ requirement: !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: '5'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: '5'
30
+ - !ruby/object:Gem::Dependency
31
+ name: bundler
32
+ requirement: !ruby/object:Gem::Requirement
33
+ requirements:
34
+ - - "~>"
35
+ - !ruby/object:Gem::Version
36
+ version: '2.0'
37
+ type: :development
38
+ prerelease: false
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - "~>"
42
+ - !ruby/object:Gem::Version
43
+ version: '2.0'
44
+ - !ruby/object:Gem::Dependency
45
+ name: rake
46
+ requirement: !ruby/object:Gem::Requirement
47
+ requirements:
48
+ - - "~>"
49
+ - !ruby/object:Gem::Version
50
+ version: '13.0'
51
+ type: :development
52
+ prerelease: false
53
+ version_requirements: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - "~>"
56
+ - !ruby/object:Gem::Version
57
+ version: '13.0'
58
+ - !ruby/object:Gem::Dependency
59
+ name: rspec-rails
60
+ requirement: !ruby/object:Gem::Requirement
61
+ requirements:
62
+ - - "~>"
63
+ - !ruby/object:Gem::Version
64
+ version: '4.0'
65
+ type: :development
66
+ prerelease: false
67
+ version_requirements: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - "~>"
70
+ - !ruby/object:Gem::Version
71
+ version: '4.0'
72
+ - !ruby/object:Gem::Dependency
73
+ name: rails-controller-testing
74
+ requirement: !ruby/object:Gem::Requirement
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
79
+ type: :development
80
+ prerelease: false
81
+ version_requirements: !ruby/object:Gem::Requirement
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ - !ruby/object:Gem::Dependency
87
+ name: sqlite3
88
+ requirement: !ruby/object:Gem::Requirement
89
+ requirements:
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ version: '0'
93
+ type: :development
94
+ prerelease: false
95
+ version_requirements: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - ">="
98
+ - !ruby/object:Gem::Version
99
+ version: '0'
100
+ - !ruby/object:Gem::Dependency
101
+ name: responders
102
+ requirement: !ruby/object:Gem::Requirement
103
+ requirements:
104
+ - - ">="
105
+ - !ruby/object:Gem::Version
106
+ version: '0'
107
+ type: :development
108
+ prerelease: false
109
+ version_requirements: !ruby/object:Gem::Requirement
110
+ requirements:
111
+ - - ">="
112
+ - !ruby/object:Gem::Version
113
+ version: '0'
114
+ - !ruby/object:Gem::Dependency
115
+ name: debug
116
+ requirement: !ruby/object:Gem::Requirement
117
+ requirements:
118
+ - - ">="
119
+ - !ruby/object:Gem::Version
120
+ version: '0'
121
+ type: :development
122
+ prerelease: false
123
+ version_requirements: !ruby/object:Gem::Requirement
124
+ requirements:
125
+ - - ">="
126
+ - !ruby/object:Gem::Version
127
+ version: '0'
128
+ description:
129
+ email:
130
+ - brain@bellawatt.com
131
+ - brandon@bellawatt.com
132
+ - eugene@bellawatt.com
133
+ - stefan@buhrmi.de
134
+ executables: []
135
+ extensions: []
136
+ extra_rdoc_files: []
137
+ files:
138
+ - ".github/workflows/push.yml"
139
+ - ".gitignore"
140
+ - ".rspec"
141
+ - CHANGELOG.md
142
+ - CODE_OF_CONDUCT.md
143
+ - Gemfile
144
+ - LICENSE.txt
145
+ - README.md
146
+ - Rakefile
147
+ - app/controllers/inertia_rails/static_controller.rb
148
+ - app/views/inertia.html.erb
149
+ - app/views/inertia_ssr.html.erb
150
+ - bin/console
151
+ - bin/setup
152
+ - inertiax_rails.gemspec
153
+ - lib/generators/inertia_rails/install/controller.rb
154
+ - lib/generators/inertia_rails/install/react/InertiaExample.jsx
155
+ - lib/generators/inertia_rails/install/react/inertia.jsx
156
+ - lib/generators/inertia_rails/install/svelte/InertiaExample.svelte
157
+ - lib/generators/inertia_rails/install/svelte/inertia.js
158
+ - lib/generators/inertia_rails/install/vue/InertiaExample.vue
159
+ - lib/generators/inertia_rails/install/vue/inertia.js
160
+ - lib/generators/inertia_rails/install_generator.rb
161
+ - lib/inertia_rails.rb
162
+ - lib/inertia_rails/controller.rb
163
+ - lib/inertia_rails/engine.rb
164
+ - lib/inertia_rails/inertia_rails.rb
165
+ - lib/inertia_rails/lazy.rb
166
+ - lib/inertia_rails/middleware.rb
167
+ - lib/inertia_rails/renderer.rb
168
+ - lib/inertia_rails/rspec.rb
169
+ - lib/inertia_rails/version.rb
170
+ - lib/patches/better_errors.rb
171
+ - lib/patches/debug_exceptions.rb
172
+ - lib/patches/debug_exceptions/patch-5-0.rb
173
+ - lib/patches/debug_exceptions/patch-5-1.rb
174
+ - lib/patches/mapper.rb
175
+ - lib/patches/request.rb
176
+ - lib/tasks/inertia_rails.rake
177
+ homepage: https://github.com/buhrmi/inertia-rails
178
+ licenses:
179
+ - MIT
180
+ metadata:
181
+ homepage_uri: https://github.com/buhrmi/inertia-rails
182
+ source_code_uri: https://github.com/buhrmi/inertia-rails
183
+ changelog_uri: https://github.com/buhrmi/inertia-rails/blob/master/CHANGELOG.md
184
+ post_install_message:
185
+ rdoc_options: []
186
+ require_paths:
187
+ - lib
188
+ required_ruby_version: !ruby/object:Gem::Requirement
189
+ requirements:
190
+ - - ">="
191
+ - !ruby/object:Gem::Version
192
+ version: '0'
193
+ required_rubygems_version: !ruby/object:Gem::Requirement
194
+ requirements:
195
+ - - ">="
196
+ - !ruby/object:Gem::Version
197
+ version: '0'
198
+ requirements: []
199
+ rubygems_version: 3.5.11
200
+ signing_key:
201
+ specification_version: 4
202
+ summary: Inertia adapter for Rails
203
+ test_files: []