inertia_rails 3.11.0 → 3.12.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -0
- data/app/controllers/inertia_rails/static_controller.rb +2 -0
- data/lib/generators/inertia/install/install_generator.rb +8 -3
- data/lib/inertia_rails/action_filter.rb +2 -1
- data/lib/inertia_rails/controller.rb +20 -15
- data/lib/inertia_rails/defer_prop.rb +5 -16
- data/lib/inertia_rails/engine.rb +6 -4
- data/lib/inertia_rails/helper.rb +26 -22
- data/lib/inertia_rails/inertia_rails.rb +8 -2
- data/lib/inertia_rails/lazy_prop.rb +1 -1
- data/lib/inertia_rails/merge_prop.rb +3 -12
- data/lib/inertia_rails/prop_mergeable.rb +83 -0
- data/lib/inertia_rails/renderer.rb +82 -23
- data/lib/inertia_rails/rspec.rb +28 -19
- data/lib/inertia_rails/scroll_metadata.rb +97 -0
- data/lib/inertia_rails/scroll_prop.rb +35 -0
- data/lib/inertia_rails/version.rb +3 -1
- data/lib/patches/better_errors.rb +4 -4
- data/lib/patches/debug_exceptions.rb +27 -10
- data/lib/patches/mapper.rb +6 -1
- data/lib/patches/request.rb +2 -0
- data/lib/tasks/inertia_rails.rake +7 -5
- metadata +5 -4
- data/lib/patches/debug_exceptions/patch-5-0.rb +0 -27
- data/lib/patches/debug_exceptions/patch-5-1.rb +0 -30
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 95b5901a42397a1ae01678a1101d5d21a6a2f2f33c6afb413a2fbca48f04e064
|
|
4
|
+
data.tar.gz: a4d04ff25ce45b4392e5ad5c5153530446f83256e2b00452999da0c920751416
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 222ebe8277d96856c05c9d712ad0d0e33cea995e7195dada790cf6423e3ad9f16b970c555c9889a1d7eb9082ad9045ca73a00bc95116fc93912f429fc1ded50f
|
|
7
|
+
data.tar.gz: f859bfb3d498ae8bc2c146e5bd8d9be8cadb65a6f3a51135c89bd1f3e86c83007f2602b9e6b115179e7f294dc663e3c96ce9073890511b478689ddf99156e1b9
|
data/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file.
|
|
|
4
4
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
5
5
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
|
+
## [3.12.0] - 2025-11-08
|
|
8
|
+
|
|
9
|
+
* Docs updates (@leenyburger, @skryukov, @bn-l)
|
|
10
|
+
* Reimplement devcontainers (@kieraneglin)
|
|
11
|
+
* Support for Inertia.js infinite scroll components (@skyrukov)
|
|
12
|
+
* New merge options (@skryukov)
|
|
13
|
+
|
|
7
14
|
## [3.11.0] - 2025-08-29
|
|
8
15
|
|
|
9
16
|
* Fix Svelte generator (@skryukov)
|
|
@@ -128,8 +128,12 @@ module Inertia
|
|
|
128
128
|
add_dependencies(*FRAMEWORKS[framework]['packages_ts'])
|
|
129
129
|
|
|
130
130
|
say 'Copying adding scripts to package.json'
|
|
131
|
-
|
|
132
|
-
|
|
131
|
+
if svelte?
|
|
132
|
+
run 'npm pkg set scripts.check="svelte-check --tsconfig ./tsconfig.json && tsc -p tsconfig.node.json"'
|
|
133
|
+
end
|
|
134
|
+
if framework == 'vue'
|
|
135
|
+
run 'npm pkg set scripts.check="vue-tsc -p tsconfig.app.json && tsc -p tsconfig.node.json"'
|
|
136
|
+
end
|
|
133
137
|
run 'npm pkg set scripts.check="tsc -p tsconfig.app.json && tsc -p tsconfig.node.json"' if framework == 'react'
|
|
134
138
|
end
|
|
135
139
|
|
|
@@ -262,8 +266,9 @@ module Inertia
|
|
|
262
266
|
end
|
|
263
267
|
|
|
264
268
|
def inertia_resolved_version
|
|
269
|
+
package = "@inertiajs/core@#{options[:inertia_version]}"
|
|
265
270
|
@inertia_resolved_version ||= Gem::Version.new(
|
|
266
|
-
`npm show
|
|
271
|
+
`npm show #{package} version --json | tail -n2 | head -n1 | tr -d '", '`.strip
|
|
267
272
|
)
|
|
268
273
|
end
|
|
269
274
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
|
|
2
3
|
#
|
|
3
4
|
# Based on AbstractController::Callbacks::ActionFilter
|
|
4
5
|
# https://github.com/rails/rails/blob/v7.2.0/actionpack/lib/abstract_controller/callbacks.rb#L39
|
|
@@ -6,7 +7,7 @@ module InertiaRails
|
|
|
6
7
|
class ActionFilter
|
|
7
8
|
def initialize(conditional_key, actions)
|
|
8
9
|
@conditional_key = conditional_key
|
|
9
|
-
@actions = Array(actions).
|
|
10
|
+
@actions = Array(actions).to_set(&:to_s)
|
|
10
11
|
end
|
|
11
12
|
|
|
12
13
|
def match?(controller)
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
require_relative
|
|
4
|
-
require_relative
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'inertia_rails'
|
|
4
|
+
require_relative 'helper'
|
|
5
|
+
require_relative 'action_filter'
|
|
6
|
+
require_relative 'meta_tag_builder'
|
|
5
7
|
|
|
6
8
|
module InertiaRails
|
|
7
9
|
module Controller
|
|
@@ -21,8 +23,8 @@ module InertiaRails
|
|
|
21
23
|
return push_to_inertia_share(**(hash || props), &block) if options.empty?
|
|
22
24
|
|
|
23
25
|
push_to_inertia_share do
|
|
24
|
-
next
|
|
25
|
-
next
|
|
26
|
+
next if options[:if] && !options[:if].all? { |filter| instance_exec(&filter) }
|
|
27
|
+
next if options[:unless]&.any? { |filter| instance_exec(&filter) }
|
|
26
28
|
|
|
27
29
|
next hash unless block
|
|
28
30
|
|
|
@@ -81,7 +83,9 @@ module InertiaRails
|
|
|
81
83
|
return options if options.empty?
|
|
82
84
|
|
|
83
85
|
if props.except(:if, :unless, :only, :except).any?
|
|
84
|
-
raise ArgumentError,
|
|
86
|
+
raise ArgumentError,
|
|
87
|
+
'You must not mix shared data and [:if, :unless, :only, :except] options, ' \
|
|
88
|
+
'pass data as a hash or a block.'
|
|
85
89
|
end
|
|
86
90
|
|
|
87
91
|
transform_inertia_share_option(options, :only, :if)
|
|
@@ -110,7 +114,7 @@ module InertiaRails
|
|
|
110
114
|
when InertiaRails::ActionFilter
|
|
111
115
|
-> { filter.match?(self) }
|
|
112
116
|
else
|
|
113
|
-
raise ArgumentError,
|
|
117
|
+
raise ArgumentError, 'You must pass a symbol or a proc as a filter.'
|
|
114
118
|
end
|
|
115
119
|
end
|
|
116
120
|
end
|
|
@@ -136,6 +140,7 @@ module InertiaRails
|
|
|
136
140
|
|
|
137
141
|
def inertia_view_assigns
|
|
138
142
|
return {} unless @_inertia_instance_props
|
|
143
|
+
|
|
139
144
|
view_assigns.except(*@_inertia_skip_props)
|
|
140
145
|
end
|
|
141
146
|
|
|
@@ -152,22 +157,22 @@ module InertiaRails
|
|
|
152
157
|
else
|
|
153
158
|
if inertia_configuration.always_include_errors_hash.nil?
|
|
154
159
|
InertiaRails.deprecator.warn(
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
160
|
+
'To comply with the Inertia protocol, an empty errors hash `{errors: {}}` ' \
|
|
161
|
+
'will be included to all responses by default starting with InertiaRails 4.0. ' \
|
|
162
|
+
'To opt-in now, set `config.always_include_errors_hash = true`. ' \
|
|
163
|
+
'To disable this warning, set it to `false`.'
|
|
159
164
|
)
|
|
160
165
|
end
|
|
161
166
|
{}
|
|
162
167
|
end
|
|
163
168
|
|
|
164
|
-
self.class._inertia_shared_data.filter_map
|
|
169
|
+
self.class._inertia_shared_data.filter_map do |shared_data|
|
|
165
170
|
if shared_data.respond_to?(:call)
|
|
166
171
|
instance_exec(&shared_data)
|
|
167
172
|
else
|
|
168
173
|
shared_data
|
|
169
174
|
end
|
|
170
|
-
|
|
175
|
+
end.reduce(initial_data, &:merge)
|
|
171
176
|
end
|
|
172
177
|
|
|
173
178
|
def inertia_location(url)
|
|
@@ -183,7 +188,7 @@ module InertiaRails
|
|
|
183
188
|
session[:inertia_errors] = inertia_errors.to_hash
|
|
184
189
|
else
|
|
185
190
|
InertiaRails.deprecator.warn(
|
|
186
|
-
|
|
191
|
+
'Object passed to `inertia: { errors: ... }` must respond to `to_hash`. Pass a hash-like object instead.'
|
|
187
192
|
)
|
|
188
193
|
session[:inertia_errors] = inertia_errors
|
|
189
194
|
end
|
|
@@ -2,27 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
module InertiaRails
|
|
4
4
|
class DeferProp < IgnoreOnFirstLoadProp
|
|
5
|
-
|
|
5
|
+
prepend PropMergeable
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
DEFAULT_GROUP = 'default'
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
raise ArgumentError, 'Cannot set both `deep_merge` and `merge` to true' if deep_merge && merge
|
|
9
|
+
attr_reader :group
|
|
11
10
|
|
|
11
|
+
def initialize(**props, &block)
|
|
12
12
|
super(&block)
|
|
13
13
|
|
|
14
|
-
@group = group || DEFAULT_GROUP
|
|
15
|
-
@merge = merge || deep_merge
|
|
16
|
-
@deep_merge = deep_merge
|
|
17
|
-
@match_on = match_on.nil? ? nil : Array(match_on)
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
def merge?
|
|
21
|
-
@merge
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def deep_merge?
|
|
25
|
-
@deep_merge
|
|
14
|
+
@group = props[:group] || DEFAULT_GROUP
|
|
26
15
|
end
|
|
27
16
|
end
|
|
28
17
|
end
|
data/lib/inertia_rails/engine.rb
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'middleware'
|
|
4
|
+
require_relative 'controller'
|
|
3
5
|
|
|
4
6
|
module InertiaRails
|
|
5
7
|
class Engine < ::Rails::Engine
|
|
6
|
-
initializer
|
|
8
|
+
initializer 'inertia_rails.configure_rails_initialization' do |app|
|
|
7
9
|
app.middleware.use ::InertiaRails::Middleware
|
|
8
10
|
end
|
|
9
11
|
|
|
10
|
-
initializer
|
|
12
|
+
initializer 'inertia_rails.action_controller' do
|
|
11
13
|
ActiveSupport.on_load(:action_controller_base) do
|
|
12
14
|
include ::InertiaRails::Controller
|
|
13
15
|
end
|
data/lib/inertia_rails/helper.rb
CHANGED
|
@@ -1,32 +1,36 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require_relative 'inertia_rails'
|
|
2
4
|
|
|
3
|
-
module InertiaRails
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
module InertiaRails
|
|
6
|
+
module Helper
|
|
7
|
+
def inertia_ssr_head
|
|
8
|
+
controller.instance_variable_get('@_inertia_ssr_head')
|
|
9
|
+
end
|
|
7
10
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
def inertia_headers
|
|
12
|
+
InertiaRails.deprecator.warn(
|
|
13
|
+
'`inertia_headers` is deprecated and will be removed in InertiaRails 4.0, use `inertia_ssr_head` instead.'
|
|
14
|
+
)
|
|
15
|
+
inertia_ssr_head
|
|
16
|
+
end
|
|
14
17
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
+
def inertia_rendering?
|
|
19
|
+
controller.instance_variable_get('@_inertia_rendering')
|
|
20
|
+
end
|
|
18
21
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
+
def inertia_page
|
|
23
|
+
controller.instance_variable_get('@_inertia_page')
|
|
24
|
+
end
|
|
22
25
|
|
|
23
|
-
|
|
24
|
-
|
|
26
|
+
def inertia_meta_tags
|
|
27
|
+
meta_tag_data = (inertia_page || {}).dig(:props, :_inertia_meta) || []
|
|
25
28
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
+
meta_tags = meta_tag_data.map do |inertia_meta_tag|
|
|
30
|
+
inertia_meta_tag.to_tag(tag)
|
|
31
|
+
end
|
|
29
32
|
|
|
30
|
-
|
|
33
|
+
safe_join(meta_tags, "\n")
|
|
34
|
+
end
|
|
31
35
|
end
|
|
32
36
|
end
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require 'inertia_rails/prop_mergeable'
|
|
3
4
|
require 'inertia_rails/base_prop'
|
|
4
5
|
require 'inertia_rails/ignore_on_first_load_prop'
|
|
5
6
|
require 'inertia_rails/always_prop'
|
|
@@ -7,6 +8,7 @@ require 'inertia_rails/lazy_prop'
|
|
|
7
8
|
require 'inertia_rails/optional_prop'
|
|
8
9
|
require 'inertia_rails/defer_prop'
|
|
9
10
|
require 'inertia_rails/merge_prop'
|
|
11
|
+
require 'inertia_rails/scroll_prop'
|
|
10
12
|
require 'inertia_rails/configuration'
|
|
11
13
|
require 'inertia_rails/meta_tag'
|
|
12
14
|
|
|
@@ -34,8 +36,8 @@ module InertiaRails
|
|
|
34
36
|
AlwaysProp.new(&block)
|
|
35
37
|
end
|
|
36
38
|
|
|
37
|
-
def merge(
|
|
38
|
-
MergeProp.new(
|
|
39
|
+
def merge(...)
|
|
40
|
+
MergeProp.new(...)
|
|
39
41
|
end
|
|
40
42
|
|
|
41
43
|
def deep_merge(match_on: nil, &block)
|
|
@@ -45,5 +47,9 @@ module InertiaRails
|
|
|
45
47
|
def defer(group: nil, merge: nil, deep_merge: nil, match_on: nil, &block)
|
|
46
48
|
DeferProp.new(group: group, merge: merge, deep_merge: deep_merge, match_on: match_on, &block)
|
|
47
49
|
end
|
|
50
|
+
|
|
51
|
+
def scroll(metadata = nil, **options, &block)
|
|
52
|
+
ScrollProp.new(metadata: metadata, **options, &block)
|
|
53
|
+
end
|
|
48
54
|
end
|
|
49
55
|
end
|
|
@@ -2,20 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
module InertiaRails
|
|
4
4
|
class MergeProp < BaseProp
|
|
5
|
-
|
|
5
|
+
prepend PropMergeable
|
|
6
6
|
|
|
7
|
-
def initialize(
|
|
7
|
+
def initialize(**_props, &block)
|
|
8
8
|
super(&block)
|
|
9
|
-
@
|
|
10
|
-
@match_on = match_on.nil? ? nil : Array(match_on)
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def merge?
|
|
14
|
-
true
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def deep_merge?
|
|
18
|
-
@deep_merge
|
|
9
|
+
@merge = true
|
|
19
10
|
end
|
|
20
11
|
end
|
|
21
12
|
end
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module InertiaRails
|
|
4
|
+
module PropMergeable
|
|
5
|
+
attr_reader :match_on, :appends_at_paths, :prepends_at_paths
|
|
6
|
+
|
|
7
|
+
def initialize(**props, &block)
|
|
8
|
+
raise ArgumentError, 'Cannot set both `deep_merge` and `merge` to true' if props[:deep_merge] && props[:merge]
|
|
9
|
+
|
|
10
|
+
@deep_merge = props.fetch(:deep_merge, false)
|
|
11
|
+
@merge = props[:merge] || @deep_merge
|
|
12
|
+
@match_on = props[:match_on].nil? ? nil : Array(props[:match_on])
|
|
13
|
+
@appends_at_paths = []
|
|
14
|
+
@prepends_at_paths = []
|
|
15
|
+
@append = true
|
|
16
|
+
|
|
17
|
+
append(props[:append]) if props.key?(:append)
|
|
18
|
+
prepend(props[:prepend]) if props.key?(:prepend)
|
|
19
|
+
|
|
20
|
+
super
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def appends_at_root?
|
|
24
|
+
@append && merges_at_root?
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def prepends_at_root?
|
|
28
|
+
!@append && merges_at_root?
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def merges_at_root?
|
|
32
|
+
merge? && appends_at_paths.none? && prepends_at_paths.none?
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def merge?
|
|
36
|
+
@merge
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def deep_merge?
|
|
40
|
+
@deep_merge
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
private
|
|
44
|
+
|
|
45
|
+
def append(path, match_on: nil)
|
|
46
|
+
case path
|
|
47
|
+
when TrueClass, FalseClass
|
|
48
|
+
@append = path
|
|
49
|
+
when String
|
|
50
|
+
@appends_at_paths << path
|
|
51
|
+
when Array
|
|
52
|
+
@appends_at_paths += path
|
|
53
|
+
when Hash
|
|
54
|
+
@match_on ||= []
|
|
55
|
+
path.each do |key, value|
|
|
56
|
+
@appends_at_paths << key.to_s
|
|
57
|
+
@match_on << "#{key}.#{value}" if value
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
(@match_on ||= []) << "#{path}.#{match_on}" if match_on && path.is_a?(String)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def prepend(path, match_on: nil)
|
|
65
|
+
case path
|
|
66
|
+
when TrueClass, FalseClass
|
|
67
|
+
@append = !path
|
|
68
|
+
when String
|
|
69
|
+
@prepends_at_paths << path
|
|
70
|
+
when Array
|
|
71
|
+
@prepends_at_paths += path
|
|
72
|
+
when Hash
|
|
73
|
+
@match_on ||= []
|
|
74
|
+
path.each do |key, value|
|
|
75
|
+
@prepends_at_paths << key.to_s
|
|
76
|
+
@match_on << "#{key}.#{value}" if value
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
(@match_on ||= []) << "#{path}.#{match_on}" if match_on && path.is_a?(String)
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
@@ -101,13 +101,16 @@ module InertiaRails
|
|
|
101
101
|
end
|
|
102
102
|
.then { |props| deep_transform_props(props) } # Internal hydration/filtering
|
|
103
103
|
.then { |props| configuration.prop_transformer(props: props) } # Apply user-defined prop transformer
|
|
104
|
-
.tap
|
|
105
|
-
|
|
104
|
+
.tap do |props| # Add meta tags last (never transformed)
|
|
105
|
+
props[:_inertia_meta] = meta_tags if meta_tags.present?
|
|
106
|
+
end
|
|
106
107
|
# rubocop:enable Style/MultilineBlockChain
|
|
107
108
|
end
|
|
108
109
|
|
|
109
110
|
def page
|
|
110
|
-
|
|
111
|
+
return @page if defined?(@page)
|
|
112
|
+
|
|
113
|
+
@page = {
|
|
111
114
|
component: component,
|
|
112
115
|
props: computed_props,
|
|
113
116
|
url: @request.original_fullpath,
|
|
@@ -117,21 +120,11 @@ module InertiaRails
|
|
|
117
120
|
}
|
|
118
121
|
|
|
119
122
|
deferred_props = deferred_props_keys
|
|
120
|
-
|
|
123
|
+
@page[:deferredProps] = deferred_props if deferred_props.present?
|
|
124
|
+
@page[:scrollProps] = scroll_props if scroll_props.present?
|
|
125
|
+
@page.merge!(resolve_merge_props)
|
|
121
126
|
|
|
122
|
-
|
|
123
|
-
prop.deep_merge?
|
|
124
|
-
end
|
|
125
|
-
|
|
126
|
-
match_props_on = all_merge_props.filter_map do |key, prop|
|
|
127
|
-
prop.match_on.map { |ms| "#{key}.#{ms}" } if prop.match_on.present?
|
|
128
|
-
end.flatten
|
|
129
|
-
|
|
130
|
-
default_page[:mergeProps] = merge_props.map(&:first) if merge_props.present?
|
|
131
|
-
default_page[:deepMergeProps] = deep_merge_props.map(&:first) if deep_merge_props.present?
|
|
132
|
-
default_page[:matchPropsOn] = match_props_on if match_props_on.present?
|
|
133
|
-
|
|
134
|
-
default_page
|
|
127
|
+
@page
|
|
135
128
|
end
|
|
136
129
|
|
|
137
130
|
def deep_transform_props(props, parent_path = [])
|
|
@@ -163,10 +156,28 @@ module InertiaRails
|
|
|
163
156
|
end
|
|
164
157
|
end
|
|
165
158
|
|
|
166
|
-
def
|
|
167
|
-
|
|
159
|
+
def resolve_merge_props
|
|
160
|
+
deep_merge_props, merge_props = all_merge_props.partition do |_key, prop|
|
|
161
|
+
prop.deep_merge?
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
{
|
|
165
|
+
mergeProps: append_merge_props(merge_props),
|
|
166
|
+
prependProps: prepend_merge_props(merge_props),
|
|
167
|
+
deepMergeProps: deep_merge_props.map!(&:first),
|
|
168
|
+
matchPropsOn: resolve_match_on_props,
|
|
169
|
+
}.delete_if { |_, v| v.blank? }
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
def resolve_match_on_props
|
|
173
|
+
all_merge_props.filter_map do |key, prop|
|
|
174
|
+
prop.match_on.map! { |ms| "#{key}.#{ms}" } if prop.match_on.present?
|
|
175
|
+
end.flatten
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
def requested_merge_props
|
|
179
|
+
@requested_merge_props ||= @props.select do |key, prop|
|
|
168
180
|
next unless prop.try(:merge?)
|
|
169
|
-
next if reset_keys.include?(key)
|
|
170
181
|
next if rendering_partial_component? && (
|
|
171
182
|
(partial_keys.present? && partial_keys.exclude?(key.name)) ||
|
|
172
183
|
(partial_except_keys.present? && partial_except_keys.include?(key.name))
|
|
@@ -176,16 +187,64 @@ module InertiaRails
|
|
|
176
187
|
end
|
|
177
188
|
end
|
|
178
189
|
|
|
190
|
+
def append_merge_props(props)
|
|
191
|
+
return props if props.empty?
|
|
192
|
+
|
|
193
|
+
root_append_props, nested_append_props = props.partition { |_key, prop| prop.appends_at_root? }
|
|
194
|
+
|
|
195
|
+
result = Set.new(root_append_props.map!(&:first))
|
|
196
|
+
|
|
197
|
+
nested_append_props.each do |key, prop|
|
|
198
|
+
prop.appends_at_paths.each do |path|
|
|
199
|
+
result.add("#{key}.#{path}")
|
|
200
|
+
end
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
result.to_a
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
def prepend_merge_props(props)
|
|
207
|
+
return props if props.empty?
|
|
208
|
+
|
|
209
|
+
root_prepend_props, nested_prepend_props = props.partition { |_key, prop| prop.prepends_at_root? }
|
|
210
|
+
|
|
211
|
+
result = Set.new(root_prepend_props.map!(&:first))
|
|
212
|
+
|
|
213
|
+
nested_prepend_props.each do |key, prop|
|
|
214
|
+
prop.prepends_at_paths.each do |path|
|
|
215
|
+
result.add("#{key}.#{path}")
|
|
216
|
+
end
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
result.to_a
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
def scroll_props
|
|
223
|
+
return @scroll_props if defined?(@scroll_props)
|
|
224
|
+
|
|
225
|
+
@scroll_props = {}
|
|
226
|
+
requested_merge_props.each do |key, prop|
|
|
227
|
+
next unless prop.is_a?(ScrollProp)
|
|
228
|
+
|
|
229
|
+
@scroll_props[key] = prop.metadata.merge!(reset: reset_keys.include?(key))
|
|
230
|
+
end
|
|
231
|
+
@scroll_props
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
def all_merge_props
|
|
235
|
+
@all_merge_props ||= requested_merge_props.reject { |key,| reset_keys.include?(key) }
|
|
236
|
+
end
|
|
237
|
+
|
|
179
238
|
def partial_keys
|
|
180
|
-
@partial_keys ||= (@request.headers['X-Inertia-Partial-Data'] || '').split(',').
|
|
239
|
+
@partial_keys ||= (@request.headers['X-Inertia-Partial-Data'] || '').split(',').compact_blank!
|
|
181
240
|
end
|
|
182
241
|
|
|
183
242
|
def reset_keys
|
|
184
|
-
(@request.headers['X-Inertia-Reset'] || '').split(',').
|
|
243
|
+
@reset_keys ||= (@request.headers['X-Inertia-Reset'] || '').split(',').compact_blank!.map!(&:to_sym)
|
|
185
244
|
end
|
|
186
245
|
|
|
187
246
|
def partial_except_keys
|
|
188
|
-
(@request.headers['X-Inertia-Partial-Except'] || '').split(',').
|
|
247
|
+
@partial_except_keys ||= (@request.headers['X-Inertia-Partial-Except'] || '').split(',').compact_blank!
|
|
189
248
|
end
|
|
190
249
|
|
|
191
250
|
def rendering_partial_component?
|
data/lib/inertia_rails/rspec.rb
CHANGED
|
@@ -1,30 +1,32 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'rspec/core'
|
|
4
|
+
require 'rspec/matchers'
|
|
3
5
|
|
|
4
6
|
module InertiaRails
|
|
5
7
|
module RSpec
|
|
6
8
|
class InertiaRenderWrapper
|
|
7
9
|
attr_reader :view_data, :props, :component
|
|
8
|
-
|
|
10
|
+
|
|
9
11
|
def initialize
|
|
10
12
|
@view_data = nil
|
|
11
13
|
@props = nil
|
|
12
14
|
@component = nil
|
|
13
15
|
end
|
|
14
|
-
|
|
16
|
+
|
|
15
17
|
def call(params)
|
|
16
|
-
|
|
18
|
+
assign_locals(params)
|
|
17
19
|
@render_method&.call(params)
|
|
18
20
|
end
|
|
19
|
-
|
|
21
|
+
|
|
20
22
|
def wrap_render(render_method)
|
|
21
23
|
@render_method = render_method
|
|
22
24
|
self
|
|
23
25
|
end
|
|
24
|
-
|
|
26
|
+
|
|
25
27
|
protected
|
|
26
|
-
|
|
27
|
-
def
|
|
28
|
+
|
|
29
|
+
def assign_locals(params)
|
|
28
30
|
if params[:locals].present?
|
|
29
31
|
@view_data = params[:locals].except(:page)
|
|
30
32
|
@props = params[:locals][:page][:props]
|
|
@@ -33,18 +35,24 @@ module InertiaRails
|
|
|
33
35
|
# Sequential Inertia request
|
|
34
36
|
@view_data = {}
|
|
35
37
|
json = JSON.parse(params[:json])
|
|
36
|
-
@props = json[
|
|
37
|
-
@component = json[
|
|
38
|
+
@props = json['props']
|
|
39
|
+
@component = json['component']
|
|
38
40
|
end
|
|
39
41
|
end
|
|
40
42
|
end
|
|
41
43
|
|
|
42
44
|
module Helpers
|
|
43
45
|
def inertia
|
|
44
|
-
|
|
46
|
+
unless inertia_tests_setup?
|
|
47
|
+
raise "Inertia test helpers aren't set up! " \
|
|
48
|
+
'Make sure you add `inertia: true` to describe blocks using inertia tests.'
|
|
49
|
+
end
|
|
45
50
|
|
|
46
51
|
if @_inertia_render_wrapper.nil? && !::RSpec.configuration.inertia[:skip_missing_renderer_warnings]
|
|
47
|
-
warn 'WARNING: the test never created an Inertia renderer.
|
|
52
|
+
warn 'WARNING: the test never created an Inertia renderer. ' \
|
|
53
|
+
"Maybe the code wasn't able to reach a `render inertia:` call? If this was intended, " \
|
|
54
|
+
"or you don't want to see this message, " \
|
|
55
|
+
'set ::RSpec.configuration.inertia[:skip_missing_renderer_warnings] = true'
|
|
48
56
|
end
|
|
49
57
|
@_inertia_render_wrapper
|
|
50
58
|
end
|
|
@@ -57,8 +65,8 @@ module InertiaRails
|
|
|
57
65
|
@_inertia_render_wrapper = InertiaRenderWrapper.new.wrap_render(render)
|
|
58
66
|
end
|
|
59
67
|
|
|
60
|
-
protected
|
|
61
|
-
|
|
68
|
+
protected
|
|
69
|
+
|
|
62
70
|
def inertia_tests_setup?
|
|
63
71
|
::RSpec.current_example.metadata.fetch(:inertia, false)
|
|
64
72
|
end
|
|
@@ -67,9 +75,9 @@ module InertiaRails
|
|
|
67
75
|
end
|
|
68
76
|
|
|
69
77
|
RSpec.configure do |config|
|
|
70
|
-
config.include
|
|
78
|
+
config.include InertiaRails::RSpec::Helpers
|
|
71
79
|
config.add_setting :inertia, default: {
|
|
72
|
-
skip_missing_renderer_warnings: false
|
|
80
|
+
skip_missing_renderer_warnings: false,
|
|
73
81
|
}
|
|
74
82
|
|
|
75
83
|
config.before(:each, inertia: true) do
|
|
@@ -106,13 +114,14 @@ RSpec::Matchers.define :render_component do |expected_component|
|
|
|
106
114
|
end
|
|
107
115
|
|
|
108
116
|
failure_message do |inertia|
|
|
109
|
-
"expected rendered inertia component to be #{expected_component},
|
|
117
|
+
"expected rendered inertia component to be #{expected_component}, " \
|
|
118
|
+
"instead received #{inertia.component || 'nothing'}"
|
|
110
119
|
end
|
|
111
120
|
end
|
|
112
121
|
|
|
113
122
|
RSpec::Matchers.define :have_exact_view_data do |expected_view_data|
|
|
114
123
|
match do |inertia|
|
|
115
|
-
expect(inertia.view_data).to eq expected_view_data
|
|
124
|
+
expect(inertia.view_data).to eq expected_view_data
|
|
116
125
|
end
|
|
117
126
|
|
|
118
127
|
failure_message do |inertia|
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module InertiaRails
|
|
4
|
+
module ScrollMetadata
|
|
5
|
+
class MissingMetadataAdapterError < StandardError; end
|
|
6
|
+
|
|
7
|
+
class Props
|
|
8
|
+
def initialize(page_name:, previous_page:, next_page:, current_page:)
|
|
9
|
+
@page_name = page_name
|
|
10
|
+
@previous_page = previous_page
|
|
11
|
+
@next_page = next_page
|
|
12
|
+
@current_page = current_page
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def as_json(_options = nil)
|
|
16
|
+
{
|
|
17
|
+
pageName: @page_name,
|
|
18
|
+
previousPage: @previous_page,
|
|
19
|
+
nextPage: @next_page,
|
|
20
|
+
currentPage: @current_page,
|
|
21
|
+
}
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
class KaminariAdapter
|
|
26
|
+
def match?(metadata)
|
|
27
|
+
defined?(Kaminari) && metadata.is_a?(Kaminari::PageScopeMethods)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def call(metadata, **_options)
|
|
31
|
+
{
|
|
32
|
+
page_name: (Kaminari.config.param_name || 'page').to_s,
|
|
33
|
+
previous_page: metadata.prev_page,
|
|
34
|
+
next_page: metadata.next_page,
|
|
35
|
+
current_page: metadata.current_page,
|
|
36
|
+
}
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
class PagyAdapter
|
|
41
|
+
def match?(metadata)
|
|
42
|
+
defined?(Pagy) && metadata.is_a?(Pagy)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def call(metadata, **_options)
|
|
46
|
+
page_name = metadata.respond_to?(:vars) ? metadata.vars.fetch(:page_param) : metadata.options[:page_key]
|
|
47
|
+
{
|
|
48
|
+
page_name: page_name.to_s,
|
|
49
|
+
previous_page: metadata.try(:prev) || metadata.try(:previous),
|
|
50
|
+
next_page: metadata.next,
|
|
51
|
+
current_page: metadata.page,
|
|
52
|
+
}
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
class HashAdapter
|
|
57
|
+
def match?(metadata)
|
|
58
|
+
metadata.is_a?(Hash)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def call(metadata, **_options)
|
|
62
|
+
{
|
|
63
|
+
page_name: metadata.fetch(:page_name),
|
|
64
|
+
previous_page: metadata.fetch(:previous_page),
|
|
65
|
+
next_page: metadata.fetch(:next_page),
|
|
66
|
+
current_page: metadata.fetch(:current_page),
|
|
67
|
+
}
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
class << self
|
|
72
|
+
attr_accessor :adapters
|
|
73
|
+
|
|
74
|
+
def extract(metadata, **options)
|
|
75
|
+
overrides = options.slice(:page_name, :previous_page, :next_page, :current_page)
|
|
76
|
+
|
|
77
|
+
adapters.each do |adapter|
|
|
78
|
+
next unless adapter.match?(metadata)
|
|
79
|
+
|
|
80
|
+
return Props.new(**adapter.call(metadata, **options).merge!(overrides)).as_json
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
begin
|
|
84
|
+
Props.new(**overrides).as_json
|
|
85
|
+
rescue ArgumentError
|
|
86
|
+
raise MissingMetadataAdapterError, "No ScrollMetadata adapter found for #{metadata}"
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def register_adapter(adapter)
|
|
91
|
+
adapters.unshift(adapter.new)
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
self.adapters = [KaminariAdapter, PagyAdapter, HashAdapter].map(&:new)
|
|
96
|
+
end
|
|
97
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'scroll_metadata'
|
|
4
|
+
|
|
5
|
+
module InertiaRails
|
|
6
|
+
class ScrollProp < BaseProp
|
|
7
|
+
prepend PropMergeable
|
|
8
|
+
|
|
9
|
+
def initialize(**options, &block)
|
|
10
|
+
super(&block)
|
|
11
|
+
|
|
12
|
+
@merge = true
|
|
13
|
+
@metadata = options.delete(:metadata)
|
|
14
|
+
@wrapper = options.delete(:wrapper)
|
|
15
|
+
|
|
16
|
+
@options = options
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def call(controller)
|
|
20
|
+
@value = super
|
|
21
|
+
configure_merge_intent(controller.request.headers['X-Inertia-Infinite-Scroll-Merge-Intent'])
|
|
22
|
+
@value
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def metadata
|
|
26
|
+
ScrollMetadata.extract(@metadata, **@options)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
private
|
|
30
|
+
|
|
31
|
+
def configure_merge_intent(scroll_intent)
|
|
32
|
+
scroll_intent == 'prepend' ? prepend(@wrapper || true) : append(@wrapper || true)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
# Patch BetterErrors::Middleware to render HTML for Inertia requests
|
|
2
4
|
#
|
|
3
5
|
# Original source:
|
|
@@ -7,13 +9,11 @@
|
|
|
7
9
|
module InertiaRails
|
|
8
10
|
module InertiaBetterErrors
|
|
9
11
|
def text?(env)
|
|
10
|
-
return false if env[
|
|
12
|
+
return false if env['HTTP_X_INERTIA']
|
|
11
13
|
|
|
12
14
|
super
|
|
13
15
|
end
|
|
14
16
|
end
|
|
15
17
|
end
|
|
16
18
|
|
|
17
|
-
if defined?(BetterErrors)
|
|
18
|
-
BetterErrors::Middleware.include InertiaRails::InertiaBetterErrors
|
|
19
|
-
end
|
|
19
|
+
BetterErrors::Middleware.include InertiaRails::InertiaBetterErrors if defined?(BetterErrors)
|
|
@@ -1,17 +1,34 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
# Patch ActionDispatch::DebugExceptions to render HTML for Inertia requests
|
|
2
4
|
#
|
|
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
5
|
# The original source needs to be patched, so that Inertia requests are
|
|
7
6
|
# NOT responded with plain text, but with HTML.
|
|
7
|
+
#
|
|
8
|
+
# Original source (unchanged since Rails 5.1):
|
|
9
|
+
# https://github.com/rails/rails/blob/5-1-stable/actionpack/lib/action_dispatch/middleware/debug_exceptions.rb
|
|
10
|
+
# https://github.com/rails/rails/blob/8-0-stable/actionpack/lib/action_dispatch/middleware/debug_exceptions.rb
|
|
11
|
+
#
|
|
8
12
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
module InertiaRails
|
|
14
|
+
module InertiaDebugExceptions
|
|
15
|
+
def render_for_browser_request(request, wrapper)
|
|
16
|
+
template = create_template(request, wrapper)
|
|
17
|
+
file = "rescues/#{wrapper.rescue_template}"
|
|
18
|
+
|
|
19
|
+
if request.xhr? && !request.headers['X-Inertia'] # <<<< this line is changed only
|
|
20
|
+
body = template.render(template: file, layout: false, formats: [:text])
|
|
21
|
+
format = 'text/plain'
|
|
22
|
+
else
|
|
23
|
+
body = template.render(template: file, layout: 'rescues/layout')
|
|
24
|
+
format = 'text/html'
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
render(wrapper.status_code, body, format)
|
|
28
|
+
end
|
|
16
29
|
end
|
|
17
30
|
end
|
|
31
|
+
|
|
32
|
+
if defined?(ActionDispatch::DebugExceptions)
|
|
33
|
+
ActionDispatch::DebugExceptions.prepend InertiaRails::InertiaDebugExceptions
|
|
34
|
+
end
|
data/lib/patches/mapper.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module InertiaRails
|
|
2
4
|
module InertiaMapper
|
|
3
5
|
def inertia(*args, **options)
|
|
@@ -12,7 +14,10 @@ module InertiaRails
|
|
|
12
14
|
if path.is_a?(Hash)
|
|
13
15
|
path.first
|
|
14
16
|
elsif resource_scope?
|
|
15
|
-
[path,
|
|
17
|
+
[path,
|
|
18
|
+
InertiaRails.configuration.component_path_resolver(
|
|
19
|
+
path: [@scope[:module], @scope[:controller]].compact.join('/'), action: path
|
|
20
|
+
)]
|
|
16
21
|
elsif @scope[:module].blank?
|
|
17
22
|
[path, path]
|
|
18
23
|
else
|
data/lib/patches/request.rb
CHANGED
|
@@ -1,16 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
namespace :inertia_rails do
|
|
2
4
|
namespace :install do
|
|
3
|
-
desc
|
|
4
|
-
task :
|
|
5
|
+
desc 'Installs inertia_rails packages and configurations for a React based app'
|
|
6
|
+
task react: :environment do
|
|
5
7
|
system 'rails g inertia_rails:install --front_end react'
|
|
6
8
|
end
|
|
7
|
-
desc
|
|
9
|
+
desc 'Installs inertia_rails packages and configurations for a Vue based app'
|
|
8
10
|
task vue: :environment do
|
|
9
11
|
system 'rails g inertia_rails:install --front_end vue'
|
|
10
12
|
end
|
|
11
|
-
desc
|
|
13
|
+
desc 'Installs inertia_rails packages and configurations for a Svelte based app'
|
|
12
14
|
task svelte: :environment do
|
|
13
15
|
system 'rails g inertia_rails:install --front_end svelte'
|
|
14
16
|
end
|
|
15
17
|
end
|
|
16
|
-
end
|
|
18
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: inertia_rails
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.
|
|
4
|
+
version: 3.12.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Brian Knoles
|
|
@@ -9,7 +9,7 @@ authors:
|
|
|
9
9
|
- Eugene Granovsky
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date: 2025-08
|
|
12
|
+
date: 2025-11-08 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: railties
|
|
@@ -229,13 +229,14 @@ files:
|
|
|
229
229
|
- lib/inertia_rails/meta_tag_builder.rb
|
|
230
230
|
- lib/inertia_rails/middleware.rb
|
|
231
231
|
- lib/inertia_rails/optional_prop.rb
|
|
232
|
+
- lib/inertia_rails/prop_mergeable.rb
|
|
232
233
|
- lib/inertia_rails/renderer.rb
|
|
233
234
|
- lib/inertia_rails/rspec.rb
|
|
235
|
+
- lib/inertia_rails/scroll_metadata.rb
|
|
236
|
+
- lib/inertia_rails/scroll_prop.rb
|
|
234
237
|
- lib/inertia_rails/version.rb
|
|
235
238
|
- lib/patches/better_errors.rb
|
|
236
239
|
- lib/patches/debug_exceptions.rb
|
|
237
|
-
- lib/patches/debug_exceptions/patch-5-0.rb
|
|
238
|
-
- lib/patches/debug_exceptions/patch-5-1.rb
|
|
239
240
|
- lib/patches/mapper.rb
|
|
240
241
|
- lib/patches/request.rb
|
|
241
242
|
- lib/tasks/inertia_rails.rake
|
|
@@ -1,27 +0,0 @@
|
|
|
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
|
-
module InertiaRails
|
|
8
|
-
module InertiaDebugExceptions
|
|
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
|
|
24
|
-
|
|
25
|
-
if defined?(ActionDispatch::DebugExceptions)
|
|
26
|
-
ActionDispatch::DebugExceptions.prepend InertiaRails::InertiaDebugExceptions
|
|
27
|
-
end
|
|
@@ -1,30 +0,0 @@
|
|
|
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
|
-
module InertiaRails
|
|
10
|
-
module InertiaDebugExceptions
|
|
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
|
|
27
|
-
|
|
28
|
-
if defined?(ActionDispatch::DebugExceptions)
|
|
29
|
-
ActionDispatch::DebugExceptions.prepend InertiaRails::InertiaDebugExceptions
|
|
30
|
-
end
|