rage-rb 1.5.0 → 1.6.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
![overview](https://github.com/rage-rb/rage/assets/2270393/0d45bbe3-622c-4b17-b8d8-552c567fecb3)
|
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
|