rage-rb 1.5.0 → 1.6.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 +13 -0
- data/OVERVIEW.md +53 -0
- data/lib/rage/configuration.rb +1 -1
- data/lib/rage/controller/api.rb +5 -5
- data/lib/rage/middleware/cors.rb +3 -3
- data/lib/rage/rails.rb +5 -3
- data/lib/rage/router/backend.rb +6 -6
- data/lib/rage/router/constrainer.rb +3 -3
- data/lib/rage/router/dsl.rb +50 -26
- data/lib/rage/router/dsl_plugins/controller_action_options.rb +25 -0
- data/lib/rage/router/dsl_plugins/legacy_hash_notation.rb +46 -0
- data/lib/rage/router/dsl_plugins/legacy_root_notation.rb +14 -0
- data/lib/rage/router/dsl_plugins/named_route_helpers.rb +13 -0
- data/lib/rage/router/handler_storage.rb +1 -1
- data/lib/rage/router/strategies/host.rb +1 -1
- data/lib/rage/router/util.rb +8 -2
- data/lib/rage/version.rb +1 -1
- data/lib/rage-rb.rb +3 -0
- metadata +7 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 39c84f49894f7ae6e8c53e78d5c84eef65885c15f3ad7d6469458a79dba6e691
|
4
|
+
data.tar.gz: 3a8b37eb48370a2a63c1b78f09417013f60593cdbcf0385958dd495ce35e494c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8db258b1f23a58def4118ca0bdb1efcf6534ff03362ac82c45ded5276c90ab42809e007a9d7f72972dc8fd2597ac5eab2bbfaf27d6efb38a3857b1133fdbecde
|
7
|
+
data.tar.gz: eb7a5910f52399ff67bc0bc4078fcc970e023fcc038dc65dd16b19e17afa902a95a7c1b62cca7f61a5f5e38ba45702dc2a314ef841868fd7cf40289a65a0fe0f
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,18 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
|
3
|
+
## [1.6.0] - 2024-07-15
|
4
|
+
|
5
|
+
### Added
|
6
|
+
|
7
|
+
- Support legacy route helpers (#90).
|
8
|
+
- Correctly handle internal Rails routes in `Rage.multi_application` (#91).
|
9
|
+
|
10
|
+
## [1.5.1] - 2024-05-26
|
11
|
+
|
12
|
+
### Fixed
|
13
|
+
|
14
|
+
- Correctly reload code in multi apps (#87).
|
15
|
+
|
3
16
|
## [1.5.0] - 2024-05-08
|
4
17
|
|
5
18
|
### Added
|
data/OVERVIEW.md
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
### Boot sequence and request lifecycle
|
2
|
+
|
3
|
+
The following diagram describes some of Rage's internal components and the way they interact with each other:
|
4
|
+
|
5
|
+

|
6
|
+
|
7
|
+
### Executing controller actions
|
8
|
+
|
9
|
+
When `Rage::Router::DSL` parses the `config/routes.rb` file and calls the `Rage::Router::Backend` class, it registers actions and stores handler procs.
|
10
|
+
|
11
|
+
Consider we have the following controller:
|
12
|
+
|
13
|
+
```ruby
|
14
|
+
class UsersController < RageController::API
|
15
|
+
before_action :find_user
|
16
|
+
rescue_from ActiveRecord::RecordNotFound, with: :render_not_found
|
17
|
+
|
18
|
+
def show
|
19
|
+
render json: @user
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def find_user
|
25
|
+
@user = User.find(params[:id])
|
26
|
+
end
|
27
|
+
|
28
|
+
def render_not_found(_)
|
29
|
+
render status: :not_found
|
30
|
+
end
|
31
|
+
end
|
32
|
+
```
|
33
|
+
|
34
|
+
Before processing requests to `UsersController#show`, Rage has to [register](https://github.com/rage-rb/rage/blob/master/lib/rage/controller/api.rb#L10) the show action. Registering means defining a new method that will look like this:
|
35
|
+
|
36
|
+
```ruby
|
37
|
+
class UsersController
|
38
|
+
def __run_show
|
39
|
+
find_user
|
40
|
+
show
|
41
|
+
rescue ActiveRecord::RecordNotFound => e
|
42
|
+
render_not_found(e)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
```
|
46
|
+
|
47
|
+
After that, Rage will create and store a handler proc that will look exactly like this:
|
48
|
+
|
49
|
+
```ruby
|
50
|
+
->(env, params) { UsersController.new(env, params).__run_show }
|
51
|
+
```
|
52
|
+
|
53
|
+
All of this happens at boot time. Once the request comes in at runtime, Rage will only need to retrieve the handler proc defined earlier and call it.
|
data/lib/rage/configuration.rb
CHANGED
@@ -114,7 +114,7 @@ class Rage::Configuration
|
|
114
114
|
def config = self
|
115
115
|
|
116
116
|
def log_formatter=(formatter)
|
117
|
-
raise "Custom log formatter should respond to `#call`" unless formatter.respond_to?(:call)
|
117
|
+
raise ArgumentError, "Custom log formatter should respond to `#call`" unless formatter.respond_to?(:call)
|
118
118
|
@log_formatter = formatter
|
119
119
|
end
|
120
120
|
|
data/lib/rage/controller/api.rb
CHANGED
@@ -168,7 +168,7 @@ class RageController::API
|
|
168
168
|
if block_given?
|
169
169
|
with = define_tmp_method(block)
|
170
170
|
else
|
171
|
-
raise "No handler provided. Pass the `with` keyword argument or provide a block."
|
171
|
+
raise ArgumentError, "No handler provided. Pass the `with` keyword argument or provide a block."
|
172
172
|
end
|
173
173
|
end
|
174
174
|
|
@@ -224,7 +224,7 @@ class RageController::API
|
|
224
224
|
|
225
225
|
# Register a new `after_action` hook. Calls with the same `action_name` will overwrite the previous ones.
|
226
226
|
#
|
227
|
-
# @param action_name [
|
227
|
+
# @param action_name [Symbol, nil] the name of the callback to add
|
228
228
|
# @param [Hash] opts action options
|
229
229
|
# @option opts [Symbol, Array<Symbol>] :only restrict the callback to run only for specific actions
|
230
230
|
# @option opts [Symbol, Array<Symbol>] :except restrict the callback to run for all actions except specified
|
@@ -250,14 +250,14 @@ class RageController::API
|
|
250
250
|
|
251
251
|
# Prevent a `before_action` hook from running.
|
252
252
|
#
|
253
|
-
# @param action_name [
|
253
|
+
# @param action_name [Symbol] the name of the callback to skip
|
254
254
|
# @param only [Symbol, Array<Symbol>] restrict the callback to be skipped only for specific actions
|
255
255
|
# @param except [Symbol, Array<Symbol>] restrict the callback to be skipped for all actions except specified
|
256
256
|
# @example
|
257
257
|
# skip_before_action :find_photo, only: :create
|
258
258
|
def skip_before_action(action_name, only: nil, except: nil)
|
259
259
|
i = @__before_actions&.find_index { |a| a[:name] == action_name }
|
260
|
-
raise "The following action was specified to be skipped but couldn't be found: #{self}##{action_name}" unless i
|
260
|
+
raise ArgumentError, "The following action was specified to be skipped but couldn't be found: #{self}##{action_name}" unless i
|
261
261
|
|
262
262
|
@__before_actions = @__before_actions.dup if @__before_actions.frozen?
|
263
263
|
|
@@ -284,7 +284,7 @@ class RageController::API
|
|
284
284
|
if block_given?
|
285
285
|
action_name = define_tmp_method(block)
|
286
286
|
elsif action_name.nil?
|
287
|
-
raise "No handler provided. Pass the `action_name` parameter or provide a block."
|
287
|
+
raise ArgumentError, "No handler provided. Pass the `action_name` parameter or provide a block."
|
288
288
|
end
|
289
289
|
|
290
290
|
_only, _except, _if, _unless = opts.values_at(:only, :except, :if, :unless)
|
data/lib/rage/middleware/cors.rb
CHANGED
@@ -64,7 +64,7 @@ class Rage::Cors
|
|
64
64
|
@methods = if methods != "*"
|
65
65
|
methods.map! { |method| method.to_s.upcase }.tap { |m|
|
66
66
|
if (invalid_methods = m - @default_methods).any?
|
67
|
-
raise "Unsupported method passed to Rage::Cors: #{invalid_methods[0]}"
|
67
|
+
raise ArgumentError, "Unsupported method passed to Rage::Cors: #{invalid_methods[0]}"
|
68
68
|
end
|
69
69
|
}.join(", ")
|
70
70
|
elsif @allow_credentials
|
@@ -74,8 +74,8 @@ class Rage::Cors
|
|
74
74
|
end
|
75
75
|
|
76
76
|
if @allow_credentials
|
77
|
-
raise "Rage::Cors requires you to explicitly list allowed headers when using `allow_credentials: true`" if @allow_headers == "*"
|
78
|
-
raise "Rage::Cors requires you to explicitly list exposed headers when using `allow_credentials: true`" if @expose_headers == "*"
|
77
|
+
raise ArgumentError, "Rage::Cors requires you to explicitly list allowed headers when using `allow_credentials: true`" if @allow_headers == "*"
|
78
|
+
raise ArgumentError, "Rage::Cors requires you to explicitly list exposed headers when using `allow_credentials: true`" if @expose_headers == "*"
|
79
79
|
end
|
80
80
|
|
81
81
|
@origins = []
|
data/lib/rage/rails.rb
CHANGED
@@ -22,12 +22,14 @@ end
|
|
22
22
|
Rails.configuration.after_initialize do
|
23
23
|
conditional_mutex = Module.new do
|
24
24
|
def call(env)
|
25
|
-
|
26
|
-
|
27
|
-
@mutex.synchronize { super }
|
25
|
+
res = if Rails.application.reloader.check! || !$rage_code_loaded
|
26
|
+
Fiber.new(blocking: true) { super }.resume
|
28
27
|
else
|
29
28
|
super
|
30
29
|
end
|
30
|
+
$rage_code_loaded = true
|
31
|
+
|
32
|
+
res
|
31
33
|
end
|
32
34
|
end
|
33
35
|
|
data/lib/rage/router/backend.rb
CHANGED
@@ -20,7 +20,7 @@ class Rage::Router::Backend
|
|
20
20
|
end
|
21
21
|
|
22
22
|
def mount(path, handler, methods)
|
23
|
-
raise "Mount handler should respond to `call`" unless handler.respond_to?(:call)
|
23
|
+
raise ArgumentError, "Mount handler should respond to `call`" unless handler.respond_to?(:call)
|
24
24
|
|
25
25
|
raw_handler = handler
|
26
26
|
is_sidekiq = handler.respond_to?(:name) && handler.name == "Sidekiq::Web"
|
@@ -52,7 +52,7 @@ class Rage::Router::Backend
|
|
52
52
|
raise "Path could not be empty" if path&.empty?
|
53
53
|
|
54
54
|
if match_index = (path =~ OPTIONAL_PARAM_REGEXP)
|
55
|
-
raise "Optional Parameter has to be the last parameter of the path" if path.length != match_index + $&.length
|
55
|
+
raise ArgumentError, "Optional Parameter has to be the last parameter of the path" if path.length != match_index + $&.length
|
56
56
|
|
57
57
|
path_full = path.sub(OPTIONAL_PARAM_REGEXP, "/#{$1}")
|
58
58
|
path_optional = path.sub(OPTIONAL_PARAM_REGEXP, "")
|
@@ -65,7 +65,7 @@ class Rage::Router::Backend
|
|
65
65
|
meta = { raw_handler: handler }
|
66
66
|
|
67
67
|
if handler.is_a?(String)
|
68
|
-
raise "Invalid route handler format, expected to match the 'controller#action' pattern" unless handler =~ STRING_HANDLER_REGEXP
|
68
|
+
raise ArgumentError, "Invalid route handler format, expected to match the 'controller#action' pattern" unless handler =~ STRING_HANDLER_REGEXP
|
69
69
|
|
70
70
|
controller, action = Rage::Router::Util.path_to_class($1), $2
|
71
71
|
|
@@ -81,7 +81,7 @@ class Rage::Router::Backend
|
|
81
81
|
handler = ->(_, _) { [404, { "X-Cascade" => "pass" }, []] }
|
82
82
|
end
|
83
83
|
else
|
84
|
-
raise "Non-string route handler should respond to `call`" unless handler.respond_to?(:call)
|
84
|
+
raise ArgumentError, "Non-string route handler should respond to `call`" unless handler.respond_to?(:call)
|
85
85
|
# while regular handlers are expected to be called with the `env` and `params` objects,
|
86
86
|
# lambda handlers expect just `env` as an argument;
|
87
87
|
# TODO: come up with something nicer?
|
@@ -189,7 +189,7 @@ class Rage::Router::Backend
|
|
189
189
|
params << "*"
|
190
190
|
current_node = current_node.create_wildcard_child
|
191
191
|
parent_node_path_index = i + 1
|
192
|
-
raise "Wildcard must be the last character in the route" if i != pattern.length - 1
|
192
|
+
raise ArgumentError, "Wildcard must be the last character in the route" if i != pattern.length - 1
|
193
193
|
end
|
194
194
|
|
195
195
|
i += 1
|
@@ -205,7 +205,7 @@ class Rage::Router::Backend
|
|
205
205
|
existing_route[:pattern] == pattern &&
|
206
206
|
existing_route[:constraints] == constraints
|
207
207
|
)
|
208
|
-
raise "Method '#{method}' already declared for route '#{pattern}' with constraints '#{constraints.inspect}'"
|
208
|
+
raise ArgumentError, "Method '#{method}' already declared for route '#{pattern}' with constraints '#{constraints.inspect}'"
|
209
209
|
end
|
210
210
|
end
|
211
211
|
|
@@ -45,14 +45,14 @@ class Rage::Router::Constrainer
|
|
45
45
|
end
|
46
46
|
|
47
47
|
def new_store_for_constraint(constraint)
|
48
|
-
raise "No strategy registered for constraint key '#{constraint}'" unless @strategies[constraint]
|
48
|
+
raise ArgumentError, "No strategy registered for constraint key '#{constraint}'" unless @strategies[constraint]
|
49
49
|
@strategies[constraint].storage
|
50
50
|
end
|
51
51
|
|
52
52
|
def validate_constraints(constraints)
|
53
53
|
constraints.each do |key, value|
|
54
54
|
strategy = @strategies[key]
|
55
|
-
raise "No strategy registered for constraint key '#{key}'" unless strategy
|
55
|
+
raise ArgumentError, "No strategy registered for constraint key '#{key}'" unless strategy
|
56
56
|
|
57
57
|
strategy.validate(value)
|
58
58
|
end
|
@@ -73,7 +73,7 @@ class Rage::Router::Constrainer
|
|
73
73
|
if key == :host
|
74
74
|
lines << " host: env['HTTP_HOST'.freeze],"
|
75
75
|
else
|
76
|
-
raise 'unknown non-custom strategy for compiling constraint derivation function'
|
76
|
+
raise ArgumentError, 'unknown non-custom strategy for compiling constraint derivation function'
|
77
77
|
end
|
78
78
|
else
|
79
79
|
lines << " #{strategy.name}: @strategies[#{key}].derive_constraint(env),"
|
data/lib/rage/router/dsl.rb
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative "dsl_plugins/legacy_hash_notation"
|
4
|
+
require_relative "dsl_plugins/legacy_root_notation"
|
5
|
+
require_relative "dsl_plugins/named_route_helpers"
|
6
|
+
require_relative "dsl_plugins/controller_action_options"
|
7
|
+
|
3
8
|
class Rage::Router::DSL
|
4
9
|
def initialize(router)
|
5
10
|
@router = router
|
@@ -47,6 +52,11 @@ class Rage::Router::DSL
|
|
47
52
|
# resources :posts
|
48
53
|
# end
|
49
54
|
class Handler
|
55
|
+
prepend Rage::Router::DSLPlugins::ControllerActionOptions
|
56
|
+
prepend Rage::Router::DSLPlugins::NamedRouteHelpers
|
57
|
+
prepend Rage::Router::DSLPlugins::LegacyHashNotation
|
58
|
+
prepend Rage::Router::DSLPlugins::LegacyRootNotation
|
59
|
+
|
50
60
|
# @private
|
51
61
|
def initialize(router)
|
52
62
|
@router = router
|
@@ -67,12 +77,13 @@ class Rage::Router::DSL
|
|
67
77
|
# @param to [String] the route handler in the format of "controller#action"
|
68
78
|
# @param constraints [Hash] a hash of constraints for the route
|
69
79
|
# @param defaults [Hash] a hash of default parameters for the route
|
80
|
+
# @param on [nil, :member, :collection] a shorthand for wrapping routes in a specific RESTful context
|
70
81
|
# @example
|
71
82
|
# get "/photos/:id", to: "photos#show", constraints: { host: /myhost/ }
|
72
83
|
# @example
|
73
84
|
# get "/photos(/:id)", to: "photos#show", defaults: { id: "-1" }
|
74
|
-
def get(path, to: nil, constraints: nil, defaults: nil)
|
75
|
-
__on("GET", path, to, constraints, defaults)
|
85
|
+
def get(path, to: nil, constraints: nil, defaults: nil, on: nil)
|
86
|
+
__with_on_scope(on) { __on("GET", path, to, constraints, defaults) }
|
76
87
|
end
|
77
88
|
|
78
89
|
# Register a new POST route.
|
@@ -81,12 +92,13 @@ class Rage::Router::DSL
|
|
81
92
|
# @param to [String] the route handler in the format of "controller#action"
|
82
93
|
# @param constraints [Hash] a hash of constraints for the route
|
83
94
|
# @param defaults [Hash] a hash of default parameters for the route
|
95
|
+
# @param on [nil, :member, :collection] a shorthand for wrapping routes in a specific RESTful context
|
84
96
|
# @example
|
85
97
|
# post "/photos", to: "photos#create", constraints: { host: /myhost/ }
|
86
98
|
# @example
|
87
99
|
# post "/photos", to: "photos#create", defaults: { format: "jpg" }
|
88
|
-
def post(path, to: nil, constraints: nil, defaults: nil)
|
89
|
-
__on("POST", path, to, constraints, defaults)
|
100
|
+
def post(path, to: nil, constraints: nil, defaults: nil, on: nil)
|
101
|
+
__with_on_scope(on) { __on("POST", path, to, constraints, defaults) }
|
90
102
|
end
|
91
103
|
|
92
104
|
# Register a new PUT route.
|
@@ -95,12 +107,13 @@ class Rage::Router::DSL
|
|
95
107
|
# @param to [String] the route handler in the format of "controller#action"
|
96
108
|
# @param constraints [Hash] a hash of constraints for the route
|
97
109
|
# @param defaults [Hash] a hash of default parameters for the route
|
110
|
+
# @param on [nil, :member, :collection] a shorthand for wrapping routes in a specific RESTful context
|
98
111
|
# @example
|
99
112
|
# put "/photos/:id", to: "photos#update", constraints: { host: /myhost/ }
|
100
113
|
# @example
|
101
114
|
# put "/photos(/:id)", to: "photos#update", defaults: { id: "-1" }
|
102
|
-
def put(path, to: nil, constraints: nil, defaults: nil)
|
103
|
-
__on("PUT", path, to, constraints, defaults)
|
115
|
+
def put(path, to: nil, constraints: nil, defaults: nil, on: nil)
|
116
|
+
__with_on_scope(on) { __on("PUT", path, to, constraints, defaults) }
|
104
117
|
end
|
105
118
|
|
106
119
|
# Register a new PATCH route.
|
@@ -109,12 +122,13 @@ class Rage::Router::DSL
|
|
109
122
|
# @param to [String] the route handler in the format of "controller#action"
|
110
123
|
# @param constraints [Hash] a hash of constraints for the route
|
111
124
|
# @param defaults [Hash] a hash of default parameters for the route
|
125
|
+
# @param on [nil, :member, :collection] a shorthand for wrapping routes in a specific RESTful context
|
112
126
|
# @example
|
113
127
|
# patch "/photos/:id", to: "photos#update", constraints: { host: /myhost/ }
|
114
128
|
# @example
|
115
129
|
# patch "/photos(/:id)", to: "photos#update", defaults: { id: "-1" }
|
116
|
-
def patch(path, to: nil, constraints: nil, defaults: nil)
|
117
|
-
__on("PATCH", path, to, constraints, defaults)
|
130
|
+
def patch(path, to: nil, constraints: nil, defaults: nil, on: nil)
|
131
|
+
__with_on_scope(on) { __on("PATCH", path, to, constraints, defaults) }
|
118
132
|
end
|
119
133
|
|
120
134
|
# Register a new DELETE route.
|
@@ -123,12 +137,13 @@ class Rage::Router::DSL
|
|
123
137
|
# @param to [String] the route handler in the format of "controller#action"
|
124
138
|
# @param constraints [Hash] a hash of constraints for the route
|
125
139
|
# @param defaults [Hash] a hash of default parameters for the route
|
140
|
+
# @param on [nil, :member, :collection] a shorthand for wrapping routes in a specific RESTful context
|
126
141
|
# @example
|
127
142
|
# delete "/photos/:id", to: "photos#destroy", constraints: { host: /myhost/ }
|
128
143
|
# @example
|
129
144
|
# delete "/photos(/:id)", to: "photos#destroy", defaults: { id: "-1" }
|
130
|
-
def delete(path, to: nil, constraints: nil, defaults: nil)
|
131
|
-
__on("DELETE", path, to, constraints, defaults)
|
145
|
+
def delete(path, to: nil, constraints: nil, defaults: nil, on: nil)
|
146
|
+
__with_on_scope(on) { __on("DELETE", path, to, constraints, defaults) }
|
132
147
|
end
|
133
148
|
|
134
149
|
# Register a new route pointing to '/'.
|
@@ -207,9 +222,9 @@ class Rage::Router::DSL
|
|
207
222
|
# Scopes a set of routes to the given default options.
|
208
223
|
#
|
209
224
|
# @param [Hash] opts scope options.
|
210
|
-
# @option opts [String] :module
|
211
|
-
# @option opts [String] :path path
|
212
|
-
# @option opts [String] :controller controller
|
225
|
+
# @option opts [String] :module the namespace for the controller
|
226
|
+
# @option opts [String] :path the path prefix for the routes
|
227
|
+
# @option opts [String] :controller scopes routes to a specific controller
|
213
228
|
# @example Route `/photos` to `Api::PhotosController`
|
214
229
|
# scope module: "api" do
|
215
230
|
# get "photos", to: "photos#index"
|
@@ -309,6 +324,12 @@ class Rage::Router::DSL
|
|
309
324
|
|
310
325
|
# Automatically create REST routes for a resource.
|
311
326
|
#
|
327
|
+
# @param [Hash] opts resource options
|
328
|
+
# @option opts [String] :module the namespace for the controller
|
329
|
+
# @option opts [String] :path the path prefix for the routes
|
330
|
+
# @option opts [Symbol, Array<Symbol>] :only only generate routes for the given actions
|
331
|
+
# @option opts [Symbol, Array<Symbol>] :except generate all routes except for the given actions
|
332
|
+
# @option opts [String] :param overrides the default param name of `:id` in the URL
|
312
333
|
# @example Create five REST routes, all mapping to the `Photos` controller:
|
313
334
|
# resources :photos
|
314
335
|
# # GET /photos => photos#index
|
@@ -325,7 +346,7 @@ class Rage::Router::DSL
|
|
325
346
|
end
|
326
347
|
|
327
348
|
_module, _path, _only, _except, _param = opts.values_at(:module, :path, :only, :except, :param)
|
328
|
-
raise ":param option can't contain colons" if _param.to_s.include?(":")
|
349
|
+
raise ArgumentError, ":param option can't contain colons" if _param.to_s.include?(":")
|
329
350
|
|
330
351
|
_only = Array(_only) if _only
|
331
352
|
_except = Array(_except) if _except
|
@@ -358,17 +379,7 @@ class Rage::Router::DSL
|
|
358
379
|
# mount Sidekiq::Web => "/sidekiq"
|
359
380
|
# @example
|
360
381
|
# mount Sidekiq::Web, at: "/sidekiq", via: :get
|
361
|
-
def mount(
|
362
|
-
if args.first.is_a?(Hash)
|
363
|
-
app = args.first.keys.first
|
364
|
-
at = args.first.values.first
|
365
|
-
via = args[0][:via]
|
366
|
-
else
|
367
|
-
app = args.first
|
368
|
-
at = args[1][:at]
|
369
|
-
via = args[1][:via]
|
370
|
-
end
|
371
|
-
|
382
|
+
def mount(app, at:, via: :all)
|
372
383
|
at = "/#{at}" unless at.start_with?("/")
|
373
384
|
at = at.delete_suffix("/") if at.end_with?("/")
|
374
385
|
|
@@ -395,7 +406,7 @@ class Rage::Router::DSL
|
|
395
406
|
if @controllers.any?
|
396
407
|
to = "#{@controllers.last}##{path}"
|
397
408
|
else
|
398
|
-
raise "Missing :to key on routes definition, please check your routes."
|
409
|
+
raise ArgumentError, "Missing :to key on routes definition, please check your routes."
|
399
410
|
end
|
400
411
|
end
|
401
412
|
|
@@ -421,6 +432,19 @@ class Rage::Router::DSL
|
|
421
432
|
end
|
422
433
|
end
|
423
434
|
|
435
|
+
def __with_on_scope(on, &block)
|
436
|
+
case on
|
437
|
+
when nil
|
438
|
+
block.call
|
439
|
+
when :member
|
440
|
+
member(&block)
|
441
|
+
when :collection
|
442
|
+
collection(&block)
|
443
|
+
else
|
444
|
+
raise ArgumentError, "Unknown scope :#{on} given to :on"
|
445
|
+
end
|
446
|
+
end
|
447
|
+
|
424
448
|
def to_singular(str)
|
425
449
|
@active_support_loaded ||= str.respond_to?(:singularize) || :false
|
426
450
|
return str.singularize if @active_support_loaded != :false
|
@@ -0,0 +1,25 @@
|
|
1
|
+
##
|
2
|
+
# Support the `:controller` and `:action` options.
|
3
|
+
#
|
4
|
+
# @example
|
5
|
+
# get :admins, controller: :users
|
6
|
+
# @example
|
7
|
+
# post :search, action: :index
|
8
|
+
module Rage::Router::DSLPlugins::ControllerActionOptions
|
9
|
+
%i(get post put patch delete).each do |action_name|
|
10
|
+
define_method(action_name) do |*args, **kwargs|
|
11
|
+
if args.length == 1 && !kwargs.has_key?(:to) && (kwargs.has_key?(:controller) || kwargs.has_key?(:action))
|
12
|
+
path = args[0]
|
13
|
+
controller = kwargs.delete(:controller) || @controllers.last || raise(ArgumentError, "Could not derive the controller value from the route definitions")
|
14
|
+
action = kwargs.delete(:action) || path.split("/").last
|
15
|
+
end
|
16
|
+
|
17
|
+
if controller && action
|
18
|
+
kwargs[:to] = "#{controller}##{action}"
|
19
|
+
super(path, **kwargs)
|
20
|
+
else
|
21
|
+
super(*args, **kwargs)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
##
|
2
|
+
# Support legacy URL helpers that use hashes instead of the `:to` keyword argument.
|
3
|
+
#
|
4
|
+
# @example
|
5
|
+
# get "/photos/:id" => "photos#show"
|
6
|
+
# @example
|
7
|
+
# mount Sidekiq::Web => "/sidekiq"
|
8
|
+
# @example
|
9
|
+
# get "search" => :index
|
10
|
+
# @example
|
11
|
+
# get "admin_users" => "users"
|
12
|
+
module Rage::Router::DSLPlugins::LegacyHashNotation
|
13
|
+
%i(get post put patch delete).each do |action_name|
|
14
|
+
define_method(action_name) do |*args, **kwargs|
|
15
|
+
if args.empty? && !kwargs.empty?
|
16
|
+
path, handler = kwargs.first
|
17
|
+
|
18
|
+
to = if handler.is_a?(Symbol)
|
19
|
+
raise ArgumentError, "Could not derive the controller value from the route definitions" if @controllers.empty?
|
20
|
+
"#{@controllers.last}##{handler}"
|
21
|
+
elsif handler.is_a?(String) && !handler.include?("#")
|
22
|
+
"#{handler}##{path.split("/").last}"
|
23
|
+
elsif handler.is_a?(String)
|
24
|
+
handler
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
if path && to
|
29
|
+
options = kwargs.except(path).merge(to: to)
|
30
|
+
super(path, **options)
|
31
|
+
else
|
32
|
+
super(*args, **kwargs)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def mount(*args, **kwargs)
|
38
|
+
if args.empty? && !kwargs.empty?
|
39
|
+
app, at = kwargs.first
|
40
|
+
options = kwargs.except(app).merge(at: at)
|
41
|
+
super(app, **options)
|
42
|
+
else
|
43
|
+
super(*args, **kwargs)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
##
|
2
|
+
# Support legacy root helpers that don't use the `:to` keyword argument.
|
3
|
+
#
|
4
|
+
# @example
|
5
|
+
# root "photos#index"
|
6
|
+
module Rage::Router::DSLPlugins::LegacyRootNotation
|
7
|
+
def root(*args, **kwargs)
|
8
|
+
if args.length == 1 && args[0].is_a?(String) && kwargs.empty?
|
9
|
+
super(to: args[0])
|
10
|
+
else
|
11
|
+
super(*args, **kwargs)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
##
|
2
|
+
# Support the `as` option. As Rage currently doesn't generate named route helpers, we simply ignore it.
|
3
|
+
#
|
4
|
+
# @example
|
5
|
+
# get "/photos/:id", to: "photos#show", as: :user_photos
|
6
|
+
module Rage::Router::DSLPlugins::NamedRouteHelpers
|
7
|
+
%i(get post put patch delete).each do |action_name|
|
8
|
+
define_method(action_name) do |*args, **kwargs|
|
9
|
+
kwargs.delete(:as)
|
10
|
+
super(*args, **kwargs)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -35,7 +35,7 @@ class Rage::Router::HandlerStorage
|
|
35
35
|
end
|
36
36
|
|
37
37
|
if @handlers.length >= 32
|
38
|
-
raise "Limit reached: a maximum of 32 route handlers per node allowed when there are constraints"
|
38
|
+
raise ArgumentError, "Limit reached: a maximum of 32 route handlers per node allowed when there are constraints"
|
39
39
|
end
|
40
40
|
|
41
41
|
@handlers << handler_object
|
data/lib/rage/router/util.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class Rage::Router::Util
|
2
4
|
class << self
|
3
5
|
# converts controller name in a path form into a class
|
@@ -40,9 +42,13 @@ class Rage::Router::Util
|
|
40
42
|
|
41
43
|
def call(env)
|
42
44
|
result = @rage_app.call(env)
|
43
|
-
return result if result[0] == :__http_defer__
|
45
|
+
return result if result[0] == :__http_defer__
|
44
46
|
|
45
|
-
|
47
|
+
if result[1]["X-Cascade"] == "pass" || env["PATH_INFO"].start_with?("/rails/")
|
48
|
+
@rails_app.call(env)
|
49
|
+
else
|
50
|
+
result
|
51
|
+
end
|
46
52
|
end
|
47
53
|
end
|
48
54
|
end
|
data/lib/rage/version.rb
CHANGED
data/lib/rage-rb.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rage-rb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Roman Samoilov
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-07-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|
@@ -94,6 +94,7 @@ files:
|
|
94
94
|
- CODE_OF_CONDUCT.md
|
95
95
|
- Gemfile
|
96
96
|
- LICENSE.txt
|
97
|
+
- OVERVIEW.md
|
97
98
|
- README.md
|
98
99
|
- Rakefile
|
99
100
|
- exe/rage
|
@@ -126,6 +127,10 @@ files:
|
|
126
127
|
- lib/rage/router/backend.rb
|
127
128
|
- lib/rage/router/constrainer.rb
|
128
129
|
- lib/rage/router/dsl.rb
|
130
|
+
- lib/rage/router/dsl_plugins/controller_action_options.rb
|
131
|
+
- lib/rage/router/dsl_plugins/legacy_hash_notation.rb
|
132
|
+
- lib/rage/router/dsl_plugins/legacy_root_notation.rb
|
133
|
+
- lib/rage/router/dsl_plugins/named_route_helpers.rb
|
129
134
|
- lib/rage/router/handler_storage.rb
|
130
135
|
- lib/rage/router/node.rb
|
131
136
|
- lib/rage/router/strategies/host.rb
|