rage-rb 1.5.1 → 1.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bef8e2aac71af98b85e2946c5ce14a8869126743cc07a023eb5a051606345968
4
- data.tar.gz: e9ebad8ddc354ed3d21bc466f5bc24b409c95510c22d8664bf47bfbef90da9d8
3
+ metadata.gz: 39c84f49894f7ae6e8c53e78d5c84eef65885c15f3ad7d6469458a79dba6e691
4
+ data.tar.gz: 3a8b37eb48370a2a63c1b78f09417013f60593cdbcf0385958dd495ce35e494c
5
5
  SHA512:
6
- metadata.gz: 3ab1605a8d6c07c9ab155c3b554ae8e51f17f09f02db1edda13c92916a4cddd4e7539c8d24e4a716253d2638c844324de187d527d4f15c733e4a6a34087f8818
7
- data.tar.gz: 3c44ce391e4d9c73f25833437ed3895815c008a4d43c60a933c6c89390e9783366789431d8bb679ca22ee95f879cd6c1bb74bc0b0c853b49975b42272763703b
6
+ metadata.gz: 8db258b1f23a58def4118ca0bdb1efcf6534ff03362ac82c45ded5276c90ab42809e007a9d7f72972dc8fd2597ac5eab2bbfaf27d6efb38a3857b1133fdbecde
7
+ data.tar.gz: eb7a5910f52399ff67bc0bc4078fcc970e023fcc038dc65dd16b19e17afa902a95a7c1b62cca7f61a5f5e38ba45702dc2a314ef841868fd7cf40289a65a0fe0f
data/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
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
+
3
10
  ## [1.5.1] - 2024-05-26
4
11
 
5
12
  ### Fixed
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.
@@ -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
 
@@ -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 [String, nil] the name of the callback to add
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 [String] the name of the callback to skip
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)
@@ -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 = []
@@ -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),"
@@ -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 module option
211
- # @option opts [String] :path path option
212
- # @option opts [String] :controller controller option
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(*args)
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
@@ -18,7 +18,7 @@ class Rage::Router::Strategies::Host
18
18
 
19
19
  def validate(value)
20
20
  if !value.is_a?(String) && !value.is_a?(Regexp)
21
- raise "Host should be a string or a Regexp"
21
+ raise ArgumentError, "Host should be a string or a Regexp"
22
22
  end
23
23
  end
24
24
 
@@ -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__ || result[1]["X-Cascade".freeze] != "pass".freeze
45
+ return result if result[0] == :__http_defer__
44
46
 
45
- @rails_app.call(env)
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Rage
4
- VERSION = "1.5.1"
4
+ VERSION = "1.6.0"
5
5
  end
data/lib/rage-rb.rb CHANGED
@@ -93,6 +93,9 @@ module Rage
93
93
  module Router
94
94
  module Strategies
95
95
  end
96
+
97
+ module DSLPlugins
98
+ end
96
99
  end
97
100
 
98
101
  module Ext
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.5.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-05-26 00:00:00.000000000 Z
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